# HG changeset patch # User Emmanuel Gil Peyrot # Date 1318204518 25200 # Node ID 364935f6e313e307187e0f743e9bb1e90be21cfd # Parent 37df8c618c2e1a87b476c666066009a4d3c1418f Implement enemy killing. diff --git a/pytouhou/game/enemy.py b/pytouhou/game/enemy.py --- a/pytouhou/game/enemy.py +++ b/pytouhou/game/enemy.py @@ -18,17 +18,19 @@ from pytouhou.vm.eclrunner import ECLRun from pytouhou.vm.anmrunner import ANMRunner from pytouhou.game.sprite import Sprite from pytouhou.game.bullet import Bullet +from pytouhou.game.item import Item from math import cos, sin, atan2, pi class Enemy(object): - def __init__(self, pos, life, _type, anm_wrapper, game, pop_enemy): + def __init__(self, pos, life, _type, bonus_dropped, anm_wrapper, game, pop_enemy): self._game = game self._anm_wrapper = anm_wrapper self._sprite = None self._anmrunner = None self._removed = False self._type = _type + self._bonus_dropped = bonus_dropped self._was_visible = False self.frame = 0 @@ -153,6 +155,17 @@ class Enemy(object): player.die() + def killed(self): + if self.touchable: + if 0 <= self._bonus_dropped < 256: + self._game.drop_bonus(self.x, self.y, 0) + elif -256 <= self._bonus_dropped < 0: + pass #TODO: should be random, search how it is done. + + #TODO: use self.death_flags + self._removed = True + + def set_pos(self, x, y, z): self.x, self.y = x, y self.interpolator = Interpolator((x, y)) @@ -263,5 +276,8 @@ class Enemy(object): if self.bullet_launch_timer == self.bullet_launch_interval: self.fire() + if self.life <= 0: + self.killed() + self.frame += 1 diff --git a/pytouhou/game/game.py b/pytouhou/game/game.py --- a/pytouhou/game/game.py +++ b/pytouhou/game/game.py @@ -65,8 +65,8 @@ class Game(object): self.bullets = [] - def new_enemy(self, pos, life, instr_type, pop_enemy): - enemy = Enemy(pos, life, instr_type, self.enm_anm_wrapper, self, pop_enemy) + def new_enemy(self, pos, life, instr_type, bonus_dropped, pop_enemy): + enemy = Enemy(pos, life, instr_type, bonus_dropped, self.enm_anm_wrapper, self, pop_enemy) self.enemies.append(enemy) return enemy diff --git a/pytouhou/vm/eclrunner.py b/pytouhou/vm/eclrunner.py --- a/pytouhou/vm/eclrunner.py +++ b/pytouhou/vm/eclrunner.py @@ -70,7 +70,7 @@ class ECLMainRunner(object): y = self._game.prng.rand_double() * 416 if z < -990: #102h.exe@0x411881 y = self._game.prng.rand_double() * 800 - enemy = self._new_enemy_func((x, y), life, instr_type, self._pop_enemy) + enemy = self._new_enemy_func((x, y), life, instr_type, bonus_dropped, self._pop_enemy) process = ECLRunner(self._ecl, sub, enemy, self._game) self.processes.append(process) process.run_iteration() @@ -674,6 +674,12 @@ class ECLRunner(object): self._enemy.pop_enemy(sub, 0, self._getval(x), self._getval(y), 0, life, bonus_dropped, unknown2, 0) # TODO: check about unknown values + @instruction(96) + def kill_enemies(self): + for enemy in self._game.enemies: + enemy.killed() + + @instruction(97) def set_anim(self, sprite_index): self._enemy.set_anim(sprite_index) @@ -778,6 +784,14 @@ class ECLRunner(object): self._enemy.touchable = bool(value) + @instruction(119) + def drop_some_bonus(self, number): + for i in range(number): + #TODO: find the formula in the binary. + self._game.drop_bonus(self._enemy.x - 64 + self._game.prng.rand_uint16() % 128, + self._enemy.y - 64 + self._game.prng.rand_uint16() % 128, 0) + + @instruction(120) def set_automatic_orientation(self, flags): #TODO: does it change anything else than the sprite's rotation? @@ -807,6 +821,11 @@ class ECLRunner(object): self.frame += self._getval(frames) + @instruction(124) + def drop_specific_bonus(self, _type): + self._game.drop_bonus(self._enemy.x, self._enemy.y, _type) + + @instruction(126) def set_remaining_lives(self, lives): self._enemy.remaining_lives = lives