|
@@ -1,19 +1,26 @@
|
1
|
1
|
# coding: utf-8
|
2
|
2
|
import typing
|
3
|
3
|
|
|
4
|
+import time
|
|
5
|
+
|
|
6
|
+import pyglet
|
4
|
7
|
from PIL import Image
|
5
|
8
|
from synergine2.config import Config
|
6
|
9
|
from synergine2.simulation import Subject
|
7
|
10
|
from synergine2_cocos2d.actor import Actor
|
8
|
11
|
|
9
|
|
-from opencombat.exception import UnknownWeapon
|
|
12
|
+from opencombat.exception import UnknownWeapon, UnknownAnimationIndex
|
10
|
13
|
from opencombat.gui.animation import ANIMATION_CRAWL
|
11
|
14
|
from opencombat.gui.animation import ANIMATION_WALK
|
12
|
15
|
from opencombat.gui.const import POSITION_MAN_STAND_UP
|
13
|
16
|
from opencombat.gui.const import POSITION_MAN_CRAWLING
|
|
17
|
+from opencombat.gui.image import TileImageCache
|
14
|
18
|
from opencombat.gui.weapon import RIFFLE
|
15
|
19
|
from opencombat.gui.weapon import WeaponImageApplier
|
16
|
20
|
|
|
21
|
+if typing.TYPE_CHECKING:
|
|
22
|
+ from opencombat.gui.fire import GuiFiringEvent
|
|
23
|
+
|
17
|
24
|
|
18
|
25
|
class BaseActor(Actor):
|
19
|
26
|
position_matching = {
|
|
@@ -31,6 +38,17 @@ class BaseActor(Actor):
|
31
|
38
|
self.weapon_image_applier = WeaponImageApplier(config, self)
|
32
|
39
|
super().__init__(image_path, subject=subject, config=config)
|
33
|
40
|
|
|
41
|
+ # Firing
|
|
42
|
+ self.last_firing_time = 0
|
|
43
|
+ self.firing_change_image_gap = 0.05 # seconds
|
|
44
|
+ self.firing_images_cache = {} # type: TODO
|
|
45
|
+
|
|
46
|
+ self.default_image_path = image_path
|
|
47
|
+
|
|
48
|
+ self.image_cache = TileImageCache(self, self.config)
|
|
49
|
+ self.image_cache.build()
|
|
50
|
+ pass
|
|
51
|
+
|
34
|
52
|
@property
|
35
|
53
|
def mode(self) -> str:
|
36
|
54
|
return self._mode
|
|
@@ -44,9 +62,9 @@ class BaseActor(Actor):
|
44
|
62
|
return []
|
45
|
63
|
|
46
|
64
|
return [
|
47
|
|
- self.weapon_image_applier.get_default_image_for_weapon(
|
|
65
|
+ self.weapon_image_applier.get_image_for_weapon(
|
48
|
66
|
self.mode,
|
49
|
|
- self.weapons[0],
|
|
67
|
+ self.weapons[0], # FIXME
|
50
|
68
|
)
|
51
|
69
|
]
|
52
|
70
|
|
|
@@ -71,8 +89,81 @@ class BaseActor(Actor):
|
71
|
89
|
except UnknownWeapon:
|
72
|
90
|
return []
|
73
|
91
|
|
74
|
|
- def firing(self) -> None:
|
75
|
|
- pass
|
|
92
|
+ def get_modes(self) -> typing.List[str]:
|
|
93
|
+ return [POSITION_MAN_STAND_UP]
|
|
94
|
+
|
|
95
|
+ # def build_firing_images(self) -> None:
|
|
96
|
+ # cache_dir = self.config.resolve('global.cache_dir_path')
|
|
97
|
+ # for mode in self.get_modes():
|
|
98
|
+ # for weapon in self.weapons:
|
|
99
|
+ # images = self.weapon_image_applier.get_firing_image(
|
|
100
|
+ # mode=mode,
|
|
101
|
+ # weapon_type=weapon,
|
|
102
|
+ # )
|
|
103
|
+ #
|
|
104
|
+ # for position in range(len(images)):
|
|
105
|
+ # pass
|
|
106
|
+ #
|
|
107
|
+ #
|
|
108
|
+ # for animation_name, animation_image_paths in self.animation_image_paths.items():
|
|
109
|
+ # self.animation_images[animation_name] = []
|
|
110
|
+ # for i, animation_image_path in enumerate(animation_image_paths):
|
|
111
|
+ # final_image_path = self.path_manager.path(animation_image_path)
|
|
112
|
+ # final_image = Image.open(final_image_path)
|
|
113
|
+ #
|
|
114
|
+ # for appliable_image in self.get_animation_appliable_images(
|
|
115
|
+ # animation_name,
|
|
116
|
+ # i,
|
|
117
|
+ # ):
|
|
118
|
+ # final_image.paste(
|
|
119
|
+ # appliable_image,
|
|
120
|
+ # (0, 0),
|
|
121
|
+ # appliable_image,
|
|
122
|
+ # )
|
|
123
|
+ #
|
|
124
|
+ # # FIXME NOW: nom des image utilise au dessus
|
|
125
|
+ # final_name = '_'.join([
|
|
126
|
+ # str(subject_id),
|
|
127
|
+ # ntpath.basename(final_image_path),
|
|
128
|
+ # ])
|
|
129
|
+ # final_path = os.path.join(cache_dir, final_name)
|
|
130
|
+ #
|
|
131
|
+ # final_image.save(final_path)
|
|
132
|
+ #
|
|
133
|
+ # self.animation_images[animation_name].append(
|
|
134
|
+ # pyglet.image.load(
|
|
135
|
+ # final_path,
|
|
136
|
+ # )
|
|
137
|
+ # )
|
|
138
|
+
|
|
139
|
+ def firing(self, firing: 'GuiFiringEvent') -> None:
|
|
140
|
+ # FIXME: move some code ?
|
|
141
|
+ now = time.time()
|
|
142
|
+ if now - self.last_firing_time >= self.firing_change_image_gap:
|
|
143
|
+ self.last_firing_time = now
|
|
144
|
+ firing.increment_animation_index()
|
|
145
|
+
|
|
146
|
+ try:
|
|
147
|
+ image = self.image_cache.firing_cache.get(
|
|
148
|
+ mode=self.mode,
|
|
149
|
+ weapon=firing.weapon,
|
|
150
|
+ position=firing.animation_index,
|
|
151
|
+ )
|
|
152
|
+ except UnknownAnimationIndex:
|
|
153
|
+ image = self.image_cache.firing_cache.get(
|
|
154
|
+ mode=self.mode,
|
|
155
|
+ weapon=firing.weapon,
|
|
156
|
+ position=0,
|
|
157
|
+ )
|
|
158
|
+ firing.reset_animation_index()
|
|
159
|
+
|
|
160
|
+ # FIXME cache: prepare before firing
|
|
161
|
+ import uuid
|
|
162
|
+ tmp_path = '/tmp/{}.png'.format(str(uuid.uuid4()))
|
|
163
|
+ image.save(tmp_path)
|
|
164
|
+ pyglet_image = pyglet.image.load(tmp_path)
|
|
165
|
+
|
|
166
|
+ self.update_image(pyglet_image.get_texture())
|
76
|
167
|
|
77
|
168
|
|
78
|
169
|
class Man(BaseActor):
|
|
@@ -108,7 +199,7 @@ class Man(BaseActor):
|
108
|
199
|
return [RIFFLE]
|
109
|
200
|
|
110
|
201
|
|
111
|
|
-class HeavyVehicle(Actor):
|
|
202
|
+class HeavyVehicle(BaseActor):
|
112
|
203
|
animation_image_paths = {
|
113
|
204
|
ANIMATION_WALK: [
|
114
|
205
|
'actors/tank1.png',
|
|
@@ -124,3 +215,8 @@ class HeavyVehicle(Actor):
|
124
|
215
|
subject: Subject,
|
125
|
216
|
) -> None:
|
126
|
217
|
super().__init__('actors/tank1.png', subject=subject, config=config)
|
|
218
|
+
|
|
219
|
+ @property
|
|
220
|
+ def weapons(self) -> typing.List[str]:
|
|
221
|
+ # TODO BS 2018-01-26: Will be managed by complex part of code
|
|
222
|
+ return [RIFFLE]
|