Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | pmbaty | 1 | /* |
2 | SDLPoP, a port/conversion of the DOS game Prince of Persia. |
||
3 | Copyright (C) 2013-2018 Dávid Nagy |
||
4 | |||
5 | This program is free software: you can redistribute it and/or modify |
||
6 | it under the terms of the GNU General Public License as published by |
||
7 | the Free Software Foundation, either version 3 of the License, or |
||
8 | (at your option) any later version. |
||
9 | |||
10 | This program is distributed in the hope that it will be useful, |
||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
13 | GNU General Public License for more details. |
||
14 | |||
15 | You should have received a copy of the GNU General Public License |
||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
||
17 | |||
18 | The authors of this program may be contacted at http://forum.princed.org |
||
19 | */ |
||
20 | |||
21 | #include "common.h" |
||
22 | |||
23 | // seg007:0000 |
||
24 | void __pascal far process_trobs() { |
||
25 | word need_delete; |
||
26 | word index; |
||
27 | word new_index; |
||
28 | need_delete = 0; |
||
29 | if (trobs_count == 0) return; |
||
30 | for (index = 0; index < trobs_count; ++index) { |
||
31 | trob = trobs[index]; |
||
32 | animate_tile(); |
||
33 | trobs[index].type = trob.type; |
||
34 | if (trob.type < 0) { |
||
35 | need_delete = 1; |
||
36 | } |
||
37 | } |
||
38 | if (need_delete) { |
||
39 | for (index = new_index = 0; index < trobs_count; ++index) { |
||
40 | if (trobs[index].type >= 0) { |
||
41 | trobs[new_index++] = trobs[index]; |
||
42 | } |
||
43 | } |
||
44 | trobs_count = new_index; |
||
45 | } |
||
46 | } |
||
47 | |||
48 | // seg007:00AF |
||
49 | void __pascal far animate_tile() { |
||
50 | get_room_address(trob.room); |
||
51 | switch (get_curr_tile(trob.tilepos)) { |
||
52 | case tiles_19_torch: |
||
53 | case tiles_30_torch_with_debris: |
||
54 | animate_torch(); |
||
55 | break; |
||
56 | case tiles_6_closer: |
||
57 | case tiles_15_opener: |
||
58 | animate_button(); |
||
59 | break; |
||
60 | case tiles_2_spike: |
||
61 | animate_spike(); |
||
62 | break; |
||
63 | case tiles_11_loose: |
||
64 | animate_loose(); |
||
65 | break; |
||
66 | case tiles_0_empty: |
||
67 | animate_empty(); |
||
68 | break; |
||
69 | case tiles_18_chomper: |
||
70 | animate_chomper(); |
||
71 | break; |
||
72 | case tiles_4_gate: |
||
73 | animate_door(); |
||
74 | break; |
||
75 | case tiles_16_level_door_left: |
||
76 | animate_leveldoor(); |
||
77 | break; |
||
78 | case tiles_10_potion: |
||
79 | animate_potion(); |
||
80 | break; |
||
81 | case tiles_22_sword: |
||
82 | animate_sword(); |
||
83 | break; |
||
84 | default: |
||
85 | trob.type = -1; |
||
86 | break; |
||
87 | } |
||
88 | curr_room_modif[trob.tilepos] = curr_modifier; |
||
89 | } |
||
90 | |||
91 | // seg007:0166 |
||
92 | short __pascal far is_trob_in_drawn_room() { |
||
93 | if (trob.room != drawn_room) { |
||
94 | trob.type = -1; |
||
95 | return 0; |
||
96 | } else { |
||
97 | return 1; |
||
98 | } |
||
99 | } |
||
100 | |||
101 | // seg007:017E |
||
102 | void __pascal far set_redraw_anim_right() { |
||
103 | set_redraw_anim(get_trob_right_pos_in_drawn_room(), 1); |
||
104 | } |
||
105 | |||
106 | // seg007:018C |
||
107 | void __pascal far set_redraw_anim_curr() { |
||
108 | set_redraw_anim(get_trob_pos_in_drawn_room(), 1); |
||
109 | } |
||
110 | |||
111 | // seg007:019A |
||
112 | void __pascal far redraw_at_trob() { |
||
113 | word tilepos; |
||
114 | redraw_height = 63; |
||
115 | tilepos = get_trob_pos_in_drawn_room(); |
||
116 | set_redraw_full(tilepos, 1); |
||
117 | set_wipe(tilepos, 1); |
||
118 | } |
||
119 | |||
120 | // seg007:01C5 |
||
121 | void __pascal far redraw_21h() { |
||
122 | redraw_height = 0x21; |
||
123 | redraw_tile_height(); |
||
124 | } |
||
125 | |||
126 | // seg007:01D0 |
||
127 | void __pascal far redraw_11h() { |
||
128 | redraw_height = 0x11; |
||
129 | redraw_tile_height(); |
||
130 | } |
||
131 | |||
132 | // seg007:01DB |
||
133 | void __pascal far redraw_20h() { |
||
134 | redraw_height = 0x20; |
||
135 | redraw_tile_height(); |
||
136 | } |
||
137 | |||
138 | // seg007:01E6 |
||
139 | void __pascal far draw_trob() { |
||
140 | word var_2; |
||
141 | var_2 = get_trob_right_pos_in_drawn_room(); |
||
142 | set_redraw_anim(var_2, 1); |
||
143 | set_redraw_fore(var_2, 1); |
||
144 | set_redraw_anim(get_trob_right_above_pos_in_drawn_room(), 1); |
||
145 | } |
||
146 | |||
147 | // seg007:0218 |
||
148 | void __pascal far redraw_tile_height() { |
||
149 | short tilepos; |
||
150 | tilepos = get_trob_pos_in_drawn_room(); |
||
151 | set_redraw_full(tilepos, 1); |
||
152 | set_wipe(tilepos, 1); |
||
153 | tilepos = get_trob_right_pos_in_drawn_room(); |
||
154 | set_redraw_full(tilepos, 1); |
||
155 | set_wipe(tilepos, 1); |
||
156 | } |
||
157 | |||
158 | // seg007:0258 |
||
159 | short __pascal far get_trob_pos_in_drawn_room() { |
||
160 | short tilepos; |
||
161 | tilepos = trob.tilepos; |
||
162 | if (trob.room == room_A) { |
||
163 | if (tilepos >= 20 && tilepos < 30) { |
||
164 | // 20..29 -> -1..-10 |
||
165 | tilepos = 19 - tilepos; |
||
166 | } else { |
||
167 | tilepos = 30; |
||
168 | } |
||
169 | } else { |
||
170 | if (trob.room != drawn_room) { |
||
171 | tilepos = 30; |
||
172 | } |
||
173 | } |
||
174 | return tilepos; |
||
175 | } |
||
176 | |||
177 | // seg007:029D |
||
178 | short __pascal far get_trob_right_pos_in_drawn_room() { |
||
179 | word tilepos; |
||
180 | tilepos = trob.tilepos; |
||
181 | if (trob.room == drawn_room) { |
||
182 | if (tilepos % 10 != 9) { |
||
183 | ++tilepos; |
||
184 | } else { |
||
185 | tilepos = 30; |
||
186 | } |
||
187 | } else if (trob.room == room_L) { |
||
188 | if (tilepos % 10 == 9) { |
||
189 | tilepos -= 9; |
||
190 | } else { |
||
191 | tilepos = 30; |
||
192 | } |
||
193 | } else if (trob.room == room_A) { |
||
194 | if (tilepos >= 20 && tilepos < 29) { |
||
195 | // 20..28 -> -2..-10 |
||
196 | tilepos = 18 - tilepos; |
||
197 | } else { |
||
198 | tilepos = 30; |
||
199 | } |
||
200 | } else if (trob.room == room_AL && tilepos == 29) { |
||
201 | tilepos = -1; |
||
202 | } else { |
||
203 | tilepos = 30; |
||
204 | } |
||
205 | return tilepos; |
||
206 | } |
||
207 | |||
208 | // seg007:032C |
||
209 | short __pascal far get_trob_right_above_pos_in_drawn_room() { |
||
210 | word tilepos; |
||
211 | tilepos = trob.tilepos; |
||
212 | if (trob.room == drawn_room) { |
||
213 | if (tilepos % 10 != 9) { |
||
214 | if (tilepos < 10) { |
||
215 | // 0..8 -> -2..-10 |
||
216 | tilepos = -(tilepos + 2); |
||
217 | } else { |
||
218 | tilepos -= 9; |
||
219 | } |
||
220 | } else { |
||
221 | tilepos = 30; |
||
222 | } |
||
223 | } else if (trob.room == room_L) { |
||
224 | if (tilepos == 9) { |
||
225 | tilepos = -1; |
||
226 | } else { |
||
227 | if (tilepos % 10 == 9) { |
||
228 | tilepos -= 19; |
||
229 | } else { |
||
230 | tilepos = 30; |
||
231 | } |
||
232 | } |
||
233 | } else if (trob.room == room_B) { |
||
234 | if (tilepos < 9) { |
||
235 | tilepos += 21; |
||
236 | } else { |
||
237 | tilepos = 30; |
||
238 | } |
||
239 | } else if (trob.room == room_BL && tilepos == 9) { |
||
240 | tilepos = 20; |
||
241 | } else { |
||
242 | tilepos = 30; |
||
243 | } |
||
244 | return tilepos; |
||
245 | } |
||
246 | |||
247 | // seg007:03CF |
||
248 | void __pascal far animate_torch() { |
||
249 | if (is_trob_in_drawn_room()) { |
||
250 | curr_modifier = get_torch_frame(curr_modifier); |
||
251 | set_redraw_anim_right(); |
||
252 | } |
||
253 | } |
||
254 | |||
255 | // seg007:03E9 |
||
256 | void __pascal far animate_potion() { |
||
257 | word type; |
||
258 | if (trob.type >= 0 && is_trob_in_drawn_room()) { |
||
259 | type = curr_modifier & 0xF8; |
||
260 | curr_modifier = bubble_next_frame(curr_modifier & 0x07) | type; |
||
261 | set_redraw_anim_curr(); |
||
262 | } |
||
263 | } |
||
264 | |||
265 | // seg007:0425 |
||
266 | void __pascal far animate_sword() { |
||
267 | if (is_trob_in_drawn_room()) { |
||
268 | --curr_modifier; |
||
269 | if (curr_modifier == 0) { |
||
270 | curr_modifier = (prandom(255) & 0x3F) + 0x28; |
||
271 | } |
||
272 | set_redraw_anim_curr(); |
||
273 | } |
||
274 | } |
||
275 | |||
276 | // seg007:0448 |
||
277 | void __pascal far animate_chomper() { |
||
278 | word blood; |
||
279 | word frame; |
||
280 | if (trob.type >= 0) { |
||
281 | blood = curr_modifier & 0x80; |
||
282 | frame = (curr_modifier & 0x7F) + 1; |
||
283 | if (frame > 15) { |
||
284 | frame = 1; |
||
285 | } |
||
286 | curr_modifier = blood | frame; |
||
287 | if (frame == 2) { |
||
288 | play_sound(sound_47_chomper); // chomper |
||
289 | } |
||
290 | // If either: |
||
291 | // - Kid left this room |
||
292 | // - Kid left this row |
||
293 | // - Kid died but not in this chomper |
||
294 | // and chomper is past frame 6 |
||
295 | // then stop. |
||
296 | if ((trob.room != drawn_room || trob.tilepos / 10 != Kid.curr_row || |
||
297 | (Kid.alive >= 0 && blood == 0)) && (curr_modifier & 0x7F) >= 6 |
||
298 | ) { |
||
299 | trob.type = -1; |
||
300 | } |
||
301 | } |
||
302 | if ((curr_modifier & 0x7F) < 6) { |
||
303 | redraw_at_trob(); |
||
304 | } |
||
305 | } |
||
306 | |||
307 | // seg007:04D3 |
||
308 | void __pascal far animate_spike() { |
||
309 | if (trob.type >= 0) { |
||
310 | // 0xFF means a disabled spike. |
||
311 | if (curr_modifier == 0xFF) return; |
||
312 | if (curr_modifier & 0x80) { |
||
313 | --curr_modifier; |
||
314 | if (curr_modifier & 0x7F) return; |
||
315 | curr_modifier = 6; |
||
316 | } else { |
||
317 | ++curr_modifier; |
||
318 | if (curr_modifier == 5) { |
||
319 | curr_modifier = 0x8F; |
||
320 | } else if (curr_modifier == 9) { |
||
321 | curr_modifier = 0; |
||
322 | trob.type = -1; |
||
323 | } |
||
324 | } |
||
325 | } |
||
326 | redraw_21h(); |
||
327 | } |
||
328 | |||
329 | // data:27B2 |
||
330 | const byte gate_close_speeds[] = {0, 0, 0, 20, 40, 60, 80, 100, 120}; |
||
331 | // data:27C0 |
||
332 | const byte door_delta[] = {-1, 4, 4}; |
||
333 | // seg007:0522 |
||
334 | void __pascal far animate_door() { |
||
335 | /* |
||
336 | Possible values of anim_type: |
||
337 | 0: closing |
||
338 | 1: open |
||
339 | 2: permanent open |
||
340 | 3,4,5,6,7,8: fast closing with speeds 20,40,60,80,100,120 /4 pixel/frame |
||
341 | */ |
||
342 | sbyte anim_type; |
||
343 | anim_type = trob.type; |
||
344 | if (anim_type >= 0) { |
||
345 | if (anim_type >= 3) { |
||
346 | // closing fast |
||
347 | if (anim_type < 8) { |
||
348 | ++anim_type; |
||
349 | trob.type = anim_type; |
||
350 | } |
||
351 | short new_mod = curr_modifier - gate_close_speeds[anim_type]; |
||
352 | curr_modifier = new_mod; |
||
353 | //if ((sbyte)curr_modifier < 0) { |
||
354 | if (new_mod < 0) { |
||
355 | //if ((curr_modifier -= gate_close_speeds[anim_type]) < 0) { |
||
356 | curr_modifier = 0; |
||
357 | trob.type = -1; |
||
358 | play_sound(sound_6_gate_closing_fast); // gate closing fast |
||
359 | } |
||
360 | } else { |
||
361 | if (curr_modifier != 0xFF) { |
||
362 | // 0xFF means permanently open. |
||
363 | curr_modifier += door_delta[anim_type]; |
||
364 | if (anim_type == 0) { |
||
365 | // closing |
||
366 | if (curr_modifier != 0) { |
||
367 | if (curr_modifier < 188) { |
||
368 | if ((curr_modifier & 3) == 3) { |
||
369 | play_door_sound_if_visible(sound_4_gate_closing); // gate closing |
||
370 | } |
||
371 | } |
||
372 | } else { |
||
373 | gate_stop(); |
||
374 | } |
||
375 | } else { |
||
376 | // opening |
||
377 | if (curr_modifier < 188) { |
||
378 | if ((curr_modifier & 7) == 0) { |
||
379 | play_sound(sound_5_gate_opening); // gate opening |
||
380 | } |
||
381 | } else { |
||
382 | // stop |
||
383 | if (anim_type < 2) { |
||
384 | // after regular open |
||
385 | curr_modifier = 238; |
||
386 | trob.type = 0; // closing |
||
387 | play_sound(sound_7_gate_stop); // gate stop (after opening) |
||
388 | } else { |
||
389 | // after permanent open |
||
390 | curr_modifier = 0xFF; // keep open |
||
391 | gate_stop(); |
||
392 | } |
||
393 | } |
||
394 | } |
||
395 | } else { |
||
396 | gate_stop(); |
||
397 | } |
||
398 | } |
||
399 | } |
||
400 | draw_trob(); |
||
401 | } |
||
402 | |||
403 | // seg007:05E3 |
||
404 | void __pascal far gate_stop() { |
||
405 | trob.type = -1; |
||
406 | play_door_sound_if_visible(sound_7_gate_stop); // gate stop (after closing) |
||
407 | } |
||
408 | |||
409 | // data:27B8 |
||
410 | const byte leveldoor_close_speeds[] = {0, 5, 17, 99, 0}; |
||
411 | // seg007:05F1 |
||
412 | void __pascal far animate_leveldoor() { |
||
413 | /* |
||
414 | Possible values of trob_type: |
||
415 | 0: open |
||
416 | 1: open (with button) |
||
417 | 2: open |
||
418 | 3,4,5,6: fast closing with speeds 0,5,17,99 pixel/frame |
||
419 | */ |
||
420 | word trob_type; |
||
421 | trob_type = trob.type; |
||
422 | if (trob.type >= 0) { |
||
423 | if (trob_type >= 3) { |
||
424 | // closing |
||
425 | ++trob.type; |
||
426 | curr_modifier -= leveldoor_close_speeds[trob.type - 3]; |
||
427 | if ((sbyte)curr_modifier < 0) { |
||
428 | curr_modifier = 0; |
||
429 | trob.type = -1; |
||
430 | play_sound(sound_14_leveldoor_closing); // level door closing |
||
431 | } else { |
||
432 | if (trob.type == 4 && |
||
433 | (sound_flags & sfDigi) |
||
434 | ) { |
||
435 | sound_interruptible[sound_15_leveldoor_sliding] = 1; |
||
436 | play_sound(sound_15_leveldoor_sliding); // level door sliding (closing) |
||
437 | } |
||
438 | } |
||
439 | } else { |
||
440 | // opening |
||
441 | ++curr_modifier; |
||
442 | if (curr_modifier >= 43) { |
||
443 | trob.type = -1; |
||
444 | #ifdef FIX_FEATHER_INTERRUPTED_BY_LEVELDOOR |
||
445 | if (!(fix_feather_interrupted_by_leveldoor && is_feather_fall)) |
||
446 | #endif |
||
447 | stop_sounds(); |
||
448 | if (leveldoor_open == 0 || leveldoor_open == 2) { |
||
449 | leveldoor_open = 1; |
||
450 | if (current_level == 4) { |
||
451 | // Special event: place mirror |
||
452 | get_tile(4, 4, 0); |
||
453 | curr_room_tiles[curr_tilepos] = tiles_13_mirror; |
||
454 | } |
||
455 | } |
||
456 | } else { |
||
457 | sound_interruptible[15] = 0; |
||
458 | play_sound(sound_15_leveldoor_sliding); // level door sliding (opening) |
||
459 | } |
||
460 | } |
||
461 | } |
||
462 | set_redraw_anim_right(); |
||
463 | } |
||
464 | |||
465 | // seg007:06AD |
||
466 | short __pascal far bubble_next_frame(short curr) { |
||
467 | short next; |
||
468 | next = curr + 1; |
||
469 | if (next >= 8) next = 1; |
||
470 | return next; |
||
471 | } |
||
472 | |||
473 | // seg007:06CD |
||
474 | short __pascal far get_torch_frame(short curr) { |
||
475 | short next; |
||
476 | next = prandom(255); |
||
477 | if (next != curr) { |
||
478 | if (next < 9) { |
||
479 | return next; |
||
480 | } else { |
||
481 | next = curr; |
||
482 | } |
||
483 | } |
||
484 | ++next; |
||
485 | if (next >= 9) next = 0; |
||
486 | return next; |
||
487 | } |
||
488 | |||
489 | // seg007:070A |
||
490 | void __pascal far set_redraw_anim(short tilepos, byte frames) { |
||
491 | if (tilepos < 30) { |
||
492 | if (tilepos < 0) { |
||
493 | ++tilepos; |
||
494 | redraw_frames_above[-tilepos] = frames; |
||
495 | // or simply: ~tilepos |
||
496 | } else { |
||
497 | redraw_frames_anim[tilepos] = frames; |
||
498 | } |
||
499 | } |
||
500 | } |
||
501 | |||
502 | // seg007:0738 |
||
503 | void __pascal far set_redraw2(short tilepos, byte frames) { |
||
504 | if (tilepos < 30) { |
||
505 | if (tilepos < 0) { |
||
506 | // trying to draw a mob at a negative tilepos, in the range -1 .. -10 |
||
507 | // used e.g. when the kid is climbing up to the room above |
||
508 | // however, loose tiles falling out of the room end up with a negative tilepos {-2 .. -11} ! |
||
509 | tilepos = (-tilepos) - 1; |
||
510 | if (tilepos > 9) tilepos = 9; // prevent array index out of bounds! |
||
511 | redraw_frames_above[tilepos] = frames; |
||
512 | } else { |
||
513 | redraw_frames2[tilepos] = frames; |
||
514 | } |
||
515 | } |
||
516 | } |
||
517 | |||
518 | // seg007:0766 |
||
519 | void __pascal far set_redraw_floor_overlay(short tilepos, byte frames) { |
||
520 | if (tilepos < 30) { |
||
521 | if (tilepos < 0) { |
||
522 | ++tilepos; |
||
523 | redraw_frames_above[-tilepos] = frames; |
||
524 | // or simply: ~tilepos |
||
525 | } else { |
||
526 | redraw_frames_floor_overlay[tilepos] = frames; |
||
527 | } |
||
528 | } |
||
529 | } |
||
530 | |||
531 | // seg007:0794 |
||
532 | void __pascal far set_redraw_full(short tilepos, byte frames) { |
||
533 | if (tilepos < 30) { |
||
534 | if (tilepos < 0) { |
||
535 | ++tilepos; |
||
536 | redraw_frames_above[-tilepos] = frames; |
||
537 | // or simply: ~tilepos |
||
538 | } else { |
||
539 | redraw_frames_full[tilepos] = frames; |
||
540 | } |
||
541 | } |
||
542 | } |
||
543 | |||
544 | // seg007:07C2 |
||
545 | void __pascal far set_redraw_fore(short tilepos, byte frames) { |
||
546 | if (tilepos < 30 && tilepos >= 0) { |
||
547 | redraw_frames_fore[tilepos] = frames; |
||
548 | } |
||
549 | } |
||
550 | |||
551 | // seg007:07DF |
||
552 | void __pascal far set_wipe(short tilepos, byte frames) { |
||
553 | if (tilepos < 30 && tilepos >= 0) { |
||
554 | if (wipe_frames[tilepos] != 0) { |
||
555 | redraw_height = MAX(wipe_heights[tilepos], redraw_height); |
||
556 | } |
||
557 | wipe_heights[tilepos] = redraw_height; |
||
558 | wipe_frames[tilepos] = frames; |
||
559 | } |
||
560 | } |
||
561 | |||
562 | // seg007:081E |
||
563 | void __pascal far start_anim_torch(short room,short tilepos) { |
||
564 | curr_room_modif[tilepos] = prandom(8); |
||
565 | add_trob(room, tilepos, 1); |
||
566 | } |
||
567 | |||
568 | // seg007:0847 |
||
569 | void __pascal far start_anim_potion(short room,short tilepos) { |
||
570 | curr_room_modif[tilepos] &= 0xF8; |
||
571 | curr_room_modif[tilepos] |= prandom(6) + 1; |
||
572 | add_trob(room, tilepos, 1); |
||
573 | } |
||
574 | |||
575 | // seg007:087C |
||
576 | void __pascal far start_anim_sword(short room,short tilepos) { |
||
577 | curr_room_modif[tilepos] = prandom(0xFF) & 0x1F; |
||
578 | add_trob(room, tilepos, 1); |
||
579 | } |
||
580 | |||
581 | // seg007:08A7 |
||
582 | void __pascal far start_anim_chomper(short room,short tilepos, byte modifier) { |
||
583 | short old_modifier; |
||
584 | old_modifier = curr_room_modif[tilepos]; |
||
585 | if (old_modifier == 0 || old_modifier >= 6) { |
||
586 | curr_room_modif[tilepos] = modifier; |
||
587 | add_trob(room, tilepos, 1); |
||
588 | } |
||
589 | } |
||
590 | |||
591 | // seg007:08E3 |
||
592 | void __pascal far start_anim_spike(short room,short tilepos) { |
||
593 | sbyte old_modifier; |
||
594 | old_modifier = curr_room_modif[tilepos]; |
||
595 | if (old_modifier <= 0) { |
||
596 | if (old_modifier == 0) { |
||
597 | add_trob(room, tilepos, 1); |
||
598 | play_sound(sound_49_spikes); // spikes |
||
599 | } else { |
||
600 | // 0xFF means a disabled spike. |
||
601 | if (old_modifier != (sbyte)0xFF) { |
||
602 | curr_room_modif[tilepos] = 0x8F; |
||
603 | } |
||
604 | } |
||
605 | } |
||
606 | } |
||
607 | |||
608 | // seg007:092C |
||
609 | short __pascal far trigger_gate(short room,short tilepos,short button_type) { |
||
610 | byte modifier; |
||
611 | modifier = curr_room_modif[tilepos]; |
||
612 | if (button_type == tiles_15_opener) { |
||
613 | // If the gate is permanently open, don't to anything. |
||
614 | if (modifier == 0xFF) return -1; |
||
615 | if (modifier >= 188) { // if it's already open |
||
616 | curr_room_modif[tilepos] = 238; // keep it open for a while |
||
617 | return -1; |
||
618 | } |
||
619 | curr_room_modif[tilepos] = (modifier + 3) & 0xFC; |
||
620 | return 1; // regular open |
||
621 | } else if (button_type == tiles_14_debris) { |
||
622 | // If it's not fully open: |
||
623 | if (modifier < 188) return 2; // permanent open |
||
624 | curr_room_modif[tilepos] = 0xFF; // keep open |
||
625 | return -1; |
||
626 | } else { |
||
627 | if (modifier != 0) { |
||
628 | return 3; // close fast |
||
629 | } else { |
||
630 | // already closed |
||
631 | return -1; |
||
632 | } |
||
633 | } |
||
634 | } |
||
635 | |||
636 | // seg007:0999 |
||
637 | short __pascal far trigger_1(short target_type,short room,short tilepos,short button_type) { |
||
638 | short result; |
||
639 | result = -1; |
||
640 | if (target_type == tiles_4_gate) { |
||
641 | result = trigger_gate(room, tilepos, button_type); |
||
642 | } else if (target_type == tiles_16_level_door_left) { |
||
643 | if (curr_room_modif[tilepos] != 0) { |
||
644 | result = -1; |
||
645 | } else { |
||
646 | result = 1; |
||
647 | } |
||
648 | } else if (allow_triggering_any_tile) { //allow_triggering_any_tile hack |
||
649 | result = 1; |
||
650 | } |
||
651 | return result; |
||
652 | } |
||
653 | |||
654 | // seg007:09E5 |
||
655 | void __pascal far do_trigger_list(short index,short button_type) { |
||
656 | word room; |
||
657 | word tilepos; |
||
658 | byte target_type; |
||
659 | sbyte trigger_result; |
||
660 | // while (doorlink1_ad[index] != -1) { // these can't be equal! |
||
661 | while (1) { // Same as the above but just a little faster and no compiler warning. |
||
662 | room = get_doorlink_room(index); |
||
663 | get_room_address(room); |
||
664 | tilepos = get_doorlink_tile(index); |
||
665 | target_type = curr_room_tiles[tilepos] & 0x1F; |
||
666 | trigger_result = trigger_1(target_type, room, tilepos, button_type); |
||
667 | if (trigger_result >= 0) { |
||
668 | add_trob(room, tilepos, trigger_result); |
||
669 | } |
||
670 | if (get_doorlink_next(index++) == 0) break; |
||
671 | } |
||
672 | } |
||
673 | |||
674 | // seg007:0A5A |
||
675 | void __pascal far add_trob(byte room,byte tilepos,sbyte type) { |
||
676 | short found; |
||
677 | if (trobs_count >= 30) { |
||
678 | show_dialog("Trobs Overflow"); |
||
679 | return /*0*/; // added |
||
680 | } |
||
681 | trob.room = room; |
||
682 | trob.tilepos = tilepos; |
||
683 | trob.type = type; |
||
684 | found = find_trob(); |
||
685 | if (found == -1) { |
||
686 | // add new |
||
687 | if (trobs_count == 30) return; |
||
688 | trobs[trobs_count++] = trob; |
||
689 | } else { |
||
690 | // change existing |
||
691 | trobs[found].type = trob.type; |
||
692 | } |
||
693 | } |
||
694 | |||
695 | // seg007:0ACA |
||
696 | short __pascal far find_trob() { |
||
697 | short index; |
||
698 | for (index = 0; index < trobs_count; ++index) { |
||
699 | if (trobs[index].tilepos == trob.tilepos && |
||
700 | trobs[index].room == trob.room) return index; |
||
701 | } |
||
702 | return -1; |
||
703 | } |
||
704 | |||
705 | // seg007:0B0A |
||
706 | void __pascal far clear_tile_wipes() { |
||
707 | memset_near(redraw_frames_full, 0, sizeof(redraw_frames_full)); |
||
708 | memset_near(wipe_frames, 0, sizeof(wipe_frames)); |
||
709 | memset_near(wipe_heights, 0, sizeof(wipe_heights)); |
||
710 | memset_near(redraw_frames_anim, 0, sizeof(redraw_frames_anim)); |
||
711 | memset_near(redraw_frames_fore, 0, sizeof(redraw_frames_fore)); |
||
712 | memset_near(redraw_frames2, 0, sizeof(redraw_frames2)); |
||
713 | memset_near(redraw_frames_floor_overlay, 0, sizeof(redraw_frames_floor_overlay)); |
||
714 | memset_near(tile_object_redraw, 0, sizeof(tile_object_redraw)); |
||
715 | memset_near(redraw_frames_above, 0, sizeof(redraw_frames_above)); |
||
716 | } |
||
717 | |||
718 | // seg007:0BB6 |
||
719 | short __pascal far get_doorlink_timer(short index) { |
||
720 | return doorlink2_ad[index] & 0x1F; |
||
721 | } |
||
722 | |||
723 | // seg007:0BCD |
||
724 | short __pascal far set_doorlink_timer(short index,byte value) { |
||
725 | doorlink2_ad[index] &= 0xE0; |
||
726 | doorlink2_ad[index] |= value & 0x1F; |
||
727 | return doorlink2_ad[index]; |
||
728 | } |
||
729 | |||
730 | // seg007:0BF2 |
||
731 | short __pascal far get_doorlink_tile(short index) { |
||
732 | return doorlink1_ad[index] & 0x1F; |
||
733 | } |
||
734 | |||
735 | // seg007:0C09 |
||
736 | short __pascal far get_doorlink_next(short index) { |
||
737 | return !(doorlink1_ad[index] & 0x80); |
||
738 | } |
||
739 | |||
740 | // seg007:0C26 |
||
741 | short __pascal far get_doorlink_room(short index) { |
||
742 | return |
||
743 | ((doorlink1_ad[index] & 0x60) >> 5) + |
||
744 | ((doorlink2_ad[index] & 0xE0) >> 3); |
||
745 | } |
||
746 | |||
747 | // seg007:0C53 |
||
748 | void __pascal far trigger_button(int playsound,int button_type,int modifier) { |
||
749 | sbyte link_timer; |
||
750 | get_curr_tile(curr_tilepos); |
||
751 | if (button_type == 0) { |
||
752 | // 0 means currently selected |
||
753 | button_type = curr_tile; |
||
754 | } |
||
755 | if (modifier == -1) { |
||
756 | // -1 means currently selected |
||
757 | modifier = curr_modifier; |
||
758 | } |
||
759 | link_timer = get_doorlink_timer(modifier); |
||
760 | // is the event jammed? |
||
761 | if (link_timer != 0x1F) { |
||
762 | set_doorlink_timer(modifier, 5); |
||
763 | if (link_timer < 2) { |
||
764 | add_trob(curr_room, curr_tilepos, 1); |
||
765 | redraw_11h(); |
||
766 | is_guard_notice = 1; |
||
767 | if (playsound) { |
||
768 | play_sound(sound_3_button_pressed); // button pressed |
||
769 | } |
||
770 | } |
||
771 | do_trigger_list(modifier, button_type); |
||
772 | } |
||
773 | } |
||
774 | |||
775 | // seg007:0CD9 |
||
776 | void __pascal far died_on_button() { |
||
777 | word button_type; |
||
778 | word modifier; |
||
779 | button_type = get_curr_tile(curr_tilepos); |
||
780 | modifier = curr_modifier; |
||
781 | if (curr_tile == tiles_15_opener) { |
||
782 | curr_room_tiles[curr_tilepos] = tiles_1_floor; |
||
783 | curr_room_modif[curr_tilepos] = 0; |
||
784 | button_type = tiles_14_debris; // force permanent open |
||
785 | } else { |
||
786 | curr_room_tiles[curr_tilepos] = tiles_5_stuck; |
||
787 | } |
||
788 | trigger_button(1, button_type, modifier); |
||
789 | } |
||
790 | |||
791 | // seg007:0D3A |
||
792 | void __pascal far animate_button() { |
||
793 | word var_2; |
||
794 | if (trob.type >= 0) { |
||
795 | set_doorlink_timer(curr_modifier, var_2 = get_doorlink_timer(curr_modifier) - 1); |
||
796 | if (var_2 < 2) { |
||
797 | trob.type = -1; |
||
798 | redraw_11h(); |
||
799 | } |
||
800 | } |
||
801 | } |
||
802 | |||
803 | // seg007:0D72 |
||
804 | void __pascal far start_level_door(short room,short tilepos) { |
||
805 | curr_room_modif[tilepos] = 43; // start fully open |
||
806 | add_trob(room, tilepos, 3); |
||
807 | } |
||
808 | |||
809 | // seg007:0D93 |
||
810 | void __pascal far animate_empty() { |
||
811 | trob.type = -1; |
||
812 | redraw_20h(); |
||
813 | } |
||
814 | |||
815 | // data:2284 |
||
816 | const word y_loose_land[] = {2, 65, 128, 191, 254}; |
||
817 | // seg007:0D9D |
||
818 | void __pascal far animate_loose() { |
||
819 | word room; |
||
820 | word row; |
||
821 | word tilepos; |
||
822 | short anim_type; |
||
823 | anim_type = trob.type; |
||
824 | if (anim_type >= 0) { |
||
825 | ++curr_modifier; |
||
826 | if (curr_modifier & 0x80) { |
||
827 | // just shaking |
||
828 | // don't shake on level 13 |
||
829 | if (current_level == 13) return; |
||
830 | if (curr_modifier >= 0x84) { |
||
831 | curr_modifier = 0; |
||
832 | trob.type = -1; |
||
833 | } |
||
834 | loose_shake(!curr_modifier); |
||
835 | } else { |
||
836 | // something is on the floor |
||
837 | // should it fall already? |
||
838 | if (curr_modifier >= 11) { |
||
839 | curr_modifier = remove_loose(room = trob.room, tilepos = trob.tilepos); |
||
840 | trob.type = -1; |
||
841 | curmob.xh = (tilepos % 10) << 2; |
||
842 | row = tilepos / 10; |
||
843 | curmob.y = y_loose_land[row + 1]; |
||
844 | curmob.room = room; |
||
845 | curmob.speed = 0; |
||
846 | curmob.type = 0; |
||
847 | curmob.row = row; |
||
848 | add_mob(); |
||
849 | } else { |
||
850 | loose_shake(0); |
||
851 | } |
||
852 | } |
||
853 | } |
||
854 | redraw_20h(); |
||
855 | } |
||
856 | |||
857 | // data:2734 |
||
858 | const byte loose_sound[] = {0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0}; |
||
859 | // seg007:0E55 |
||
860 | void __pascal far loose_shake(int arg_0) { |
||
861 | word sound_id; |
||
862 | if (arg_0 || loose_sound[curr_modifier & 0x7F]) { |
||
863 | do { |
||
864 | // Sounds 20,21,22: loose floor shaking |
||
865 | sound_id = prandom(2) + sound_20_loose_shake_1; |
||
866 | } while(sound_id == last_loose_sound); |
||
867 | if (sound_flags & sfDigi) { |
||
868 | last_loose_sound = sound_id; |
||
869 | // random sample rate (10500..11500) |
||
870 | //sound_pointers[sound_id]->samplerate = prandom(1000) + 10500; |
||
871 | } |
||
872 | play_sound(sound_id); |
||
873 | } |
||
874 | } |
||
875 | |||
876 | // seg007:0EB8 |
||
877 | int __pascal far remove_loose(int room, int tilepos) { |
||
878 | curr_room_tiles[tilepos] = tiles_0_empty; |
||
879 | // note: the level type is used to determine the modifier of the empty space left behind |
||
880 | return tbl_level_type[current_level]; |
||
881 | } |
||
882 | |||
883 | // seg007:0ED5 |
||
884 | void __pascal far make_loose_fall(byte modifier) { |
||
885 | // is it a "solid" loose floor? |
||
886 | if ((curr_room_tiles[curr_tilepos] & 0x20) == 0) { |
||
887 | if ((sbyte)curr_room_modif[curr_tilepos] <= 0) { |
||
888 | curr_room_modif[curr_tilepos] = modifier; |
||
889 | add_trob(curr_room, curr_tilepos, 0); |
||
890 | redraw_20h(); |
||
891 | } |
||
892 | } |
||
893 | } |
||
894 | |||
895 | // seg007:0F13 |
||
896 | void __pascal far start_chompers() { |
||
897 | short timing; |
||
898 | short modifier; |
||
899 | short tilepos; |
||
900 | short column; |
||
901 | timing = 15; |
||
902 | if ((byte)Char.curr_row < 3) { |
||
903 | get_room_address(Char.room); |
||
904 | for (column = 0, tilepos = tbl_line[Char.curr_row]; |
||
905 | column < 10; ++column, ++tilepos |
||
906 | ){ |
||
907 | if (get_curr_tile(tilepos) == tiles_18_chomper) { |
||
908 | modifier = curr_modifier & 0x7F; |
||
909 | if (modifier == 0 || modifier >= 6) { |
||
910 | start_anim_chomper(Char.room, tilepos, timing | (curr_modifier & 0x80)); |
||
911 | timing = next_chomper_timing(timing); |
||
912 | } |
||
913 | } |
||
914 | } |
||
915 | } |
||
916 | } |
||
917 | |||
918 | // seg007:0F9A |
||
919 | int __pascal far next_chomper_timing(byte timing) { |
||
920 | // 15,12,9,6,13,10,7,14,11,8,repeat |
||
921 | timing -= 3; |
||
922 | if (timing < 6) { |
||
923 | timing += 10; |
||
924 | } |
||
925 | return timing; |
||
926 | } |
||
927 | |||
928 | // seg007:0FB4 |
||
929 | void __pascal far loose_make_shake() { |
||
930 | if (curr_room_modif[curr_tilepos] == 0 && current_level != 13) { |
||
931 | curr_room_modif[curr_tilepos] = 0x80; |
||
932 | add_trob(curr_room, curr_tilepos, 1); |
||
933 | } |
||
934 | } |
||
935 | |||
936 | // seg007:0FE0 |
||
937 | void __pascal far do_knock(int room,int tile_row) { |
||
938 | short tile_col; |
||
939 | for (tile_col = 0; tile_col < 10; ++tile_col) { |
||
940 | if (get_tile(room, tile_col, tile_row) == tiles_11_loose) { |
||
941 | loose_make_shake(); |
||
942 | } |
||
943 | } |
||
944 | } |
||
945 | |||
946 | // seg007:1010 |
||
947 | void __pascal far add_mob() { |
||
948 | if (mobs_count >= 14) { |
||
949 | show_dialog("Mobs Overflow"); |
||
950 | return /*0*/; // added |
||
951 | } |
||
952 | mobs[mobs_count++] = curmob; |
||
953 | } |
||
954 | |||
955 | // seg007:1041 |
||
956 | short __pascal far get_curr_tile(short tilepos) { |
||
957 | curr_modifier = curr_room_modif[tilepos]; |
||
958 | return curr_tile = curr_room_tiles[tilepos] & 0x1F; |
||
959 | } |
||
960 | |||
961 | // data:43DC |
||
962 | word curmob_index; |
||
963 | |||
964 | // seg007:1063 |
||
965 | void __pascal far do_mobs() { |
||
966 | short n_mobs; |
||
967 | short index; |
||
968 | short new_index; |
||
969 | n_mobs = mobs_count; |
||
970 | for (curmob_index = 0; n_mobs > curmob_index; ++curmob_index) { |
||
971 | curmob = mobs[curmob_index]; |
||
972 | move_mob(); |
||
973 | check_loose_fall_on_kid(); |
||
974 | mobs[curmob_index] = curmob; |
||
975 | } |
||
976 | new_index = 0; |
||
977 | for (index = 0; index < mobs_count; ++index) { |
||
978 | if (mobs[index].speed != -1) { |
||
979 | mobs[new_index++] = mobs[index]; |
||
980 | } |
||
981 | } |
||
982 | mobs_count = new_index; |
||
983 | } |
||
984 | |||
985 | // seg007:110F |
||
986 | void __pascal far move_mob() { |
||
987 | if (curmob.type == 0) { |
||
988 | move_loose(); |
||
989 | } |
||
990 | if (curmob.speed <= 0) { |
||
991 | ++curmob.speed; |
||
992 | } |
||
993 | } |
||
994 | |||
995 | // data:227A |
||
996 | const short y_something[] = {-1, 62, 125, 188, 25}; |
||
997 | // data:594A |
||
998 | word curr_tile_temp; |
||
999 | // seg007:1126 |
||
1000 | void __pascal far move_loose() { |
||
1001 | if (curmob.speed < 0) return; |
||
1002 | if (curmob.speed < 29) curmob.speed += 3; |
||
1003 | curmob.y += curmob.speed; |
||
1004 | if (curmob.room == 0) { |
||
1005 | if (curmob.y < 210) { |
||
1006 | return; |
||
1007 | } else { |
||
1008 | curmob.speed = -2; |
||
1009 | return; |
||
1010 | } |
||
1011 | } |
||
1012 | if (curmob.y < 226 && y_something[curmob.row + 1] <= curmob.y) { |
||
1013 | // fell into a different row |
||
1014 | curr_tile_temp = get_tile(curmob.room, curmob.xh >> 2, curmob.row); |
||
1015 | if (curr_tile_temp == tiles_11_loose) { |
||
1016 | loose_fall(); |
||
1017 | } |
||
1018 | if (curr_tile_temp == tiles_0_empty || |
||
1019 | curr_tile_temp == tiles_11_loose |
||
1020 | ) { |
||
1021 | mob_down_a_row(); |
||
1022 | return; |
||
1023 | } |
||
1024 | play_sound(sound_2_tile_crashing); // tile crashing |
||
1025 | do_knock(curmob.room, curmob.row); |
||
1026 | curmob.y = y_something[curmob.row + 1]; |
||
1027 | curmob.speed = -2; |
||
1028 | loose_land(); |
||
1029 | } |
||
1030 | } |
||
1031 | |||
1032 | // seg007:11E8 |
||
1033 | void __pascal far loose_land() { |
||
1034 | short button_type; |
||
1035 | short tiletype; |
||
1036 | button_type = 0; |
||
1037 | tiletype = get_tile(curmob.room, curmob.xh >> 2, curmob.row); |
||
1038 | switch (tiletype) { |
||
1039 | case tiles_15_opener: |
||
1040 | curr_room_tiles[curr_tilepos] = tiles_14_debris; |
||
1041 | button_type = tiles_14_debris; |
||
1042 | // fallthrough! |
||
1043 | case tiles_6_closer: |
||
1044 | trigger_button(1, button_type, -1); |
||
1045 | tiletype = get_tile(curmob.room, curmob.xh >> 2, curmob.row); |
||
1046 | // fallthrough! |
||
1047 | case tiles_1_floor: |
||
1048 | case tiles_2_spike: |
||
1049 | case tiles_10_potion: |
||
1050 | case tiles_19_torch: |
||
1051 | case tiles_30_torch_with_debris: |
||
1052 | if (tiletype == tiles_19_torch || |
||
1053 | tiletype == tiles_30_torch_with_debris |
||
1054 | ) { |
||
1055 | curr_room_tiles[curr_tilepos] = tiles_30_torch_with_debris; |
||
1056 | } else { |
||
1057 | curr_room_tiles[curr_tilepos] = tiles_14_debris; |
||
1058 | } |
||
1059 | redraw_at_cur_mob(); |
||
1060 | if (tile_col != 0) { |
||
1061 | set_redraw_full(curr_tilepos - 1, 1); |
||
1062 | } |
||
1063 | } |
||
1064 | } |
||
1065 | |||
1066 | // seg007:12CB |
||
1067 | void __pascal far loose_fall() { |
||
1068 | curr_room_modif[curr_tilepos] = remove_loose(curr_room, curr_tilepos); |
||
1069 | curmob.speed >>= 1; |
||
1070 | mobs[curmob_index] = curmob; |
||
1071 | curmob.y += 6; |
||
1072 | mob_down_a_row(); |
||
1073 | add_mob(); |
||
1074 | curmob = mobs[curmob_index]; |
||
1075 | redraw_at_cur_mob(); |
||
1076 | } |
||
1077 | |||
1078 | // seg007:132C |
||
1079 | void __pascal far redraw_at_cur_mob() { |
||
1080 | if (curmob.room == drawn_room) { |
||
1081 | redraw_height = 0x20; |
||
1082 | set_redraw_full(curr_tilepos, 1); |
||
1083 | set_wipe(curr_tilepos, 1); |
||
1084 | // Redraw tile to the right only if it's in the same room. |
||
1085 | if ((curr_tilepos % 10) + 1 < 10) { // changed |
||
1086 | set_redraw_full(curr_tilepos + 1, 1); |
||
1087 | set_wipe(curr_tilepos + 1, 1); |
||
1088 | } |
||
1089 | } |
||
1090 | } |
||
1091 | |||
1092 | // seg007:1387 |
||
1093 | void __pascal far mob_down_a_row() { |
||
1094 | ++curmob.row; |
||
1095 | if (curmob.row >= 3) { |
||
1096 | curmob.y -= 192; |
||
1097 | curmob.row = 0; |
||
1098 | curmob.room = level.roomlinks[curmob.room - 1].down; |
||
1099 | } |
||
1100 | } |
||
1101 | |||
1102 | // seg007:13AE |
||
1103 | void __pascal far draw_mobs() { |
||
1104 | short index; |
||
1105 | for (index = 0; index < mobs_count; ++index) { |
||
1106 | curmob = mobs[index]; |
||
1107 | draw_mob(); |
||
1108 | } |
||
1109 | } |
||
1110 | |||
1111 | // seg007:13E5 |
||
1112 | void __pascal far draw_mob() { |
||
1113 | short tile_row; |
||
1114 | short ypos; |
||
1115 | short top_row; |
||
1116 | short tilepos; |
||
1117 | short tile_col; |
||
1118 | ypos = curmob.y; |
||
1119 | if (curmob.room == drawn_room) { |
||
1120 | if (curmob.y >= 210) return; |
||
1121 | } else if (curmob.room == room_B) { |
||
1122 | if (ABS(ypos) >= 18) return; |
||
1123 | curmob.y += 192; |
||
1124 | ypos = curmob.y; |
||
1125 | } else if (curmob.room == room_A) { |
||
1126 | if (curmob.y < 174) return; |
||
1127 | ypos = curmob.y - 189; |
||
1128 | } else { |
||
1129 | return; |
||
1130 | } |
||
1131 | tile_col = curmob.xh >> 2; |
||
1132 | tile_row = y_to_row_mod4(ypos); |
||
1133 | obj_tilepos = get_tilepos_nominus(tile_col, tile_row); |
||
1134 | ++tile_col; |
||
1135 | tilepos = get_tilepos(tile_col, tile_row); |
||
1136 | set_redraw2(tilepos, 1); |
||
1137 | set_redraw_fore(tilepos, 1); |
||
1138 | top_row = y_to_row_mod4(ypos - 18); |
||
1139 | if (top_row != tile_row) { |
||
1140 | tilepos = get_tilepos(tile_col, top_row); |
||
1141 | set_redraw2(tilepos, 1); |
||
1142 | set_redraw_fore(tilepos, 1); |
||
1143 | } |
||
1144 | add_mob_to_objtable(ypos); |
||
1145 | } |
||
1146 | |||
1147 | // seg007:14DE |
||
1148 | void __pascal far add_mob_to_objtable(int ypos) { |
||
1149 | word index; |
||
1150 | objtable_type* curr_obj; |
||
1151 | index = objtable_count++; |
||
1152 | curr_obj = &objtable[index]; |
||
1153 | curr_obj->obj_type = curmob.type | 0x80; |
||
1154 | curr_obj->xh = curmob.xh; |
||
1155 | curr_obj->xl = 0; |
||
1156 | curr_obj->y = ypos; |
||
1157 | curr_obj->chtab_id = id_chtab_6_environment; |
||
1158 | curr_obj->id = 10; |
||
1159 | curr_obj->clip.top = 0; |
||
1160 | curr_obj->clip.left = 0; |
||
1161 | curr_obj->clip.right = 40; |
||
1162 | mark_obj_tile_redraw(index); |
||
1163 | } |
||
1164 | |||
1165 | // seg007:153E |
||
1166 | void __pascal far sub_9A8E() { |
||
1167 | // This function is not used. |
||
1168 | method_1_blit_rect(onscreen_surface_, offscreen_surface, &rect_top, &rect_top, 0); |
||
1169 | } |
||
1170 | |||
1171 | // seg007:1556 |
||
1172 | int __pascal far is_spike_harmful() { |
||
1173 | sbyte modifier; |
||
1174 | modifier = curr_room_modif[curr_tilepos]; |
||
1175 | if (modifier == 0 || modifier == -1) { |
||
1176 | return 0; |
||
1177 | } else if (modifier < 0) { |
||
1178 | return 1; |
||
1179 | } else if (modifier < 5) { |
||
1180 | return 2; |
||
1181 | } else { |
||
1182 | return 0; |
||
1183 | } |
||
1184 | } |
||
1185 | |||
1186 | // seg007:1591 |
||
1187 | void __pascal far check_loose_fall_on_kid() { |
||
1188 | loadkid(); |
||
1189 | if (Char.room == curmob.room && |
||
1190 | Char.curr_col == curmob.xh >> 2 && |
||
1191 | curmob.y < Char.y && |
||
1192 | Char.y - 30 < curmob.y |
||
1193 | ) { |
||
1194 | fell_on_your_head(); |
||
1195 | savekid(); |
||
1196 | } |
||
1197 | } |
||
1198 | |||
1199 | // seg007:15D3 |
||
1200 | void __pascal far fell_on_your_head() { |
||
1201 | short frame; |
||
1202 | short action; |
||
1203 | frame = Char.frame; |
||
1204 | action = Char.action; |
||
1205 | // loose floors hurt you in frames 5..14 (running) only on level 13 |
||
1206 | if ( |
||
1207 | (current_level == 13 || (frame < frame_5_start_run || frame >= 15)) && |
||
1208 | (action < actions_2_hang_climb || action == actions_7_turn) |
||
1209 | ) { |
||
1210 | Char.y = y_land[Char.curr_row + 1]; |
||
1211 | if (take_hp(1)) { |
||
1212 | seqtbl_offset_char(seq_22_crushed); // dead (because of loose floor) |
||
1213 | if (frame == frame_177_spiked) { // spiked |
||
1214 | Char.x = char_dx_forward(-12); |
||
1215 | } |
||
1216 | } else { |
||
1217 | if (frame != frame_109_crouch) { // crouching |
||
1218 | if (get_tile_behind_char() == 0) { |
||
1219 | Char.x = char_dx_forward(-2); |
||
1220 | } |
||
1221 | seqtbl_offset_char(seq_52_loose_floor_fell_on_kid); // loose floor fell on Kid |
||
1222 | } |
||
1223 | } |
||
1224 | } |
||
1225 | } |
||
1226 | |||
1227 | // seg007:1669 |
||
1228 | void __pascal far play_door_sound_if_visible(int sound_id) { |
||
1229 | word has_sound; |
||
1230 | word tilepos; |
||
1231 | word gate_room; |
||
1232 | tilepos = trob.tilepos; |
||
1233 | gate_room = trob.room; |
||
1234 | has_sound = 0; |
||
1235 | |||
1236 | #ifdef FIX_GATE_SOUNDS |
||
1237 | sbyte has_sound_condition; |
||
1238 | if (fix_gate_sounds) |
||
1239 | has_sound_condition = (gate_room == room_L && tilepos % 10 == 9) || |
||
1240 | (gate_room == drawn_room && tilepos % 10 != 9); |
||
1241 | else |
||
1242 | has_sound_condition = gate_room == room_L ? tilepos % 10 == 9 : |
||
1243 | (gate_room == drawn_room && tilepos % 10 != 9); |
||
1244 | #define GATE_SOUND_CONDITION has_sound_condition |
||
1245 | #else |
||
1246 | #define GATE_SOUND_CONDITION gate_room == room_L ? tilepos % 10 == 9 : \ |
||
1247 | (gate_room == drawn_room && tilepos % 10 != 9) |
||
1248 | #endif |
||
1249 | // Special event: sound of closing gates |
||
1250 | if ((current_level == 3 && gate_room == 2) || GATE_SOUND_CONDITION) { |
||
1251 | has_sound = 1; |
||
1252 | } |
||
1253 | if (has_sound) { |
||
1254 | play_sound(sound_id); |
||
1255 | } |
||
1256 | } |