Bastien Sevajol 6 years ago
parent
commit
11827693fe
8 changed files with 149 additions and 3 deletions
  1. 1 0
      config.yaml
  2. 16 0
      opencombat/gui/base.py
  3. 33 0
      opencombat/gui/state.py
  4. 27 1
      opencombat/state.py
  5. 7 0
      opencombat/state_template.xml
  6. 1 0
      opencombat/user_action.py
  7. 12 1
      run.py
  8. 52 1
      tests/test_state.py

+ 1 - 0
config.yaml View File

23
 global:
23
 global:
24
     state_loader: "opencombat.state.StateLoader"
24
     state_loader: "opencombat.state.StateLoader"
25
     state_schema: "opencombat/state.xsd"
25
     state_schema: "opencombat/state.xsd"
26
+    state_template: "opencombat/state_template.xml"
26
     cache_dir_path: 'cache'
27
     cache_dir_path: 'cache'
27
     include_path:
28
     include_path:
28
       maps:
29
       maps:

+ 16 - 0
opencombat/gui/base.py View File

21
 from opencombat.gui.animation import ANIMATION_WALK
21
 from opencombat.gui.animation import ANIMATION_WALK
22
 from opencombat.gui.animation import ANIMATION_CRAWL
22
 from opencombat.gui.animation import ANIMATION_CRAWL
23
 from opencombat.gui.fire import GuiFiringEvent
23
 from opencombat.gui.fire import GuiFiringEvent
24
+from opencombat.gui.state import SaveStateInteraction
24
 from opencombat.simulation.interior import InteriorManager
25
 from opencombat.simulation.interior import InteriorManager
25
 from opencombat.simulation.tmx import TileMap
26
 from opencombat.simulation.tmx import TileMap
26
 from opencombat.user_action import UserAction
27
 from opencombat.user_action import UserAction
59
             if k == key.F:
60
             if k == key.F:
60
                 self.user_action_pending = UserAction.ORDER_FIRE
61
                 self.user_action_pending = UserAction.ORDER_FIRE
61
 
62
 
63
+        if k == key.S:
64
+            self.run_save_state()
65
+
62
     def draw(self) -> None:
66
     def draw(self) -> None:
63
         super().draw()
67
         super().draw()
64
 
68
 
69
+    def run_save_state(self) -> None:
70
+        interaction = self.layer_manager\
71
+            .interaction_manager\
72
+            .get_for_user_action(
73
+                UserAction.SAVE_STATE,
74
+            )
75
+        interaction.execute()
76
+
65
 
77
 
66
 class BackgroundLayer(cocos.layer.Layer):
78
 class BackgroundLayer(cocos.layer.Layer):
67
     def __init__(
79
     def __init__(
272
         self.layer_manager.interaction_manager.register(MoveFastActorInteraction, self.layer_manager)
284
         self.layer_manager.interaction_manager.register(MoveFastActorInteraction, self.layer_manager)
273
         self.layer_manager.interaction_manager.register(MoveCrawlActorInteraction, self.layer_manager)
285
         self.layer_manager.interaction_manager.register(MoveCrawlActorInteraction, self.layer_manager)
274
         self.layer_manager.interaction_manager.register(FireActorInteraction, self.layer_manager)
286
         self.layer_manager.interaction_manager.register(FireActorInteraction, self.layer_manager)
287
+        self.layer_manager.interaction_manager.register(
288
+            SaveStateInteraction,
289
+            self.layer_manager,
290
+        )
275
 
291
 
276
     def set_subject_position(
292
     def set_subject_position(
277
         self,
293
         self,

+ 33 - 0
opencombat/gui/state.py View File

1
+# coding: utf-8
2
+import typing
3
+
4
+from synergine2.simulation import SimulationBehaviour
5
+from synergine2.simulation import Event
6
+from synergine2.terminals import TerminalPackage
7
+from synergine2_cocos2d.interaction import Interaction
8
+
9
+from opencombat.user_action import UserAction
10
+
11
+
12
+class SaveStateSimulationAction(SimulationBehaviour):
13
+    def run(self, data):
14
+        pass
15
+
16
+    def action(self, data) -> typing.List[Event]:
17
+        # TODO BS 2018-06-14: dump state here
18
+        pass
19
+
20
+    @classmethod
21
+    def merge_data(cls, new_data, start_data=None):
22
+        pass
23
+
24
+
25
+class SaveStateInteraction(Interaction):
26
+    gui_action = UserAction.SAVE_STATE
27
+
28
+    def get_package_for_terminal(self) -> TerminalPackage:
29
+        return TerminalPackage(
30
+            simulation_actions=[
31
+                (SaveStateSimulationAction, {}),
32
+            ]
33
+        )

+ 27 - 1
opencombat/state.py View File

13
 from opencombat.simulation.subject import TileSubject
13
 from opencombat.simulation.subject import TileSubject
14
 from opencombat.util import get_class_from_string_path
14
 from opencombat.util import get_class_from_string_path
15
 from opencombat.util import get_text_xml_element
15
 from opencombat.util import get_text_xml_element
16
-from opencombat.const import FLAG, SIDE
16
+from opencombat.const import FLAG
17
+from opencombat.const import SIDE
17
 from opencombat.const import FLAG_DE
18
 from opencombat.const import FLAG_DE
18
 from opencombat.const import DE_COLOR
19
 from opencombat.const import DE_COLOR
19
 from opencombat.const import URSS_COLOR
20
 from opencombat.const import URSS_COLOR
74
             get_text_xml_element(subject_element, 'direction'),
75
             get_text_xml_element(subject_element, 'direction'),
75
         )
76
         )
76
 
77
 
78
+        # FIXME BS 218-06-14: There is a confusion: don't use side but
79
+        # "team". It probably need change in other code.
77
         side = get_text_xml_element(subject_element, 'side')
80
         side = get_text_xml_element(subject_element, 'side')
78
         if side == 'DE':
81
         if side == 'DE':
79
             subject_properties.update({
82
             subject_properties.update({
95
         subject.properties = subject_properties
98
         subject.properties = subject_properties
96
 
99
 
97
 
100
 
101
+class StateDumper(object):
102
+    def __init__(
103
+        self,
104
+        config: Config,
105
+        simulation: TileStrategySimulation,
106
+    ) -> None:
107
+        self._logger = get_logger('StateDumper', config)
108
+        self._config = config
109
+        self._simulation = simulation
110
+
111
+        state_template = self._config.resolve(
112
+           'global.state_template',
113
+           'opencombat/state_template.xml',
114
+        )
115
+        with open(state_template, 'r') as xml_file:
116
+            template_str = xml_file.read()
117
+        self._state_root = etree.fromstring(template_str.encode('utf-8'))
118
+
119
+    def get_state_dump(self) -> Element:
120
+        # TODO BS 2018-06-14: Code here xml construction
121
+        return self._state_root
122
+
123
+
98
 class StateLoader(object):
124
 class StateLoader(object):
99
     def __init__(
125
     def __init__(
100
         self,
126
         self,

+ 7 - 0
opencombat/state_template.xml View File

1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<state type="before_battle">
3
+    <map>
4
+    </map>
5
+    <subjects>
6
+    </subjects>
7
+</state>

+ 1 - 0
opencombat/user_action.py View File

3
 
3
 
4
 
4
 
5
 class UserAction(BaseUserAction):
5
 class UserAction(BaseUserAction):
6
+    SAVE_STATE = 'SAVE_STATE'
6
     ORDER_MOVE = 'ORDER_MOVE'
7
     ORDER_MOVE = 'ORDER_MOVE'
7
     ORDER_MOVE_FAST = 'ORDER_MOVE_FAST'
8
     ORDER_MOVE_FAST = 'ORDER_MOVE_FAST'
8
     ORDER_MOVE_CRAWL = 'ORDER_MOVE_CRAWL'
9
     ORDER_MOVE_CRAWL = 'ORDER_MOVE_CRAWL'

+ 12 - 1
run.py View File

20
     map_dir_path: str,
20
     map_dir_path: str,
21
     seed_value: int=None,
21
     seed_value: int=None,
22
     state_file_path: str=None,
22
     state_file_path: str=None,
23
+    state_save_dir: str='.',
23
 ):
24
 ):
24
     if seed_value is not None:
25
     if seed_value is not None:
25
         seed(seed_value)
26
         seed(seed_value)
66
     parser.add_argument('map_dir_path', help='map directory path')
67
     parser.add_argument('map_dir_path', help='map directory path')
67
     parser.add_argument('--seed', dest='seed', default=None)
68
     parser.add_argument('--seed', dest='seed', default=None)
68
     parser.add_argument('--state', dest='state', default=None)
69
     parser.add_argument('--state', dest='state', default=None)
70
+    parser.add_argument(
71
+        '--state-save-dir',
72
+        dest='state_save_dir',
73
+        default='.',
74
+    )
69
 
75
 
70
     args = parser.parse_args()
76
     args = parser.parse_args()
71
 
77
 
72
-    main(args.map_dir_path, seed_value=args.seed, state_file_path=args.state)
78
+    main(
79
+        args.map_dir_path,
80
+        seed_value=args.seed,
81
+        state_file_path=args.state,
82
+        state_save_dir=args.state_save_dir,
83
+    )

+ 52 - 1
tests/test_state.py View File

1
 # coding: utf-8
1
 # coding: utf-8
2
 import pytest
2
 import pytest
3
 from synergine2.config import Config
3
 from synergine2.config import Config
4
+from synergine2_cocos2d.const import SELECTION_COLOR_RGB
4
 
5
 
5
 from opencombat.exception import StateLoadError
6
 from opencombat.exception import StateLoadError
7
+from opencombat.simulation.base import TileStrategySimulation
8
+from opencombat.simulation.base import TileStrategySubjects
6
 from opencombat.simulation.subject import ManSubject
9
 from opencombat.simulation.subject import ManSubject
7
-from opencombat.state import StateLoaderBuilder, StateLoader
10
+from opencombat.state import StateLoaderBuilder, StateDumper
11
+from opencombat.state import StateLoader
12
+from opencombat.const import FLAG
13
+from opencombat.const import SIDE
14
+from opencombat.const import FLAG_DE
15
+from opencombat.const import DE_COLOR
16
+from opencombat.const import URSS_COLOR
17
+from opencombat.const import FLAG_URSS
8
 
18
 
9
 
19
 
10
 class MyStateLoader(StateLoader):
20
 class MyStateLoader(StateLoader):
16
     return StateLoader(config, simulation)
26
     return StateLoader(config, simulation)
17
 
27
 
18
 
28
 
29
+@pytest.fixture
30
+def simulation_for_dump(config) -> TileStrategySimulation:
31
+    simulation = TileStrategySimulation(
32
+        config,
33
+        'tests/fixtures/map_a/map_a.tmx',
34
+    )
35
+    subjects = TileStrategySubjects(simulation=simulation)
36
+
37
+    man1 = ManSubject(config, simulation)
38
+    man1.position = (10, 11)
39
+    man1.direction = 42
40
+    man1.properties = {
41
+        SELECTION_COLOR_RGB: DE_COLOR,
42
+        FLAG: FLAG_DE,
43
+        SIDE: 'AXIS',
44
+    }
45
+
46
+    man2 = ManSubject(config, simulation)
47
+    man2.position = (16, 8)
48
+    man2.direction = 197
49
+    man2.properties = {
50
+        SELECTION_COLOR_RGB: URSS_COLOR,
51
+        FLAG: FLAG_URSS,
52
+        SIDE: 'ALLIES',
53
+    }
54
+
55
+    subjects.append(man1)
56
+    subjects.append(man2)
57
+
58
+    return simulation
59
+
60
+
19
 def test_state_loader_builder__ok__nominal_case(
61
 def test_state_loader_builder__ok__nominal_case(
20
     simulation,
62
     simulation,
21
 ):
63
 ):
64
     assert (10, 10) == state.subjects[1].position
106
     assert (10, 10) == state.subjects[1].position
65
     assert 90.0 == state.subjects[0].direction
107
     assert 90.0 == state.subjects[0].direction
66
     assert 270.0 == state.subjects[1].direction
108
     assert 270.0 == state.subjects[1].direction
109
+
110
+
111
+def test_state__ok__dump(
112
+    config: Config,
113
+    simulation_for_dump: TileStrategySimulation,
114
+):
115
+    state_dumper = StateDumper(config, simulation_for_dump)
116
+    state_xml = state_dumper.get_state_dump()
117
+    assert False