forgot to set 'dead' flag when falling out of level
[awish.git] / asm / game / falling.awa
blobba49a2c6bd7159649a734131bf3949a2131f5261
1 /*
2  * This program is free software: you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation, either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
14  */
15 proc: game_check_monster_eating
16   bsr game_item_at_prof
17   jne .quit, ITEM_HARRY
18   set [monster_tid], [rst_result]
19   ; never returns
20   jmp game_do_die_monster
21 .quit:
22   ret
23 endp: game_check_monster_eating
26 ; check if we can slide left or right while flying
27 ; and slide if can
28 ; 'game_fan_dx_v' will be set to 0 if prof not slides
29 proc: game_do_fans_flyslide
30 locals: .f
31   ; game_fan_dx_v is correct here
32   ; check if we can move to the corresponding side
33   psh [pos_x]
34   add [game_fan_dx_v]
35   psh [pos_y]
36   mgf
37   jne .noslide, FTILE_EMPTY
38   ; ok, we can slide, do that
39   set [.f], 10
40 .fanslide:
41   ; change pos_tx
42   psh [game_fan_dx_v]
43   mul 2
44   add [pos_tx]
45   pop [pos_tx]
46   ; change pos_ty
47   add [pos_ty], 1
48   bsr game_next_frame
49   sub [.f], 1
50   jgt .fanslide, [.f], 0
51   set [pos_tx], 0
52   set [pos_ty], 0
53   add [pos_x], [game_fan_dx_v]
54   add [pos_y], 1
55   bsr prof_fix_position
56   ret
57   ;
58 .noslide:
59   set [game_fan_dx_v], 0  ; clear 'sliding' flag
60   ret
61 endp: game_do_fans_flyslide
64 ; will not return if 'falling' mode activated
65 proc: game_check_fall
66 local: .umb_act         ; umbrella activated?
67 local: .prof_fall_count ; # of tiles before prof hits the ground
68 locals: .sy, .type, .tid, .tmp
69   ;
70   set [.umb_act], 0
71   set [.prof_fall_count], 0
72   ;
73   jeq .nowcheat, [key_walk_cheat], 0
74   ret
75 .nowcheat:
76   ;
77   mgf [pos_x], [pos_y]
78   jeq .really_falling, FTILE_EMPTY
79   ;
80   bsr game_check_monster_eating
81   bsr game_is_on_exit
82   jne game_do_door_exit, 0
83   ret
84   ;
85 .really_falling:
86   ;jeq .fall_loop, [key_walk_cheat], 0
87   ;jmp .nospecials
88 .fall_loop:
89   add [.prof_fall_count], 1  ; one more tile
90   ;
91   jlt .noumb, [prof_item], 1 ; no items -- no umbrella
92   get [prof_item], item_id
93   jne .noumb, ITEM_UMBRELLA
94   jne .noumb, [.prof_fall_count], 4  ; open only at 4th tile
95   ; don't activate umbrella if prof is about to land
96   mgf [pos_x], [pos_y]
97   jne .noumb, FTILE_EMPTY
98   ; activate umbrella
99   set [.umb_act], 1  ; 'umbrella activated' flag
100   set [prof_dir], PDIR_FACING
101   jeq .noturn, [spr_num], PSPR_FACING
102   ; turn and open umbrella
103   set [spr_num], PSPR_TURNING
104   set [pos_ty], 0
105   bsr game_next_frame
106   ;
107   set [spr_dir], DIR_LEFT
108   set [spr_num], PSPR_FACING
109   set [pos_ty], 2
110   bsr game_next_frame
111   ;
112   set [spr_num], 22
113   set [spr_item], 19
114   set [pos_ty], 4
115   bsr game_next_frame
116   ;
117   set [spr_num], 23
118   set [spr_item], 20
119   set [pos_ty], 8
120   bsr game_next_frame
121   ;
122   set [spr_item], 21
123   jmp .nexty
124   ;
125 .noturn:
126   ; just open umbrella
127   set [spr_dir], DIR_LEFT
128   set [pos_ty], 2
129   bsr game_next_frame
130   ;
131   set [spr_num], 22
132   set [spr_item], 19
133   set [pos_ty], 4
134   bsr game_next_frame
135   ;
136   set [spr_num], 23
137   set [spr_item], 20
138   set [pos_ty], 8
139   bsr game_next_frame
140   ;
141   set [spr_item], 21
142   jmp .nexty
143   ;
144 .noumb:
145   jeq .fastfall, [.umb_act], 0
146   ; umbrella active, fall slowly
147 .slowfall_loop:
148   add [pos_ty], 1
149   bsr game_next_frame
150   jlt .slowfall_loop, [pos_ty], 10
151   jmp .nexty
152   ;
153 .fastfall:
154   ; no umbrella, fall fast
155   set [pos_ty], 3
156   bsr game_next_frame
157   set [pos_ty], 6
158   bsr game_next_frame
159   ;
160 .nexty:
161   ; next tile
162   set [pos_ty], 0
163   add [pos_y], 1
164   ;
165   bsr prof_fix_position
166   bsr game_do_scrolls
167   bsr game_next_frame
168   ;
169 .fancheck_again:
170   ; are we out of level?
171   set [.sy], [map_height]
172   add [.sy], 1
173   jge .out_of_level, [pos_y], [.sy]
174   ;
175   ; process fans
176   jeq .nofan, [.umb_act], 0
177   bsr game_check_fans
178   jeq .nofan, [game_fan_dx_v], 0
179   bsr game_do_fans_flyslide
180   bsr prof_fix_position
181   bsr game_do_scrolls
182   ;add [.prof_fall_count], 1  ; one more tile
183   jne .fancheck_again, [game_fan_dx_v], 0
184   ;
185 .nofan:
186   mgf [pos_x], [pos_y]
187   jeq .fall_loop, FTILE_EMPTY
188   ; ok, prof is landed
189   jne .quit_cheat, [key_fall_cheat], 0
190   ; check 'special' tiles if umbrella wasn't used
191   jeq .checkbricks, [.umb_act], 0
192   ; close and hide umbrella
193   set [spr_item], 21
194   bsr game_next_frame
195   set [spr_item], 20
196   bsr game_next_frame
197   set [spr_item], 20
198   set [spr_num], 22
199   bsr game_next_frame
200   set [spr_item], 19
201   bsr game_next_frame
202   set [spr_item], -1
203   set [spr_num], PSPR_FACING
204   bsr game_next_frame
205   ; now facing
206   set [prof_dir], PDIR_FACING
207   set [spr_num], PSPR_FACING
208   set [spr_dir], DIR_LEFT
209   ; no returning
210   bsr clear_stack
211   jmp game_facing_loop_w2f
212   ;
213 .checkbricks:
214   ; check 'special' tiles
215   mgf [pos_x], [pos_y], [.type]
216   jeq .bounce, [.type], FTILE_BOUNCE
217   ; prof dies when falls 5 or more tiles
218   jge .dead, [.prof_fall_count], 5
219   ; prof is alive, process specials
220   bsr game_check_monster_eating
221   ;
222   jeq .glass, [.type], FTILE_GLASS
223   jeq .ice, [.type], FTILE_ICE
224   ;
225 .quit_cheat:
226 .nospecials:
227   bsr clear_stack
228   bsr game_is_on_exit
229   jne game_do_door_exit, 0
230   jeq game_facing_loop_w2f, [spr_num], PSPR_FACING
231   jmp game_lr_stand_loop
232   ;
233 ; landed on glass
234 .glass:
235   jlt .nospecials, [.prof_fall_count], 2 ; get out if glass should not be broken
236   ;
237   new entry_bdis, [.tid]
238   set pos_x, [pos_x], [.tid]
239   add 1, [pos_y], [.tmp]
240   set pos_y, [.tmp], [.tid]
241 .glassloop:
242   bsr game_next_frame
243   sta [.tid]
244   jeq .glassloop, 0
245   ; and fall again
246   set [.prof_fall_count], 0
247   jmp .really_falling
248   ;
249 ; landed on bounce pad
250 .bounce:
251   ; bounce animation: down and up
252   new entry_bstat, [.tid]
253   set pos_x, [pos_x], [.tid]
254   set pos_y, [pos_y], [.tid]
255   set [pos_ty], 1
256   bsr game_next_frame
257   bsr game_next_frame
258   set [pos_ty], 0
259   kil [.tid]
260   bsr game_next_frame
261   bsr game_next_frame
262   jeq .nospecials, [spr_num], PSPR_FACING
263   ;
264   set [spr_num], PSPR_JUMPING
265   ; move prof up
266 .bouncemovingup:
267   jle .bouncejump, [.prof_fall_count], 1
268   set [pos_ty], -3
269   bsr game_next_frame
270   set [pos_ty], -6
271   bsr game_next_frame
272   set [pos_ty], 0
273   sub [pos_y], 1
274   bsr prof_fix_position
275   bsr game_do_scrolls
276   bsr game_next_frame
277   sub [.prof_fall_count], 1
278   jmp .bouncemovingup
279 .bouncejump:
280   bsr game_can_jump
281   jeq .bounce_turns, 0
282   bsr game_do_jump
283   jmp .nospecials
284 .bounce_turns:
285   ; one more tile up
286   set [pos_ty], -3
287   bsr game_next_frame
288   set [pos_ty], -6
289   bsr game_next_frame
290   set [pos_ty], 0
291   sub [pos_y], 1
292   bsr prof_fix_position
293   ;bsr game_do_scrolls
294   ; here we can't jump, do turning
295   psh [prof_dir]
296   bsr prof_turn_to_player
297   pop [prof_dir]
298   ;
299   mul [prof_dir], -1  ; opposite direction
300   bsr game_can_jump
301   jne .bounce_full_turn, 0
302   ; stay facing the player
303   set [prof_dir], PDIR_FACING
304   jmp game_check_fall
305 .bounce_full_turn:
306   bsr prof_turn_to_dir
307   jmp game_check_fall
308   ;
309 ; landed on ice
310 .ice:
311   jne .nospecials, [spr_num], PSPR_STANDING
312   ; slide!
313   bsr clear_stack
314   jmp game_check_do_slide_move
315   ;
316 .dead:
317   set [monster_tid], -666
318   jmp game_do_die_fall ; never returns
319 ; prof falls out of level
320 .out_of_level:
321   set [.sy], [map_height]
322   add [.sy], 5
323   jge .out_dead, [pos_y], [.sy]
324   ; fall one more tile
325   jeq .fastfall_x01, [.umb_act], 0
326   ; umbrella active, fall slowly
327 .slowfall_loop_x01:
328   add [pos_ty], 1
329   bsr game_next_frame
330   jlt .slowfall_loop_x01, [pos_ty], 10
331   jmp .nexty_x01
332   ;
333 .fastfall_x01:
334   ; no umbrella, fall fast
335   set [pos_ty], 3
336   bsr game_next_frame
337   set [pos_ty], 6
338   bsr game_next_frame
339   ;
340 .nexty_x01:
341   ; next tile
342   set [pos_ty], 0
343   add [pos_y], 1
344   ;
345   bsr prof_fix_position
346   bsr game_next_frame
347   jmp .out_of_level
348 .out_dead:
349   set [game_state], GAME_STATE_DEAD
350   jmp game_wait_and_restart
351 endp: game_check_fall