fixed game logic bug with jumping; fixed demo saving
[awish.git] / asm / game / falling.awa
blob9e3e1da617a6ee93a579c985abc26102d022d6a2
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   rst FRST_PLAY_SOUND, SND_UMBRELLA
100   set [.umb_act], 1  ; 'umbrella activated' flag
101   set [prof_dir], PDIR_FACING
102   jeq .noturn, [spr_num], PSPR_FACING
103   ; turn and open umbrella
104   set [spr_num], PSPR_TURNING
105   set [pos_ty], 0
106   bsr game_next_frame
107   ;
108   set [spr_dir], DIR_LEFT
109   set [spr_num], PSPR_FACING
110   set [pos_ty], 2
111   bsr game_next_frame
112   ;
113   set [spr_num], 22
114   set [spr_item], 19
115   set [pos_ty], 4
116   bsr game_next_frame
117   ;
118   set [spr_num], 23
119   set [spr_item], 20
120   set [pos_ty], 8
121   bsr game_next_frame
122   ;
123   set [spr_item], 21
124   jmp .nexty
125   ;
126 .noturn:
127   ; just open umbrella
128   set [spr_dir], DIR_LEFT
129   set [pos_ty], 2
130   bsr game_next_frame
131   ;
132   set [spr_num], 22
133   set [spr_item], 19
134   set [pos_ty], 4
135   bsr game_next_frame
136   ;
137   set [spr_num], 23
138   set [spr_item], 20
139   set [pos_ty], 8
140   bsr game_next_frame
141   ;
142   set [spr_item], 21
143   jmp .nexty
144   ;
145 .noumb:
146   jeq .fastfall, [.umb_act], 0
147   ; umbrella active, fall slowly
148 .slowfall_loop:
149   add [pos_ty], 1
150   bsr game_next_frame
151   jlt .slowfall_loop, [pos_ty], 10
152   jmp .nexty
153   ;
154 .fastfall:
155   ; no umbrella, fall fast
156   set [pos_ty], 3
157   bsr game_next_frame
158   set [pos_ty], 6
159   bsr game_next_frame
160   ;
161 .nexty:
162   ; next tile
163   set [pos_ty], 0
164   add [pos_y], 1
165   ;
166   bsr prof_fix_position
167   bsr game_do_scrolls
168   bsr game_next_frame
169   ;
170 .fancheck_again:
171   ; are we out of level?
172   set [.sy], [map_height]
173   add [.sy], 1
174   jge .out_of_level, [pos_y], [.sy]
175   ;
176   ; process fans
177   jeq .nofan, [.umb_act], 0
178   bsr game_check_fans
179   jeq .nofan, [game_fan_dx_v], 0
180   bsr game_do_fans_flyslide
181   bsr prof_fix_position
182   bsr game_do_scrolls
183   ;add [.prof_fall_count], 1  ; one more tile
184   jne .fancheck_again, [game_fan_dx_v], 0
185   ;
186 .nofan:
187   mgf [pos_x], [pos_y]
188   jeq .fall_loop, FTILE_EMPTY
189   ; ok, prof is landed
190   jne .quit_cheat, [key_fall_cheat], 0
191   ; check 'special' tiles if umbrella wasn't used
192   jeq .checkbricks, [.umb_act], 0
193   ; close and hide umbrella
194   set [spr_item], 21
195   bsr game_next_frame
196   set [spr_item], 20
197   bsr game_next_frame
198   set [spr_item], 20
199   set [spr_num], 22
200   bsr game_next_frame
201   set [spr_item], 19
202   bsr game_next_frame
203   set [spr_item], -1
204   set [spr_num], PSPR_FACING
205   bsr game_next_frame
206   ; now facing
207   set [prof_dir], PDIR_FACING
208   set [spr_num], PSPR_FACING
209   set [spr_dir], DIR_LEFT
210   ; no returning
211   bsr clear_stack
212   jmp game_facing_loop_w2f
213   ;
214 .checkbricks:
215   ; check 'special' tiles
216   mgf [pos_x], [pos_y], [.type]
217   jeq .bounce, [.type], FTILE_BOUNCE
218   ; prof dies when falls 5 or more tiles
219   jge .dead, [.prof_fall_count], 5
220   ; prof is alive, process specials
221   bsr game_check_monster_eating
222   ;
223   jeq .glass, [.type], FTILE_GLASS
224   jeq .ice, [.type], FTILE_ICE
225   ;
226 .quit_cheat:
227 .nospecials:
228   bsr clear_stack
229   bsr game_is_on_exit
230   jne game_do_door_exit, 0
231   jeq game_facing_loop_w2f, [spr_num], PSPR_FACING
232   jmp game_lr_stand_loop
233   ;
234 ; landed on glass
235 .glass:
236   jlt .nospecials, [.prof_fall_count], 2 ; get out if glass should not be broken
237   ;
238   rst FRST_PLAY_SOUND, SND_GLASS
239   new entry_bdis, [.tid]
240   set pos_x, [pos_x], [.tid]
241   add 1, [pos_y], [.tmp]
242   set pos_y, [.tmp], [.tid]
243 .glassloop:
244   bsr game_next_frame
245   sta [.tid]
246   jeq .glassloop, 0
247   ; and fall again
248   set [.prof_fall_count], 0
249   jmp .really_falling
250   ;
251 ; landed on bounce pad
252 .bounce:
253   ; bounce animation: down and up
254   rst FRST_PLAY_SOUND, SND_BOUNCE
255   new entry_bstat, [.tid]
256   set pos_x, [pos_x], [.tid]
257   set pos_y, [pos_y], [.tid]
258   set [pos_ty], 1
259   bsr game_next_frame
260   bsr game_next_frame
261   set [pos_ty], 0
262   kil [.tid]
263   bsr game_next_frame
264   bsr game_next_frame
265   jeq .nospecials, [spr_num], PSPR_FACING
266   ;
267   set [spr_num], PSPR_JUMPING
268   ; move prof up
269 .bouncemovingup:
270   jle .bouncejump, [.prof_fall_count], 1
271   set [pos_ty], -3
272   bsr game_next_frame
273   set [pos_ty], -6
274   bsr game_next_frame
275   set [pos_ty], 0
276   sub [pos_y], 1
277   bsr prof_fix_position
278   bsr game_do_scrolls
279   bsr game_next_frame
280   sub [.prof_fall_count], 1
281   jmp .bouncemovingup
282 .bouncejump:
283   bsr game_can_jump
284   jeq .bounce_turns, 0
285   bsr game_do_jump
286   drp
287   jmp .nospecials
288 .bounce_turns:
289   ; one more tile up
290   set [pos_ty], -3
291   bsr game_next_frame
292   set [pos_ty], -6
293   bsr game_next_frame
294   set [pos_ty], 0
295   sub [pos_y], 1
296   bsr prof_fix_position
297   ;bsr game_do_scrolls
298   ; here we can't jump, do turning
299   psh [prof_dir]
300   bsr prof_turn_to_player
301   pop [prof_dir]
302   ;
303   mul [prof_dir], -1  ; opposite direction
304   bsr game_can_jump
305   jne .bounce_full_turn, 0
306   ; stay facing the player
307   set [prof_dir], PDIR_FACING
308   jmp game_check_fall
309 .bounce_full_turn:
310   bsr prof_turn_to_dir
311   jmp game_check_fall
312   ;
313 ; landed on ice
314 .ice:
315   jne .nospecials, [spr_num], PSPR_STANDING
316   ; slide!
317   bsr clear_stack
318   jmp game_check_do_slide_move
319   ;
320 .dead:
321   set [monster_tid], -666
322   jmp game_do_die_fall ; never returns
323 ; prof falls out of level
324 .out_of_level:
325   set [.sy], [map_height]
326   add [.sy], 5
327   jge .out_dead, [pos_y], [.sy]
328   ; fall one more tile
329   jeq .fastfall_x01, [.umb_act], 0
330   ; umbrella active, fall slowly
331 .slowfall_loop_x01:
332   add [pos_ty], 1
333   bsr game_next_frame
334   jlt .slowfall_loop_x01, [pos_ty], 10
335   jmp .nexty_x01
336   ;
337 .fastfall_x01:
338   ; no umbrella, fall fast
339   set [pos_ty], 3
340   bsr game_next_frame
341   set [pos_ty], 6
342   bsr game_next_frame
343   ;
344 .nexty_x01:
345   ; next tile
346   set [pos_ty], 0
347   add [pos_y], 1
348   ;
349   bsr prof_fix_position
350   bsr game_next_frame
351   jmp .out_of_level
352 .out_dead:
353   set [game_state], GAME_STATE_DEAD
354   jmp game_wait_and_restart
355 endp: game_check_fall