Browse Source

initial commit

Bastien Sevajol 6 years ago
parent
commit
dd2fde082b
67 changed files with 1259 additions and 32 deletions
  1. 5 32
      .gitignore
  2. 16 0
      config.yaml
  3. 1 0
      opencc/__init__.py
  4. 14 0
      opencc/const.py
  5. 1 0
      opencc/gui/__init__.py
  6. 42 0
      opencc/gui/actor.py
  7. 239 0
      opencc/gui/base.py
  8. 89 0
      opencc/gui/fire.py
  9. 48 0
      opencc/gui/move.py
  10. 140 0
      opencc/maps/003/003.tmx
  11. BIN
      opencc/maps/003/actors/man.png
  12. BIN
      opencc/maps/003/actors/man_c1.png
  13. BIN
      opencc/maps/003/actors/man_c2.png
  14. BIN
      opencc/maps/003/actors/man_c3.png
  15. BIN
      opencc/maps/003/actors/man_c4.png
  16. BIN
      opencc/maps/003/actors/man_d1.png
  17. BIN
      opencc/maps/003/actors/man_w1.png
  18. BIN
      opencc/maps/003/actors/man_w10.png
  19. BIN
      opencc/maps/003/actors/man_w2.png
  20. BIN
      opencc/maps/003/actors/man_w3.png
  21. BIN
      opencc/maps/003/actors/man_w4.png
  22. BIN
      opencc/maps/003/actors/man_w5.png
  23. BIN
      opencc/maps/003/actors/man_w6.png
  24. BIN
      opencc/maps/003/actors/man_w7.png
  25. BIN
      opencc/maps/003/actors/man_w8.png
  26. BIN
      opencc/maps/003/actors/man_w9.png
  27. BIN
      opencc/maps/003/background.png
  28. BIN
      opencc/maps/003/terrain.png
  29. 22 0
      opencc/maps/003/terrain.tsx
  30. BIN
      opencc/maps/003/trees_64x64.png
  31. 4 0
      opencc/maps/003/trees_64x64.tsx
  32. 23 0
      opencc/maps/004/004.tmx
  33. BIN
      opencc/maps/004/actors/man.png
  34. BIN
      opencc/maps/004/actors/man_c1.png
  35. BIN
      opencc/maps/004/actors/man_c2.png
  36. BIN
      opencc/maps/004/actors/man_c3.png
  37. BIN
      opencc/maps/004/actors/man_c4.png
  38. BIN
      opencc/maps/004/actors/man_w1.png
  39. BIN
      opencc/maps/004/actors/man_w10.png
  40. BIN
      opencc/maps/004/actors/man_w2.png
  41. BIN
      opencc/maps/004/actors/man_w3.png
  42. BIN
      opencc/maps/004/actors/man_w4.png
  43. BIN
      opencc/maps/004/actors/man_w5.png
  44. BIN
      opencc/maps/004/actors/man_w6.png
  45. BIN
      opencc/maps/004/actors/man_w7.png
  46. BIN
      opencc/maps/004/actors/man_w8.png
  47. BIN
      opencc/maps/004/actors/man_w9.png
  48. BIN
      opencc/maps/004/background.png
  49. BIN
      opencc/maps/004/terrain.png
  50. 18 0
      opencc/maps/004/terrain.tsx
  51. BIN
      opencc/maps/004/trees_64x64.png
  52. 4 0
      opencc/maps/004/trees_64x64.tsx
  53. 1 0
      opencc/simulation/__init__.py
  54. 42 0
      opencc/simulation/base.py
  55. 154 0
      opencc/simulation/behaviour.py
  56. 47 0
      opencc/simulation/event.py
  57. 39 0
      opencc/simulation/fire.py
  58. 16 0
      opencc/simulation/mechanism.py
  59. 80 0
      opencc/simulation/physics.py
  60. 22 0
      opencc/simulation/subject.py
  61. 16 0
      opencc/simulation/tmx.py
  62. BIN
      opencc/sounds/204010__duckduckpony__homemade-gunshot-2.ogg
  63. 1 0
      opencc/terminal/__init__.py
  64. 53 0
      opencc/terminal/base.py
  65. 9 0
      opencc/user_action.py
  66. 17 0
      requirements.txt
  67. 96 0
      run.py

+ 5 - 32
.gitignore View File

@@ -8,7 +8,7 @@ __pycache__/
8 8
 
9 9
 # Distribution / packaging
10 10
 .Python
11
-env/
11
+venv/
12 12
 build/
13 13
 develop-eggs/
14 14
 dist/
@@ -50,52 +50,25 @@ coverage.xml
50 50
 *.mo
51 51
 *.pot
52 52
 
53
-# Django stuff:
54
-*.log
55
-local_settings.py
56
-
57
-# Flask stuff:
58
-instance/
59
-.webassets-cache
60
-
61
-# Scrapy stuff:
62
-.scrapy
63
-
64 53
 # Sphinx documentation
65 54
 docs/_build/
66 55
 
56
+# Pycharm
57
+.idea
58
+
67 59
 # PyBuilder
68 60
 target/
69 61
 
70
-# Jupyter Notebook
71
-.ipynb_checkpoints
72
-
73 62
 # pyenv
74 63
 .python-version
75 64
 
76
-# celery beat schedule file
77
-celerybeat-schedule
78
-
79
-# SageMath parsed files
80
-*.sage.py
81
-
82 65
 # dotenv
83 66
 .env
84 67
 
85 68
 # virtualenv
86 69
 .venv
87
-venv/
70
+/venv*/
88 71
 ENV/
89 72
 
90
-# Spyder project settings
91
-.spyderproject
92
-.spyproject
93
-
94
-# Rope project settings
95
-.ropeproject
96
-
97
-# mkdocs documentation
98
-/site
99
-
100 73
 # mypy
101 74
 .mypy_cache/

+ 16 - 0
config.yaml View File

@@ -0,0 +1,16 @@
1
+core:
2
+    cycle_duration: 0.25
3
+    use_x_cores: 2
4
+terminals:
5
+    sync: True
6
+game:
7
+    look_around:
8
+        frequency: 1
9
+    engage:
10
+        frequency: 1
11
+    move:
12
+        walk_ref_time: 3
13
+        run_ref_time: 1
14
+        crawl_ref_time: 10
15
+global:
16
+    debug: true

+ 1 - 0
opencc/__init__.py View File

@@ -0,0 +1 @@
1
+# coding: utf-8

+ 14 - 0
opencc/const.py View File

@@ -0,0 +1,14 @@
1
+# coding: utf-8
2
+
3
+COLLECTION_ALIVE = 'ALIVE'
4
+
5
+FLAG = 'FLAG'
6
+FLAG_DE = 'DE'
7
+FLAG_URSS = 'URSS'
8
+
9
+SIDE = 'SIDE'
10
+COMBAT_MODE = 'COMBAT_MODE'
11
+COMBAT_MODE_DEFENSE = 'COMBAT_MODE_DEFENSE'
12
+
13
+DE_COLOR = (0, 81, 211)
14
+URSS_COLOR = (204, 0, 0)

+ 1 - 0
opencc/gui/__init__.py View File

@@ -0,0 +1 @@
1
+# coding: utf-8

+ 42 - 0
opencc/gui/actor.py View File

@@ -0,0 +1,42 @@
1
+# coding: utf-8
2
+import pyglet
3
+
4
+from synergine2.simulation import Subject
5
+from synergine2_cocos2d.actor import Actor
6
+from synergine2_cocos2d.animation import ANIMATION_WALK
7
+from synergine2_cocos2d.animation import ANIMATION_CRAWL
8
+
9
+
10
+FLAG_DE = 'DE'
11
+FLAG_URSS = 'URSS'
12
+
13
+FLAG_COLORS = {
14
+    FLAG_DE
15
+}
16
+
17
+
18
+class Man(Actor):
19
+    animation_image_paths = {
20
+        ANIMATION_WALK: [
21
+            'actors/man.png',
22
+            'actors/man_w1.png',
23
+            'actors/man_w2.png',
24
+            'actors/man_w3.png',
25
+            'actors/man_w4.png',
26
+            'actors/man_w5.png',
27
+            'actors/man_w6.png',
28
+            'actors/man_w7.png',
29
+        ],
30
+        ANIMATION_CRAWL: [
31
+            'actors/man_c1.png',
32
+            'actors/man_c2.png',
33
+            'actors/man_c3.png',
34
+            'actors/man_c4.png',
35
+        ]
36
+    }
37
+
38
+    def __init__(
39
+        self,
40
+        subject: Subject,
41
+    ) -> None:
42
+        super().__init__(pyglet.resource.image('actors/man.png'), subject=subject)

+ 239 - 0
opencc/gui/base.py View File

@@ -0,0 +1,239 @@
1
+# coding: utf-8
2
+import os
3
+import random
4
+import typing
5
+
6
+import pyglet
7
+from pyglet.window import key
8
+
9
+from cocos.actions import MoveTo as BaseMoveTo
10
+from cocos.audio.pygame.mixer import Sound
11
+from opencc.user_action import UserAction
12
+from synergine2.config import Config
13
+from synergine2.log import SynergineLogger
14
+from synergine2.terminals import Terminal
15
+from synergine2_cocos2d.actions import MoveTo
16
+from synergine2_cocos2d.animation import ANIMATION_CRAWL
17
+from synergine2_cocos2d.animation import ANIMATION_WALK
18
+from synergine2_cocos2d.animation import Animate
19
+from synergine2_cocos2d.gl import draw_line
20
+from synergine2_cocos2d.gui import EditLayer as BaseEditLayer
21
+from synergine2_cocos2d.gui import TMXGui
22
+from synergine2_cocos2d.layer import LayerManager
23
+from synergine2_xyz.move.simulation import FinishMoveEvent
24
+from synergine2_xyz.move.simulation import StartMoveEvent
25
+from synergine2_xyz.physics import Physics
26
+from synergine2_xyz.utils import get_angle
27
+from opencc.simulation.event import NewVisibleOpponent
28
+from opencc.simulation.event import NoLongerVisibleOpponent
29
+from opencc.simulation.event import FireEvent
30
+from opencc.simulation.event import DieEvent
31
+
32
+
33
+class EditLayer(BaseEditLayer):
34
+    def __init__(self, *args, **kwargs) -> None:
35
+        super().__init__(*args, **kwargs)
36
+
37
+    def _on_key_press(self, k, m):
38
+        if self.selection:
39
+            if k == key.M:
40
+                self.user_action_pending = UserAction.ORDER_MOVE
41
+            if k == key.R:
42
+                self.user_action_pending = UserAction.ORDER_MOVE_FAST
43
+            if k == key.C:
44
+                self.user_action_pending = UserAction.ORDER_MOVE_CRAWL
45
+            if k == key.F:
46
+                self.user_action_pending = UserAction.ORDER_FIRE
47
+
48
+
49
+class TileLayerManager(LayerManager):
50
+    edit_layer_class = EditLayer
51
+
52
+
53
+# TODO: Move into synergine2cocos2d
54
+class AudioLibrary(object):
55
+    sound_file_paths = {
56
+        'gunshot_default': '204010__duckduckpony__homemade-gunshot-2.ogg',
57
+    }
58
+
59
+    def __init__(self, sound_dir_path: str) -> None:
60
+        self._sound_dir_path = sound_dir_path
61
+        self._sounds = {}
62
+
63
+    def get_sound(self, name: str) -> Sound:
64
+        if name not in self._sounds:
65
+            sound_file_name = self.sound_file_paths[name]
66
+            self._sounds[name] = Sound(os.path.join(self._sound_dir_path, sound_file_name))
67
+        return self._sounds[name]
68
+
69
+
70
+class Game(TMXGui):
71
+    layer_manager_class = TileLayerManager
72
+
73
+    def __init__(
74
+        self,
75
+        config: Config,
76
+        logger: SynergineLogger,
77
+        terminal: Terminal,
78
+        physics: Physics,
79
+        read_queue_interval: float = 1 / 60.0,
80
+        map_dir_path: str=None,
81
+    ):
82
+        super().__init__(
83
+            config,
84
+            logger,
85
+            terminal,
86
+            physics=physics,
87
+            read_queue_interval=read_queue_interval,
88
+            map_dir_path=map_dir_path,
89
+        )
90
+        self.sound_lib = AudioLibrary('opencc/sounds/')
91
+
92
+        self.terminal.register_event_handler(
93
+            FinishMoveEvent,
94
+            self.set_subject_position,
95
+        )
96
+
97
+        self.terminal.register_event_handler(
98
+            StartMoveEvent,
99
+            self.start_move_subject,
100
+        )
101
+
102
+        self.terminal.register_event_handler(
103
+            NewVisibleOpponent,
104
+            self.new_visible_opponent,
105
+        )
106
+
107
+        self.terminal.register_event_handler(
108
+            NoLongerVisibleOpponent,
109
+            self.no_longer_visible_opponent,
110
+        )
111
+
112
+        self.terminal.register_event_handler(
113
+            FireEvent,
114
+            self.fire_happen,
115
+        )
116
+
117
+        self.terminal.register_event_handler(
118
+            DieEvent,
119
+            self.subject_die,
120
+        )
121
+
122
+        # configs
123
+        self.move_duration_ref = float(self.config.resolve('game.move.walk_ref_time'))
124
+        self.move_fast_duration_ref = float(self.config.resolve('game.move.run_ref_time'))
125
+        self.move_crawl_duration_ref = float(self.config.resolve('game.move.crawl_ref_time'))
126
+
127
+    def before_run(self) -> None:
128
+        from opencc.gui.move import MoveActorInteraction
129
+        from opencc.gui.move import MoveFastActorInteraction
130
+        from opencc.gui.move import MoveCrawlActorInteraction
131
+        from opencc.gui.fire import FireActorInteraction
132
+
133
+        self.layer_manager.interaction_manager.register(MoveActorInteraction, self.layer_manager)
134
+        self.layer_manager.interaction_manager.register(MoveFastActorInteraction, self.layer_manager)
135
+        self.layer_manager.interaction_manager.register(MoveCrawlActorInteraction, self.layer_manager)
136
+        self.layer_manager.interaction_manager.register(FireActorInteraction, self.layer_manager)
137
+
138
+    def set_subject_position(self, event: FinishMoveEvent):
139
+        actor = self.layer_manager.subject_layer.subjects_index[event.subject_id]
140
+        new_world_position = self.layer_manager.grid_manager.get_world_position_of_grid_position(event.to_position)
141
+
142
+        actor.stop_actions((BaseMoveTo,))
143
+        actor.set_position(*new_world_position)
144
+
145
+    def start_move_subject(self, event: StartMoveEvent):
146
+        actor = self.layer_manager.subject_layer.subjects_index[event.subject_id]
147
+        new_world_position = self.layer_manager.grid_manager.get_world_position_of_grid_position(event.to_position)
148
+
149
+        if event.gui_action == UserAction.ORDER_MOVE:
150
+            animation = ANIMATION_WALK
151
+            cycle_duration = 2
152
+            move_duration = self.move_duration_ref
153
+        elif event.gui_action == UserAction.ORDER_MOVE_FAST:
154
+            animation = ANIMATION_WALK
155
+            cycle_duration = 0.5
156
+            move_duration = self.move_fast_duration_ref
157
+        elif event.gui_action == UserAction.ORDER_MOVE_CRAWL:
158
+            animation = ANIMATION_CRAWL
159
+            cycle_duration = 2
160
+            move_duration = self.move_crawl_duration_ref
161
+        else:
162
+            raise NotImplementedError()
163
+
164
+        move_action = MoveTo(new_world_position, move_duration)
165
+        actor.do(move_action)
166
+        actor.do(Animate(animation, duration=move_duration, cycle_duration=cycle_duration))
167
+        actor.rotation = get_angle(event.from_position, event.to_position)
168
+
169
+    def new_visible_opponent(self, event: NewVisibleOpponent):
170
+        self.visible_or_no_longer_visible_opponent(event, (153, 0, 153))
171
+
172
+    def no_longer_visible_opponent(self, event: NoLongerVisibleOpponent):
173
+        self.visible_or_no_longer_visible_opponent(event, (255, 102, 0))
174
+
175
+    def visible_or_no_longer_visible_opponent(
176
+        self,
177
+        event: typing.Union[NoLongerVisibleOpponent, NewVisibleOpponent],
178
+        line_color,
179
+    ) -> None:
180
+        if self.layer_manager.debug:
181
+            observer_actor = self.layer_manager.subject_layer.subjects_index[event.observer_subject_id]
182
+            observed_actor = self.layer_manager.subject_layer.subjects_index[event.observed_subject_id]
183
+
184
+            observer_pixel_position = self.layer_manager.scrolling_manager.world_to_screen(
185
+                *self.layer_manager.grid_manager.get_world_position_of_grid_position(
186
+                    observer_actor.subject.position,
187
+                )
188
+            )
189
+            observed_pixel_position = self.layer_manager.scrolling_manager.world_to_screen(
190
+                *self.layer_manager.grid_manager.get_world_position_of_grid_position(
191
+                    observed_actor.subject.position,
192
+                )
193
+            )
194
+
195
+            def draw_visible_opponent():
196
+                draw_line(
197
+                    observer_pixel_position,
198
+                    observed_pixel_position,
199
+                    line_color,
200
+                )
201
+
202
+            # TODO: Not in edit layer !
203
+            self.layer_manager.edit_layer.append_callback(draw_visible_opponent, 1.0)
204
+
205
+    def fire_happen(self, event: FireEvent) -> None:
206
+        # TODO: Not in edit layer !
207
+        shooter_actor = self.layer_manager.subject_layer.subjects_index[event.shooter_subject_id]
208
+        shooter_pixel_position = self.layer_manager.scrolling_manager.world_to_screen(
209
+            *self.layer_manager.grid_manager.get_world_position_of_grid_position(
210
+                shooter_actor.subject.position,
211
+            )
212
+        )
213
+        fire_to_pixel_position = self.layer_manager.scrolling_manager.world_to_screen(
214
+            *self.layer_manager.grid_manager.get_world_position_of_grid_position(
215
+                event.target_position,
216
+            )
217
+        )
218
+
219
+        def gunshot_trace():
220
+            draw_line(
221
+                shooter_pixel_position,
222
+                fire_to_pixel_position,
223
+                color=(255, 0, 0),
224
+            )
225
+
226
+        def gunshot_sound():
227
+            self.sound_lib.get_sound('gunshot_default').play()
228
+
229
+        # To avoid all in same time
230
+        delay = random.uniform(0.0, 0.6)
231
+
232
+        self.layer_manager.edit_layer.append_callback(gunshot_trace, duration=0.1, delay=delay)
233
+        self.layer_manager.edit_layer.append_callback(gunshot_sound, duration=0.0, delay=delay)
234
+
235
+    def subject_die(self, event: DieEvent) -> None:
236
+        killed_actor = self.layer_manager.subject_layer.subjects_index[event.shoot_subject_id]
237
+        dead_image = pyglet.resource.image('opencc/maps/003/actors/man_d1.png')
238
+        killed_actor.update_image(dead_image)
239
+        killed_actor.freeze()

+ 89 - 0
opencc/gui/fire.py View File

@@ -0,0 +1,89 @@
1
+# coding: utf-8
2
+import typing
3
+
4
+from opencc.simulation.fire import RequestFireBehaviour
5
+from synergine2_cocos2d.interaction import BaseActorInteraction
6
+from opencc.user_action import UserAction
7
+from synergine2.simulation import SimulationBehaviour
8
+from synergine2_cocos2d.actor import Actor
9
+from synergine2_cocos2d.gl import draw_line
10
+
11
+
12
+class BaseFireActorInteraction(BaseActorInteraction):
13
+    gui_action = None
14
+    color = None
15
+    not_visible_color = (0, 0, 0)
16
+    request_move_behaviour_class = RequestFireBehaviour
17
+
18
+    def draw_pending(self) -> None:
19
+        for actor in self.layer_manager.edit_layer.selection:
20
+            actor_grid_position = self.layer_manager.grid_manager.get_grid_position(actor.position)
21
+            actor_pixel_position = self.layer_manager.grid_manager.get_world_position_of_grid_position(
22
+                actor_grid_position,
23
+            )
24
+            mouse_grid_position = self.layer_manager.grid_manager.get_grid_position(
25
+                self.layer_manager.scrolling_manager.screen_to_world(
26
+                    *self.layer_manager.edit_layer.screen_mouse,
27
+                )
28
+            )
29
+            draw_to_pixel = self.layer_manager.edit_layer.screen_mouse
30
+
31
+            obstacle_grid_position = self.layer_manager.gui.physics.get_visibility_obstacle(
32
+                subject=actor.subject,
33
+                to_position=mouse_grid_position,
34
+                matrix_name='visibility',
35
+                opacity_property_name='opacity',
36
+            )
37
+
38
+            # DEBUG
39
+            if self.layer_manager.debug:
40
+                grid_paths = self.layer_manager.gui.physics.matrixes.get_path_positions(
41
+                    from_=actor_grid_position,
42
+                    to=mouse_grid_position,
43
+                )
44
+                previous_grid_path = None
45
+                for grid_path in grid_paths:
46
+                    if previous_grid_path:
47
+                        previous_grid_path_pixel = self.layer_manager.grid_manager.get_world_position_of_grid_position(
48
+                            previous_grid_path,
49
+                        )
50
+                        current_grid_pixel = self.layer_manager.grid_manager.get_world_position_of_grid_position(
51
+                            grid_path,
52
+                        )
53
+                        draw_line(
54
+                            self.layer_manager.scrolling_manager.world_to_screen(*previous_grid_path_pixel),
55
+                            self.layer_manager.scrolling_manager.world_to_screen(*current_grid_pixel),
56
+                            (25, 125, 25),
57
+                        )
58
+                    previous_grid_path = grid_path
59
+
60
+            if obstacle_grid_position:
61
+                obstacle_pixel = self.layer_manager.grid_manager.get_world_position_of_grid_position(
62
+                    obstacle_grid_position,
63
+                )
64
+                draw_to_pixel = self.layer_manager.scrolling_manager.world_to_screen(*obstacle_pixel)
65
+
66
+                draw_line(
67
+                    self.layer_manager.scrolling_manager.world_to_screen(*obstacle_pixel),
68
+                    self.layer_manager.edit_layer.screen_mouse,
69
+                    self.not_visible_color,
70
+                )
71
+
72
+            draw_line(
73
+                self.layer_manager.scrolling_manager.world_to_screen(*actor_pixel_position),
74
+                draw_to_pixel,
75
+                self.color,
76
+            )
77
+
78
+    def get_behaviour(self, actor: Actor, mouse_grid_position) -> typing.Tuple[typing.Type[SimulationBehaviour], dict]:
79
+        raise NotImplementedError()
80
+        return self.request_move_behaviour_class, {
81
+            'subject_id': actor.subject.id,
82
+            'move_to': mouse_grid_position,
83
+            'gui_action': self.gui_action,
84
+        }
85
+
86
+
87
+class FireActorInteraction(BaseFireActorInteraction):
88
+    gui_action = UserAction.ORDER_FIRE
89
+    color = (255, 0, 0)

+ 48 - 0
opencc/gui/move.py View File

@@ -0,0 +1,48 @@
1
+# coding: utf-8
2
+import typing
3
+
4
+from synergine2_cocos2d.interaction import BaseActorInteraction
5
+from opencc.user_action import UserAction
6
+from synergine2.simulation import SimulationBehaviour
7
+from synergine2_cocos2d.actor import Actor
8
+from synergine2_cocos2d.gl import draw_line
9
+from synergine2_xyz.move.simulation import RequestMoveBehaviour
10
+
11
+
12
+class BaseMoveActorInteraction(BaseActorInteraction):
13
+    gui_action = None
14
+    color = None
15
+    request_move_behaviour_class = RequestMoveBehaviour
16
+
17
+    def draw_pending(self) -> None:
18
+        for actor in self.layer_manager.edit_layer.selection:
19
+            grid_position = self.layer_manager.grid_manager.get_grid_position(actor.position)
20
+            pixel_position = self.layer_manager.grid_manager.get_world_position_of_grid_position(grid_position)
21
+
22
+            draw_line(
23
+                self.layer_manager.scrolling_manager.world_to_screen(*pixel_position),
24
+                self.layer_manager.edit_layer.screen_mouse,
25
+                self.color,
26
+            )
27
+
28
+    def get_behaviour(self, actor: Actor, mouse_grid_position) -> typing.Tuple[typing.Type[SimulationBehaviour], dict]:
29
+        return self.request_move_behaviour_class, {
30
+            'subject_id': actor.subject.id,
31
+            'move_to': mouse_grid_position,
32
+            'gui_action': self.gui_action,
33
+        }
34
+
35
+
36
+class MoveActorInteraction(BaseMoveActorInteraction):
37
+    gui_action = UserAction.ORDER_MOVE
38
+    color = (0, 0, 255)
39
+
40
+
41
+class MoveFastActorInteraction(BaseMoveActorInteraction):
42
+    gui_action = UserAction.ORDER_MOVE_FAST
43
+    color = (72, 244, 66)
44
+
45
+
46
+class MoveCrawlActorInteraction(BaseMoveActorInteraction):
47
+    gui_action = UserAction.ORDER_MOVE_CRAWL
48
+    color = (235, 244, 66)

+ 140 - 0
opencc/maps/003/003.tmx View File

@@ -0,0 +1,140 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<map version="1.0" tiledversion="2017.07.26" orientation="orthogonal" renderorder="left-up" width="70" height="40" tilewidth="8" tileheight="8" nextobjectid="4">
3
+ <tileset firstgid="1" source="trees_64x64.tsx"/>
4
+ <tileset firstgid="10" source="terrain.tsx"/>
5
+ <imagelayer name="background">
6
+  <image source="background.png" width="560" height="320"/>
7
+ </imagelayer>
8
+ <layer name="terrain" width="70" height="40" opacity="0.3">
9
+  <data encoding="csv">
10
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
11
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
12
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,
13
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,10,
14
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,10,
15
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,10,
16
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,10,
17
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,10,
18
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,10,
19
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,10,
20
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,
21
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
22
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
23
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
24
+10,10,10,10,11,11,11,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
25
+10,10,10,10,11,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
26
+10,10,10,10,11,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
27
+10,10,10,10,11,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
28
+10,10,10,10,11,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
29
+10,10,10,10,11,0,0,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
30
+10,10,10,10,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
31
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
32
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,10,10,10,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,10,10,10,10,10,10,10,
33
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,0,0,0,11,10,10,10,11,0,0,0,0,0,0,11,10,11,0,0,0,0,0,0,11,10,10,10,10,10,10,10,
34
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,11,10,10,10,11,0,0,0,0,0,0,11,10,11,0,0,0,0,0,0,11,10,10,10,10,10,10,10,
35
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,11,11,10,10,11,0,0,0,0,0,0,11,10,11,0,0,0,0,0,0,11,10,10,10,10,10,10,10,
36
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,0,0,0,0,0,11,10,10,11,0,0,0,0,0,0,11,10,11,0,0,0,0,0,0,11,10,10,10,10,10,10,10,
37
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,11,10,10,11,11,11,11,11,11,11,11,10,11,0,0,0,0,0,0,11,10,10,10,10,10,10,10,
38
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,10,10,11,11,11,0,0,0,0,0,11,11,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,11,10,10,10,10,10,10,10,
39
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,0,0,0,11,11,11,11,0,0,0,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,11,10,10,10,10,10,10,10,
40
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,11,10,10,10,10,10,10,10,
41
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,10,10,10,10,10,10,10,
42
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
43
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
44
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
45
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
46
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
47
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,0,11,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
48
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,11,11,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
49
+10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10
50
+</data>
51
+ </layer>
52
+ <layer name="ground" width="70" height="40">
53
+  <data encoding="csv">
54
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
55
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
56
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
57
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
58
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
59
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
60
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
61
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
62
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
63
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
64
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
65
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
66
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
67
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
68
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
69
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
70
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
71
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
72
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
73
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
74
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
75
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
76
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
77
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
78
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
79
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
80
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
81
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
82
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
83
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
84
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
85
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
86
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
87
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
88
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
89
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
90
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
91
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
92
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
93
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
94
+</data>
95
+ </layer>
96
+ <layer name="top" width="70" height="40">
97
+  <data encoding="csv">
98
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
99
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
100
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
101
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
102
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
103
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
104
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
105
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,
106
+0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
107
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
108
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
109
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
110
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
111
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
112
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
113
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
114
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
115
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
116
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
117
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
118
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
119
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
120
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
121
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
122
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
123
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
124
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
125
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
126
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
127
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
128
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
129
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
130
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
131
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
132
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
133
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
134
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
135
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
136
+0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
137
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
138
+</data>
139
+ </layer>
140
+</map>

BIN
opencc/maps/003/actors/man.png View File


BIN
opencc/maps/003/actors/man_c1.png View File


BIN
opencc/maps/003/actors/man_c2.png View File


BIN
opencc/maps/003/actors/man_c3.png View File


BIN
opencc/maps/003/actors/man_c4.png View File


BIN
opencc/maps/003/actors/man_d1.png View File


BIN
opencc/maps/003/actors/man_w1.png View File


BIN
opencc/maps/003/actors/man_w10.png View File


BIN
opencc/maps/003/actors/man_w2.png View File


BIN
opencc/maps/003/actors/man_w3.png View File


BIN
opencc/maps/003/actors/man_w4.png View File


BIN
opencc/maps/003/actors/man_w5.png View File


BIN
opencc/maps/003/actors/man_w6.png View File


BIN
opencc/maps/003/actors/man_w7.png View File


BIN
opencc/maps/003/actors/man_w8.png View File


BIN
opencc/maps/003/actors/man_w9.png View File


BIN
opencc/maps/003/background.png View File


BIN
opencc/maps/003/terrain.png View File


+ 22 - 0
opencc/maps/003/terrain.tsx View File

@@ -0,0 +1,22 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<tileset name="terrain" tilewidth="8" tileheight="8" spacing="1" tilecount="49" columns="7">
3
+ <image source="terrain.png" width="64" height="64"/>
4
+ <tile id="0">
5
+  <properties>
6
+   <property name="name" type="str" value="Grass"/>
7
+   <property name="traversable_by_man" type="bool" value="true"/>
8
+   <property name="traversable_by_vehicle" type="bool" value="true"/>
9
+   <property name="opacity" type="float" value="0.0"/>
10
+   <property name="height" type="float" value="0.0"/>
11
+  </properties>
12
+ </tile>
13
+ <tile id="1">
14
+  <properties>
15
+   <property name="name" type="str" value="Wood wall"/>
16
+   <property name="traversable_by_man" type="bool" value="false"/>
17
+   <property name="traversable_by_vehicle" type="bool" value="false"/>
18
+   <property name="opacity" type="float" value="100.0"/>
19
+   <property name="height" type="float" value="2.0"/>
20
+  </properties>
21
+ </tile>
22
+</tileset>

BIN
opencc/maps/003/trees_64x64.png View File


+ 4 - 0
opencc/maps/003/trees_64x64.tsx View File

@@ -0,0 +1,4 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<tileset name="trees_64x64" tilewidth="64" tileheight="64" tilecount="9" columns="3">
3
+ <image source="trees_64x64.png" width="192" height="192"/>
4
+</tileset>

+ 23 - 0
opencc/maps/004/004.tmx View File

@@ -0,0 +1,23 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<map version="1.0" tiledversion="2017.07.26" orientation="orthogonal" renderorder="left-up" width="15" height="5" tilewidth="8" tileheight="8" nextobjectid="4">
3
+ <tileset firstgid="1" source="trees_64x64.tsx"/>
4
+ <tileset firstgid="10" source="terrain.tsx"/>
5
+ <imagelayer name="background" visible="0">
6
+  <image source="background.png" width="24" height="40"/>
7
+ </imagelayer>
8
+ <layer name="terrain" width="15" height="5" opacity="0.5">
9
+  <data encoding="base64">
10
+   CgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAoAAAALAAAACwAAAAsAAAAKAAAACgAAAAsAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAsAAAAKAAAACgAAAAsAAAALAAAACwAAAAoAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAA
11
+  </data>
12
+ </layer>
13
+ <layer name="ground" width="15" height="5">
14
+  <data encoding="base64">
15
+   CgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAoAAAALAAAACwAAAAsAAAAKAAAACgAAAAsAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAsAAAAKAAAACgAAAAsAAAALAAAACwAAAAoAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAA
16
+  </data>
17
+ </layer>
18
+ <layer name="top" width="15" height="5">
19
+  <data encoding="base64">
20
+   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
21
+  </data>
22
+ </layer>
23
+</map>

BIN
opencc/maps/004/actors/man.png View File


BIN
opencc/maps/004/actors/man_c1.png View File


BIN
opencc/maps/004/actors/man_c2.png View File


BIN
opencc/maps/004/actors/man_c3.png View File


BIN
opencc/maps/004/actors/man_c4.png View File


BIN
opencc/maps/004/actors/man_w1.png View File


BIN
opencc/maps/004/actors/man_w10.png View File


BIN
opencc/maps/004/actors/man_w2.png View File


BIN
opencc/maps/004/actors/man_w3.png View File


BIN
opencc/maps/004/actors/man_w4.png View File


BIN
opencc/maps/004/actors/man_w5.png View File


BIN
opencc/maps/004/actors/man_w6.png View File


BIN
opencc/maps/004/actors/man_w7.png View File


BIN
opencc/maps/004/actors/man_w8.png View File


BIN
opencc/maps/004/actors/man_w9.png View File


BIN
opencc/maps/004/background.png View File


BIN
opencc/maps/004/terrain.png View File


+ 18 - 0
opencc/maps/004/terrain.tsx View File

@@ -0,0 +1,18 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<tileset name="terrain" tilewidth="8" tileheight="8" spacing="1" tilecount="49" columns="7">
3
+ <image source="terrain.png" width="64" height="64"/>
4
+ <tile id="0">
5
+  <properties>
6
+   <property name="name" type="str" value="Grass"/>
7
+   <property name="traversable_by_man" type="bool" value="true"/>
8
+   <property name="traversable_by_vehicle" type="bool" value="true"/>
9
+  </properties>
10
+ </tile>
11
+ <tile id="1">
12
+  <properties>
13
+   <property name="name" type="str" value="Wood wall"/>
14
+   <property name="traversable_by_man" type="bool" value="false"/>
15
+   <property name="traversable_by_vehicle" type="bool" value="false"/>
16
+  </properties>
17
+ </tile>
18
+</tileset>

BIN
opencc/maps/004/trees_64x64.png View File


+ 4 - 0
opencc/maps/004/trees_64x64.tsx View File

@@ -0,0 +1,4 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<tileset name="trees_64x64" tilewidth="64" tileheight="64" tilecount="9" columns="3">
3
+ <image source="trees_64x64.png" width="192" height="192"/>
4
+</tileset>

+ 1 - 0
opencc/simulation/__init__.py View File

@@ -0,0 +1 @@
1
+# coding: utf-8

+ 42 - 0
opencc/simulation/base.py View File

@@ -0,0 +1,42 @@
1
+# coding: utf-8
2
+from opencc.const import COLLECTION_ALIVE
3
+from opencc.simulation.physics import TilePhysics
4
+from synergine2.config import Config
5
+from synergine2.simulation import SubjectBehaviour
6
+from synergine2_xyz.physics import Physics
7
+from synergine2_xyz.simulation import XYZSimulation
8
+from synergine2_xyz.subjects import XYZSubject
9
+from synergine2_xyz.subjects import XYZSubjects
10
+
11
+
12
+class TileStrategySimulation(XYZSimulation):
13
+    behaviours_classes = [
14
+
15
+    ]
16
+
17
+    def __init__(
18
+        self,
19
+        config: Config,
20
+        map_file_path: str,
21
+    ) -> None:
22
+        self.map_file_path = map_file_path
23
+        super().__init__(config)
24
+
25
+    def create_physics(self) -> Physics:
26
+        return TilePhysics(
27
+            config=self.config,
28
+            map_file_path=self.map_file_path,
29
+        )
30
+
31
+
32
+class TileStrategySubjects(XYZSubjects):
33
+    pass
34
+
35
+
36
+class BaseSubject(XYZSubject):
37
+    pass
38
+
39
+
40
+class AliveSubjectBehaviour(SubjectBehaviour):
41
+    def is_terminated(self) -> bool:
42
+        return COLLECTION_ALIVE not in self.subject.collections

+ 154 - 0
opencc/simulation/behaviour.py View File

@@ -0,0 +1,154 @@
1
+# coding: utf-8
2
+import random
3
+import time
4
+import typing
5
+
6
+from opencc.const import COLLECTION_ALIVE
7
+from opencc.simulation.base import AliveSubjectBehaviour
8
+from opencc.simulation.event import NoLongerVisibleOpponent
9
+from opencc.simulation.event import FireEvent
10
+from opencc.simulation.event import DieEvent
11
+from opencc.simulation.event import NewVisibleOpponent
12
+from opencc.simulation.mechanism import OpponentVisibleMechanism
13
+from opencc.user_action import UserAction
14
+from synergine2.config import Config
15
+from synergine2.simulation import Simulation
16
+from synergine2.simulation import Event
17
+from synergine2.simulation import Subject
18
+from synergine2_xyz.move.simulation import MoveToBehaviour as BaseMoveToBehaviour
19
+
20
+
21
+class MoveToBehaviour(BaseMoveToBehaviour):
22
+    def __init__(
23
+        self,
24
+        config: Config,
25
+        simulation: Simulation,
26
+        subject: Subject,
27
+    ) -> None:
28
+        super().__init__(config, simulation, subject)
29
+        self._walk_duration = float(self.config.resolve('game.move.walk_ref_time'))
30
+        self._run_duration = float(self.config.resolve('game.move.run_ref_time'))
31
+        self._crawl_duration = float(self.config.resolve('game.move.crawl_ref_time'))
32
+
33
+    def is_terminated(self) -> bool:
34
+        return COLLECTION_ALIVE not in self.subject.collections
35
+
36
+    def _can_move_to_next_step(self, move_to_data: dict) -> bool:
37
+        if move_to_data['gui_action'] == UserAction.ORDER_MOVE:
38
+            return time.time() - move_to_data['last_intention_time'] >= self._walk_duration
39
+        if move_to_data['gui_action'] == UserAction.ORDER_MOVE_FAST:
40
+            return time.time() - move_to_data['last_intention_time'] >= self._run_duration
41
+        if move_to_data['gui_action'] == UserAction.ORDER_MOVE_CRAWL:
42
+            return time.time() - move_to_data['last_intention_time'] >= self._crawl_duration
43
+
44
+
45
+class LookAroundBehaviour(AliveSubjectBehaviour):
46
+    """
47
+    Behaviour who permit to reference visible things like enemies
48
+    """
49
+    visible_mechanism = OpponentVisibleMechanism
50
+    use = [visible_mechanism]
51
+
52
+    def __init__(self, *args, **kwargs) -> None:
53
+        super().__init__(*args, **kwargs)
54
+        self._seconds_frequency = float(self.config.resolve('game.look_around.frequency'))
55
+
56
+    @property
57
+    def seconds_frequency(self) -> typing.Optional[float]:
58
+        return self._seconds_frequency
59
+
60
+    def action(self, data) -> [Event]:
61
+        new_visible_subject_events = []
62
+        no_longer_visible_subject_events = []
63
+
64
+        for no_longer_visible_subject_id in data['no_longer_visible_subject_ids']:
65
+            no_longer_visible_subject_events.append(NoLongerVisibleOpponent(
66
+                observer_subject_id=self.subject.id,
67
+                observed_subject_id=no_longer_visible_subject_id,
68
+            ))
69
+            self.subject.visible_opponent_ids.remove(no_longer_visible_subject_id)
70
+
71
+        for new_visible_subject_id in data['new_visible_subject_ids']:
72
+            new_visible_subject_events.append(NewVisibleOpponent(
73
+                observer_subject_id=self.subject.id,
74
+                observed_subject_id=new_visible_subject_id,
75
+            ))
76
+            self.subject.visible_opponent_ids.append(new_visible_subject_id)
77
+
78
+        return new_visible_subject_events + no_longer_visible_subject_events
79
+
80
+    def run(self, data):
81
+        visible_subjects = data[self.visible_mechanism]['visible_subjects']
82
+        visible_subject_ids = [s.id for s in visible_subjects]
83
+        new_visible_subject_ids = []
84
+        no_longer_visible_subject_ids = []
85
+
86
+        for subject_id in self.subject.visible_opponent_ids:
87
+            if subject_id not in visible_subject_ids:
88
+                no_longer_visible_subject_ids.append(subject_id)
89
+
90
+        for subject in visible_subjects:
91
+            if subject.id not in self.subject.visible_opponent_ids:
92
+                new_visible_subject_ids.append(subject.id)
93
+
94
+        return {
95
+            'new_visible_subject_ids': new_visible_subject_ids,
96
+            'no_longer_visible_subject_ids': no_longer_visible_subject_ids,
97
+        }
98
+
99
+
100
+class EngageOpponent(AliveSubjectBehaviour):
101
+    visible_mechanism = OpponentVisibleMechanism
102
+    use = [visible_mechanism]
103
+
104
+    def __init__(self, *args, **kwargs) -> None:
105
+        super().__init__(*args, **kwargs)
106
+        self._seconds_frequency = float(self.config.resolve('game.engage.frequency'))
107
+
108
+    @property
109
+    def seconds_frequency(self) -> typing.Optional[float]:
110
+        return self._seconds_frequency
111
+
112
+    def action(self, data) -> [Event]:
113
+        kill = data['kill']
114
+        target_subject_id = data['target_subject_id']
115
+        target_subject = self.simulation.subjects.index[target_subject_id]
116
+        target_position = data['target_position']
117
+
118
+        events = list()
119
+        events.append(FireEvent(shooter_subject_id=self.subject.id, target_position=target_position))
120
+
121
+        # Must be check if target is not already dead (killed same cycle)
122
+        if kill and COLLECTION_ALIVE in target_subject.collections:
123
+            target_subject.collections.remove(COLLECTION_ALIVE)
124
+            # FIXME: Must be automatic when manipulate subject collections !
125
+            self.simulation.collections[COLLECTION_ALIVE].remove(target_subject_id)
126
+            self.simulation.collections[COLLECTION_ALIVE] = self.simulation.collections[COLLECTION_ALIVE]
127
+            events.append(DieEvent(shooter_subject_id=self.subject.id, shoot_subject_id=target_subject_id))
128
+
129
+        return events
130
+
131
+    def run(self, data):
132
+        visible_subjects = data[self.visible_mechanism]['visible_subjects']
133
+        if not visible_subjects:
134
+            return
135
+        # Manage selected target (can change, better visibility, etc ...)
136
+        # Manage weapon munition to be able to fire
137
+        # Manage fear/under fire ...
138
+        # Manage weapon reload time
139
+
140
+        # For dev fun, don't fire at random
141
+        if random.randint(1, 3) == -1:
142
+            # Executed but decided to fail
143
+            self.last_execution_time = time.time()
144
+            return False
145
+
146
+        target_subject = random.choice(visible_subjects)
147
+        kill = random.randint(0, 100) >= 75
148
+
149
+        # Manage fire miss or touch (visibility, fear, opponent hiding, etc ...)
150
+        return {
151
+            'kill': kill,
152
+            'target_subject_id': target_subject.id,
153
+            'target_position': target_subject.position,
154
+        }

+ 47 - 0
opencc/simulation/event.py View File

@@ -0,0 +1,47 @@
1
+# coding: utf-8
2
+
3
+
4
+# TODO: Reprendre les events Move, pour les lister tous ici
5
+import typing
6
+
7
+from synergine2.simulation import Event
8
+
9
+
10
+class NewVisibleOpponent(Event):
11
+    def __init__(
12
+        self,
13
+        observer_subject_id: int,
14
+        observed_subject_id: int,
15
+    ) -> None:
16
+        self.observer_subject_id = observer_subject_id
17
+        self.observed_subject_id = observed_subject_id
18
+
19
+
20
+class NoLongerVisibleOpponent(Event):
21
+    def __init__(
22
+        self,
23
+        observer_subject_id: int,
24
+        observed_subject_id: int,
25
+    ) -> None:
26
+        self.observer_subject_id = observer_subject_id
27
+        self.observed_subject_id = observed_subject_id
28
+
29
+
30
+class FireEvent(Event):
31
+    def __init__(
32
+        self,
33
+        shooter_subject_id: int,
34
+        target_position: typing.Tuple[int, int],
35
+    ) -> None:
36
+        self.shooter_subject_id = shooter_subject_id
37
+        self.target_position = target_position
38
+
39
+
40
+class DieEvent(Event):
41
+    def __init__(
42
+        self,
43
+        shooter_subject_id: int,
44
+        shoot_subject_id: int,
45
+    ) -> None:
46
+        self.shooter_subject_id = shooter_subject_id
47
+        self.shoot_subject_id = shoot_subject_id

+ 39 - 0
opencc/simulation/fire.py View File

@@ -0,0 +1,39 @@
1
+# coding: utf-8
2
+import typing
3
+
4
+from synergine2.config import Config
5
+from synergine2.simulation import SimulationBehaviour
6
+from synergine2.simulation import Simulation
7
+from synergine2.simulation import Event
8
+from synergine2.simulation import Intention
9
+from synergine2_xyz.simulation import XYZSimulation
10
+
11
+
12
+class FireIntention(Intention):
13
+    def __init__(
14
+        self,
15
+        to_position: typing.Tuple[int, int],
16
+        to_subject_id: int,
17
+        gui_action: typing.Any,
18
+    ) -> None:
19
+        self.to_position = to_position
20
+        self.to_subject_id = to_subject_id
21
+        self.gui_action = gui_action
22
+
23
+
24
+class RequestFireBehaviour(SimulationBehaviour):
25
+    move_intention_class = FireIntention
26
+
27
+    def __init__(
28
+        self,
29
+        config: Config,
30
+        simulation: Simulation,
31
+    ):
32
+        super().__init__(config, simulation)
33
+        self.simulation = typing.cast(XYZSimulation, self.simulation)
34
+
35
+    def action(self, data) -> typing.List[Event]:
36
+        to_position = data['to_position']
37
+        to_subject_id = data['to_subject_id']
38
+
39
+        return []

+ 16 - 0
opencc/simulation/mechanism.py View File

@@ -0,0 +1,16 @@
1
+# coding: utf-8
2
+import typing
3
+
4
+from opencc.const import SIDE, COLLECTION_ALIVE
5
+from synergine2_xyz.subjects import XYZSubject
6
+from synergine2_xyz.visible.simulation import VisibleMechanism
7
+
8
+
9
+class OpponentVisibleMechanism(VisibleMechanism):
10
+    from_collection = COLLECTION_ALIVE
11
+
12
+    def reduce_subjects(self, subjects: typing.List[XYZSubject]) -> typing.Iterator[XYZSubject]:
13
+        def filter_subject(subject: XYZSubject) -> bool:
14
+            return self.subject.properties[SIDE] != subject.properties[SIDE]
15
+
16
+        return filter(filter_subject, subjects)

+ 80 - 0
opencc/simulation/physics.py View File

@@ -0,0 +1,80 @@
1
+# coding: utf-8
2
+import typing
3
+
4
+from opencc.simulation.tmx import TileMap
5
+from opencc.simulation.tmx import TerrainTile
6
+from synergine2_xyz.physics import MoveCostComputer
7
+from synergine2_xyz.physics import TMXPhysics
8
+from synergine2_xyz.subjects import XYZSubject
9
+
10
+if typing.TYPE_CHECKING:
11
+    from opencc.simulation.base import BaseSubject
12
+    from opencc.simulation.subject import TileSubject
13
+
14
+
15
+class TileMoveCostComputer(MoveCostComputer):
16
+    def compute_move_cost(
17
+        self,
18
+        subject: 'BaseSubject',
19
+        tile: TerrainTile,
20
+        previous_node: str,
21
+        next_node: str,
22
+        unknown,
23
+    ) -> float:
24
+        # TODO: Objets/IT qui compute les couts de déplacement
25
+
26
+        if not tile.property('traversable_by_man'):
27
+            # TODO: revoir la lib disjkstar because les mecs traverses quand meme ...
28
+            return 100
29
+
30
+        return 1.0
31
+
32
+
33
+class TilePhysics(TMXPhysics):
34
+    tmx_map_class = TileMap
35
+    move_cost_computer_class = TileMoveCostComputer
36
+    matrixes_configuration = {
37
+        'visibility': [
38
+            'height',
39
+            'opacity',
40
+        ]
41
+    }
42
+
43
+    def get_visibility_obstacle(
44
+        self,
45
+        subject: XYZSubject,
46
+        to_position: typing.Tuple[int, int],
47
+        matrix_name: str,
48
+        opacity_property_name: str='opacity',
49
+    ) -> typing.Union[None, typing.Tuple[int, int]]:
50
+        """
51
+        Return grid position obstacle if any between given subject and given to_position
52
+        :param subject: Subject observer
53
+        :param to_position: position to observe
54
+        :param matrix_name: matrix name to use
55
+        :param opacity_property_name: name of property containing opacity property
56
+        :return: obstacle grid position or None if not
57
+        """
58
+        from_x, from_y = subject.position
59
+        path_positions = self.matrixes.get_path_positions(from_=(from_x, from_y), to=to_position)
60
+        path_opacities = self.matrixes.get_values_for_path(
61
+            matrix_name,
62
+            path_positions=path_positions,
63
+            value_name=opacity_property_name,
64
+        )
65
+
66
+        # FIXME: This algo is not ok, it is for test
67
+        actual_opacity = 0
68
+        for i, path_opacity in enumerate(path_opacities):
69
+            actual_opacity += path_opacity
70
+            if actual_opacity >= 100:
71
+                return path_positions[i]
72
+
73
+        return None
74
+
75
+    def subject_see_subject(self, observer: 'TileSubject', observed: 'TileSubject') -> bool:
76
+        return not bool(self.get_visibility_obstacle(
77
+            observer,
78
+            observed.position,
79
+            matrix_name='visibility',
80
+        ))

+ 22 - 0
opencc/simulation/subject.py View File

@@ -0,0 +1,22 @@
1
+# coding: utf-8
2
+from opencc.const import COLLECTION_ALIVE, COMBAT_MODE_DEFENSE
3
+from opencc.simulation.base import BaseSubject
4
+from opencc.simulation.behaviour import MoveToBehaviour
5
+from opencc.simulation.behaviour import EngageOpponent
6
+from opencc.simulation.behaviour import LookAroundBehaviour
7
+from synergine2.share import shared
8
+
9
+
10
+class TileSubject(BaseSubject):
11
+    start_collections = [
12
+        COLLECTION_ALIVE,
13
+    ]
14
+    behaviours_classes = [
15
+        MoveToBehaviour,
16
+        LookAroundBehaviour,
17
+        EngageOpponent,
18
+    ]
19
+    visible_opponent_ids = shared.create_self('visible_opponent_ids', lambda: [])
20
+    combat_mode = shared.create_self('combat_mode', COMBAT_MODE_DEFENSE)
21
+    # TODO: implement (copied from engulf)
22
+    # behaviour_selector_class = CellBehaviourSelector

+ 16 - 0
opencc/simulation/tmx.py View File

@@ -0,0 +1,16 @@
1
+# coding: utf-8
2
+import tmx
3
+
4
+from synergine2_xyz.map import TMXMap
5
+from synergine2_xyz.map import XYZTile
6
+
7
+
8
+class TerrainTile(XYZTile):
9
+    pass
10
+
11
+
12
+class TileMap(TMXMap):
13
+    xyz_tile_class = TerrainTile
14
+
15
+    def get_default_tileset(self) -> tmx.Tileset:
16
+        return self.tmx_tilesets['terrain']

BIN
opencc/sounds/204010__duckduckpony__homemade-gunshot-2.ogg View File


+ 1 - 0
opencc/terminal/__init__.py View File

@@ -0,0 +1 @@
1
+# coding: utf-8

+ 53 - 0
opencc/terminal/base.py View File

@@ -0,0 +1,53 @@
1
+# coding: utf-8
2
+from opencc.simulation.event import NewVisibleOpponent
3
+from opencc.simulation.event import FireEvent
4
+from opencc.simulation.event import DieEvent
5
+from opencc.simulation.event import NoLongerVisibleOpponent
6
+from opencc.simulation.physics import TilePhysics
7
+from opencc.simulation.subject import TileSubject as ManSubject
8
+from opencc.gui.actor import Man as ManActor
9
+from synergine2_cocos2d.terminal import GameTerminal
10
+from synergine2_cocos2d.util import get_map_file_path_from_dir
11
+from synergine2_xyz.move.simulation import FinishMoveEvent
12
+from synergine2_xyz.move.simulation import StartMoveEvent
13
+
14
+
15
+class CocosTerminal(GameTerminal):
16
+    subscribed_events = [
17
+        FinishMoveEvent,
18
+        StartMoveEvent,
19
+        NewVisibleOpponent,
20
+        NoLongerVisibleOpponent,
21
+        FireEvent,
22
+        DieEvent,
23
+    ]
24
+
25
+    def __init__(self, *args, asynchronous: bool, map_dir_path: str, **kwargs):
26
+        super().__init__(*args, **kwargs)
27
+        self.asynchronous = asynchronous
28
+        map_file_path = get_map_file_path_from_dir(map_dir_path)
29
+        self.physics = TilePhysics(
30
+            self.config,
31
+            map_file_path=map_file_path,
32
+        )
33
+        self.map_dir_path = map_dir_path
34
+
35
+    def run(self):
36
+        from opencc.gui.base import Game
37
+        from synergine2_cocos2d.gui import SubjectMapper
38
+
39
+        self.gui = Game(
40
+            self.config,
41
+            self.logger,
42
+            self,
43
+            physics=self.physics,
44
+            map_dir_path=self.map_dir_path,
45
+        )
46
+
47
+        # TODO: Defind on some other place ?
48
+        self.gui.subject_mapper_factory.register_mapper(
49
+            ManSubject,
50
+            SubjectMapper(ManActor),
51
+        )
52
+
53
+        self.gui.run()

+ 9 - 0
opencc/user_action.py View File

@@ -0,0 +1,9 @@
1
+# coding: utf-8
2
+from synergine2_cocos2d.user_action import UserAction as BaseUserAction
3
+
4
+
5
+class UserAction(BaseUserAction):
6
+    ORDER_MOVE = 'ORDER_MOVE'
7
+    ORDER_MOVE_FAST = 'ORDER_MOVE_FAST'
8
+    ORDER_MOVE_CRAWL = 'ORDER_MOVE_CRAWL'
9
+    ORDER_FIRE = 'ORDER_FIRE'

+ 17 - 0
requirements.txt View File

@@ -0,0 +1,17 @@
1
+attrs==17.3.0
2
+cocos2d==0.6.5
3
+Dijkstar==2.3.0
4
+freezegun==0.3.9
5
+future==0.16.0
6
+numpy==1.13.3
7
+pluggy==0.6.0
8
+psutil==5.4.1
9
+py==1.5.2
10
+pyglet==1.3.0
11
+pytest==3.3.0
12
+python-dateutil==2.6.1
13
+PyYAML==3.12
14
+redis==2.10.6
15
+six==1.11.0
16
+synergine2==1.0
17
+tmx==1.9.1

+ 96 - 0
run.py View File

@@ -0,0 +1,96 @@
1
+# coding: utf-8
2
+import argparse
3
+import logging
4
+from random import seed
5
+
6
+from synergine2.log import get_default_logger
7
+from synergine2.config import Config
8
+from synergine2_cocos2d.const import SELECTION_COLOR_RGB
9
+from synergine2_cocos2d.util import get_map_file_path_from_dir
10
+from synergine2.core import Core
11
+from synergine2.cycle import CycleManager
12
+from synergine2.terminals import TerminalManager
13
+
14
+from opencc.const import FLAG, SIDE
15
+from opencc.const import FLAG_DE
16
+from opencc.const import DE_COLOR
17
+from opencc.const import URSS_COLOR
18
+from opencc.const import FLAG_URSS
19
+from opencc.simulation.subject import TileSubject
20
+from opencc.simulation.base import TileStrategySimulation
21
+from opencc.simulation.base import TileStrategySubjects
22
+from opencc.terminal.base import CocosTerminal
23
+
24
+
25
+def main(map_dir_path: str, seed_value: int=None):
26
+    if seed_value is not None:
27
+        seed(seed_value)
28
+
29
+    config = Config()
30
+    config.load_yaml('config.yaml')
31
+    logger = get_default_logger(level=logging.ERROR)
32
+
33
+    map_file_path = get_map_file_path_from_dir(map_dir_path)
34
+
35
+    simulation = TileStrategySimulation(config, map_file_path=map_file_path)
36
+    subjects = TileStrategySubjects(simulation=simulation)
37
+
38
+    for position in ((10, 2), (11, 3), (11, 4), (12, 5),):
39
+        man = TileSubject(
40
+            config=config,
41
+            simulation=simulation,
42
+            position=position,
43
+            properties={
44
+                SELECTION_COLOR_RGB: DE_COLOR,
45
+                FLAG: FLAG_DE,
46
+                SIDE: 'AXIS',
47
+            }
48
+        )
49
+        subjects.append(man)
50
+
51
+    for position in ((30, 15), (31, 16), (32, 17), (33, 18),):
52
+        man = TileSubject(
53
+            config=config,
54
+            simulation=simulation,
55
+            position=position,
56
+            properties={
57
+                SELECTION_COLOR_RGB: URSS_COLOR,
58
+                FLAG: FLAG_URSS,
59
+                SIDE: 'ALLIES',
60
+            }
61
+        )
62
+        subjects.append(man)
63
+
64
+    simulation.subjects = subjects
65
+
66
+    core = Core(
67
+        config=config,
68
+        logger=logger,
69
+        simulation=simulation,
70
+        cycle_manager=CycleManager(
71
+            config=config,
72
+            logger=logger,
73
+            simulation=simulation,
74
+        ),
75
+        terminal_manager=TerminalManager(
76
+            config=config,
77
+            logger=logger,
78
+            terminals=[CocosTerminal(
79
+                config,
80
+                logger,
81
+                asynchronous=False,
82
+                map_dir_path=map_dir_path,
83
+            )]
84
+        ),
85
+        cycles_per_seconds=1 / config.resolve('core.cycle_duration'),
86
+    )
87
+    core.run()
88
+
89
+if __name__ == '__main__':
90
+    parser = argparse.ArgumentParser(description='Run TileStrategy')
91
+    parser.add_argument('map_dir_path', help='map directory path')
92
+    parser.add_argument('--seed', dest='seed', default=None)
93
+
94
+    args = parser.parse_args()
95
+
96
+    main(args.map_dir_path, seed_value=args.seed)