changeset 48:8353c33d53d4

Support a few more instructions
author Thibaut Girka <thib@sitedethib.com>
date Mon, 22 Aug 2011 15:45:42 +0200
parents 1f1793e7ec8e
children cbe1cb50f2fd
files pytouhou/game/eclrunner.py pytouhou/game/enemymanager.py
diffstat 2 files changed, 110 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/pytouhou/game/eclrunner.py
+++ b/pytouhou/game/eclrunner.py
@@ -12,8 +12,11 @@ class ECLRunner(object):
         self.stack = []
 
         self.implementation = {4: self.set_variable,
+                               5: self.set_variable,
                                2: self.relative_jump,
                                3: self.relative_jump_ex,
+                               20: self.add,
+                               21: self.substract,
                                35: self.call,
                                36: self.ret,
                                109: self.memory_write}
@@ -21,6 +24,27 @@ class ECLRunner(object):
             self.implementation.update(implementation)
 
 
+    def _get_value(self, value): #TODO: -10013 and beyond!
+        assert not -10025 <= value <= -10013
+        if -10012 <= value <= -10001:
+            return self.variables[int(-10001-value)]
+        else:
+            return value
+
+
+    def add(self, variable_id, a, b):
+        #TODO: proper variable handling
+        #TODO: int vs float thing
+        self.variables[-10001-variable_id] = self._get_value(a) + self._get_value(b)
+
+
+    def substract(self, variable_id, a, b):
+        #TODO: proper variable handling
+        #TODO: int vs float thing
+        self.variables[-10001-variable_id] = self._get_value(a) - self._get_value(b)
+
+
+
     def memory_write(self, value, index):
         #TODO
         #XXX: this is a hack to display bosses although we don't handle MSG :)
@@ -45,10 +69,9 @@ class ECLRunner(object):
         self.sub, self.frame, self.instruction_pointer, self.variables = self.stack.pop()
 
 
-
     def set_variable(self, variable_id, value):
         #TODO: -10013 and beyond!
-        self.variables[-10000-variable_id] = value
+        self.variables[-10001-variable_id] = self._get_value(value)
 
 
     def relative_jump(self, frame, instruction_pointer):
@@ -56,8 +79,8 @@ class ECLRunner(object):
 
 
     def relative_jump_ex(self, frame, instruction_pointer, variable_id):
-        if self.variables[-10000-variable_id]:
-            self.variables[-10000-variable_id] -= 1
+        if self.variables[-10001-variable_id]:
+            self.variables[-10001-variable_id] -= 1
             self.frame, self.instruction_pointer = frame, instruction_pointer
 
 
--- a/pytouhou/game/enemymanager.py
+++ b/pytouhou/game/enemymanager.py
@@ -24,8 +24,17 @@ class Enemy(object):
         self.frame = 0
         self.sprite = None
         self.pending_bullets = []
-        self.bullet_attributes = []
+        self.bullet_attributes = None
         self.bullet_launch_offset = (0, 0)
+        self.vulnerable = True
+        self.death_callback = None
+        self.low_life_callback = None
+        self.low_life_trigger = None
+        self.timeout = None
+        self.remaining_lives = -1
+
+        self.bullet_launch_interval = 0
+        self.delay_attack = False
 
         self.death_sprite = None
         self.movement_dependant_sprites = None
@@ -38,19 +47,79 @@ class Enemy(object):
 
         self.hitbox = (0, 0)
 
-        self.ecl_runner.implementation.update({#67: ('HHIIffffI', self.set_bullet_attributes),
-                                               97: (self.set_sprite),
-                                               98: (self.set_multiple_sprites),
-                                               45: (self.set_angle_speed),
-                                               43: (self.set_pos),
-                                               46: (self.set_rotation_speed),
-                                               47: (self.set_speed),
-                                               48: (self.set_acceleration),
-                                               51: (self.target_player),
-                                               57: (self.move_to),
-                                               100: (self.set_death_sprite),
-                                               103: (self.set_hitbox)}) #TODO
+        self.ecl_runner.implementation.update({67: self.set_bullet_attributes,
+                                               97: self.set_sprite,
+                                               98: self.set_multiple_sprites,
+                                               45: self.set_angle_speed,
+                                               43: self.set_pos,
+                                               46: self.set_rotation_speed,
+                                               47: self.set_speed,
+                                               48: self.set_acceleration,
+                                               51: self.target_player,
+                                               57: self.move_to,
+                                               77: self.set_bullet_interval,
+                                               78: self.set_delay_attack,
+                                               79: self.set_no_delay_attack,
+                                               81: self.set_bullet_launch_offset,
+                                               100: self.set_death_sprite,
+                                               103: self.set_hitbox,
+                                               105: self.set_vulnerable,
+                                               108: self.set_death_callback,
+                                               113: self.set_low_life_trigger,
+                                               114: self.set_low_life_callback,
+                                               115: self.set_timeout,
+                                               126: self.set_remaining_lives}) #TODO
+
+
+    def set_remaining_lives(self, lives):
+        self.remaining_lives = lives
+
+
+    def set_death_callback(self, sub):
+        self.death_callback = sub
+
+
+    def set_low_life_trigger(self, value):
+        self.low_life_trigger = value
+
 
+    def set_low_life_callback(self, sub):
+        self.low_life_callback = sub
+
+
+    def set_timeout(self, timeout):
+        self.timeout = timeout
+
+
+    def set_vulnerable(self, vulnerable):
+        self.vulnerable = bool(vulnerable & 1)
+
+
+    def set_bullet_launch_offset(self, x, y, z):
+        self.bullet_launch_offset = (x, y)
+
+
+    def set_bullet_attributes(self, bullet_anim, launch_anim, bullets_per_shot,
+                              number_of_shots, speed, unknown, launch_angle,
+                              angle, flags):
+        self.bullet_attributes = (1, bullet_anim, launch_anim, bullets_per_shot,
+                                  number_of_shots, speed, unknown, launch_angle,
+                                  angle, flags)
+        if not self.delay_attack:
+            pass
+            #TODO: actually fire
+
+
+    def set_bullet_interval(self, value):
+        self.bullet_launch_interval = value
+
+
+    def set_delay_attack(self):
+        self.delay_attack = True
+
+
+    def set_no_delay_attack(self):
+        self.delay_attack = False
 
 
     def set_death_sprite(self, sprite_index):
@@ -94,7 +163,7 @@ class Enemy(object):
 
     def target_player(self, unknown, speed):
         self.speed = speed #TODO: unknown
-        player_x, player_y = 192., 400.#TODO
+        player_x, player_y = 192., 384.#TODO
         self.angle = atan2(player_y - self.y, player_x - self.x)