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