Mercurial > touhou
comparison pytouhou/vm/eclrunner.py @ 286:4838e9bab0f9
Implement dialogs (MSG files).
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Sun, 12 Feb 2012 16:06:03 +0100 |
parents | 91eb0afcb1e3 |
children | 981d1893d564 |
comparison
equal
deleted
inserted
replaced
285:2100276c289d | 286:4838e9bab0f9 |
---|---|
48 try: | 48 try: |
49 frame, sub, instr_type, args = self._ecl.main[self.instruction_pointer] | 49 frame, sub, instr_type, args = self._ecl.main[self.instruction_pointer] |
50 except IndexError: | 50 except IndexError: |
51 break | 51 break |
52 | 52 |
53 if frame > self.frame: | 53 # The msg_wait instruction stops the reading of the ECL, not just the frame incrementation. |
54 if frame > self.frame or self._game.msg_wait or self.time_stopped: | |
54 break | 55 break |
55 else: | 56 else: |
56 self.instruction_pointer += 1 | 57 self.instruction_pointer += 1 |
57 | 58 |
58 if frame == self.frame: | 59 if frame == self.frame: |
64 callback(self, sub, instr_type, *args) | 65 callback(self, sub, instr_type, *args) |
65 | 66 |
66 self.processes[:] = (process for process in self.processes | 67 self.processes[:] = (process for process in self.processes |
67 if process.run_iteration()) | 68 if process.run_iteration()) |
68 | 69 |
69 if not self.time_stopped: | 70 if not (self._game.msg_wait or self.time_stopped): |
70 self.frame += 1 | 71 self.frame += 1 |
71 | 72 |
72 | 73 |
73 def _pop_enemy(self, sub, instr_type, x, y, z, life, bonus_dropped, die_score): | 74 def _pop_enemy(self, sub, instr_type, x, y, z, life, bonus_dropped, die_score): |
74 if instr_type & 4: | 75 if instr_type & 4: |
92 if self._game.boss: | 93 if self._game.boss: |
93 return | 94 return |
94 self._pop_enemy(sub, instr_type, x, y, z, life, bonus_dropped, die_score) | 95 self._pop_enemy(sub, instr_type, x, y, z, life, bonus_dropped, die_score) |
95 | 96 |
96 | 97 |
98 @instruction(8) | |
99 def call_msg(self, sub, instr_type): | |
100 self._game.new_msg(sub) | |
101 | |
102 | |
103 @instruction(9) | |
104 def wait_msg(self, sub, instr_type): | |
105 self._game.msg_wait = True | |
106 | |
107 | |
108 @instruction(10) | |
109 def resume_ecl(self, sub, instr_type, unk1, unk2): | |
110 boss = self._game.boss | |
111 enemy = boss._enemy | |
112 self._game.msg_wait = False | |
113 if enemy.boss_callback: | |
114 boss.frame = 0 | |
115 boss.sub = enemy.boss_callback | |
116 boss.instruction_pointer = 0 | |
117 enemy.boss_callback = None | |
118 else: | |
119 raise Exception #TODO | |
120 | |
121 | |
97 @instruction(12) | 122 @instruction(12) |
98 def stop_time(self, sub, instr_type): | 123 def stop_time(self, sub, instr_type): |
99 self.time_stopped = True | 124 self.time_stopped = True |
100 | 125 |
101 | 126 |
125 | 150 |
126 | 151 |
127 def handle_callbacks(self): | 152 def handle_callbacks(self): |
128 #TODO: implement missing callbacks and clean up! | 153 #TODO: implement missing callbacks and clean up! |
129 enm = self._enemy | 154 enm = self._enemy |
130 if enm.boss_callback is not None: #XXX: MSG's job! | |
131 self.frame = 0 | |
132 self.sub = enm.boss_callback | |
133 self.instruction_pointer = 0 | |
134 enm.boss_callback = None | |
135 if enm.life <= 0 and enm.touchable: | 155 if enm.life <= 0 and enm.touchable: |
136 death_flags = enm.death_flags & 7 | 156 death_flags = enm.death_flags & 7 |
137 | 157 |
138 enm.die_anim() | 158 enm.die_anim() |
139 | 159 |
859 #TODO: if there are multiple boss, spawned by a 95, | 879 #TODO: if there are multiple boss, spawned by a 95, |
860 # only the last one has her life displayed, | 880 # only the last one has her life displayed, |
861 # but standard enemies are blocked only until any of them is killed. | 881 # but standard enemies are blocked only until any of them is killed. |
862 if value == 0: | 882 if value == 0: |
863 self._enemy.boss = True | 883 self._enemy.boss = True |
864 self._game.boss = self._enemy | 884 self._game.boss = self |
865 elif value == -1: | 885 elif value == -1: |
866 self._enemy.boss = False | 886 self._enemy.boss = False |
867 self._game.boss = None | 887 self._game.boss = None |
868 else: | 888 else: |
869 raise Exception #TODO | 889 raise Exception #TODO |
922 self._enemy.frame = value | 942 self._enemy.frame = value |
923 | 943 |
924 | 944 |
925 @instruction(113) | 945 @instruction(113) |
926 def set_low_life_trigger(self, value): | 946 def set_low_life_trigger(self, value): |
947 #XXX: this instruction takes 100 frames to fill the enemy's life bar | |
948 self.frame -= 100 | |
927 self._enemy.low_life_trigger = value | 949 self._enemy.low_life_trigger = value |
928 | 950 |
929 | 951 |
930 @instruction(114) | 952 @instruction(114) |
931 def set_low_life_callback(self, sub): | 953 def set_low_life_callback(self, sub): |
932 self._enemy.low_life_callback = sub | 954 self._enemy.low_life_callback = sub |
933 | 955 |
934 | 956 |
935 @instruction(115) | 957 @instruction(115) |
936 def set_timeout(self, timeout): | 958 def set_timeout(self, timeout): |
959 self._enemy.frame = 0 | |
937 self._enemy.timeout = timeout | 960 self._enemy.timeout = timeout |
938 | 961 |
939 | 962 |
940 @instruction(116) | 963 @instruction(116) |
941 def set_timeout_callback(self, sub): | 964 def set_timeout_callback(self, sub): |