Mercurial > touhou
changeset 235:e59bd7979ddc
Do a little cleanup, and fix PCB SHT usage.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Sat, 31 Dec 2011 16:31:10 +0100 |
parents | 3cbfa2c11dec |
children | 741860192b56 |
files | pytouhou/formats/exe.py pytouhou/formats/sht.py pytouhou/game/player.py pytouhou/games/eosd.py pytouhou/games/pcb.py |
diffstat | 5 files changed, 82 insertions(+), 109 deletions(-) [+] |
line wrap: on
line diff
--- a/pytouhou/formats/exe.py +++ b/pytouhou/formats/exe.py @@ -13,7 +13,9 @@ ## GNU General Public License for more details. ## +from copy import copy from struct import Struct, unpack + from pytouhou.utils.pe import PEFile from pytouhou.utils.helpers import get_logger @@ -125,7 +127,7 @@ class SHT(object): character_records_va = list(cls.find_character_defs(pe_file))[0] characters = [] - shots_offsets = [] + shots_offsets = {} for character in xrange(4): sht = cls() @@ -140,15 +142,21 @@ class SHT(object): sht.diagonal_speed = speed * SQ2 sht.diagonal_focused_speed = speed_focused * SQ2 - # Read from “push” operand - pe_file.seek_to_va(shots_func_offset + 4) - offset = unpack('<I', file.read(4))[0] - shots_offsets.append(offset) + # Characters might have different shot types whether they are + # focused or not, but properties read earlier apply to both modes. + focused_sht = copy(sht) + characters.append((sht, focused_sht)) - characters.append(sht) + for sht, func_offset in ((sht, shots_func_offset), (focused_sht, shots_func_offset_focused)): + # Read from “push” operand + pe_file.seek_to_va(func_offset + 4) + offset, = unpack('<I', file.read(4)) + if offset not in shots_offsets: + shots_offsets[offset] = [] + shots_offsets[offset].append(sht) character = 0 - for shots_offset in shots_offsets: + for shots_offset, shts in shots_offsets.iteritems(): pe_file.seek_to_va(shots_offset) level_count = 9 @@ -157,11 +165,10 @@ class SHT(object): shots_count, power, offset = unpack('<III', file.read(3*4)) levels.append((shots_count, power, offset)) - sht = characters[character] - sht.shots = {} + shots = {} for shots_count, power, offset in levels: - sht.shots[power] = [] + shots[power] = [] pe_file.seek_to_va(offset) for i in xrange(shots_count): @@ -175,7 +182,10 @@ class SHT(object): shot.pos = (x, y) shot.hitbox = (hitbox_x, hitbox_y) - sht.shots[power].append(shot) + shots[power].append(shot) + + for sht in shts: + sht.shots = shots character += 1
--- a/pytouhou/formats/sht.py +++ b/pytouhou/formats/sht.py @@ -29,7 +29,7 @@ class Shot(object): self.speed = 0. self.damage = 0 self.orb = 0 - self.shot_type = 0 + self.type = 0 self.sprite = 0 self.unknown1 = None self.unknown2 = None
--- a/pytouhou/game/player.py +++ b/pytouhou/game/player.py @@ -16,6 +16,7 @@ from pytouhou.game.sprite import Sprite from pytouhou.vm.anmrunner import ANMRunner from pytouhou.game.bullettype import BulletType +from pytouhou.game.bullet import Bullet from math import pi @@ -43,23 +44,20 @@ class PlayerState(object): class Player(object): - def __init__(self, state, game, anm_wrapper, hitbox_size=2.5, graze_hitbox_size=42., speeds=None): + def __init__(self, state, game, anm_wrapper): self._sprite = None self._anmrunner = None self._game = game self.anm_wrapper = anm_wrapper - self.speeds = speeds + self.speeds = (self.sht.horizontal_vertical_speed, + self.sht.diagonal_speed, + self.sht.horizontal_vertical_focused_speed, + self.sht.diagonal_focused_speed) - self.hitbox_size = hitbox_size - self.hitbox_half_size = self.hitbox_size / 2. - self.graze_hitbox_size = graze_hitbox_size - self.graze_hitbox_half_size = self.graze_hitbox_size / 2. + self.hitbox_half_size = self.sht.hitbox / 2. + self.graze_hitbox_half_size = self.sht.graze_hitbox / 2. - self.bullet_type = BulletType(anm_wrapper, 64, 96, 0, 0, 0, hitbox_size=4) - self.bullet_launch_interval = 5 - self.bullet_speed = 12. - self.bullet_launch_angle = -pi/2 self.fire_time = 0 self.state = state @@ -107,6 +105,47 @@ class Player(object): self.state.focused = False + def fire(self): + sht = self.focused_sht if self.state.focused else self.sht + power = min(power for power in sht.shots if self.state.power < power) + + bullets = self._game.players_bullets + nb_bullets_max = self._game.nb_bullets_max + + for shot in sht.shots[power]: + if shot.type == 3: # TODO: Lasers aren't implemented yet + continue + + if (self.fire_time + shot.delay) % shot.interval != 0: + continue + + if nb_bullets_max is not None and len(bullets) == nb_bullets_max: + break + + origin = self.orbs[shot.orb - 1] if shot.orb else self + 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_wrapper, shot.sprite % 256, + shot.sprite % 256 + 32, #TODO: find the real cancel anim + 0, 0, 0, 0.) + if shot.type == 2: + #TODO: triple-check acceleration! + 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_bullet=True, + damage=shot.damage, hitbox=shot.hitbox)) + #TODO: types 1 and 4 + 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_bullet=True, + damage=shot.damage, hitbox=shot.hitbox)) + + def update(self, keystate): 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]
--- a/pytouhou/games/eosd.py +++ b/pytouhou/games/eosd.py @@ -18,7 +18,6 @@ from pytouhou.game.game import Game from pytouhou.game.bullettype import BulletType from pytouhou.game.itemtype import ItemType from pytouhou.game.player import Player -from pytouhou.game.bullet import Bullet from pytouhou.game.orb import Orb from math import pi @@ -41,7 +40,7 @@ class EoSDGame(Game): BulletType(etama3, 7, 13, 20, 20, 20, hitbox_size=11), BulletType(etama3, 8, 13, 20, 20, 20, hitbox_size=9), BulletType(etama4, 0, 1, 2, 2, 2, hitbox_size=32)] - #TODO: hitbox + item_types = [ItemType(etama3, 0, 7), #Power ItemType(etama3, 1, 8), #Point ItemType(etama3, 2, 9), #Big power @@ -51,10 +50,7 @@ class EoSDGame(Game): ItemType(etama3, 6, 13)] #Star characters = resource_loader.get_eosd_characters('102h.exe') - - players = [] - for player in player_states: - players.append(EoSDPlayer(player, self, resource_loader, sht=characters[player.character])) + players = [EoSDPlayer(state, self, resource_loader, characters[state.character]) for state in player_states] Game.__init__(self, resource_loader, players, stage, rank, difficulty, bullet_types, item_types, nb_bullets_max=640, **kwargs) @@ -62,16 +58,13 @@ class EoSDGame(Game): class EoSDPlayer(Player): - def __init__(self, state, game, resource_loader, speeds=None, hitbox_size=2.5, graze_hitbox_size=42., sht=None): - self.sht = sht + def __init__(self, state, game, resource_loader, character): + self.sht = character[0] + self.focused_sht = character[1] anm_wrapper = resource_loader.get_anm_wrapper(('player0%d.anm' % (state.character // 2),)) self.anm_wrapper = anm_wrapper - Player.__init__(self, state, game, anm_wrapper, - speeds=(self.sht.horizontal_vertical_speed, - self.sht.diagonal_speed, - self.sht.horizontal_vertical_focused_speed, - self.sht.diagonal_focused_speed)) + Player.__init__(self, state, game, anm_wrapper) self.orbs = [Orb(self.anm_wrapper, 128, self.state, None), Orb(self.anm_wrapper, 129, self.state, None)] @@ -123,44 +116,3 @@ class EoSDPlayer(Player): for orb in self.orbs: orb.update() - - def fire(self): - sht = self.sht - power = min(power for power in sht.shots if self.state.power < power) - - bullets = self._game.players_bullets - nb_bullets_max = self._game.nb_bullets_max - - for shot in sht.shots[power]: - if shot.type == 3: # TODO: Lasers aren't implemented yet - continue - - if self.fire_time % shot.interval != shot.delay: - continue - - if nb_bullets_max is not None and len(bullets) == nb_bullets_max: - break - - origin = self.orbs[shot.orb - 1] if shot.orb else self - 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_wrapper, shot.sprite % 256, - shot.sprite % 256 + 32, #TODO: find the real cancel anim - 0, 0, 0, 0.) - if shot.type == 2: - #TODO: triple-check acceleration! - 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_bullet=True, - damage=shot.damage, hitbox=shot.hitbox)) - #TODO: types 1 and 4 - 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_bullet=True, - damage=shot.damage, hitbox=shot.hitbox)) -
--- a/pytouhou/games/pcb.py +++ b/pytouhou/games/pcb.py @@ -18,7 +18,6 @@ from pytouhou.game.game import Game from pytouhou.game.bullettype import BulletType from pytouhou.game.itemtype import ItemType from pytouhou.game.player import Player -from pytouhou.game.bullet import Bullet from pytouhou.game.orb import Orb from math import pi @@ -38,7 +37,7 @@ class PCBGame(Game): BulletType(etama3, 7, 13, 20, 20, 20, hitbox_size=11), BulletType(etama3, 8, 13, 20, 20, 20, hitbox_size=9), BulletType(etama4, 0, 1, 2, 2, 2, hitbox_size=32)] - #TODO: hitbox + item_types = [ItemType(etama3, 0, 7), #Power ItemType(etama3, 1, 8), #Point ItemType(etama3, 2, 9), #Big power @@ -47,9 +46,7 @@ class PCBGame(Game): ItemType(etama3, 5, 12), #1up ItemType(etama3, 6, 13)] #Star - players = [] - for player in player_states: - players.append(PCBPlayer(player, self, resource_loader)) + players = [PCBPlayer(state, self, resource_loader) for state in player_states] Game.__init__(self, resource_loader, players, stage, rank, difficulty, bullet_types, item_types, nb_bullets_max=640, **kwargs) @@ -57,17 +54,14 @@ class PCBGame(Game): class PCBPlayer(Player): - def __init__(self, state, game, resource_loader, speed=4., hitbox_size=2.5, graze_hitbox_size=42.): + def __init__(self, state, game, resource_loader): number = '%d%s' % (state.character // 2, 'b' if state.character % 2 else 'a') self.sht = resource_loader.get_sht('ply0%s.sht' % number) self.focused_sht = resource_loader.get_sht('ply0%ss.sht' % number) anm_wrapper = resource_loader.get_anm_wrapper(('player0%d.anm' % (state.character // 2),)) + self.anm_wrapper = anm_wrapper - Player.__init__(self, state, game, anm_wrapper, - speeds=(self.sht.horizontal_vertical_speed, - self.sht.diagonal_speed, - self.sht.horizontal_vertical_focused_speed, - self.sht.diagonal_focused_speed)) + Player.__init__(self, state, game, anm_wrapper) self.orbs = [Orb(self.anm_wrapper, 128, self.state, None), Orb(self.anm_wrapper, 129, self.state, None)] @@ -119,25 +113,3 @@ class PCBPlayer(Player): for orb in self.orbs: orb.update() - - def fire(self): - sht = self.focused_sht if self.state.focused else self.sht - power = min(power for power in sht.shots if self.state.power < power) - - bullets = self._game.players_bullets - nb_bullets_max = self._game.nb_bullets_max - - for shot in sht.shots[power]: - if self.fire_time % shot.interval == 0: - if nb_bullets_max is not None and len(bullets) == nb_bullets_max: - break - - origin = self.orbs[shot.orb - 1] if shot.orb else self - x = origin.x + shot.pos[0] - y = origin.y + shot.pos[1] - - bullets.append(Bullet((x, y), self.bullet_type, 0, - shot.angle, shot.speed, - (0, 0, 0, 0, 0., 0., 0., 0.), - 0, self, self._game, player_bullet=True, - damage=shot.damage, hitbox=shot.hitbox))