Browse Source

Look around mechanism

Bastien Sevajol 6 years ago
parent
commit
6525d86f07

+ 2 - 0
sandbox/tile/const.py View File

@@ -6,5 +6,7 @@ FLAG = 'FLAG'
6 6
 FLAG_DE = 'DE'
7 7
 FLAG_URSS = 'URSS'
8 8
 
9
+SIDE = 'SIDE'
10
+
9 11
 DE_COLOR = (0, 81, 211)
10 12
 URSS_COLOR = (204, 0, 0)

+ 50 - 10
sandbox/tile/gui/base.py View File

@@ -1,35 +1,32 @@
1 1
 # coding: utf-8
2
+import typing
2 3
 
3 4
 from pyglet.window import key
4 5
 
5 6
 from cocos.actions import MoveTo as BaseMoveTo
6
-from sandbox.tile.simulation.physics import TilePhysics
7 7
 from sandbox.tile.user_action import UserAction
8 8
 from synergine2.config import Config
9 9
 from synergine2.log import SynergineLogger
10 10
 from synergine2.terminals import Terminal
11 11
 from synergine2_cocos2d.actions import MoveTo
12
-# TODO NOW: MOVE
13 12
 from synergine2_cocos2d.animation import ANIMATION_CRAWL
14 13
 from synergine2_cocos2d.animation import ANIMATION_WALK
15 14
 from synergine2_cocos2d.animation import Animate
15
+from synergine2_cocos2d.gl import draw_line
16 16
 from synergine2_cocos2d.gui import EditLayer as BaseEditLayer
17 17
 from synergine2_cocos2d.gui import TMXGui
18 18
 from synergine2_cocos2d.layer import LayerManager
19 19
 from synergine2_xyz.move.simulation import FinishMoveEvent
20 20
 from synergine2_xyz.move.simulation import StartMoveEvent
21
-from synergine2_xyz.physics import Matrixes
21
+from synergine2_xyz.physics import Physics
22 22
 from synergine2_xyz.utils import get_angle
23
+from sandbox.tile.simulation.event import NewVisibleOpponent
24
+from sandbox.tile.simulation.event import NoLongerVisibleOpponent
23 25
 
24 26
 
25 27
 class EditLayer(BaseEditLayer):
26 28
     def __init__(self, *args, **kwargs) -> None:
27 29
         super().__init__(*args, **kwargs)
28
-        self.matrixes = Matrixes()
29
-        self.physics = TilePhysics(
30
-            self.config,
31
-            map_file_path='sandbox/tile/maps/003/003.tmx',  # FIXME: HARDCODED
32
-        )
33 30
 
34 31
     def _on_key_press(self, k, m):
35 32
         if self.selection:
@@ -55,6 +52,7 @@ class Game(TMXGui):
55 52
         config: Config,
56 53
         logger: SynergineLogger,
57 54
         terminal: Terminal,
55
+        physics: Physics,
58 56
         read_queue_interval: float = 1 / 60.0,
59 57
         map_dir_path: str=None,
60 58
     ):
@@ -62,8 +60,9 @@ class Game(TMXGui):
62 60
             config,
63 61
             logger,
64 62
             terminal,
65
-            read_queue_interval,
66
-            map_dir_path,
63
+            physics=physics,
64
+            read_queue_interval=read_queue_interval,
65
+            map_dir_path=map_dir_path,
67 66
         )
68 67
 
69 68
         self.terminal.register_event_handler(
@@ -76,6 +75,16 @@ class Game(TMXGui):
76 75
             self.start_move_subject,
77 76
         )
78 77
 
78
+        self.terminal.register_event_handler(
79
+            NewVisibleOpponent,
80
+            self.new_visible_opponent,
81
+        )
82
+
83
+        self.terminal.register_event_handler(
84
+            NoLongerVisibleOpponent,
85
+            self.no_longer_visible_opponent,
86
+        )
87
+
79 88
         # configs
80 89
         self.move_duration_ref = float(self.config.resolve('game.move.walk_ref_time'))
81 90
         self.move_fast_duration_ref = float(self.config.resolve('game.move.run_ref_time'))
@@ -122,3 +131,34 @@ class Game(TMXGui):
122 131
         actor.do(move_action)
123 132
         actor.do(Animate(animation, duration=move_duration, cycle_duration=cycle_duration))
124 133
         actor.rotation = get_angle(event.from_position, event.to_position)
134
+
135
+    def new_visible_opponent(self, event: NewVisibleOpponent):
136
+        self.visible_or_no_longer_visible_opponent(event, (153, 0, 153))
137
+
138
+    def no_longer_visible_opponent(self, event: NoLongerVisibleOpponent):
139
+        self.visible_or_no_longer_visible_opponent(event, (255, 102, 0))
140
+
141
+    def visible_or_no_longer_visible_opponent(
142
+        self,
143
+        event: typing.Union[NoLongerVisibleOpponent, NewVisibleOpponent],
144
+        line_color,
145
+    ) -> None:
146
+        if self.layer_manager.debug:
147
+            observer_actor = self.layer_manager.subject_layer.subjects_index[event.observer_subject_id]
148
+            observed_actor = self.layer_manager.subject_layer.subjects_index[event.observed_subject_id]
149
+
150
+            observer_pixel_position = self.layer_manager.grid_manager.get_pixel_position_of_grid_position(
151
+                observer_actor.subject.position,
152
+            )
153
+            observed_pixel_position = self.layer_manager.grid_manager.get_pixel_position_of_grid_position(
154
+                observed_actor.subject.position,
155
+            )
156
+
157
+            def draw_visible_opponent():
158
+                draw_line(
159
+                    observer_pixel_position,
160
+                    observed_pixel_position,
161
+                    line_color,
162
+                )
163
+
164
+            self.layer_manager.edit_layer.append_callback(draw_visible_opponent, 1.0)

+ 1 - 2
sandbox/tile/gui/fire.py View File

@@ -31,14 +31,13 @@ class BaseFireActorInteraction(BaseActorInteraction):
31 31
             obstacle_grid_position = self.layer_manager.edit_layer.physics.get_visibility_obstacle(
32 32
                 subject=actor.subject,
33 33
                 to_position=mouse_grid_position,
34
-                matrixes=self.layer_manager.edit_layer.matrixes,
35 34
                 matrix_name='visibility',
36 35
                 opacity_property_name='opacity',
37 36
             )
38 37
 
39 38
             # DEBUG
40 39
             if self.layer_manager.debug:
41
-                grid_paths = self.layer_manager.edit_layer.matrixes.get_path_positions(
40
+                grid_paths = self.layer_manager.edit_layer.physics.matrixes.get_path_positions(
42 41
                     from_=actor_grid_position,
43 42
                     to=mouse_grid_position,
44 43
                 )

+ 13 - 11
sandbox/tile/run.py View File

@@ -5,17 +5,17 @@ import sys
5 5
 import logging
6 6
 from random import seed
7 7
 
8
-from sandbox.tile.const import FLAG
8
+synergine2_path = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../'))
9
+sys.path.append(synergine2_path)
10
+
11
+from sandbox.tile.const import FLAG, SIDE
9 12
 from sandbox.tile.const import FLAG_DE
10 13
 from sandbox.tile.const import DE_COLOR
11 14
 from sandbox.tile.const import URSS_COLOR
12 15
 from sandbox.tile.const import FLAG_URSS
13 16
 from synergine2_cocos2d.const import SELECTION_COLOR_RGB
14
-
15
-synergine2_path = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../'))
16
-sys.path.append(synergine2_path)
17
-
18
-from sandbox.tile.simulation.subject import Man
17
+from synergine2_cocos2d.util import get_map_file_path_from_dir
18
+from sandbox.tile.simulation.subject import TileSubject
19 19
 from sandbox.tile.simulation.base import TileStrategySimulation
20 20
 from sandbox.tile.simulation.base import TileStrategySubjects
21 21
 from synergine2.log import get_default_logger
@@ -33,31 +33,33 @@ def main(map_dir_path: str, seed_value: int=42):
33 33
     config.load_yaml('sandbox/tile/config.yaml')
34 34
     logger = get_default_logger(level=logging.ERROR)
35 35
 
36
-    map_file_path = 'sandbox/tile/{}.tmx'.format(os.path.join(map_dir_path, os.path.basename(map_dir_path)))
36
+    map_file_path = get_map_file_path_from_dir(map_dir_path)
37 37
 
38 38
     simulation = TileStrategySimulation(config, map_file_path=map_file_path)
39 39
     subjects = TileStrategySubjects(simulation=simulation)
40 40
 
41
-    for position in ((0, 2),):
42
-        man = Man(
41
+    for position in ((10, 2),):
42
+        man = TileSubject(
43 43
             config=config,
44 44
             simulation=simulation,
45 45
             position=position,
46 46
             properties={
47 47
                 SELECTION_COLOR_RGB: DE_COLOR,
48 48
                 FLAG: FLAG_DE,
49
+                SIDE: 'AXIS',
49 50
             }
50 51
         )
51 52
         subjects.append(man)
52 53
 
53
-    for position in ((20, 10),):
54
-        man = Man(
54
+    for position in ((30, 14),):
55
+        man = TileSubject(
55 56
             config=config,
56 57
             simulation=simulation,
57 58
             position=position,
58 59
             properties={
59 60
                 SELECTION_COLOR_RGB: URSS_COLOR,
60 61
                 FLAG: FLAG_URSS,
62
+                SIDE: 'ALLIES',
61 63
             }
62 64
         )
63 65
         subjects.append(man)

+ 53 - 0
sandbox/tile/simulation/behaviour.py View File

@@ -1,9 +1,14 @@
1 1
 # coding: utf-8
2 2
 import time
3 3
 
4
+from sandbox.tile.simulation.event import NoLongerVisibleOpponent
5
+from sandbox.tile.simulation.event import NewVisibleOpponent
6
+from sandbox.tile.simulation.mechanism import OpponentVisibleMechanism
4 7
 from sandbox.tile.user_action import UserAction
5 8
 from synergine2.config import Config
6 9
 from synergine2.simulation import Simulation
10
+from synergine2.simulation import SubjectBehaviour
11
+from synergine2.simulation import Event
7 12
 from synergine2.simulation import Subject
8 13
 from synergine2_xyz.move.simulation import MoveToBehaviour as BaseMoveToBehaviour
9 14
 
@@ -27,3 +32,51 @@ class MoveToBehaviour(BaseMoveToBehaviour):
27 32
             return time.time() - move_to_data['last_intention_time'] >= self._run_duration
28 33
         if move_to_data['gui_action'] == UserAction.ORDER_MOVE_CRAWL:
29 34
             return time.time() - move_to_data['last_intention_time'] >= self._crawl_duration
35
+
36
+
37
+class LookAroundBehaviour(SubjectBehaviour):
38
+    """
39
+    Behaviour who permit to reference visible things like enemies
40
+    """
41
+    visible_mechanism = OpponentVisibleMechanism
42
+    use = [visible_mechanism]
43
+    force_action = True
44
+
45
+    def action(self, data) -> [Event]:
46
+        new_visible_subject_events = []
47
+        no_longer_visible_subject_events = []
48
+
49
+        for no_longer_visible_subject_id in data['no_longer_visible_subject_ids']:
50
+            no_longer_visible_subject_events.append(NoLongerVisibleOpponent(
51
+                observer_subject_id=self.subject.id,
52
+                observed_subject_id=no_longer_visible_subject_id,
53
+            ))
54
+            self.subject.visible_opponent_ids.remove(no_longer_visible_subject_id)
55
+
56
+        for new_visible_subject_id in data['new_visible_subject_ids']:
57
+            new_visible_subject_events.append(NewVisibleOpponent(
58
+                observer_subject_id=self.subject.id,
59
+                observed_subject_id=new_visible_subject_id,
60
+            ))
61
+            self.subject.visible_opponent_ids.append(new_visible_subject_id)
62
+
63
+        return new_visible_subject_events + no_longer_visible_subject_events
64
+
65
+    def run(self, data):
66
+        visible_subjects = data[self.visible_mechanism]['visible_subjects']
67
+        visible_subject_ids = [s.id for s in visible_subjects]
68
+        new_visible_subject_ids = []
69
+        no_longer_visible_subject_ids = []
70
+
71
+        for subject_id in self.subject.visible_opponent_ids:
72
+            if subject_id not in visible_subject_ids:
73
+                no_longer_visible_subject_ids.append(subject_id)
74
+
75
+        for subject in visible_subjects:
76
+            if subject.id not in self.subject.visible_opponent_ids:
77
+                new_visible_subject_ids.append(subject.id)
78
+
79
+        return {
80
+            'new_visible_subject_ids': new_visible_subject_ids,
81
+            'no_longer_visible_subject_ids': no_longer_visible_subject_ids,
82
+        }

+ 25 - 0
sandbox/tile/simulation/event.py View File

@@ -0,0 +1,25 @@
1
+# coding: utf-8
2
+
3
+
4
+# TODO: Reprendre les events Move, pour les lister tous ici
5
+from synergine2.simulation import Event
6
+
7
+
8
+class NewVisibleOpponent(Event):
9
+    def __init__(
10
+        self,
11
+        observer_subject_id: int,
12
+        observed_subject_id: int,
13
+    ) -> None:
14
+        self.observer_subject_id = observer_subject_id
15
+        self.observed_subject_id = observed_subject_id
16
+
17
+
18
+class NoLongerVisibleOpponent(Event):
19
+    def __init__(
20
+        self,
21
+        observer_subject_id: int,
22
+        observed_subject_id: int,
23
+    ) -> None:
24
+        self.observer_subject_id = observer_subject_id
25
+        self.observed_subject_id = observed_subject_id

+ 14 - 0
sandbox/tile/simulation/mechanism.py View File

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

+ 11 - 6
sandbox/tile/simulation/physics.py View File

@@ -3,13 +3,13 @@ import typing
3 3
 
4 4
 from sandbox.tile.simulation.tmx import TileMap
5 5
 from sandbox.tile.simulation.tmx import TerrainTile
6
-from synergine2_xyz.physics import Matrixes
7 6
 from synergine2_xyz.physics import MoveCostComputer
8 7
 from synergine2_xyz.physics import TMXPhysics
9 8
 from synergine2_xyz.subjects import XYZSubject
10 9
 
11
-if False:
10
+if typing.TYPE_CHECKING:
12 11
     from sandbox.tile.simulation.base import BaseSubject
12
+    from sandbox.tile.simulation.subject import TileSubject
13 13
 
14 14
 
15 15
 class TileMoveCostComputer(MoveCostComputer):
@@ -44,7 +44,6 @@ class TilePhysics(TMXPhysics):
44 44
         self,
45 45
         subject: XYZSubject,
46 46
         to_position: typing.Tuple[int, int],
47
-        matrixes: Matrixes,
48 47
         matrix_name: str,
49 48
         opacity_property_name: str='opacity',
50 49
     ) -> typing.Union[None, typing.Tuple[int, int]]:
@@ -52,14 +51,13 @@ class TilePhysics(TMXPhysics):
52 51
         Return grid position obstacle if any between given subject and given to_position
53 52
         :param subject: Subject observer
54 53
         :param to_position: position to observe
55
-        :param matrixes: Matrixes instance
56 54
         :param matrix_name: matrix name to use
57 55
         :param opacity_property_name: name of property containing opacity property
58 56
         :return: obstacle grid position or None if not
59 57
         """
60 58
         from_x, from_y = subject.position
61
-        path_positions = matrixes.get_path_positions(from_=(from_x, from_y), to=to_position)
62
-        path_opacities = matrixes.get_values_for_path(
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(
63 61
             matrix_name,
64 62
             path_positions=path_positions,
65 63
             value_name=opacity_property_name,
@@ -73,3 +71,10 @@ class TilePhysics(TMXPhysics):
73 71
                 return path_positions[i]
74 72
 
75 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
+        ))

+ 5 - 1
sandbox/tile/simulation/subject.py View File

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

+ 13 - 1
sandbox/tile/terminal/base.py View File

@@ -1,7 +1,11 @@
1 1
 # coding: utf-8
2
-from sandbox.tile.simulation.subject import Man as ManSubject
2
+from sandbox.tile.simulation.event import NewVisibleOpponent
3
+from sandbox.tile.simulation.event import NoLongerVisibleOpponent
4
+from sandbox.tile.simulation.physics import TilePhysics
5
+from sandbox.tile.simulation.subject import TileSubject as ManSubject
3 6
 from sandbox.tile.gui.actor import Man as ManActor
4 7
 from synergine2_cocos2d.terminal import GameTerminal
8
+from synergine2_cocos2d.util import get_map_file_path_from_dir
5 9
 from synergine2_xyz.move.simulation import FinishMoveEvent
6 10
 from synergine2_xyz.move.simulation import StartMoveEvent
7 11
 
@@ -10,11 +14,18 @@ class CocosTerminal(GameTerminal):
10 14
     subscribed_events = [
11 15
         FinishMoveEvent,
12 16
         StartMoveEvent,
17
+        NewVisibleOpponent,
18
+        NoLongerVisibleOpponent,
13 19
     ]
14 20
 
15 21
     def __init__(self, *args, asynchronous: bool, map_dir_path: str, **kwargs):
16 22
         super().__init__(*args, **kwargs)
17 23
         self.asynchronous = asynchronous
24
+        map_file_path = get_map_file_path_from_dir(map_dir_path)
25
+        self.physics = TilePhysics(
26
+            self.config,
27
+            map_file_path=map_file_path,
28
+        )
18 29
         self.map_dir_path = map_dir_path
19 30
 
20 31
     def run(self):
@@ -25,6 +36,7 @@ class CocosTerminal(GameTerminal):
25 36
             self.config,
26 37
             self.logger,
27 38
             self,
39
+            physics=self.physics,
28 40
             map_dir_path=self.map_dir_path,
29 41
         )
30 42
 

+ 4 - 0
synergine2/share.py View File

@@ -98,6 +98,10 @@ class TrackedList(list):
98 98
         super().append(p_object)
99 99
         self.shared.set(self.shared_data.get_final_key(self.instance), list(self))
100 100
 
101
+    def remove(self, object_):
102
+        super().remove(object_)
103
+        self.shared.set(self.shared_data.get_final_key(self.instance), list(self))
104
+
101 105
     # TODO: Cover all methods
102 106
 
103 107
 

+ 0 - 3
synergine2/simulation.py View File

@@ -275,9 +275,6 @@ class SimulationMechanism(Mechanism):
275 275
 
276 276
 
277 277
 class Event(BaseObject):
278
-    def __init__(self, *args, **kwargs):
279
-        pass
280
-
281 278
     def repr_debug(self) -> str:
282 279
         return self.__class__.__name__
283 280
 

+ 45 - 0
synergine2_cocos2d/gui.py View File

@@ -4,6 +4,7 @@ import weakref
4 4
 from math import floor
5 5
 
6 6
 import pyglet
7
+import time
7 8
 from pyglet.window import mouse
8 9
 
9 10
 import cocos
@@ -26,6 +27,7 @@ from synergine2_cocos2d.layer import LayerManager
26 27
 from synergine2_cocos2d.middleware import MapMiddleware
27 28
 from synergine2_cocos2d.middleware import TMXMiddleware
28 29
 from synergine2_cocos2d.user_action import UserAction
30
+from synergine2_xyz.physics import Physics
29 31
 from synergine2_xyz.xyz import XYZSubjectMixin
30 32
 
31 33
 
@@ -111,6 +113,31 @@ class MinMaxRect(cocos.cocosnode.CocosNode):
111 113
         self.vertexes = [(minx, miny), (minx, maxy), (maxx, maxy), (maxx, miny)]
112 114
 
113 115
 
116
+class FinishedCallback(Exception):
117
+    pass
118
+
119
+
120
+class Callback(object):
121
+    def __init__(
122
+        self,
123
+        func: typing.Callable[[], None],
124
+        duration: float,
125
+    ) -> None:
126
+        self.func = func
127
+        self.duration = duration
128
+        # Started timestamp
129
+        self.started = None  # type: float
130
+
131
+    def execute(self) -> None:
132
+        if self.started is None:
133
+            self.started = time.time()
134
+
135
+        if time.time() - self.started < self.duration:
136
+            self.func()
137
+        else:
138
+            raise FinishedCallback()
139
+
140
+
114 141
 class EditLayer(cocos.layer.Layer):
115 142
     is_event_handler = True
116 143
 
@@ -201,6 +228,14 @@ class EditLayer(cocos.layer.Layer):
201 228
 
202 229
         self.schedule(self.update)
203 230
         self.selectable_actors = []
231
+        # TODO: In top level class: to be available in all layers
232
+        self.callbacks = []  # type: typing.List[Callback]
233
+
234
+    def append_callback(self, callback: typing.Callable[[], None], duration: float) -> None:
235
+        self.callbacks.append(Callback(
236
+            callback,
237
+            duration,
238
+        ))
204 239
 
205 240
     def set_selectable(self, actor: Actor) -> None:
206 241
         self.selectable_actors.append(actor)
@@ -214,6 +249,14 @@ class EditLayer(cocos.layer.Layer):
214 249
         self.draw_update_cshapes()
215 250
         self.draw_selection()
216 251
         self.draw_interactions()
252
+        self.execute_callbacks()
253
+
254
+    def execute_callbacks(self) -> None:
255
+        for callback in self.callbacks[:]:
256
+            try:
257
+                callback.execute()
258
+            except FinishedCallback:
259
+                self.callbacks.remove(callback)
217 260
 
218 261
     def draw_update_cshapes(self) -> None:
219 262
         for actor in self.selectable_actors:
@@ -731,6 +774,7 @@ class TMXGui(Gui):
731 774
         config: Config,
732 775
         logger: SynergineLogger,
733 776
         terminal: Terminal,
777
+        physics: Physics,
734 778
         read_queue_interval: float = 1 / 60.0,
735 779
         map_dir_path: str=None,
736 780
     ):
@@ -742,6 +786,7 @@ class TMXGui(Gui):
742 786
             terminal,
743 787
             read_queue_interval,
744 788
         )
789
+        self.physics = physics
745 790
 
746 791
     def get_layer_middleware(self) -> MapMiddleware:
747 792
         return TMXMiddleware(

+ 1 - 1
synergine2_cocos2d/layer.py View File

@@ -50,7 +50,7 @@ class ScrollingManager(cocos.layer.ScrollingManager):
50 50
 class SubjectLayer(cocos.layer.ScrollableLayer):
51 51
     def __init__(self, parallax: int=1):
52 52
         super().__init__(parallax)
53
-        self.subjects_index = {}
53
+        self.subjects_index = {}  # type: typing.Dict[int, Actor]
54 54
 
55 55
     def add_subject(self, actor: 'Actor') -> None:
56 56
         self.add(actor)

+ 7 - 0
synergine2_cocos2d/util.py View File

@@ -0,0 +1,7 @@
1
+# coding: utf-8
2
+import os
3
+
4
+
5
+def get_map_file_path_from_dir(map_dir_path: str) -> str:
6
+    # TODO: path is temp here
7
+    return 'sandbox/tile/{}.tmx'.format(os.path.join(map_dir_path, os.path.basename(map_dir_path)))

+ 1 - 1
synergine2_xyz/move/simulation.py View File

@@ -150,8 +150,8 @@ class StartMoveEvent(Event):
150 150
 
151 151
 
152 152
 class MoveToBehaviour(SubjectBehaviour):
153
-    use = [MoveToMechanism]
154 153
     move_to_mechanism = MoveToMechanism
154
+    use = [move_to_mechanism]
155 155
 
156 156
     def run(self, data):
157 157
         move_to_data = data[self.move_to_mechanism]

+ 7 - 2
synergine2_xyz/physics.py View File

@@ -6,7 +6,8 @@ from dijkstar import find_path
6 6
 
7 7
 from synergine2.config import Config
8 8
 from synergine2.share import shared
9
-from synergine2_xyz.map import TMXMap, XYZTile
9
+from synergine2_xyz.map import TMXMap
10
+from synergine2_xyz.map import XYZTile
10 11
 from synergine2_xyz.subjects import XYZSubject
11 12
 from synergine2_xyz.tmx_utils import fill_matrix
12 13
 from synergine2_xyz.utils import get_line_xy_path
@@ -147,11 +148,12 @@ class TMXPhysics(Physics):
147 148
         self,
148 149
         config: Config,
149 150
         map_file_path: str,
151
+        matrixes: Matrixes=None,
150 152
     ) -> None:
151 153
         super().__init__(config)
152 154
         self.map_file_path = map_file_path
153 155
         self.tmx_map = self.tmx_map_class(map_file_path)
154
-        self.matrixes = Matrixes()
156
+        self.matrixes = matrixes or Matrixes()
155 157
 
156 158
     def load(self) -> None:
157 159
         self.load_graph_from_map(self.map_file_path)
@@ -190,3 +192,6 @@ class TMXPhysics(Physics):
190 192
                 value_structure=properties,
191 193
             )
192 194
             fill_matrix(self.tmx_map, self.matrixes, 'terrain', matrix_name, properties)
195
+
196
+    def subject_see_subject(self, observer: XYZSubject, observed: XYZSubject) -> bool:
197
+        raise NotImplementedError()

+ 2 - 0
synergine2_xyz/simulation.py View File

@@ -21,8 +21,10 @@ class XYZSimulation(BaseSimulation):
21 21
     def create_physics(self) -> Physics:
22 22
         return Physics(self.config)
23 23
 
24
+    # TODO: Move into physics
24 25
     def is_possible_subject_position(self, subject: XYZSubject, position: tuple) -> bool:
25 26
         return self.is_possible_position(position)
26 27
 
28
+    # TODO: Move into physics
27 29
     def is_possible_position(self, position: tuple) -> bool:
28 30
         return True

+ 1 - 0
synergine2_xyz/visible/__init__.py View File

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

+ 32 - 0
synergine2_xyz/visible/simulation.py View File

@@ -0,0 +1,32 @@
1
+# coding: utf-8
2
+import typing
3
+
4
+from synergine2.config import Config
5
+from synergine2.simulation import SubjectMechanism, Simulation, Subject
6
+from synergine2_xyz.simulation import XYZSimulation
7
+from synergine2_xyz.subjects import XYZSubject
8
+
9
+
10
+class VisibleMechanism(SubjectMechanism):
11
+    def __init__(
12
+        self,
13
+        config: Config,
14
+        simulation: Simulation,
15
+        subject: Subject,
16
+    ) -> None:
17
+        super().__init__(config, simulation, subject)
18
+        self.simulation = typing.cast(XYZSimulation, self.simulation)
19
+        self.subject = typing.cast(XYZSubject, self.subject)
20
+
21
+    def reduce_subjects(self, subjects: typing.List[XYZSubject]) -> typing.Iterator[XYZSubject]:
22
+        return subjects
23
+
24
+    def is_visible(self, observed: XYZSubject) -> bool:
25
+        return self.simulation.physics.subject_see_subject(self.subject, observed)
26
+
27
+    def run(self) -> dict:
28
+        subjects_to_parse = self.reduce_subjects(self.simulation.subjects)
29
+        subjects_visible = list(filter(self.is_visible, subjects_to_parse))
30
+        return {
31
+            'visible_subjects': subjects_visible,
32
+        }