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 | // data:0E32 |
||
24 | const word strikeprob [] = { 61,100, 61, 61, 61, 40,100,220, 0, 48, 32, 48}; |
||
25 | // data:0E4A |
||
26 | const word restrikeprob[] = { 0, 0, 0, 5, 5,175, 16, 8, 0,255,255,150}; |
||
27 | // data:0E62 |
||
28 | const word blockprob [] = { 0,150,150,200,200,255,200,250, 0,255,255,255}; |
||
29 | // data:0E7A |
||
30 | const word impblockprob[] = { 0, 61, 61,100,100,145,100,250, 0,145,255,175}; |
||
31 | // data:0E92 |
||
32 | const word advprob [] = {255,200,200,200,255,255,200, 0, 0,255,100,100}; |
||
33 | // data:0EAA |
||
34 | const word refractimer [] = { 16, 16, 16, 16, 8, 8, 8, 8, 0, 8, 0, 0}; |
||
35 | // data:0EC2 |
||
36 | const word extrastrength[] = {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}; |
||
37 | |||
38 | // seg002:0000 |
||
39 | void __pascal far do_init_shad(const byte *source,int seq_index) { |
||
40 | memcpy_near(&Char, source, 7); |
||
41 | seqtbl_offset_char(seq_index); |
||
42 | Char.charid = charid_1_shadow; |
||
43 | demo_time = 0; |
||
44 | guard_skill = 3; |
||
45 | guardhp_delta = guardhp_curr = guardhp_max = 4; |
||
46 | saveshad(); |
||
47 | } |
||
48 | |||
49 | // seg002:0044 |
||
50 | void __pascal far get_guard_hp() { |
||
51 | guardhp_delta = guardhp_curr = guardhp_max = extrastrength[guard_skill] + tbl_guard_hp[current_level]; |
||
52 | } |
||
53 | |||
54 | // data:0EEA |
||
55 | const byte init_shad_6[] = {0x0F, 0x51, 0x76, 0, 0, 1, 0, 0}; |
||
56 | // data:0EF2 |
||
57 | const byte init_shad_5[] = {0x0F, 0x37, 0x37, 0, 0xFF, 0, 0, 0}; |
||
58 | // data:0EFA |
||
59 | const byte init_shad_12[] = {0x0F, 0x51, 0xE8, 0, 0, 0, 0, 0}; |
||
60 | |||
61 | // seg002:0064 |
||
62 | void __pascal far check_shadow() { |
||
63 | offguard = 0; |
||
64 | if (current_level == 12) { |
||
65 | // Special event: level 12 shadow |
||
66 | if (!united_with_shadow && drawn_room == 15) { |
||
67 | Char.room = drawn_room; |
||
68 | if (get_tile(15, 1, 0) == tiles_22_sword) { |
||
69 | return; |
||
70 | } |
||
71 | shadow_initialized = 0; |
||
72 | do_init_shad(/*&*/init_shad_12, 7 /*fall*/); |
||
73 | return; |
||
74 | } |
||
75 | } else if (current_level == 6) { |
||
76 | // Special event: level 6 shadow |
||
77 | Char.room = drawn_room; |
||
78 | if (Char.room == 1) { |
||
79 | if (leveldoor_open != 0x4D) { |
||
80 | play_sound(sound_25_presentation); // presentation (level 6 shadow) |
||
81 | leveldoor_open = 0x4D; |
||
82 | } |
||
83 | do_init_shad(/*&*/init_shad_6, 2 /*stand*/); |
||
84 | return; |
||
85 | } |
||
86 | } else if (current_level == 5) { |
||
87 | // Special event: level 5 shadow |
||
88 | Char.room = drawn_room; |
||
89 | if (Char.room == 24) { |
||
90 | if (get_tile(24, 3, 0) != tiles_10_potion) { |
||
91 | return; |
||
92 | } |
||
93 | do_init_shad(/*&*/init_shad_5, 2 /*stand*/); |
||
94 | return; |
||
95 | } |
||
96 | } |
||
97 | enter_guard(); |
||
98 | } |
||
99 | |||
100 | // seg002:0112 |
||
101 | void __pascal far enter_guard() { |
||
102 | word room_minus_1; |
||
103 | word guard_tile; |
||
104 | word frame; |
||
105 | byte seq_hi; |
||
106 | // arrays are indexed 0..23 instead of 1..24 |
||
107 | room_minus_1 = drawn_room - 1; |
||
108 | frame = Char.frame; // hm? |
||
109 | guard_tile = level.guards_tile[room_minus_1]; |
||
110 | |||
111 | #ifndef FIX_OFFSCREEN_GUARDS_DISAPPEARING |
||
112 | if (guard_tile >= 30) return; |
||
113 | #else |
||
114 | if (guard_tile >= 30) { |
||
115 | if (!fix_offscreen_guards_disappearing) return; |
||
116 | |||
117 | // try to see if there are offscreen guards in the left and right rooms that might be visible from this room |
||
118 | word left_guard_tile = 31; |
||
119 | word right_guard_tile = 31; |
||
120 | if (room_L > 0) left_guard_tile = level.guards_tile[room_L-1]; |
||
121 | if (room_R > 0) right_guard_tile = level.guards_tile[room_R-1]; |
||
122 | |||
123 | int other_guard_x; |
||
124 | sbyte other_guard_dir; |
||
125 | int delta_x; |
||
126 | int other_room_minus_1; |
||
127 | if (right_guard_tile >= 0 && right_guard_tile < 30) { |
||
128 | other_room_minus_1 = room_R - 1; |
||
129 | other_guard_x = level.guards_x[other_room_minus_1]; |
||
130 | other_guard_dir = level.guards_dir[other_room_minus_1]; |
||
131 | // left edge of the guard matters |
||
132 | if (other_guard_dir == dir_0_right) other_guard_x -= 9; // only retrieve a guard if they will be visible |
||
133 | if (other_guard_dir == dir_FF_left) other_guard_x += 1; // getting these right was mostly trial and error |
||
134 | // only retrieve offscreen guards |
||
135 | if (!(other_guard_x < 58 + 4)) return; |
||
136 | delta_x = 140; // guard leaves to the left |
||
137 | guard_tile = right_guard_tile; |
||
138 | } |
||
139 | else if (left_guard_tile >= 0 && left_guard_tile < 30) { |
||
140 | other_room_minus_1 = room_L - 1; |
||
141 | other_guard_x = level.guards_x[other_room_minus_1]; |
||
142 | other_guard_dir = level.guards_dir[other_room_minus_1]; |
||
143 | // right edge of the guard matters |
||
144 | if (other_guard_dir == dir_0_right) other_guard_x -= 9; |
||
145 | if (other_guard_dir == dir_FF_left) other_guard_x += 1; |
||
146 | // only retrieve offscreen guards |
||
147 | if (!(other_guard_x > 190 - 4)) return; |
||
148 | delta_x = -140; // guard leaves to the right |
||
149 | guard_tile = left_guard_tile; |
||
150 | } |
||
151 | else return; |
||
152 | |||
153 | // retrieve guard from adjacent room |
||
154 | level.guards_x[room_minus_1] = level.guards_x[other_room_minus_1] + delta_x; |
||
155 | level.guards_color[room_minus_1] = level.guards_color[other_room_minus_1]; |
||
156 | level.guards_dir[room_minus_1] = level.guards_dir[other_room_minus_1]; |
||
157 | level.guards_seq_hi[room_minus_1] = level.guards_seq_hi[other_room_minus_1]; |
||
158 | level.guards_seq_lo[room_minus_1] = level.guards_seq_lo[other_room_minus_1]; |
||
159 | level.guards_skill[room_minus_1] = level.guards_skill[other_room_minus_1]; |
||
160 | |||
161 | level.guards_tile[other_room_minus_1] = 0xFF; |
||
162 | level.guards_seq_hi[other_room_minus_1] = 0; |
||
163 | } |
||
164 | #endif |
||
165 | |||
166 | Char.room = drawn_room; |
||
167 | Char.curr_row = guard_tile / 10; |
||
168 | Char.y = y_land[Char.curr_row + 1]; |
||
169 | Char.x = level.guards_x[room_minus_1]; |
||
170 | Char.curr_col = get_tile_div_mod_m7(Char.x); |
||
171 | Char.direction = level.guards_dir[room_minus_1]; |
||
172 | // only regular guards have different colors (and only on VGA) |
||
173 | if (graphics_mode == gmMcgaVga && tbl_guard_type[current_level] == 0) { |
||
174 | curr_guard_color = level.guards_color[room_minus_1]; |
||
175 | } else { |
||
176 | curr_guard_color = 0; |
||
177 | } |
||
178 | |||
179 | #ifdef REMEMBER_GUARD_HP |
||
180 | int remembered_hp = (curr_guard_color & 0xF0) >> 4; |
||
181 | #endif |
||
182 | curr_guard_color &= 0x0F; // added; only least significant 4 bits are used for guard color |
||
183 | |||
184 | // level 3 has skeletons with infinite lives |
||
185 | if (current_level == 3) { |
||
186 | Char.charid = charid_4_skeleton; |
||
187 | } else { |
||
188 | Char.charid = charid_2_guard; |
||
189 | } |
||
190 | seq_hi = level.guards_seq_hi[room_minus_1]; |
||
191 | if (seq_hi == 0) { |
||
192 | if (Char.charid == charid_4_skeleton) { |
||
193 | Char.sword = sword_2_drawn; |
||
194 | seqtbl_offset_char(seq_63_guard_stand_active); // stand active (when entering room) (skeleton) |
||
195 | } else { |
||
196 | Char.sword = sword_0_sheathed; |
||
197 | seqtbl_offset_char(seq_77_guard_stand_inactive); // stand inactive (when entering room) |
||
198 | } |
||
199 | } else { |
||
200 | Char.curr_seq = level.guards_seq_lo[room_minus_1] + (seq_hi << 8); |
||
201 | } |
||
202 | play_seq(); |
||
203 | guard_skill = level.guards_skill[room_minus_1]; |
||
204 | if (guard_skill >= 12) { |
||
205 | guard_skill = 3; |
||
206 | } |
||
207 | frame = Char.frame; |
||
208 | if (frame == frame_185_dead || frame == frame_177_spiked || frame == frame_178_chomped) { |
||
209 | Char.alive = 1; |
||
210 | draw_guard_hp(0, guardhp_curr); |
||
211 | guardhp_curr = 0; |
||
212 | } else { |
||
213 | Char.alive = -1; |
||
214 | justblocked = 0; |
||
215 | guard_refrac = 0; |
||
216 | is_guard_notice = 0; |
||
217 | get_guard_hp(); |
||
218 | #ifdef REMEMBER_GUARD_HP |
||
219 | if (enable_remember_guard_hp && remembered_hp > 0) |
||
220 | guardhp_delta = guardhp_curr = (word) remembered_hp; |
||
221 | #endif |
||
222 | } |
||
223 | Char.fall_y = 0; |
||
224 | Char.fall_x = 0; |
||
225 | Char.action = actions_1_run_jump; |
||
226 | saveshad(); |
||
227 | } |
||
228 | |||
229 | // seg002:0269 |
||
230 | void __pascal far check_guard_fallout() { |
||
231 | if (Guard.direction == dir_56_none || Guard.y < 211) { |
||
232 | return; |
||
233 | } |
||
234 | if (Guard.charid == charid_1_shadow) { |
||
235 | if (Guard.action != actions_4_in_freefall) { |
||
236 | return; |
||
237 | } |
||
238 | loadshad(); |
||
239 | clear_char(); |
||
240 | saveshad(); |
||
241 | } else if (Guard.charid == charid_4_skeleton && |
||
242 | (Guard.room = level.roomlinks[Guard.room - 1].down) == 3) { |
||
243 | // if skeleton falls down into room 3 |
||
244 | Guard.x = 133; |
||
245 | Guard.curr_row = 1; |
||
246 | Guard.direction = dir_0_right; |
||
247 | Guard.alive = -1; |
||
248 | leave_guard(); |
||
249 | } else { |
||
250 | on_guard_killed(); |
||
251 | level.guards_tile[drawn_room - 1] = -1; |
||
252 | Guard.direction = dir_56_none; |
||
253 | draw_guard_hp(0, guardhp_curr); |
||
254 | guardhp_curr = 0; |
||
255 | } |
||
256 | } |
||
257 | |||
258 | // seg002:02F5 |
||
259 | void __pascal far leave_guard() { |
||
260 | word room_minus_1; |
||
261 | if (Guard.direction == dir_56_none || Guard.charid == charid_1_shadow || Guard.charid == charid_24_mouse) { |
||
262 | return; |
||
263 | } |
||
264 | // arrays are indexed 0..23 instead of 1..24 |
||
265 | room_minus_1 = Guard.room - 1; |
||
266 | level.guards_tile[room_minus_1] = get_tilepos(0, Guard.curr_row); |
||
267 | |||
268 | level.guards_color[room_minus_1] = curr_guard_color & 0x0F; // restriction to 4 bits added |
||
269 | #ifdef REMEMBER_GUARD_HP |
||
270 | if (enable_remember_guard_hp && guardhp_curr < 16) // can remember 1..15 hp |
||
271 | level.guards_color[room_minus_1] |= (guardhp_curr << 4); |
||
272 | #endif |
||
273 | |||
274 | level.guards_x[room_minus_1] = Guard.x; |
||
275 | level.guards_dir[room_minus_1] = Guard.direction; |
||
276 | level.guards_skill[room_minus_1] = guard_skill; |
||
277 | if (Guard.alive < 0) { |
||
278 | level.guards_seq_hi[room_minus_1] = 0; |
||
279 | } else { |
||
280 | level.guards_seq_lo[room_minus_1] = Guard.curr_seq; |
||
281 | level.guards_seq_hi[room_minus_1] = Guard.curr_seq >> 8; |
||
282 | } |
||
283 | Guard.direction = dir_56_none; |
||
284 | draw_guard_hp(0, guardhp_curr); |
||
285 | guardhp_curr = 0; |
||
286 | } |
||
287 | |||
288 | // seg002:039E |
||
289 | void __pascal far follow_guard() { |
||
290 | level.guards_tile[Kid.room - 1] = 0xFF; |
||
291 | level.guards_tile[Guard.room - 1] = 0xFF; |
||
292 | loadshad(); |
||
293 | goto_other_room(roomleave_result); |
||
294 | saveshad(); |
||
295 | } |
||
296 | |||
297 | // seg002:03C7 |
||
298 | void __pascal far exit_room() { |
||
299 | word leave; |
||
300 | word kid_room_m1; |
||
301 | leave = 0; |
||
302 | if (exit_room_timer != 0) { |
||
303 | --exit_room_timer; |
||
304 | return; |
||
305 | } |
||
306 | loadkid(); |
||
307 | load_frame_to_obj(); |
||
308 | set_char_collision(); |
||
309 | roomleave_result = leave_room(); |
||
310 | if (roomleave_result < 0) { |
||
311 | return; |
||
312 | } |
||
313 | savekid(); |
||
314 | next_room = Char.room; |
||
315 | if (Guard.direction == dir_56_none) return; |
||
316 | if (Guard.alive < 0 && Guard.sword == sword_2_drawn) { |
||
317 | kid_room_m1 = Kid.room - 1; |
||
318 | if (level.guards_tile[kid_room_m1] >= 30 || |
||
319 | level.guards_seq_hi[kid_room_m1] != 0 |
||
320 | ) { |
||
321 | if (roomleave_result == 0) { |
||
322 | // left |
||
323 | if (Guard.x >= 91) leave = 1; |
||
324 | #ifdef FIX_GUARD_FOLLOWING_THROUGH_CLOSED_GATES |
||
325 | else if (fix_guard_following_through_closed_gates && can_guard_see_kid != 2 && |
||
326 | Kid.sword != sword_2_drawn) { |
||
327 | leave = 1; |
||
328 | } |
||
329 | #endif |
||
330 | } else if (roomleave_result == 1) { |
||
331 | // right |
||
332 | if (Guard.x < 165) leave = 1; |
||
333 | #ifdef FIX_GUARD_FOLLOWING_THROUGH_CLOSED_GATES |
||
334 | else if (fix_guard_following_through_closed_gates && can_guard_see_kid != 2 && |
||
335 | Kid.sword != sword_2_drawn) { |
||
336 | leave = 1; |
||
337 | } |
||
338 | #endif |
||
339 | } else if (roomleave_result == 2) { |
||
340 | // up |
||
341 | if (Guard.curr_row >= 0) leave = 1; |
||
342 | } else { |
||
343 | // down |
||
344 | if (Guard.curr_row < 3) leave = 1; |
||
345 | } |
||
346 | } else { |
||
347 | leave = 1; |
||
348 | } |
||
349 | } else { |
||
350 | leave = 1; |
||
351 | } |
||
352 | if (leave) { |
||
353 | leave_guard(); |
||
354 | } else { |
||
355 | follow_guard(); |
||
356 | } |
||
357 | } |
||
358 | |||
359 | // seg002:0486 |
||
360 | int __pascal far goto_other_room(short direction) { |
||
361 | short opposite_dir; |
||
362 | Char.room = ((byte*)&level.roomlinks[Char.room - 1])[direction]; |
||
363 | if (direction == 0) { |
||
364 | // left |
||
365 | Char.x += 140; |
||
366 | opposite_dir = 1; |
||
367 | } else if (direction == 1) { |
||
368 | // right |
||
369 | Char.x -= 140; |
||
370 | opposite_dir = 0; |
||
371 | } else if (direction == 2) { |
||
372 | // up |
||
373 | Char.y += 189; |
||
374 | Char.curr_row = y_to_row_mod4(Char.y); |
||
375 | opposite_dir = 3; |
||
376 | } else { |
||
377 | // down |
||
378 | Char.y -= 189; |
||
379 | Char.curr_row = y_to_row_mod4(Char.y); |
||
380 | opposite_dir = 2; |
||
381 | } |
||
382 | return opposite_dir; |
||
383 | } |
||
384 | |||
385 | // seg002:0504 |
||
386 | short __pascal far leave_room() { |
||
387 | short frame; |
||
388 | word action; |
||
389 | short chary; |
||
390 | short leave_dir; |
||
391 | chary = Char.y; |
||
392 | action = Char.action; |
||
393 | frame = Char.frame; |
||
394 | if (action != actions_5_bumped && |
||
395 | action != actions_4_in_freefall && |
||
396 | action != actions_3_in_midair && |
||
397 | (sbyte)chary < 10 && (sbyte)chary > -16 |
||
398 | ) { |
||
399 | leave_dir = 2; // up |
||
400 | } else if (chary >= 211) { |
||
401 | leave_dir = 3; // down |
||
402 | } else if ( |
||
403 | // frames 135..149: climb up |
||
404 | (frame >= frame_135_climbing_1 && frame < 150) || |
||
405 | // frames 110..119: standing up from crouch |
||
406 | (frame >= frame_110_stand_up_from_crouch_1 && frame < 120) || |
||
407 | // frames 150..162: with sword |
||
408 | (frame >= frame_150_parry && frame < 163 |
||
409 | |||
410 | #ifdef FIX_RETREAT_WITHOUT_LEAVING_ROOM |
||
411 | // By repeatedly pressing 'back' in a swordfight, you can retreat out of a room without the room changing. (Trick 35) |
||
412 | |||
413 | // The game waits for a 'legal frame' (e.g. frame_170_stand_with_sword) until leaving is possible; |
||
414 | // However, this frame is never reached if you press 'back' in the correct pattern! |
||
415 | |||
416 | // Solution: also allow the room to be changed on frame_157_walk_with_sword |
||
417 | // Note that this means that the delay for leaving rooms in a swordfight becomes noticably shorter. |
||
418 | |||
419 | && (frame != frame_157_walk_with_sword || !fix_retreat_without_leaving_room) |
||
420 | #endif |
||
421 | |||
422 | ) || |
||
423 | // frames 166..168: with sword |
||
424 | (frame >= frame_166_stand_inactive && frame < 169) || |
||
425 | action == actions_7_turn // turn |
||
426 | ) { |
||
427 | return -1; |
||
428 | } else if (Char.direction != dir_0_right) { |
||
429 | // looking left |
||
430 | if (char_x_left <= 54) { |
||
431 | leave_dir = 0; // left |
||
432 | } else if (char_x_left >= 198) { |
||
433 | leave_dir = 1; // right |
||
434 | } else { |
||
435 | return -1; |
||
436 | } |
||
437 | } else { |
||
438 | // looking right |
||
439 | get_tile(Char.room, 9, Char.curr_row); |
||
440 | if (curr_tile2 != tiles_7_doortop_with_floor && |
||
441 | curr_tile2 != tiles_12_doortop && |
||
442 | char_x_right >= 201 |
||
443 | ) { |
||
444 | leave_dir = 1; // right |
||
445 | } else if (char_x_right <= 57) { |
||
446 | leave_dir = 0; // left |
||
447 | } else { |
||
448 | return -1; |
||
449 | } |
||
450 | } |
||
451 | switch (leave_dir) { |
||
452 | case 0: // left |
||
453 | play_mirr_mus(); |
||
454 | level3_set_chkp(); |
||
455 | Jaffar_exit(); |
||
456 | break; |
||
457 | case 1: // right |
||
458 | sword_disappears(); |
||
459 | meet_Jaffar(); |
||
460 | break; |
||
461 | //case 2: // up |
||
462 | case 3: // down |
||
463 | // Special event: falling exit |
||
464 | if (current_level == 6 && Char.room == 1) { |
||
465 | return -2; |
||
466 | } |
||
467 | break; |
||
468 | } |
||
469 | goto_other_room(leave_dir); |
||
470 | #ifdef USE_REPLAY |
||
471 | if (skipping_replay && replay_seek_target == replay_seek_0_next_room) skipping_replay = 0; |
||
472 | #endif |
||
473 | return leave_dir; |
||
474 | } |
||
475 | |||
476 | // seg002:0643 |
||
477 | void __pascal far Jaffar_exit() { |
||
478 | if (leveldoor_open == 2) { |
||
479 | get_tile(24, 0, 0); |
||
480 | trigger_button(0, 0, -1); |
||
481 | } |
||
482 | } |
||
483 | |||
484 | // seg002:0665 |
||
485 | void __pascal far level3_set_chkp() { |
||
486 | // Special event: set checkpoint |
||
487 | if (current_level == 3 && Char.room == 7) { |
||
488 | checkpoint = 1; |
||
489 | hitp_beg_lev = hitp_max; |
||
490 | } |
||
491 | } |
||
492 | |||
493 | // seg002:0680 |
||
494 | void __pascal far sword_disappears() { |
||
495 | // Special event: sword disappears |
||
496 | if (current_level == 12 && Char.room == 18) { |
||
497 | get_tile(15, 1, 0); |
||
498 | curr_room_tiles[curr_tilepos] = tiles_1_floor; |
||
499 | curr_room_modif[curr_tilepos] = 0; // added, a nonzero modifier may show fake tiles |
||
500 | } |
||
501 | } |
||
502 | |||
503 | // seg002:06AE |
||
504 | void __pascal far meet_Jaffar() { |
||
505 | // Special event: play music |
||
506 | if (current_level == 13 && leveldoor_open == 0 && Char.room == 3) { |
||
507 | play_sound(sound_29_meet_Jaffar); // meet Jaffar |
||
508 | // Special event: Jaffar waits a bit (28/12=2.33 seconds) |
||
509 | guard_notice_timer = 28; |
||
510 | } |
||
511 | } |
||
512 | |||
513 | // seg002:06D3 |
||
514 | void __pascal far play_mirr_mus() { |
||
515 | // Special event: mirror music |
||
516 | if ( |
||
517 | leveldoor_open != 0 && |
||
518 | leveldoor_open != 0x4D && // was the music played already? |
||
519 | current_level == 4 && |
||
520 | Char.curr_row == 0 && |
||
521 | Char.room == 11 |
||
522 | ) { |
||
523 | play_sound(sound_25_presentation); // presentation (level 4 mirror) |
||
524 | leveldoor_open = 0x4D; |
||
525 | } |
||
526 | } |
||
527 | |||
528 | // seg002:0706 |
||
529 | void __pascal far move_0_nothing() { |
||
530 | control_shift = 0; |
||
531 | control_y = 0; |
||
532 | control_x = 0; |
||
533 | control_shift2 = 0; |
||
534 | control_down = 0; |
||
535 | control_up = 0; |
||
536 | control_backward = 0; |
||
537 | control_forward = 0; |
||
538 | } |
||
539 | |||
540 | // seg002:0721 |
||
541 | void __pascal far move_1_forward() { |
||
542 | control_x = -1; |
||
543 | control_forward = -1; |
||
544 | } |
||
545 | |||
546 | // seg002:072A |
||
547 | void __pascal far move_2_backward() { |
||
548 | control_backward = -1; |
||
549 | control_x = 1; |
||
550 | } |
||
551 | |||
552 | // seg002:0735 |
||
553 | void __pascal far move_3_up() { |
||
554 | control_y = -1; |
||
555 | control_up = -1; |
||
556 | } |
||
557 | |||
558 | // seg002:073E |
||
559 | void __pascal far move_4_down() { |
||
560 | control_down = -1; |
||
561 | control_y = 1; |
||
562 | } |
||
563 | |||
564 | // seg002:0749 |
||
565 | void __pascal far move_up_back() { |
||
566 | control_up = -1; |
||
567 | move_2_backward(); |
||
568 | } |
||
569 | |||
570 | // seg002:0753 |
||
571 | void __pascal far move_down_back() { |
||
572 | control_down = -1; |
||
573 | move_2_backward(); |
||
574 | } |
||
575 | |||
576 | // seg002:075D |
||
577 | void __pascal far move_down_forw() { |
||
578 | control_down = -1; |
||
579 | move_1_forward(); |
||
580 | } |
||
581 | |||
582 | // seg002:0767 |
||
583 | void __pascal far move_6_shift() { |
||
584 | control_shift = -1; |
||
585 | control_shift2 = -1; |
||
586 | } |
||
587 | |||
588 | // seg002:0770 |
||
589 | void __pascal far move_7() { |
||
590 | control_shift = 0; |
||
591 | } |
||
592 | |||
593 | // seg002:0776 |
||
594 | void __pascal far autocontrol_opponent() { |
||
595 | word charid; |
||
596 | move_0_nothing(); |
||
597 | charid = Char.charid; |
||
598 | if (charid == charid_0_kid) { |
||
599 | autocontrol_kid(); |
||
600 | } else { |
||
601 | if (justblocked) --justblocked; |
||
602 | if (kid_sword_strike) --kid_sword_strike; |
||
603 | if (guard_refrac) --guard_refrac; |
||
604 | if (charid == charid_24_mouse) { |
||
605 | autocontrol_mouse(); |
||
606 | } else if (charid == charid_4_skeleton) { |
||
607 | autocontrol_skeleton(); |
||
608 | } else if (charid == charid_1_shadow) { |
||
609 | autocontrol_shadow(); |
||
610 | } else if (current_level == 13) { |
||
611 | autocontrol_Jaffar(); |
||
612 | } else { |
||
613 | autocontrol_guard(); |
||
614 | } |
||
615 | } |
||
616 | } |
||
617 | |||
618 | // seg002:07EB |
||
619 | void __pascal far autocontrol_mouse() { |
||
620 | if (Char.direction == dir_56_none) { |
||
621 | return; |
||
622 | } |
||
623 | if (Char.action == actions_0_stand) { |
||
624 | if (Char.x >= 200) { |
||
625 | clear_char(); |
||
626 | } |
||
627 | } else { |
||
628 | if (Char.x < 166) { |
||
629 | seqtbl_offset_char(seq_107_mouse_stand_up_and_go); // mouse |
||
630 | play_seq(); |
||
631 | } |
||
632 | } |
||
633 | } |
||
634 | |||
635 | // seg002:081D |
||
636 | void __pascal far autocontrol_shadow() { |
||
637 | if (current_level == 4) { |
||
638 | autocontrol_shadow_level4(); |
||
639 | } else if (current_level == 5) { |
||
640 | autocontrol_shadow_level5(); |
||
641 | } else if (current_level == 6) { |
||
642 | autocontrol_shadow_level6(); |
||
643 | } else if (current_level == 12) { |
||
644 | autocontrol_shadow_level12(); |
||
645 | } |
||
646 | } |
||
647 | |||
648 | // seg002:0850 |
||
649 | void __pascal far autocontrol_skeleton() { |
||
650 | Char.sword = sword_2_drawn; |
||
651 | autocontrol_guard(); |
||
652 | } |
||
653 | |||
654 | // seg002:085A |
||
655 | void __pascal far autocontrol_Jaffar() { |
||
656 | autocontrol_guard(); |
||
657 | } |
||
658 | |||
659 | // seg002:085F |
||
660 | void __pascal far autocontrol_kid() { |
||
661 | autocontrol_guard(); |
||
662 | } |
||
663 | |||
664 | // seg002:0864 |
||
665 | void __pascal far autocontrol_guard() { |
||
666 | if (Char.sword < sword_2_drawn) { |
||
667 | autocontrol_guard_inactive(); |
||
668 | } else { |
||
669 | autocontrol_guard_active(); |
||
670 | } |
||
671 | } |
||
672 | |||
673 | // seg002:0876 |
||
674 | void __pascal far autocontrol_guard_inactive() { |
||
675 | short distance; |
||
676 | if (Kid.alive >= 0) return; |
||
677 | distance = char_opp_dist(); |
||
678 | if (Opp.curr_row != Char.curr_row || (word)distance < (word)-8) { |
||
679 | // If Kid made a sound ... |
||
680 | if (is_guard_notice) { |
||
681 | is_guard_notice = 0; |
||
682 | if (distance < 0) { |
||
683 | // ... and Kid is behind Guard, Guard turns around. |
||
684 | if ((word)distance < (word)-4) { |
||
685 | move_4_down(); |
||
686 | } |
||
687 | return; |
||
688 | } |
||
689 | } else if (distance < 0) { |
||
690 | return; |
||
691 | } |
||
692 | } |
||
693 | if (can_guard_see_kid) { |
||
694 | // If Guard can see Kid, Guard moves to fighting pose. |
||
695 | if (current_level != 13 || guard_notice_timer == 0) { |
||
696 | move_down_forw(); |
||
697 | } |
||
698 | } |
||
699 | } |
||
700 | |||
701 | // seg002:08DC |
||
702 | void __pascal far autocontrol_guard_active() { |
||
703 | short opp_frame; |
||
704 | short char_frame; |
||
705 | short distance; |
||
706 | char_frame = Char.frame; |
||
707 | if (char_frame != frame_166_stand_inactive && char_frame >= 150 && can_guard_see_kid != 1) { |
||
708 | if (can_guard_see_kid == 0) { |
||
709 | if (droppedout != 0) { |
||
710 | guard_follows_kid_down(); |
||
711 | //return; |
||
712 | } else if (Char.charid != charid_4_skeleton) { |
||
713 | move_down_back(); |
||
714 | } |
||
715 | //return; |
||
716 | } else { // can_guard_see_kid == 2 |
||
717 | opp_frame = Opp.frame; |
||
718 | distance = char_opp_dist(); |
||
719 | if (distance >= 12 && |
||
720 | // frames 102..117: falling and landing |
||
721 | opp_frame >= frame_102_start_fall_1 && opp_frame < frame_118_stand_up_from_crouch_9 && |
||
722 | Opp.action == actions_5_bumped |
||
723 | ) { |
||
724 | return; |
||
725 | } |
||
726 | if (distance < 35) { |
||
727 | if ((Char.sword < sword_2_drawn && distance < 8) || distance < 12) { |
||
728 | if (Char.direction == Opp.direction) { |
||
729 | // turn around |
||
730 | move_2_backward(); |
||
731 | //return; |
||
732 | } else { |
||
733 | move_1_forward(); |
||
734 | //return; |
||
735 | } |
||
736 | } else { |
||
737 | autocontrol_guard_kid_in_sight(distance); |
||
738 | //return; |
||
739 | } |
||
740 | } else { |
||
741 | if (guard_refrac != 0) return; |
||
742 | if (Char.direction != Opp.direction) { |
||
743 | // frames 7..14: running |
||
744 | // frames 34..43: run-jump |
||
745 | if (opp_frame >= frame_7_run && opp_frame < 15) { |
||
746 | if (distance < 40) move_6_shift(); |
||
747 | return; |
||
748 | } else if (opp_frame >= frame_34_start_run_jump_1 && opp_frame < 44) { |
||
749 | if (distance < 50) move_6_shift(); |
||
750 | return; |
||
751 | //return; |
||
752 | } |
||
753 | } |
||
754 | autocontrol_guard_kid_far(); |
||
755 | } |
||
756 | //... |
||
757 | } |
||
758 | //... |
||
759 | } |
||
760 | } |
||
761 | |||
762 | // seg002:09CB |
||
763 | void __pascal far autocontrol_guard_kid_far() { |
||
764 | if (tile_is_floor(get_tile_infrontof_char()) || |
||
765 | tile_is_floor(get_tile_infrontof2_char())) { |
||
766 | move_1_forward(); |
||
767 | } else { |
||
768 | move_2_backward(); |
||
769 | } |
||
770 | } |
||
771 | |||
772 | // seg002:09F8 |
||
773 | void __pascal far guard_follows_kid_down() { |
||
774 | // This is called from autocontrol_guard_active, so char=Guard, Opp=Kid |
||
775 | word opp_action; |
||
776 | opp_action = Opp.action; |
||
777 | if (opp_action == actions_2_hang_climb || opp_action == actions_6_hang_straight) { |
||
778 | return; |
||
779 | } |
||
780 | if (// there is wall in front of Guard |
||
781 | wall_type(get_tile_infrontof_char()) != 0 || |
||
782 | (! tile_is_floor(curr_tile2) && ( |
||
783 | (get_tile(curr_room, tile_col, ++tile_row) == tiles_2_spike || |
||
784 | // Guard would fall on loose floor |
||
785 | curr_tile2 == tiles_11_loose || |
||
786 | // ... or wall (?) |
||
787 | wall_type(curr_tile2) != 0 || |
||
788 | // ... or into a chasm |
||
789 | ! tile_is_floor(curr_tile2)) || |
||
790 | // ... or Kid is not below |
||
791 | Char.curr_row + 1 != Opp.curr_row |
||
792 | )) |
||
793 | ) { |
||
794 | // don't follow |
||
795 | droppedout = 0; |
||
796 | move_2_backward(); |
||
797 | } else { |
||
798 | // follow |
||
799 | move_1_forward(); |
||
800 | } |
||
801 | } |
||
802 | |||
803 | // seg002:0A93 |
||
804 | void __pascal far autocontrol_guard_kid_in_sight(short distance) { |
||
805 | if (Opp.sword == sword_2_drawn) { |
||
806 | autocontrol_guard_kid_armed(distance); |
||
807 | } else if (guard_refrac == 0) { |
||
808 | if (distance < 29) { |
||
809 | move_6_shift(); |
||
810 | } else { |
||
811 | move_1_forward(); |
||
812 | } |
||
813 | } |
||
814 | } |
||
815 | |||
816 | // seg002:0AC1 |
||
817 | void __pascal far autocontrol_guard_kid_armed(short distance) { |
||
818 | if (distance < 10 || distance >= 29) { |
||
819 | guard_advance(); |
||
820 | } else { |
||
821 | guard_block(); |
||
822 | if (guard_refrac == 0) { |
||
823 | if (distance < 12 || distance >= 29) { |
||
824 | guard_advance(); |
||
825 | } else { |
||
826 | guard_strike(); |
||
827 | } |
||
828 | } |
||
829 | } |
||
830 | } |
||
831 | |||
832 | // seg002:0AF5 |
||
833 | void __pascal far guard_advance() { |
||
834 | if (guard_skill == 0 || kid_sword_strike == 0) { |
||
835 | if (advprob[guard_skill] > prandom(255)) { |
||
836 | move_1_forward(); |
||
837 | } |
||
838 | } |
||
839 | } |
||
840 | |||
841 | // seg002:0B1D |
||
842 | void __pascal far guard_block() { |
||
843 | word opp_frame; |
||
844 | opp_frame = Opp.frame; |
||
845 | if (opp_frame == frame_152_strike_2 || opp_frame == frame_153_strike_3 || opp_frame == frame_162_block_to_strike) { |
||
846 | if (justblocked != 0) { |
||
847 | if (impblockprob[guard_skill] > prandom(255)) { |
||
848 | move_3_up(); |
||
849 | } |
||
850 | } else { |
||
851 | if (blockprob[guard_skill] > prandom(255)) { |
||
852 | move_3_up(); |
||
853 | } |
||
854 | } |
||
855 | } |
||
856 | } |
||
857 | |||
858 | // seg002:0B73 |
||
859 | void __pascal far guard_strike() { |
||
860 | word opp_frame; |
||
861 | word char_frame; |
||
862 | opp_frame = Opp.frame; |
||
863 | if (opp_frame == frame_169_begin_block || opp_frame == frame_151_strike_1) return; |
||
864 | char_frame = Char.frame; |
||
865 | if (char_frame == frame_161_parry || char_frame == frame_150_parry) { |
||
866 | if (restrikeprob[guard_skill] > prandom(255)) { |
||
867 | move_6_shift(); |
||
868 | } |
||
869 | } else { |
||
870 | if (strikeprob[guard_skill] > prandom(255)) { |
||
871 | move_6_shift(); |
||
872 | } |
||
873 | } |
||
874 | } |
||
875 | |||
876 | // seg002:0BCD |
||
877 | void __pascal far hurt_by_sword() { |
||
878 | short distance; |
||
879 | if (Char.alive >= 0) return; |
||
880 | if (Char.sword != sword_2_drawn) { |
||
881 | // Being hurt when not in fighting pose means death. |
||
882 | take_hp(100); |
||
883 | seqtbl_offset_char(seq_85_stabbed_to_death); // dying (stabbed unarmed) |
||
884 | loc_4276: |
||
885 | if (get_tile_behind_char() != 0 || |
||
886 | (distance = distance_to_edge_weight()) < 4 |
||
887 | ) { |
||
888 | seqtbl_offset_char(seq_85_stabbed_to_death); // dying (stabbed) |
||
889 | if (Char.charid != charid_0_kid && |
||
890 | Char.direction < dir_0_right && // looking left |
||
891 | (curr_tile2 == tiles_4_gate || get_tile_at_char() == tiles_4_gate) |
||
892 | ) { |
||
893 | Char.x = x_bump[tile_col - (curr_tile2 != tiles_4_gate) + 5] + 7; |
||
894 | Char.x = char_dx_forward(10); |
||
895 | } |
||
896 | Char.y = y_land[Char.curr_row + 1]; |
||
897 | Char.fall_y = 0; |
||
898 | } else { |
||
899 | Char.x = char_dx_forward(distance - 20); |
||
900 | load_fram_det_col(); |
||
901 | inc_curr_row(); |
||
902 | seqtbl_offset_char(seq_81_kid_pushed_off_ledge); // Kid/Guard is killed and pushed off the ledge |
||
903 | } |
||
904 | } else { |
||
905 | // You can't hurt skeletons |
||
906 | if (Char.charid != charid_4_skeleton) { |
||
907 | if (take_hp(1)) goto loc_4276; |
||
908 | } |
||
909 | seqtbl_offset_char(seq_74_hit_by_sword); // being hit with sword |
||
910 | Char.y = y_land[Char.curr_row + 1]; |
||
911 | Char.fall_y = 0; |
||
912 | } |
||
913 | // sound 13: Kid hurt (by sword), sound 12: Guard hurt (by sword) |
||
914 | play_sound(Char.charid == charid_0_kid ? sound_13_kid_hurt : sound_12_guard_hurt); |
||
915 | play_seq(); |
||
916 | } |
||
917 | |||
918 | // seg002:0CD4 |
||
919 | void __pascal far check_sword_hurt() { |
||
920 | if (Guard.action == actions_99_hurt) { |
||
921 | if (Kid.action == actions_99_hurt) { |
||
922 | Kid.action = actions_1_run_jump; |
||
923 | } |
||
924 | loadshad(); |
||
925 | hurt_by_sword(); |
||
926 | saveshad(); |
||
927 | guard_refrac = refractimer[guard_skill]; |
||
928 | } else { |
||
929 | if (Kid.action == actions_99_hurt) { |
||
930 | loadkid(); |
||
931 | hurt_by_sword(); |
||
932 | savekid(); |
||
933 | } |
||
934 | } |
||
935 | } |
||
936 | |||
937 | // seg002:0D1A |
||
938 | void __pascal far check_sword_hurting() { |
||
939 | short kid_frame; |
||
940 | kid_frame = Kid.frame; |
||
941 | // frames 217..228: go up on stairs |
||
942 | if (kid_frame != 0 && (kid_frame < frame_219_exit_stairs_3 || kid_frame >= 229)) { |
||
943 | loadshad_and_opp(); |
||
944 | check_hurting(); |
||
945 | saveshad_and_opp(); |
||
946 | loadkid_and_opp(); |
||
947 | check_hurting(); |
||
948 | savekid_and_opp(); |
||
949 | } |
||
950 | } |
||
951 | |||
952 | // seg002:0D56 |
||
953 | void __pascal far check_hurting() { |
||
954 | short opp_frame, char_frame, distance, min_hurt_range; |
||
955 | if (Char.sword != sword_2_drawn) return; |
||
956 | if (Char.curr_row != Opp.curr_row) return; |
||
957 | char_frame = Char.frame; |
||
958 | // frames 153..154: poking with sword |
||
959 | if (char_frame != frame_153_strike_3 && char_frame != frame_154_poking) return; |
||
960 | // If char is poking ... |
||
961 | distance = char_opp_dist(); |
||
962 | opp_frame = Opp.frame; |
||
963 | // frames 161 and 150: parrying |
||
964 | if (distance < 0 || distance >= 29 || |
||
965 | (opp_frame != frame_161_parry && opp_frame != frame_150_parry) |
||
966 | ) { |
||
967 | // ... and Opp is not parrying |
||
968 | // frame 154: poking |
||
969 | if (Char.frame == frame_154_poking) { |
||
970 | if (Opp.sword < sword_2_drawn) { |
||
971 | min_hurt_range = 8; |
||
972 | } else { |
||
973 | min_hurt_range = 12; |
||
974 | } |
||
975 | distance = char_opp_dist(); |
||
976 | if (distance >= min_hurt_range && distance < 29) { |
||
977 | Opp.action = actions_99_hurt; |
||
978 | } |
||
979 | } |
||
980 | } else { |
||
981 | Opp.frame = frame_161_parry; |
||
982 | if (Char.charid != charid_0_kid) { |
||
983 | justblocked = 4; |
||
984 | } |
||
985 | seqtbl_offset_char(seq_69_attack_was_parried); // attack was parried |
||
986 | play_seq(); |
||
987 | } |
||
988 | // frame 154: poking |
||
989 | // frame 161: parrying |
||
990 | if (Char.frame == frame_154_poking && Opp.frame != frame_161_parry && Opp.action != actions_99_hurt) { |
||
991 | play_sound(sound_11_sword_moving); // sword moving |
||
992 | } |
||
993 | } |
||
994 | |||
995 | // seg002:0E1F |
||
996 | void __pascal far check_skel() { |
||
997 | // Special event: skeleton wakes |
||
998 | if (current_level == 3 && |
||
999 | Guard.direction == dir_56_none && |
||
1000 | drawn_room == 1 && |
||
1001 | leveldoor_open != 0 && |
||
1002 | (Kid.curr_col == 2 || Kid.curr_col == 3) |
||
1003 | ) { |
||
1004 | get_tile(drawn_room, 5, 1); |
||
1005 | if (curr_tile2 == tiles_21_skeleton) { |
||
1006 | // erase skeleton |
||
1007 | curr_room_tiles[curr_tilepos] = tiles_1_floor; |
||
1008 | redraw_height = 24; |
||
1009 | set_redraw_full(curr_tilepos, 1); |
||
1010 | set_wipe(curr_tilepos, 1); |
||
1011 | ++curr_tilepos; |
||
1012 | set_redraw_full(curr_tilepos, 1); |
||
1013 | set_wipe(curr_tilepos, 1); |
||
1014 | Char.room = drawn_room; |
||
1015 | Char.curr_row = 1; |
||
1016 | Char.y = y_land[Char.curr_row + 1]; |
||
1017 | Char.curr_col = 5; |
||
1018 | Char.x = x_bump[Char.curr_col + 5] + 14; |
||
1019 | Char.direction = dir_FF_left; |
||
1020 | seqtbl_offset_char(seq_88_skel_wake_up); // skel wake up |
||
1021 | play_seq(); |
||
1022 | play_sound(sound_44_skel_alive); // skel alive |
||
1023 | guard_skill = 2; |
||
1024 | Char.alive = -1; |
||
1025 | guardhp_max = guardhp_curr = 3; |
||
1026 | Char.fall_x = Char.fall_y = 0; |
||
1027 | is_guard_notice = guard_refrac = 0; |
||
1028 | Char.sword = sword_2_drawn; |
||
1029 | Char.charid = charid_4_skeleton; |
||
1030 | saveshad(); |
||
1031 | } |
||
1032 | } |
||
1033 | } |
||
1034 | |||
1035 | // seg002:0F3F |
||
1036 | void __pascal far do_auto_moves(const auto_move_type *moves_ptr) { |
||
1037 | short demoindex; |
||
1038 | short curr_move; |
||
1039 | if (demo_time >= 0xFE) return; |
||
1040 | ++demo_time; |
||
1041 | demoindex = demo_index; |
||
1042 | if (moves_ptr[demoindex].time <= demo_time) { |
||
1043 | ++demo_index; |
||
1044 | } else { |
||
1045 | demoindex = demo_index - 1; |
||
1046 | } |
||
1047 | curr_move = moves_ptr[demoindex].move; |
||
1048 | switch (curr_move) { |
||
1049 | case -1: |
||
1050 | break; |
||
1051 | case 0: |
||
1052 | move_0_nothing(); |
||
1053 | break; |
||
1054 | case 1: |
||
1055 | move_1_forward(); |
||
1056 | break; |
||
1057 | case 2: |
||
1058 | move_2_backward(); |
||
1059 | break; |
||
1060 | case 3: |
||
1061 | move_3_up(); |
||
1062 | break; |
||
1063 | case 4: |
||
1064 | move_4_down(); |
||
1065 | break; |
||
1066 | case 5: |
||
1067 | move_3_up(); |
||
1068 | move_1_forward(); |
||
1069 | break; |
||
1070 | case 6: |
||
1071 | move_6_shift(); |
||
1072 | break; |
||
1073 | case 7: |
||
1074 | move_7(); |
||
1075 | break; |
||
1076 | } |
||
1077 | } |
||
1078 | |||
1079 | // seg002:1000 |
||
1080 | void __pascal far autocontrol_shadow_level4() { |
||
1081 | if (Char.room == 4) { |
||
1082 | if (Char.x < 80) { |
||
1083 | clear_char(); |
||
1084 | } else { |
||
1085 | move_1_forward(); |
||
1086 | } |
||
1087 | } |
||
1088 | } |
||
1089 | |||
1090 | // data:0F02 |
||
1091 | const auto_move_type shad_drink_move[] = { |
||
1092 | {0x00, 0}, |
||
1093 | {0x01, 1}, |
||
1094 | {0x0E, 0}, |
||
1095 | {0x12, 6}, |
||
1096 | {0x1D, 7}, |
||
1097 | {0x2D, 2}, |
||
1098 | {0x31, 1}, |
||
1099 | {0xFF,-2}, |
||
1100 | }; |
||
1101 | |||
1102 | // seg002:101A |
||
1103 | void __pascal far autocontrol_shadow_level5() { |
||
1104 | if (Char.room == 24) { |
||
1105 | if (demo_time == 0) { |
||
1106 | get_tile(24, 1, 0); |
||
1107 | // is the door open? |
||
1108 | if (curr_room_modif[curr_tilepos] < 80) return; |
||
1109 | demo_index = 0; |
||
1110 | } |
||
1111 | do_auto_moves(shad_drink_move); |
||
1112 | if (Char.x < 15) { |
||
1113 | clear_char(); |
||
1114 | } |
||
1115 | } |
||
1116 | } |
||
1117 | |||
1118 | // seg002:1064 |
||
1119 | void __pascal far autocontrol_shadow_level6() { |
||
1120 | if (Char.room == 1 && |
||
1121 | Kid.frame == frame_43_running_jump_4 && // a frame in run-jump |
||
1122 | Kid.x < 128 |
||
1123 | ) { |
||
1124 | move_6_shift(); |
||
1125 | move_1_forward(); |
||
1126 | } |
||
1127 | } |
||
1128 | |||
1129 | // seg002:1082 |
||
1130 | void __pascal far autocontrol_shadow_level12() { |
||
1131 | short opp_frame; |
||
1132 | short xdiff; |
||
1133 | if (Char.room == 15 && shadow_initialized == 0) { |
||
1134 | if (Opp.x >= 150) { |
||
1135 | do_init_shad(/*&*/init_shad_12, 7 /*fall*/); |
||
1136 | return; |
||
1137 | } |
||
1138 | shadow_initialized = 1; |
||
1139 | } |
||
1140 | if (Char.sword >= sword_2_drawn) { |
||
1141 | // if the Kid puts his sword away, the shadow does the same, |
||
1142 | // but only if the shadow was already hurt (?) |
||
1143 | if (offguard == 0 || guard_refrac == 0) { |
||
1144 | autocontrol_guard_active(); |
||
1145 | } else { |
||
1146 | move_4_down(); |
||
1147 | } |
||
1148 | return; |
||
1149 | } |
||
1150 | if (Opp.sword >= sword_2_drawn || offguard == 0) { |
||
1151 | xdiff = 0x7000; // bugfix/workaround |
||
1152 | // This behavior matches the DOS version but not the Apple II source. |
||
1153 | if (can_guard_see_kid < 2 || (xdiff = char_opp_dist()) >= 90) { |
||
1154 | if (xdiff < 0) { |
||
1155 | move_2_backward(); |
||
1156 | } |
||
1157 | return; |
||
1158 | } |
||
1159 | // Shadow draws his sword |
||
1160 | if (Char.frame == 15) { |
||
1161 | move_down_forw(); |
||
1162 | } |
||
1163 | return; |
||
1164 | } |
||
1165 | if (char_opp_dist() < 10) { |
||
1166 | // unite with the shadow |
||
1167 | flash_color = color_15_brightwhite; // white |
||
1168 | flash_time = 18; |
||
1169 | // get an extra HP for uniting the shadow |
||
1170 | add_life(); |
||
1171 | // time of Kid-shadow flash |
||
1172 | united_with_shadow = 42; |
||
1173 | // put the Kid where the shadow was |
||
1174 | Char.charid = charid_0_kid; |
||
1175 | savekid(); |
||
1176 | // remove the shadow |
||
1177 | clear_char(); |
||
1178 | return; |
||
1179 | } |
||
1180 | if (can_guard_see_kid == 2) { |
||
1181 | // If Kid runs to shadow, shadow runs to Kid. |
||
1182 | opp_frame = Opp.frame; |
||
1183 | // frames 1..14: running |
||
1184 | // frames 121..132: stepping |
||
1185 | if ((opp_frame >= frame_3_start_run && opp_frame < frame_15_stand) || |
||
1186 | (opp_frame >= frame_127_stepping_7 && opp_frame < 133) |
||
1187 | ) { |
||
1188 | move_1_forward(); |
||
1189 | } |
||
1190 | } |
||
1191 | } |