Mercurial > touhou
comparison pytouhou/vm/eclrunner.py @ 291:f6b8483a990d
Refactor a bit and fix Rumia's disparition.
author | Thibaut Girka <thib@sitedethib.com> |
---|---|
date | Wed, 15 Feb 2012 19:20:06 +0100 |
parents | 981d1893d564 |
children | 2a60642e8892 |
comparison
equal
deleted
inserted
replaced
290:18e4ed141dd8 | 291:f6b8483a990d |
---|---|
147 self.instruction_pointer = 0 | 147 self.instruction_pointer = 0 |
148 | 148 |
149 self.stack = [] | 149 self.stack = [] |
150 | 150 |
151 | 151 |
152 def switch_to_sub(self, sub): | |
153 self.frame = 0 | |
154 self.sub = sub | |
155 self.instruction_pointer = 0 | |
156 | |
157 | |
152 def handle_callbacks(self): | 158 def handle_callbacks(self): |
153 #TODO: implement missing callbacks and clean up! | 159 #TODO: implement missing callbacks and clean up! |
154 enm = self._enemy | 160 enm = self._enemy |
155 if enm.life <= 0 and enm.touchable: | 161 if enm.life <= 0 and enm.touchable: |
156 death_flags = enm.death_flags & 7 | 162 death_flags = enm.death_flags & 7 |
157 | 163 |
158 enm.die_anim() | 164 enm.die_anim() |
159 | 165 |
160 if death_flags < 4: | 166 if death_flags < 4: |
161 if enm._bonus_dropped >= 0: | 167 if enm._bonus_dropped > -1: |
162 enm.drop_particles(7, 0) | 168 enm.drop_particles(7, 0) |
163 self._game.drop_bonus(enm.x, enm.y, enm._bonus_dropped) | 169 self._game.drop_bonus(enm.x, enm.y, enm._bonus_dropped) |
164 elif enm._bonus_dropped == -1: | 170 elif enm._bonus_dropped == -1: |
165 if self._game.deaths_count % 3 == 0: | 171 if self._game.deaths_count % 3 == 0: |
166 enm.drop_particles(10, 0) | 172 enm.drop_particles(10, 0) |
184 #TODO: disable boss mode | 190 #TODO: disable boss mode |
185 enm.damageable = False | 191 enm.damageable = False |
186 enm.life = 1 | 192 enm.life = 1 |
187 enm.death_flags = 0 | 193 enm.death_flags = 0 |
188 | 194 |
189 if death_flags != 0 and enm.death_callback >= 0: | 195 if death_flags != 0 and enm.death_callback > -1: |
190 self.frame = 0 | 196 self.switch_to_sub(enm.death_callback) |
191 self.sub = enm.death_callback | |
192 self.instruction_pointer = 0 | |
193 enm.death_callback = -1 | 197 enm.death_callback = -1 |
194 elif enm.life <= enm.low_life_trigger and enm.low_life_callback >= 0: | 198 elif enm.life <= enm.low_life_trigger and enm.low_life_callback > -1: |
195 self.frame = 0 | 199 self.switch_to_sub(enm.low_life_callback) |
196 self.sub = enm.low_life_callback | |
197 self.instruction_pointer = 0 | |
198 enm.low_life_callback = -1 | 200 enm.low_life_callback = -1 |
199 elif enm.timeout and enm.frame == enm.timeout: | 201 elif enm.timeout != -1 and enm.frame == enm.timeout: |
200 enm.frame = 0 | 202 enm.frame = 0 |
201 if enm.timeout_callback >= 0: | 203 if enm.timeout_callback > -1: |
202 self.frame = 0 | 204 self.switch_to_sub(enm.timeout_callback) |
203 self.sub = enm.timeout_callback | |
204 self.instruction_pointer = 0 | |
205 enm.timeout_callback = -1 | 205 enm.timeout_callback = -1 |
206 elif enm.touchable: | 206 elif enm.touchable: |
207 enm.life = 0 | 207 enm.life = 0 |
208 elif enm.death_callback >= 0: | 208 elif enm.death_callback > -1: |
209 self.frame = 0 | 209 self.switch_to_sub(enm.death_callback) |
210 self.sub = enm.death_callback | |
211 self.instruction_pointer = 0 | |
212 enm.death_callback = -1 | 210 enm.death_callback = -1 |
213 enm.timeout = -1 #TODO: check | 211 enm.timeout = -1 #TODO: check |
214 else: | 212 else: |
215 raise Exception('What the hell, man!') | 213 raise Exception('What the hell, man!') |
216 | |
217 | 214 |
218 def run_iteration(self): | 215 def run_iteration(self): |
219 # First, if enemy is dead, return | 216 # First, if enemy is dead, return |
220 if self._enemy._removed: | 217 if self._enemy._removed: |
221 return False | 218 return False |
233 if frame > self.frame: | 230 if frame > self.frame: |
234 break | 231 break |
235 else: | 232 else: |
236 self.instruction_pointer += 1 | 233 self.instruction_pointer += 1 |
237 | 234 |
238 | |
239 #TODO: skip bad ranks | |
240 if not rank_mask & (0x100 << self._game.rank): | 235 if not rank_mask & (0x100 << self._game.rank): |
241 continue | 236 continue |
242 | |
243 | 237 |
244 if frame == self.frame: | 238 if frame == self.frame: |
245 try: | 239 try: |
246 callback = self._handlers[instr_type] | 240 callback = self._handlers[instr_type] |
247 except KeyError: | 241 except KeyError: |
479 | 473 |
480 @instruction(35) | 474 @instruction(35) |
481 def call(self, sub, param1, param2): | 475 def call(self, sub, param1, param2): |
482 self.stack.append((self.sub, self.frame, self.instruction_pointer, | 476 self.stack.append((self.sub, self.frame, self.instruction_pointer, |
483 list(self.variables), self.comparison_reg)) | 477 list(self.variables), self.comparison_reg)) |
484 self.sub = sub | |
485 self.frame = 0 | |
486 self.instruction_pointer = 0 | |
487 self.variables[0] = param1 | 478 self.variables[0] = param1 |
488 self.variables[4] = param2 | 479 self.variables[4] = param2 |
480 self.switch_to_sub(sub) | |
489 | 481 |
490 | 482 |
491 @instruction(36) | 483 @instruction(36) |
492 def ret(self): | 484 def ret(self): |
493 self.sub, self.frame, self.instruction_pointer, self.variables, self.comparison_reg = self.stack.pop() | 485 self.sub, self.frame, self.instruction_pointer, self.variables, self.comparison_reg = self.stack.pop() |
918 self._enemy.death_callback = sub | 910 self._enemy.death_callback = sub |
919 | 911 |
920 | 912 |
921 @instruction(109) | 913 @instruction(109) |
922 def memory_write(self, value, index): | 914 def memory_write(self, value, index): |
923 #TODO | |
924 #XXX: this is a hack to display bosses although we don't handle MSG :) | |
925 if index == 0: | 915 if index == 0: |
926 self._enemy.boss_callback = value | 916 self._enemy.boss_callback = value |
927 else: | 917 else: |
928 raise Exception #TODO | 918 raise Exception #TODO |
929 | 919 |
942 self._enemy.frame = value | 932 self._enemy.frame = value |
943 | 933 |
944 | 934 |
945 @instruction(113) | 935 @instruction(113) |
946 def set_low_life_trigger(self, value): | 936 def set_low_life_trigger(self, value): |
947 #XXX: this instruction takes 100 frames to fill the enemy's life bar | 937 #TODO: the enemy's life bar fills in 100 frames. |
948 self.frame -= 100 | 938 # During those frames, the ECL doesn't seem to be executed. |
939 # However, the ECL isn't directly paused by this instruction itself. | |
949 self._enemy.low_life_trigger = value | 940 self._enemy.low_life_trigger = value |
950 | 941 |
951 | 942 |
952 @instruction(114) | 943 @instruction(114) |
953 def set_low_life_callback(self, sub): | 944 def set_low_life_callback(self, sub): |