Browse Source

troop selection: dump troop file

Bastien Sevajol 11 months ago
parent
commit
7cb345ede9

+ 2 - 0
config.yaml View File

@@ -29,6 +29,8 @@ global:
29 29
     team_stash: "opencombat.strategy.team.stash.TeamStash"
30 30
     teams_schema: "opencombat/strategy/teams.xsd"
31 31
     units_schema: "opencombat/strategy/units.xsd"
32
+    troop_dumper: "opencombat.strategy.troops.TroopDumper"
33
+    troop_schema: "opencombat/strategy/troops.xsd"
32 34
     cache_dir_path: 'cache'
33 35
     include_path:
34 36
       maps:

+ 13 - 3
opencombat/strategy/manager.py View File

@@ -1,7 +1,10 @@
1 1
 # coding: utf-8
2
+import typing
3
+
2 4
 from synergine2.config import Config
3 5
 from synergine2.log import get_logger
4 6
 
7
+from opencombat.strategy.team.model import TeamModel
5 8
 from opencombat.strategy.team.stash import TeamStash
6 9
 from opencombat.strategy.troops import TroopClassBuilder
7 10
 from opencombat.strategy.unit.stash import UnitStash
@@ -17,11 +20,11 @@ class TroopManager(object):
17 20
         self._config = config
18 21
         self._logger = get_logger('TroopManager', config)
19 22
 
20
-        builder = TroopClassBuilder(config)
21
-        self._unit_stash = builder.get_unit_stash(
23
+        self._builder = TroopClassBuilder(config)
24
+        self._unit_stash = self._builder.get_unit_stash(
22 25
             units_file_path,
23 26
         )
24
-        self._team_stash = builder.get_team_stash(
27
+        self._team_stash = self._builder.get_team_stash(
25 28
             units_file_path,
26 29
             teams_file_path,
27 30
         )
@@ -33,3 +36,10 @@ class TroopManager(object):
33 36
     @property
34 37
     def unit_stash(self) -> UnitStash:
35 38
         return self._unit_stash
39
+
40
+    def get_troop_dump(
41
+        self,
42
+        countries_troops: typing.Dict[str, typing.List[TeamModel]],
43
+    ):
44
+        dumper = self._builder.get_troop_dumper()
45
+        return dumper.get_troop_dump(countries_troops)

+ 45 - 0
opencombat/strategy/selection/gui.py View File

@@ -1,4 +1,5 @@
1 1
 # coding: utf-8
2
+import os
2 3
 import typing
3 4
 from tkinter import Tk
4 5
 from tkinter import Button
@@ -6,12 +7,17 @@ from tkinter import YES
6 7
 from tkinter import StringVar
7 8
 from tkinter import OptionMenu
8 9
 from tkinter import W
10
+from tkinter import E
11
+from tkinter import messagebox
9 12
 from tkinter.ttk import Combobox
10 13
 from tkinter.ttk import Treeview
11 14
 
15
+
16
+import time
12 17
 from synergine2.config import Config
13 18
 
14 19
 from opencombat.gui import Gui
20
+from opencombat.strategy.manager import TroopManager
15 21
 from opencombat.strategy.team.stash import TeamStash
16 22
 
17 23
 
@@ -21,11 +27,16 @@ class SelectTroopsGui(Gui):
21 27
         config: Config,
22 28
         master: Tk,
23 29
         team_stash: TeamStash,
30
+        troop_manager: TroopManager,
24 31
         countries: typing.List[str],
32
+        troops_dir_path: str = '.',
25 33
     ) -> None:
26 34
         super().__init__(config, master)
27 35
         self._master.title('Troops selection')
36
+        self._countries = countries
28 37
         self._team_stash = team_stash
38
+        self._troop_manager = troop_manager
39
+        self._troops_dir_path = troops_dir_path
29 40
         self._countries_troops = {}  # type: typing.Dict[str, typing.List[TeamModel]]  # nopep8
30 41
 
31 42
         # Widgets
@@ -72,12 +83,21 @@ class SelectTroopsGui(Gui):
72 83
         self._troops_view.column('#0', stretch=YES)
73 84
         self._troops_view.column('#1', stretch=YES)
74 85
 
86
+        self._generate_troops_var = StringVar(self._master)
87
+        self._generate_troops_button = Button(
88
+            self._master,
89
+            textvariable=self._generate_troops_var,
90
+            command=self._generate_troops,
91
+        )
92
+        self._generate_troops_var.set('Generate troops')
93
+
75 94
         # Layout
76 95
         self._select_country_menu.grid(row=0, column=0, sticky=W)
77 96
         self._teams_list.grid(row=1, column=0, sticky=W)
78 97
         self._add_troop_button.grid(row=2, column=0, sticky=W)
79 98
         self._troops_view.grid(row=3, column=0, sticky=W)
80 99
         self._remove_troop_button.grid(row=4, column=0, sticky=W)
100
+        self._generate_troops_button.grid(row=4, column=0, sticky=E)
81 101
 
82 102
         # Default behaviours
83 103
         self._selected_country_var.set(countries[0])
@@ -153,3 +173,28 @@ class SelectTroopsGui(Gui):
153 173
                 text=team.name,
154 174
                 values=('o' * len(team.units,))
155 175
             )
176
+
177
+    def _generate_troops(self, *args, **kwargs) -> None:
178
+        # Must have team(s) in all countries
179
+        if len(self._countries_troops.keys()) == len(self._countries) \
180
+                and all(self._countries_troops.values()):
181
+
182
+            troops_file_path = os.path.join(
183
+                self._troops_dir_path,
184
+                'troops_{}.xml'.format(str(time.time())),
185
+            )
186
+
187
+            self._logger.info('Generate troops into file "{}"'.format(
188
+                troops_file_path,
189
+            ))
190
+
191
+            troops_xml = self._troop_manager.get_troop_dump(
192
+                self._countries_troops,
193
+            )
194
+            with open(troops_file_path, 'w+') as file:
195
+                file.write(troops_xml)
196
+        else:
197
+            messagebox.showinfo(
198
+                'Missing information',
199
+                'All countries must have teams',
200
+            )

+ 58 - 1
opencombat/strategy/troops.py View File

@@ -1,10 +1,53 @@
1 1
 # coding: utf-8
2
+import typing
3
+
4
+from lxml import etree
5
+
2 6
 from synergine2.config import Config
3 7
 from synergine2.log import get_logger
4 8
 
9
+from opencombat.strategy.team.model import TeamModel
5 10
 from opencombat.strategy.team.stash import TeamStash
6 11
 from opencombat.strategy.unit.stash import UnitStash
7
-from opencombat.util import get_class_from_string_path
12
+from opencombat.util import get_class_from_string_path, pretty_xml
13
+
14
+
15
+class TroopDumper(object):
16
+    def __init__(
17
+        self,
18
+        config: Config,
19
+    ) -> None:
20
+        self._config = config
21
+        self._logger = get_logger('TroopDumper', config)
22
+
23
+    def get_troop_dump(
24
+        self,
25
+        countries_troops: typing.Dict[str, typing.List[TeamModel]],
26
+    ) -> str:
27
+        troops_template = self._config.resolve(
28
+            'global.troops_template',
29
+            'opencombat/strategy/troops_template.xml',
30
+        )
31
+        with open(troops_template, 'r') as xml_file:
32
+            template_str = xml_file.read()
33
+
34
+        parser = etree.XMLParser(remove_blank_text=True)
35
+        state_root = etree.fromstring(
36
+            template_str.encode('utf-8'),
37
+            parser,
38
+        )
39
+
40
+        for country, teams in countries_troops.items():
41
+            for team in teams:
42
+                troop_element = etree.SubElement(state_root, 'troop')
43
+                troop_element.attrib['country'] = country
44
+                troop_element.attrib['team_id'] = team.id
45
+
46
+        return pretty_xml(
47
+            etree.tostring(
48
+                state_root,
49
+            ).decode('utf-8'),
50
+        )
8 51
 
9 52
 
10 53
 class TroopClassBuilder(object):
@@ -52,3 +95,17 @@ class TroopClassBuilder(object):
52 95
             teams_file_path,
53 96
             unit_stash=unit_stash,
54 97
         )
98
+
99
+    def get_troop_dumper(self) -> TroopDumper:
100
+        class_address = self._config.resolve(
101
+            'global.troop_dumper',
102
+            'opencombat.strategy.troops.TroopDumper',
103
+        )
104
+        class_ = get_class_from_string_path(
105
+            self._config,
106
+            class_address,
107
+        )
108
+
109
+        return class_(
110
+            self._config,
111
+        )

+ 9 - 0
select_troops.py View File

@@ -13,6 +13,7 @@ def main(
13 13
     units_file_path: str,
14 14
     teams_file_path: str,
15 15
     countries: typing.List[str],
16
+    troops_dir_path: str = '.',
16 17
 ) -> None:
17 18
     config = Config()
18 19
     config.load_yaml('config.yaml')
@@ -28,7 +29,9 @@ def main(
28 29
         config,
29 30
         master=master,
30 31
         team_stash=troop_manager.team_stash,
32
+        troop_manager=troop_manager,
31 33
         countries=countries,
34
+        troops_dir_path=troops_dir_path,
32 35
     )
33 36
     master.mainloop()
34 37
 
@@ -52,10 +55,16 @@ if __name__ == '__main__':
52 55
         action='append',
53 56
         dest='countries',
54 57
     )
58
+    parser.add_argument(
59
+        '--troops-dir-path',
60
+        dest='troops_dir_path',
61
+        default='.',
62
+    )
55 63
     args = parser.parse_args()
56 64
 
57 65
     main(
58 66
         units_file_path=args.units_file_path,
59 67
         teams_file_path=args.teams_file_path,
60 68
         countries=args.countries,
69
+        troops_dir_path=args.troops_dir_path,
61 70
     )

+ 2 - 0
test_config.yaml View File

@@ -29,6 +29,8 @@ global:
29 29
     team_stash: "opencombat.strategy.team.stash.TeamStash"
30 30
     teams_schema: "opencombat/strategy/teams.xsd"
31 31
     units_schema: "opencombat/strategy/units.xsd"
32
+    troop_dumper: "opencombat.strategy.troops.TroopDumper"
33
+    troop_schema: "opencombat/strategy/troops.xsd"
32 34
     cache_dir_path: 'cache'
33 35
     include_path:
34 36
       maps: