Mercurial > touhou
comparison pytouhou/games/eosd.py @ 229:5afc75f71fed
Add “SHT” support to EoSD, and do a little cleanup.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Fri, 30 Dec 2011 18:37:06 +0100 |
parents | 0595315d3880 |
children | 1c24a6d93c1b |
comparison
equal
deleted
inserted
replaced
228:8f4cd1c01d22 | 229:5afc75f71fed |
---|---|
48 ItemType(etama3, 3, 10), #Bomb | 48 ItemType(etama3, 3, 10), #Bomb |
49 ItemType(etama3, 4, 11), #Full power | 49 ItemType(etama3, 4, 11), #Full power |
50 ItemType(etama3, 5, 12), #1up | 50 ItemType(etama3, 5, 12), #1up |
51 ItemType(etama3, 6, 13)] #Star | 51 ItemType(etama3, 6, 13)] #Star |
52 | 52 |
53 eosd_characters = [ReimuA, ReimuB, MarisaA, MarisaB] | 53 characters = resource_loader.get_eosd_characters('102h.exe') |
54 print characters[0] | |
55 | |
56 #eosd_characters = [ReimuA, ReimuB, MarisaA, MarisaB] | |
54 players = [] | 57 players = [] |
55 for player in player_states: | 58 for player in player_states: |
56 players.append(eosd_characters[player.character](player, self, resource_loader)) | 59 #players.append(eosd_characters[player.character](player, self, resource_loader)) |
60 players.append(EoSDPlayer(player, self, resource_loader, sht=characters[player.character])) | |
57 | 61 |
58 Game.__init__(self, resource_loader, players, stage, rank, difficulty, | 62 Game.__init__(self, resource_loader, players, stage, rank, difficulty, |
59 bullet_types, item_types, nb_bullets_max=640, **kwargs) | 63 bullet_types, item_types, nb_bullets_max=640, **kwargs) |
60 | 64 |
61 | 65 |
62 | 66 |
63 class EoSDPlayer(Player): | 67 class EoSDPlayer(Player): |
64 def __init__(self, state, game, anm_wrapper, speeds=None, hitbox_size=2.5, graze_hitbox_size=42.): | 68 def __init__(self, state, game, resource_loader, speeds=None, hitbox_size=2.5, graze_hitbox_size=42., sht=None): |
65 Player.__init__(self, state, game, anm_wrapper, speeds=speeds) | 69 self.sht = sht |
70 anm_wrapper = resource_loader.get_anm_wrapper(('player0%d.anm' % (state.character // 2),)) | |
71 self.anm_wrapper = anm_wrapper | |
66 | 72 |
67 self.orbs = [Orb(self.anm_wrapper, 128, self.state, self.orb_fire), | 73 Player.__init__(self, state, game, anm_wrapper, |
68 Orb(self.anm_wrapper, 129, self.state, self.orb_fire)] | 74 speeds=(self.sht.horizontal_vertical_speed, |
75 self.sht.diagonal_speed, | |
76 self.sht.horizontal_vertical_focused_speed, | |
77 self.sht.diagonal_focused_speed)) | |
78 | |
79 self.orbs = [Orb(self.anm_wrapper, 128, self.state, None), | |
80 Orb(self.anm_wrapper, 129, self.state, None)] | |
69 | 81 |
70 self.orbs[0].offset_x = -24 | 82 self.orbs[0].offset_x = -24 |
71 self.orbs[1].offset_x = 24 | 83 self.orbs[1].offset_x = 24 |
72 | 84 |
73 self.orb_dx_interpolator = None | 85 self.orb_dx_interpolator = None |
113 | 125 |
114 for orb in self.orbs: | 126 for orb in self.orbs: |
115 orb.update() | 127 orb.update() |
116 | 128 |
117 | 129 |
118 def orb_fire(self, orb): | 130 def fire(self): |
119 pass | 131 sht = self.sht |
132 power = min(power for power in sht.shots if self.state.power < power) | |
120 | 133 |
134 bullets = self._game.players_bullets | |
135 nb_bullets_max = self._game.nb_bullets_max | |
121 | 136 |
122 | 137 for shot in sht.shots[power]: |
123 class Reimu(EoSDPlayer): | 138 if self.fire_time % shot.interval == shot.delay: |
124 def __init__(self, state, game, resource_loader): | |
125 anm_wrapper = resource_loader.get_anm_wrapper(('player00.anm',)) | |
126 self.bullet_angle = pi/30 #TODO: check | |
127 | |
128 EoSDPlayer.__init__(self, state, game, anm_wrapper, speeds=(4., 4. * SQ2, 2., 2. * SQ2)) | |
129 | |
130 | |
131 def fire(self): | |
132 if self.fire_time % self.bullet_launch_interval == 0: | |
133 if self.state.power < 16: | |
134 bullets_per_shot = 1 | |
135 elif self.state.power < 48: | |
136 bullets_per_shot = 2 | |
137 elif self.state.power < 96: | |
138 bullets_per_shot = 3 | |
139 elif self.state.power < 128: | |
140 bullets_per_shot = 4 | |
141 else: | |
142 bullets_per_shot = 5 | |
143 | |
144 bullets = self._game.players_bullets | |
145 nb_bullets_max = self._game.nb_bullets_max | |
146 | |
147 bullet_angle = self.bullet_launch_angle - self.bullet_angle * (bullets_per_shot - 1) / 2. | |
148 for bullet_nb in range(bullets_per_shot): | |
149 if nb_bullets_max is not None and len(bullets) == nb_bullets_max: | 139 if nb_bullets_max is not None and len(bullets) == nb_bullets_max: |
150 break | 140 break |
151 | 141 |
152 bullets.append(Bullet((self.x, self.y), self.bullet_type, 0, | 142 origin = self.orbs[shot.orb - 1] if shot.orb else self |
153 bullet_angle, self.bullet_speed, | 143 x = origin.x + shot.pos[0] |
144 y = origin.y + shot.pos[1] | |
145 | |
146 #TODO: find a better way to do that. | |
147 bullet_type = BulletType(self.anm_wrapper, shot.sprite % 256, | |
148 shot.sprite % 256 + 32, #TODO: find the real cancel anim | |
149 0, 0, 0, 0.) | |
150 bullets.append(Bullet((x, y), bullet_type, 0, | |
151 shot.angle, shot.speed, | |
154 (0, 0, 0, 0, 0., 0., 0., 0.), | 152 (0, 0, 0, 0, 0., 0., 0., 0.), |
155 0, self, self._game, damage=48, player_bullet=True)) | 153 0, self, self._game, player_bullet=True, damage=shot.damage, hitbox=shot.hitbox)) |
156 bullet_angle += self.bullet_angle | |
157 | |
158 for orb in self.orbs: | |
159 orb.fire(orb) | |
160 | |
161 | |
162 | |
163 class ReimuA(Reimu): | |
164 def __init__(self, state, game, resource_loader): | |
165 Reimu.__init__(self, state, game, resource_loader) | |
166 | |
167 self.bulletA_type = BulletType(self.anm_wrapper, 65, 97, 0, 0, 0, hitbox_size=4) #TODO: verify the hitbox, damage is 14. | |
168 self.bulletA_speed = 12. | |
169 | |
170 | |
171 def fire(self): | |
172 Reimu.fire(self) | |
173 | |
174 if self.state.power < 8: | |
175 return | |
176 | |
177 else: | |
178 pass #TODO | |
179 | |
180 | |
181 | |
182 class ReimuB(Reimu): | |
183 def __init__(self, state, game, resource_loader): | |
184 Reimu.__init__(self, state, game, resource_loader) | |
185 | |
186 self.bulletB_type = BulletType(self.anm_wrapper, 66, 98, 0, 0, 0, hitbox_size=4) #TODO: verify the hitbox. | |
187 self.bulletB_speed = 22. | |
188 | |
189 | |
190 def fire_spine(self, orb, offset_x): | |
191 bullets = self._game.players_bullets | |
192 nb_bullets_max = self._game.nb_bullets_max | |
193 | |
194 if nb_bullets_max is not None and len(bullets) == nb_bullets_max: | |
195 return | |
196 | |
197 bullets.append(Bullet((orb.x + offset_x, orb.y), self.bulletB_type, 0, | |
198 self.bullet_launch_angle, self.bulletB_speed, | |
199 (0, 0, 0, 0, 0., 0., 0., 0.), | |
200 0, self, self._game, damage=12, player_bullet=True)) | |
201 | |
202 def orb_fire(self, orb): | |
203 if self.state.power < 8: | |
204 return | |
205 | |
206 elif self.state.power < 16: | |
207 if self.fire_time % 15 == 0: | |
208 self.fire_spine(orb, 0) | |
209 | |
210 elif self.state.power < 32: | |
211 if self.fire_time % 10 == 0: | |
212 self.fire_spine(orb, 0) | |
213 | |
214 elif self.state.power < 48: | |
215 if self.fire_time % 8 == 0: | |
216 self.fire_spine(orb, 0) | |
217 | |
218 elif self.state.power < 96: | |
219 if self.fire_time % 8 == 0: | |
220 self.fire_spine(orb, -8) | |
221 if self.fire_time % 5 == 0: | |
222 self.fire_spine(orb, 8) | |
223 | |
224 elif self.state.power < 128: | |
225 if self.fire_time % 5 == 0: | |
226 self.fire_spine(orb, -12) | |
227 if self.fire_time % 10 == 0: | |
228 self.fire_spine(orb, 0) | |
229 if self.fire_time % 3 == 0: | |
230 self.fire_spine(orb, 12) | |
231 | |
232 else: | |
233 if self.fire_time % 3 == 0: | |
234 self.fire_spine(orb, -12) | |
235 self.fire_spine(orb, 12) | |
236 if self.fire_time % 5 == 0: | |
237 self.fire_spine(orb, 0) | |
238 | |
239 | |
240 | |
241 class Marisa(EoSDPlayer): | |
242 def __init__(self, state, game, resource_loader): | |
243 anm_wrapper = resource_loader.get_anm_wrapper(('player01.anm',)) | |
244 self.bullet_angle = pi/40 #TODO: check | |
245 | |
246 EoSDPlayer.__init__(self, state, game, anm_wrapper, speeds=(5., 5. * SQ2, 2.5, 2.5 * SQ2)) | |
247 | |
248 | |
249 def fire(self): | |
250 if self.fire_time % self.bullet_launch_interval == 0: | |
251 if self.state.power < 32: | |
252 bullets_per_shot = 1 | |
253 elif self.state.power < 96: | |
254 bullets_per_shot = 2 | |
255 elif self.state.power < 128: | |
256 bullets_per_shot = 3 | |
257 else: | |
258 bullets_per_shot = 5 | |
259 | |
260 bullets = self._game.players_bullets | |
261 nb_bullets_max = self._game.nb_bullets_max | |
262 | |
263 bullet_angle = self.bullet_launch_angle - self.bullet_angle * (bullets_per_shot - 1) / 2. | |
264 for bullet_nb in range(bullets_per_shot): | |
265 if nb_bullets_max is not None and len(bullets) == nb_bullets_max: | |
266 break | |
267 | |
268 bullets.append(Bullet((self.x, self.y), self.bullet_type, 0, | |
269 bullet_angle, self.bullet_speed, | |
270 (0, 0, 0, 0, 0., 0., 0., 0.), | |
271 0, self, self._game, damage=48, player_bullet=True)) | |
272 bullet_angle += self.bullet_angle | |
273 | |
274 | |
275 | |
276 class MarisaA(Marisa): | |
277 def __init__(self, state, game, resource_loader): | |
278 Marisa.__init__(self, state, game, resource_loader) | |
279 | |
280 #TODO: verify the hitbox and damages. | |
281 self.bulletA_types = [BulletType(self.anm_wrapper, 65, 0, 0, 0, 0, hitbox_size=4), # damage is 40. | |
282 BulletType(self.anm_wrapper, 66, 0, 0, 0, 0, hitbox_size=4), | |
283 BulletType(self.anm_wrapper, 67, 0, 0, 0, 0, hitbox_size=4), | |
284 BulletType(self.anm_wrapper, 68, 0, 0, 0, 0, hitbox_size=4)] | |
285 self.bulletA_speed_interpolator = None | |
286 | |
287 | |
288 def fire(self): | |
289 Marisa.fire(self) | |
290 | |
291 if self.state.power < 8: | |
292 return | |
293 | |
294 else: | |
295 pass #TODO | |
296 | |
297 | |
298 | |
299 class MarisaB(Marisa): | |
300 def __init__(self, state, game, resource_loader): | |
301 Marisa.__init__(self, state, game, resource_loader) | |
302 | |
303 #TODO: power damages period | |
304 # 8 240 120 | |
305 # 16 390 170 | |
306 # 32 480 ??? | |
307 # 48 510 ??? | |
308 # 64 760 ??? | |
309 # 80 840 ??? | |
310 # 96 1150 270 | |
311 # 128 1740 330 | |
312 # The duration of the laser is period - 42. | |
313 # The damages are given for one laser shot on one enemy for its entire duration. | |
314 | |
315 | |
316 def fire(self): | |
317 Marisa.fire(self) | |
318 | |
319 if self.state.power < 8: | |
320 return | |
321 | |
322 else: | |
323 pass #TODO | |
324 |