# HG changeset patch # User Emmanuel Gil Peyrot # Date 1381745461 -7200 # Node ID 6be9c99a3a249ee805228669e30ed668595e70da # Parent 26c082870dcfcdd18f9a799d621852799480e83c Merge PlayerState into Player, fix player respawn position. diff --git a/eosd b/eosd --- a/eosd +++ b/eosd @@ -60,7 +60,7 @@ from pytouhou.lib.sdl import SDL from pytouhou.ui.window import Window from pytouhou.resource.loader import Loader from pytouhou.ui.gamerunner import GameRunner -from pytouhou.game.player import PlayerState, GameOver +from pytouhou.game.player import GameOver from pytouhou.formats.t6rp import T6RP, Level from pytouhou.utils.random import Random from pytouhou.vm.msgrunner import NextStage @@ -82,8 +82,8 @@ class GameBossRush(Game): Game.run_iter(self, keystate | 256 if i == 0 else 0) if not self.enemies and self.frame % 90 == 0: for player in self.players: - if player.state.power < 128: - player.state.power += 1 + if player.power < 128: + player.power += 1 if not skip: break @@ -141,7 +141,6 @@ def main(window, path, data, stage_num, save_replay.character = character difficulty = 16 - default_power = [0, 64, 128, 128, 128, 128, 0][stage_num - 1] if port != 0: if remote: @@ -154,12 +153,11 @@ def main(window, path, data, stage_num, prng = Random(0) con = Network(port, addr, selected_player) - states = [PlayerState(0, character=1, power=default_power, continues=continues), - PlayerState(1, character=3, power=default_power, continues=continues)] + characters = [1, 3] else: con = None selected_player = 0 - states = [PlayerState(0, character=character, power=default_power, continues=continues)] + characters = [character] if hints: with open(hints, 'rb') as file: @@ -167,9 +165,11 @@ def main(window, path, data, stage_num, game_class = GameBossRush if boss_rush else Game - common = Common(resource_loader, states[selected_player]) + common = Common(resource_loader, characters, continues, stage_num - 1) runner = GameRunner(window, resource_loader, skip=skip_replay, con=con) while True: + first_player = common.players[0] + if replay: level = replay.levels[stage_num - 1] if not level: @@ -181,12 +181,12 @@ def main(window, path, data, stage_num, #TODO: see if the stored score is used or if it’s the one from the previous stage. if stage_num != 1 and stage_num - 2 in replay.levels: previous_level = replay.levels[stage_num - 1] - states[0].score = previous_level.score - states[0].effective_score = previous_level.score - states[0].points = level.point_items - states[0].power = level.power - states[0].lives = level.lives - states[0].bombs = level.bombs + first_player.score = previous_level.score + first_player.effective_score = previous_level.score + first_player.points = level.point_items + first_player.power = level.power + first_player.lives = level.lives + first_player.bombs = level.bombs difficulty = level.difficulty elif port == 0: prng = Random() @@ -194,18 +194,18 @@ def main(window, path, data, stage_num, if save_filename: if not replay: save_replay.levels[stage_num - 1] = level = Level() - level.score = states[0].score level.random_seed = prng.seed - level.point_items = states[0].points - level.power = states[0].power - level.lives = states[0].lives - level.bombs = states[0].bombs + level.score = first_player.score + level.point_items = first_player.points + level.power = first_player.power + level.lives = first_player.lives + level.bombs = first_player.bombs level.difficulty = difficulty save_keystates = [] hints_stage = hints.stages[stage_num - 1] if hints else None - game = game_class(resource_loader, states, stage_num, rank, difficulty, + game = game_class(resource_loader, stage_num, rank, difficulty, common, prng=prng, hints=hints_stage, friendly_fire=friendly_fire) @@ -227,7 +227,6 @@ def main(window, path, data, stage_num, if not story or stage_num == (7 if boss_rush else 6 if rank > 0 else 5): break stage_num += 1 - states = [player.state for player in game.players] except GameOver: print('Game over') break diff --git a/pytouhou/game/enemy.pyx b/pytouhou/game/enemy.pyx --- a/pytouhou/game/enemy.pyx +++ b/pytouhou/game/enemy.pyx @@ -221,7 +221,7 @@ cdef class Enemy(Element): if player is None: player = self.select_player() x, y = pos or (self.x, self.y) - return atan2(player.state.y - y, player.state.x - x) + return atan2(player.y - y, player.x - x) cpdef set_anim(self, index): @@ -350,7 +350,7 @@ cdef class Enemy(Element): ey1, ey2 = ey - ehalf_size_y * 2. / 3., ey + ehalf_size_y * 2. / 3. if self.collidable: for player in self._game.players: - px, py = player.state.x, player.state.y + px, py = player.x, player.y phalf_size = player.sht.hitbox px1, px2 = px - phalf_size, px + phalf_size py1, py2 = py - phalf_size, py + phalf_size @@ -364,7 +364,7 @@ cdef class Enemy(Element): # Adjust damages damages = min(70, damages) score = (damages // 5) * 10 - self._game.players[0].state.score += score #TODO: better distribution amongst the players. + self._game.players[0].score += score #TODO: better distribution amongst the players. if self.damageable: if self._game.spellcard is not None: @@ -388,7 +388,7 @@ cdef class Enemy(Element): self.die_anim() #TODO: verify if the score is added with all the different flags. - self._game.players[0].state.score += self.die_score #TODO: better distribution amongst the players. + self._game.players[0].score += self.die_score #TODO: better distribution amongst the players. #TODO: verify if that should really be there. if self.boss: @@ -540,5 +540,5 @@ cdef class Enemy(Element): self.frame += 1 - def select_player_key(self, p): - return ((p.x - self.x) ** 2 + (p.y - self.y) ** 2, p.state.character) + def select_player_key(self, player): + return ((player.x - self.x) ** 2 + (player.y - self.y) ** 2, player.character) diff --git a/pytouhou/game/game.pyx b/pytouhou/game/game.pyx --- a/pytouhou/game/game.pyx +++ b/pytouhou/game/game.pyx @@ -192,7 +192,7 @@ cdef class Game: #TODO: do we really want to give it to each player? for player in self.players: - player.state.score += score + player.score += score cpdef kill_enemies(self): @@ -358,8 +358,8 @@ cdef class Game: player.update(keystate) #TODO: differentiate keystates (multiplayer mode) #XXX: Why 78910? Is it really the right value? - player.state.effective_score = min(player.state.effective_score + 78910, - player.state.score) + player.effective_score = min(player.effective_score + 78910, + player.score) #TODO: give extra lives to the player @@ -408,12 +408,10 @@ cdef class Game: item.update() for player in self.players: - player_state = player.state - - if not player_state.touchable: + if not player.touchable: continue - px, py = player_state.x, player_state.y + px, py = player.x, player.y player_pos[:] = [px, py] phalf_size = player.sht.hitbox px1, px2 = px - phalf_size, px + phalf_size @@ -425,11 +423,11 @@ cdef class Game: for laser in self.lasers: if laser.check_collision(player_pos): - if player_state.invulnerable_time == 0: + if player.invulnerable_time == 0: player.collide() elif laser.check_grazing(player_pos): - player_state.graze += 1 #TODO - player_state.score += 500 #TODO + player.graze += 1 #TODO + player.score += 500 #TODO player.play_sound('graze') self.modify_difficulty(+6) #TODO self.new_particle((px, py), 9, 192) #TODO @@ -447,14 +445,14 @@ cdef class Game: if not (bx2 < px1 or bx1 > px2 or by2 < py1 or by1 > py2): bullet.collide() - if player_state.invulnerable_time == 0: + if player.invulnerable_time == 0: player.collide() elif not bullet.grazed and not (bx2 < gx1 or bx1 > gx2 or by2 < gy1 or by1 > gy2): bullet.grazed = True - player_state.graze += 1 - player_state.score += 500 # found experimentally + player.graze += 1 + player.score += 500 # found experimentally player.play_sound('graze') self.modify_difficulty(+6) self.new_particle((px, py), 9, 192) #TODO: find the real size and range. @@ -467,7 +465,7 @@ cdef class Game: if bullet.state != LAUNCHED: continue - if bullet.player == player_state.number: + if bullet.player == player.number: continue bhalf_width = bullet.hitbox[0] @@ -479,7 +477,7 @@ cdef class Game: if not (bx2 < px1 or bx1 > px2 or by2 < py1 or by1 > py2): bullet.collide() - if player_state.invulnerable_time == 0: + if player.invulnerable_time == 0: player.collide() for plaser in self.players_lasers: @@ -492,11 +490,11 @@ cdef class Game: if not (lx2 < px1 or lx1 > px2 or ly < py1): - if player_state.invulnerable_time == 0: + if player.invulnerable_time == 0: player.collide() #TODO: is it the right place? - if py < 128 and player_state.power >= 128: #TODO: check py. + if py < 128 and player.power >= 128: #TODO: check py. self.autocollect(player) ihalf_size = player.sht.item_hitbox @@ -594,4 +592,4 @@ cdef list filter_removed(list elements): def select_player_key(player): - return (player.state.score, player.state.character) + return (player.score, player.character) diff --git a/pytouhou/game/item.pyx b/pytouhou/game/item.pyx --- a/pytouhou/game/item.pyx +++ b/pytouhou/game/item.pyx @@ -78,8 +78,7 @@ cdef class Item(Element): cdef void on_collect(self, Player player): cdef long level, poc - player_state = player.state - old_power = player_state.power + old_power = player.power score = 0 label = None color = 'white' @@ -87,19 +86,19 @@ cdef class Item(Element): if self._type == 0 or self._type == 2: # power or big power if old_power < 128: - player_state.power_bonus = 0 + player.power_bonus = 0 score = 10 - player_state.power += (1 if self._type == 0 else 8) - if player_state.power > 128: - player_state.power = 128 + player.power += (1 if self._type == 0 else 8) + if player.power > 128: + player.power = 128 for level in (8, 16, 32, 48, 64, 96): - if old_power < level and player_state.power >= level: + if old_power < level and player.power >= level: label = self._game.new_label((self.x, self.y), b':') # Actually a “PowerUp” character. color = 'blue' label.set_color(color) labeled = True else: - bonus = player_state.power_bonus + (1 if self._type == 0 else 8) + bonus = player.power_bonus + (1 if self._type == 0 else 8) if bonus > 30: bonus = 30 if bonus < 9: @@ -111,13 +110,13 @@ cdef class Item(Element): elif bonus == 30: score = 51200 color = 'yellow' - player_state.power_bonus = bonus + player.power_bonus = bonus self._game.modify_difficulty(+1) elif self._type == 1: # point - player_state.points += 1 + player.points += 1 poc = player.sht.point_of_collection - if player_state.y < poc: + if player.y < poc: score = 100000 self._game.modify_difficulty(+30) color = 'yellow' @@ -126,29 +125,29 @@ cdef class Item(Element): self._game.modify_difficulty(+3) elif self._type == 3: # bomb - if player_state.bombs < 8: - player_state.bombs += 1 + if player.bombs < 8: + player.bombs += 1 self._game.modify_difficulty(+5) elif self._type == 4: # full power score = 1000 - player_state.power = 128 + player.power = 128 elif self._type == 5: # 1up - if player_state.lives < 8: - player_state.lives += 1 + if player.lives < 8: + player.lives += 1 self._game.modify_difficulty(+200) player.play_sound('extend') elif self._type == 6: # star score = 500 - if old_power < 128 and player_state.power == 128: + if old_power < 128 and player.power == 128: #TODO: display “full power”. self._game.change_bullets_into_star_items() if score > 0: - player_state.score += score + player.score += score if label is None: label = self._game.new_label((self.x, self.y), str(score)) if color != 'white': @@ -165,8 +164,7 @@ cdef class Item(Element): (3.,), 180) if self.player is not None: - player_state = self.player.state - self.angle = atan2(player_state.y - self.y, player_state.x - self.x) + self.angle = atan2(self.player.y - self.y, self.player.x - self.x) self.x += cos(self.angle) * self.speed self.y += sin(self.angle) * self.speed elif self.speed_interpolator is None: diff --git a/pytouhou/game/orb.pxd b/pytouhou/game/orb.pxd --- a/pytouhou/game/orb.pxd +++ b/pytouhou/game/orb.pxd @@ -1,10 +1,10 @@ from pytouhou.game.element cimport Element from pytouhou.game.sprite cimport Sprite -from pytouhou.game.player cimport PlayerState +from pytouhou.game.player cimport Player cdef class Orb(Element): cdef public double offset_x, offset_y - cdef PlayerState player_state + cdef Player player cdef object fire cpdef update(self) diff --git a/pytouhou/game/orb.py b/pytouhou/game/orb.py --- a/pytouhou/game/orb.py +++ b/pytouhou/game/orb.py @@ -16,7 +16,7 @@ from pytouhou.vm.anmrunner import ANMRun class Orb(Element): - def __init__(self, anm, index, player_state): + def __init__(self, anm, index, player): Element.__init__(self) self.sprite = Sprite() @@ -25,10 +25,10 @@ class Orb(Element): self.offset_x = 0 self.offset_y = 0 - self.player_state = player_state + self.player = player def update(self): self.anmrunner.run_frame() - self.x = self.player_state.x + self.offset_x - self.y = self.player_state.y + self.offset_y + self.x = self.player.x + self.offset_x + self.y = self.player.y + self.offset_y diff --git a/pytouhou/game/player.pxd b/pytouhou/game/player.pxd --- a/pytouhou/game/player.pxd +++ b/pytouhou/game/player.pxd @@ -1,8 +1,9 @@ from pytouhou.game.element cimport Element from pytouhou.game.game cimport Game -cdef class PlayerState: - cdef public double x, y +cdef class Player(Element): + cdef public Game _game + cdef public long death_time cdef public bint touchable, focused cdef public long character, score, effective_score, lives, bombs, power cdef public long graze, points @@ -11,12 +12,6 @@ cdef class PlayerState: cdef long invulnerable_time, power_bonus, continues, continues_used, miss, cdef long bombs_used - -cdef class Player(Element): - cdef public PlayerState state - cdef public long death_time - cdef public Game _game - cdef object anm cdef tuple speeds cdef long fire_time, bomb_time, direction diff --git a/pytouhou/game/player.pyx b/pytouhou/game/player.pyx --- a/pytouhou/game/player.pyx +++ b/pytouhou/game/player.pyx @@ -26,9 +26,11 @@ class GameOver(Exception): pass -cdef class PlayerState: - def __init__(self, long number, long character=0, long score=0, - long power=0, long lives=2, long bombs=3, long continues=0): +cdef class Player(Element): + def __init__(self, long number, anm, long character=0, long power=0, + long continues=0, long lives=2, long bombs=3, long score=0): + Element.__init__(self) + self.number = number self.character = character # ReimuA/ReimuB/MarisaA/MarisaB/... @@ -36,8 +38,8 @@ cdef class PlayerState: self.effective_score = score self.lives = lives self.bombs = bombs + self.continues = continues self.power = power - self.continues = continues self.continues_used = 0 self.miss = 0 @@ -55,12 +57,7 @@ cdef class PlayerState: self.power_bonus = 0 # Never goes over 30. - -cdef class Player(Element): - def __init__(self, PlayerState state, Game game, anm): - Element.__init__(self) - - self._game = game + self._game = None self.anm = anm self.speeds = (self.sht.horizontal_vertical_speed, @@ -70,7 +67,6 @@ cdef class Player(Element): self.fire_time = 0 - self.state = state self.direction = 0 self.set_anim(0) @@ -88,33 +84,32 @@ cdef class Player(Element): cdef void collide(self): - if not self.state.invulnerable_time and not self.death_time and self.state.touchable: # Border Between Life and Death + if not self.invulnerable_time and not self.death_time and self.touchable: # Border Between Life and Death self.death_time = self._game.frame - self._game.new_effect((self.state.x, self.state.y), 17) + self._game.new_effect((self.x, self.y), 17) self._game.modify_difficulty(-1600) self.play_sound('pldead00') for i in xrange(16): - self._game.new_particle((self.state.x, self.state.y), 11, 256) #TODO: find the real size and range. + self._game.new_particle((self.x, self.y), 11, 256) #TODO: find the real size and range. def start_focusing(self): - self.state.focused = True + self.focused = True def stop_focusing(self): - self.state.focused = False + self.focused = False cdef void fire(self): - cdef double x, y cdef long shot_power - sht = self.focused_sht if self.state.focused else self.sht + sht = self.focused_sht if self.focused else self.sht # Don’t use min() since sht.shots could be an empty dict. power = 999 for shot_power in sht.shots: - if self.state.power < shot_power: + if self.power < shot_power: power = power if power < shot_power else shot_power bullets = self._game.players_bullets @@ -125,7 +120,7 @@ cdef class Player(Element): self.play_sound('plst00') for shot in sht.shots[power]: - origin = self.orbs[shot.orb - 1] if shot.orb else self.state + origin = (self.orbs[shot.orb - 1] if shot.orb else self) shot_type = shot.type if shot_type == 3: @@ -149,8 +144,8 @@ cdef class Player(Element): if nb_bullets_max != 0 and len(bullets) == nb_bullets_max: break - x = origin.x + shot.pos[0] - y = origin.y + shot.pos[1] + x = origin.x + shot.pos[0] + y = origin.y + shot.pos[1] #TODO: find a better way to do that. bullet_type = BulletType(self.anm, shot.sprite % 256, @@ -162,13 +157,13 @@ cdef class Player(Element): bullets.append(Bullet((x, y), bullet_type, 0, shot.angle, shot.speed, (-1, 0, 0, 0, 0.15, -pi/2., 0., 0.), - 16, self, self._game, player=self.state.number, + 16, self, self._game, player=self.number, damage=shot.damage, hitbox=shot.hitbox)) else: bullets.append(Bullet((x, y), bullet_type, 0, shot.angle, shot.speed, (0, 0, 0, 0, 0., 0., 0., 0.), - 0, self, self._game, player=self.state.number, + 0, self, self._game, player=self.number, damage=shot.damage, hitbox=shot.hitbox)) @@ -176,7 +171,7 @@ cdef class Player(Element): cdef double dx, dy if self.death_time == 0 or self._game.frame - self.death_time > 60: - speed, diag_speed = self.speeds[2:] if self.state.focused else self.speeds[:2] + speed, diag_speed = self.speeds[2:] if self.focused else self.speeds[:2] try: dx, dy = {16: (0., -speed), 32: (0., speed), 64: (-speed, 0.), 128: (speed, 0.), 16|64: (-diag_speed, -diag_speed), 16|128: (diag_speed, -diag_speed), @@ -194,32 +189,28 @@ cdef class Player(Element): self.set_anim({-1: 2, +1: 4}[self.direction]) self.direction = 0 - self.state.x += dx - self.state.y += dy - - #XXX - self.x = self.state.x - self.y = self.state.y + self.x += dx + self.y += dy - if self.state.x < 8.: - self.state.x = 8. - if self.state.x > self._game.width - 8: - self.state.x = self._game.width - 8. - if self.state.y < 16.: - self.state.y = 16. - if self.state.y > self._game.height - 16: - self.state.y = self._game.height -16. + if self.x < 8.: + self.x = 8. + if self.x > self._game.width - 8: + self.x = self._game.width - 8. + if self.y < 16.: + self.y = 16. + if self.y > self._game.height - 16: + self.y = self._game.height -16. - if not self.state.focused and keystate & 4: + if not self.focused and keystate & 4: self.start_focusing() - elif self.state.focused and not keystate & 4: + elif self.focused and not keystate & 4: self.stop_focusing() - if self.state.invulnerable_time > 0: - self.state.invulnerable_time -= 1 + if self.invulnerable_time > 0: + self.invulnerable_time -= 1 - m = self.state.invulnerable_time % 8 - if m == 7 or self.state.invulnerable_time == 0: + m = self.invulnerable_time % 8 + if m == 7 or self.invulnerable_time == 0: self.sprite.color = (255, 255, 255) self.sprite.changed = True elif m == 1: @@ -243,43 +234,43 @@ cdef class Player(Element): if self.death_time: time = self._game.frame - self.death_time if time == 6: # too late, you are dead :( - self.state.touchable = False - if self.state.power > 16: - self.state.power -= 16 + self.touchable = False + if self.power > 16: + self.power -= 16 else: - self.state.power = 0 + self.power = 0 self._game.cancel_player_lasers() - self.state.miss += 1 - self.state.lives -= 1 - if self.state.lives < 0: + self.miss += 1 + self.lives -= 1 + if self.lives < 0: #TODO: display a menu to ask the players if they want to continue. - if self.state.continues == 0: + if self.continues == 0: raise GameOver # Don’t decrement if it’s infinite. - if self.state.continues >= 0: - self.state.continues -= 1 - self.state.continues_used += 1 + if self.continues >= 0: + self.continues -= 1 + self.continues_used += 1 for i in xrange(5): - self._game.drop_bonus(self.state.x, self.state.y, 4, + self._game.drop_bonus(self.x, self.y, 4, end_pos=(self._game.prng.rand_double() * 288 + 48, self._game.prng.rand_double() * 192 - 64)) - self.state.score = 0 - self.state.effective_score = 0 - self.state.lives = 2 #TODO: use the right default. - self.state.bombs = 3 #TODO: use the right default. - self.state.power = 0 + self.score = 0 + self.effective_score = 0 + self.lives = 2 #TODO: use the right default. + self.bombs = 3 #TODO: use the right default. + self.power = 0 - self.state.graze = 0 - self.state.points = 0 + self.graze = 0 + self.points = 0 else: - self._game.drop_bonus(self.state.x, self.state.y, 2, + self._game.drop_bonus(self.x, self.y, 2, end_pos=(self._game.prng.rand_double() * 288 + 48, # 102h.exe@0x41f3dc self._game.prng.rand_double() * 192 - 64)) # @0x41f3 for i in xrange(5): - self._game.drop_bonus(self.state.x, self.state.y, 0, + self._game.drop_bonus(self.x, self.y, 0, end_pos=(self._game.prng.rand_double() * 288 + 48, self._game.prng.rand_double() * 192 - 64)) @@ -295,8 +286,8 @@ cdef class Player(Element): self._game.cancel_bullets() elif time == 32: - self.state.x = float(self._game.width) / 2. #TODO - self.state.y = float(self._game.width) #TODO + self.x = float(self._game.width) / 2. #TODO + self.y = float(self._game.width) #TODO self.direction = 0 self.sprite = Sprite() @@ -308,8 +299,8 @@ cdef class Player(Element): self.sprite.scale_in(30, 1., 1.) elif time == 61: # respawned - self.state.touchable = True - self.state.invulnerable_time = 240 + self.touchable = True + self.invulnerable_time = 240 self.sprite.blendfunc = 0 self.sprite.changed = True diff --git a/pytouhou/games/eosd.py b/pytouhou/games/eosd.py --- a/pytouhou/games/eosd.py +++ b/pytouhou/games/eosd.py @@ -28,7 +28,7 @@ from pytouhou.vm.eclrunner import ECLMai class EoSDCommon(object): - def __init__(self, resource_loader, player_state): + def __init__(self, resource_loader, player_characters, continues, stage): self.etama = resource_loader.get_multi_anm(('etama3.anm', 'etama4.anm')) self.bullet_types = [BulletType(self.etama[0], 0, 11, 14, 15, 16, hitbox_size=2, type_id=0), @@ -74,13 +74,31 @@ class EoSDCommon(object): ('face09b.anm', 'face10a.anm', 'face10b.anm'), ('face08a.anm', 'face12a.anm', 'face12b.anm', 'face12c.anm')] - self.characters = resource_loader.get_eosd_characters() - self.interface = EoSDInterface(resource_loader, player_state) + default_power = [0, 64, 128, 128, 128, 128, 0][stage] + + eosd_characters = resource_loader.get_eosd_characters() + self.first_character = player_characters[0] // 2 + self.player_anms = {} + self.players = [None] * len(player_characters) + for i, player_character in enumerate(player_characters): + character = player_character // 2 + if character not in self.player_anms: + face = resource_loader.get_multi_anm(('face0%da.anm' % character, + 'face0%db.anm' % character, + 'face0%dc.anm' % character)) + anm = resource_loader.get_single_anm('player0%d.anm' % character) + self.player_anms[character] = (anm, face) + + self.players[i] = EoSDPlayer(i, self.player_anms[character][0], + eosd_characters[player_character], + character, default_power, continues) + + self.interface = EoSDInterface(resource_loader, self.players[0]) #XXX class EoSDGame(Game): - def __init__(self, resource_loader, player_states, stage, rank, difficulty, + def __init__(self, resource_loader, stage, rank, difficulty, common, nb_bullets_max=640, width=384, height=448, prng=None, hints=None, friendly_fire=True): @@ -95,11 +113,8 @@ class EoSDGame(Game): self.spellcard_effect_anm = resource_loader.get_single_anm('eff0%d.anm' % stage) - player_face = player_states[0].character // 2 self.msg = resource_loader.get_msg('msg%d.dat' % stage) - msg_anm = [resource_loader.get_multi_anm(('face0%da.anm' % player_face, - 'face0%db.anm' % player_face, - 'face0%dc.anm' % player_face)), + msg_anm = [common.player_anms[common.first_character][1], #TODO: does it break bomb face of non-first player? resource_loader.get_multi_anm(common.enemy_face[stage - 1])] self.msg_anm = [[], []] @@ -108,7 +123,8 @@ class EoSDGame(Game): for sprite in anm.sprites.values(): self.msg_anm[i].append((anm, sprite)) - players = [EoSDPlayer(state, self, resource_loader, common.characters[state.character]) for state in player_states] + for player in common.players: + player._game = self # Load stage data self.std = resource_loader.get_stage('stage%d.std' % stage) @@ -121,7 +137,7 @@ class EoSDGame(Game): self.resource_loader = resource_loader #XXX: currently used for texture preload in pytouhou.ui.gamerunner. Wipe it! - Game.__init__(self, players, stage, rank, difficulty, + Game.__init__(self, common.players, stage, rank, difficulty, common.bullet_types, common.laser_types, common.item_types, nb_bullets_max, width, height, prng, common.interface, hints, friendly_fire) @@ -144,8 +160,8 @@ class EoSDInterface(object): [Effect((416 + 32 * i, 32 * j), 6, front) for i in range(7) for j in range(15)] + [Effect((32 + 32 * i, 0), 7, front) for i in range(12)] + [Effect((32 + 32 * i, 464), 8, front) for i in range(12)] + - [Effect((0, 0), 5, front)] + - [Effect((0, 0), i, front) for i in range(5) + range(9, 16)]) + [Effect((0, 0), i, front) for i in reversed(range(6))] + + [Effect((0, 0), i, front) for i in range(9, 16)]) for item in self.items: item.sprite.allow_dest_offset = True #XXX @@ -269,15 +285,14 @@ class EoSDInterface(object): class EoSDPlayer(Player): - def __init__(self, state, game, resource_loader, character): - self.sht = character[0] - self.focused_sht = character[1] - self.anm = resource_loader.get_single_anm('player0%d.anm' % (state.character // 2)) + def __init__(self, number, anm, shts, character, power, continues): + self.sht = shts[0] + self.focused_sht = shts[1] - Player.__init__(self, state, game, self.anm) + Player.__init__(self, number, anm, character, power, continues) - self.orbs = [Orb(self.anm, 128, self.state), - Orb(self.anm, 129, self.state)] + self.orbs = [Orb(anm, 128, self), + Orb(anm, 129, self)] self.orbs[0].offset_x = -24 self.orbs[1].offset_x = 24 @@ -292,7 +307,7 @@ class EoSDPlayer(Player): lambda x: x ** 2) self.orb_dy_interpolator = Interpolator((0,), self._game.frame, (-32,), self._game.frame + 8) - self.state.focused = True + self.focused = True def stop_focusing(self): @@ -301,12 +316,12 @@ class EoSDPlayer(Player): lambda x: x ** 2) self.orb_dy_interpolator = Interpolator((-32,), self._game.frame, (0,), self._game.frame + 8) - self.state.focused = False + self.focused = False @property def objects(self): - return [self] + (self.orbs if self.state.power >= 8 else []) + return [self] + (self.orbs if self.power >= 8 else []) def update(self, keystate): diff --git a/pytouhou/ui/gamerunner.pyx b/pytouhou/ui/gamerunner.pyx --- a/pytouhou/ui/gamerunner.pyx +++ b/pytouhou/ui/gamerunner.pyx @@ -48,9 +48,9 @@ cdef class GameRunner(Runner): self.set_input(replay) if replay and replay.levels[game.stage - 1]: - game.players[0].state.lives = self.replay_level.lives - game.players[0].state.power = self.replay_level.power - game.players[0].state.bombs = self.replay_level.bombs + game.players[0].lives = self.replay_level.lives + game.players[0].power = self.replay_level.power + game.players[0].bombs = self.replay_level.bombs game.difficulty = self.replay_level.difficulty self.save_keystates = save_keystates diff --git a/pytouhou/vm/eclrunner.py b/pytouhou/vm/eclrunner.py --- a/pytouhou/vm/eclrunner.py +++ b/pytouhou/vm/eclrunner.py @@ -203,10 +203,10 @@ class ECLRunner(object): return self._enemy.z elif value == -10018: player = self._enemy.select_player() - return player.state.x + return player.x elif value == -10019: player = self._enemy.select_player() - return player.state.y + return player.y elif value == -10021: return self._enemy.get_player_angle() elif value == -10022: @@ -214,7 +214,7 @@ class ECLRunner(object): elif value == -10024: return self._enemy.life elif value == -10025: - return self._enemy.select_player().state.character #TODO + return self._enemy.select_player().character #TODO raise NotImplementedError(value) #TODO else: return value @@ -932,7 +932,7 @@ class ECLRunner(object): @instruction(119) def drop_some_bonus(self, number): - if self._enemy.select_player().state.power < 128: + if self._enemy.select_player().power < 128: if number > 0: #TODO: find the real formula in the binary. self._game.drop_bonus(self._enemy.x - 64 + self._game.prng.rand_double() * 128, @@ -981,7 +981,7 @@ class ECLRunner(object): [2, 3, 4], [1, 4, 0], [4, 2, 3]] - character = self._enemy.select_player().state.character + character = self._enemy.select_player().character self.variables[1:4] = values[character] elif function == 4: if arg == 1: diff --git a/pytouhou/vm/msgrunner.py b/pytouhou/vm/msgrunner.py --- a/pytouhou/vm/msgrunner.py +++ b/pytouhou/vm/msgrunner.py @@ -31,7 +31,7 @@ class MSGRunner(object): 'handlers') def __init__(self, msg, script, game): - self._msg = msg.msgs[script + 10 * (game.players[0].state.character // 2)] + self._msg = msg.msgs[script + 10 * (game.players[0].character // 2)] self._game = game self.handlers = self._handlers[6] self.frame = 0