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:1888 |
||
| 24 | extern const word seqtbl_offsets[]; |
||
| 25 | |||
| 26 | // seg005:000A |
||
| 27 | void __pascal far seqtbl_offset_char(short seq_index) { |
||
| 28 | Char.curr_seq = seqtbl_offsets[seq_index]; |
||
| 29 | } |
||
| 30 | |||
| 31 | // seg005:001D |
||
| 32 | void __pascal far seqtbl_offset_opp(int seq_index) { |
||
| 33 | Opp.curr_seq = seqtbl_offsets[seq_index]; |
||
| 34 | } |
||
| 35 | |||
| 36 | // seg005:0030 |
||
| 37 | void __pascal far do_fall() { |
||
| 38 | if (is_screaming == 0 && Char.fall_y >= 31) { |
||
| 39 | play_sound(sound_1_falling); // falling |
||
| 40 | is_screaming = 1; |
||
| 41 | } |
||
| 42 | if ((word)y_land[Char.curr_row + 1] > (word)Char.y) { |
||
| 43 | check_grab(); |
||
| 44 | |||
| 45 | #ifdef FIX_GLIDE_THROUGH_WALL |
||
| 46 | if (fix_glide_through_wall) { |
||
| 47 | // Fix for the kid falling through walls after turning around while running (especially when weightless) |
||
| 48 | determine_col(); |
||
| 49 | get_tile_at_char(); |
||
| 50 | if (curr_tile2 == tiles_20_wall || |
||
| 51 | ((curr_tile2 == tiles_12_doortop || curr_tile2 == tiles_7_doortop_with_floor) && |
||
| 52 | Char.direction == dir_FF_left) |
||
| 53 | ) { |
||
| 54 | int delta_x = distance_to_edge_weight(); |
||
| 55 | //printf("delta_x = %d\n", delta_x); |
||
| 56 | // When falling into a wall or doortop after turning or running, delta_x is likely to be either 8, 11 or 12 |
||
| 57 | // Calling in_wall() here produces the desired fix (no glitching through wall), but only when delta_x >= 10 |
||
| 58 | // The code below "emulates" in_wall() to always get the same effect as if delta_x == 10 |
||
| 59 | // (which distance actually looks/behaves best is a matter of preference) |
||
| 60 | #define delta_x_reference 10 |
||
| 61 | if (delta_x >= 8) { |
||
| 62 | delta_x = -5 + delta_x - delta_x_reference; |
||
| 63 | Char.x = (byte) char_dx_forward(delta_x); |
||
| 64 | |||
| 65 | Char.fall_x = 0; // not in in_wall(), but we do need to cancel horizontal movement |
||
| 66 | } |
||
| 67 | } |
||
| 68 | } |
||
| 69 | #endif |
||
| 70 | |||
| 71 | } else { |
||
| 72 | |||
| 73 | #ifdef FIX_JUMP_THROUGH_WALL_ABOVE_GATE |
||
| 74 | if (fix_jump_through_wall_above_gate) { |
||
| 75 | // At this point, Char.curr_col has not yet been updated since check_bumped() |
||
| 76 | // Basically, Char.curr_col is still set to the column of the wall itself (even though the kid |
||
| 77 | // may have 'bumped' against the wall, with Char.x being offset) |
||
| 78 | |||
| 79 | // To prevent in_wall() from being called we need to update Char.curr_col here. |
||
| 80 | // (in_wall() only makes things worse, because it tries to 'eject' the kid from the wall the wrong way. |
||
| 81 | // For this reason, the kid can end up behind a closed gate below, like is possible in Level 7) |
||
| 82 | |||
| 83 | // The fix is calling determine_col() here. |
||
| 84 | |||
| 85 | // One caveat: the kid can also land on the rightmost edge of a closed gate tile, when doing a running jump |
||
| 86 | // to the left from two floors up. This 'trick' can be used in original PoP, but is 'fixed' by this change. |
||
| 87 | // To still allow this trick to be possible, we can check that we not jumping into a gate tile. |
||
| 88 | // (By the way, strangely enough, in unmodified PoP the trick even works with a tapestry + floor tile...) |
||
| 89 | |||
| 90 | if (get_tile_at_char() != tiles_4_gate) |
||
| 91 | determine_col(); |
||
| 92 | } |
||
| 93 | #endif |
||
| 94 | |||
| 95 | if (get_tile_at_char() == tiles_20_wall) { |
||
| 96 | in_wall(); |
||
| 97 | } |
||
| 98 | #ifdef FIX_DROP_THROUGH_TAPESTRY |
||
| 99 | else if (fix_drop_through_tapestry && get_tile_at_char() == tiles_12_doortop && Char.direction == dir_FF_left) { |
||
| 100 | if (distance_to_edge_weight() >= 8) // only intervene if the kid is actually IN FRONT of the tapestry |
||
| 101 | in_wall(); |
||
| 102 | } |
||
| 103 | #endif |
||
| 104 | |||
| 105 | if (tile_is_floor(curr_tile2)) { |
||
| 106 | land(); |
||
| 107 | } else { |
||
| 108 | inc_curr_row(); |
||
| 109 | } |
||
| 110 | } |
||
| 111 | } |
||
| 112 | |||
| 113 | // seg005:0090 |
||
| 114 | void __pascal far land() { |
||
| 115 | word seq_id; |
||
| 116 | is_screaming = 0; |
||
| 117 | Char.y = y_land[Char.curr_row + 1]; |
||
| 118 | if (get_tile_at_char() != tiles_2_spike) { |
||
| 119 | |||
| 120 | |||
| 121 | if (! tile_is_floor(get_tile_infrontof_char()) && |
||
| 122 | distance_to_edge_weight() < 3 |
||
| 123 | ) { |
||
| 124 | Char.x = char_dx_forward(-3); |
||
| 125 | } |
||
| 126 | |||
| 127 | #ifdef FIX_LAND_AGAINST_GATE_OR_TAPESTRY |
||
| 128 | else if (fix_land_against_gate_or_tapestry) { |
||
| 129 | // A closed gate right in front of the landing spot should not behave like an open floor tile, but like a wall |
||
| 130 | // Similar for a tapestry tile (with floor) |
||
| 131 | get_tile_infrontof_char(); |
||
| 132 | if (Char.direction == dir_FF_left && ( |
||
| 133 | (curr_tile2 == tiles_4_gate && can_bump_into_gate()) || |
||
| 134 | (curr_tile2 == tiles_7_doortop_with_floor)) |
||
| 135 | && distance_to_edge_weight() < 3 |
||
| 136 | ) { |
||
| 137 | Char.x = char_dx_forward(-3); |
||
| 138 | } |
||
| 139 | } |
||
| 140 | #endif |
||
| 141 | start_chompers(); |
||
| 142 | } else { |
||
| 143 | // fell on spikes |
||
| 144 | goto loc_5EE6; |
||
| 145 | } |
||
| 146 | if (Char.alive < 0) { |
||
| 147 | // alive |
||
| 148 | if ((distance_to_edge_weight() >= 12 && |
||
| 149 | get_tile_behind_char() == tiles_2_spike) || |
||
| 150 | get_tile_at_char() == tiles_2_spike |
||
| 151 | ) { |
||
| 152 | // fell on spikes |
||
| 153 | loc_5EE6: |
||
| 154 | if (is_spike_harmful()) { |
||
| 155 | spiked(); |
||
| 156 | return; |
||
| 157 | } |
||
| 158 | #ifdef FIX_SAFE_LANDING_ON_SPIKES |
||
| 159 | else if (fix_safe_landing_on_spikes && curr_room_modif[curr_tilepos] == 0) { |
||
| 160 | // spikes ARE dangerous, just not out yet. |
||
| 161 | spiked(); |
||
| 162 | return; |
||
| 163 | } |
||
| 164 | #endif // FIX_SAFE_LANDING_ON_SPIKES |
||
| 165 | } |
||
| 166 | { |
||
| 167 | if (Char.fall_y < 22) { |
||
| 168 | // fell 1 row |
||
| 169 | loc_5EFD: |
||
| 170 | if (Char.charid >= charid_2_guard || Char.sword == sword_2_drawn) { |
||
| 171 | Char.sword = sword_2_drawn; |
||
| 172 | seq_id = seq_63_guard_stand_active; // stand active after landing |
||
| 173 | } else { |
||
| 174 | seq_id = seq_17_soft_land; // crouch (soft land) |
||
| 175 | } |
||
| 176 | if (Char.charid == charid_0_kid) { |
||
| 177 | play_sound(sound_17_soft_land); // soft land (crouch) |
||
| 178 | is_guard_notice = 1; |
||
| 179 | } |
||
| 180 | } else if (Char.fall_y < 33) { |
||
| 181 | // fell 2 rows |
||
| 182 | if (Char.charid == charid_1_shadow) goto loc_5EFD; |
||
| 183 | if (Char.charid == charid_2_guard) goto loc_5F6C; |
||
| 184 | // kid (or skeleton (bug!)) |
||
| 185 | if (! take_hp(1)) { |
||
| 186 | // still alive |
||
| 187 | play_sound(sound_16_medium_land); // medium land |
||
| 188 | is_guard_notice = 1; |
||
| 189 | seq_id = seq_20_medium_land; // medium land (lose 1 HP, crouch) |
||
| 190 | } else { |
||
| 191 | // dead (this was the last HP) |
||
| 192 | goto loc_5F75; |
||
| 193 | } |
||
| 194 | } else { |
||
| 195 | // fell 3 or more rows |
||
| 196 | goto loc_5F6C; |
||
| 197 | } |
||
| 198 | } |
||
| 199 | } else { |
||
| 200 | // dead |
||
| 201 | loc_5F6C: |
||
| 202 | take_hp(100); |
||
| 203 | loc_5F75: |
||
| 204 | play_sound(sound_0_fell_to_death); // prince crashing into the floor |
||
| 205 | seq_id = seq_22_crushed; // dead (after falling) |
||
| 206 | } |
||
| 207 | seqtbl_offset_char(seq_id); |
||
| 208 | play_seq(); |
||
| 209 | Char.fall_y = 0; |
||
| 210 | } |
||
| 211 | |||
| 212 | // seg005:01B7 |
||
| 213 | void __pascal far spiked() { |
||
| 214 | // If someone falls into spikes, those spikes become harmless (to others). |
||
| 215 | curr_room_modif[curr_tilepos] = 0xFF; |
||
| 216 | Char.y = y_land[Char.curr_row + 1]; |
||
| 217 | Char.x = x_bump[tile_col + 5] + 10; |
||
| 218 | Char.x = char_dx_forward(8); |
||
| 219 | Char.fall_y = 0; |
||
| 220 | play_sound(sound_48_spiked); // something spiked |
||
| 221 | take_hp(100); |
||
| 222 | seqtbl_offset_char(seq_51_spiked); // spiked |
||
| 223 | play_seq(); |
||
| 224 | } |
||
| 225 | |||
| 226 | // seg005:0213 |
||
| 227 | void __pascal far control() { |
||
| 228 | short char_frame; |
||
| 229 | short char_action; |
||
| 230 | char_frame = Char.frame; |
||
| 231 | if (Char.alive >= 0) { |
||
| 232 | if (char_frame == frame_15_stand || // stand |
||
| 233 | char_frame == frame_166_stand_inactive || // stand |
||
| 234 | char_frame == frame_158_stand_with_sword || // stand with sword |
||
| 235 | char_frame == frame_171_stand_with_sword // stand with sword |
||
| 236 | ) { |
||
| 237 | seqtbl_offset_char(seq_71_dying); // dying (not stabbed) |
||
| 238 | } |
||
| 239 | } else { |
||
| 240 | char_action = Char.action; |
||
| 241 | if (char_action == actions_5_bumped || |
||
| 242 | char_action == actions_4_in_freefall |
||
| 243 | ) { |
||
| 244 | release_arrows(); |
||
| 245 | } else if (Char.sword == sword_2_drawn) { |
||
| 246 | control_with_sword(); |
||
| 247 | } else if (Char.charid >= charid_2_guard) { |
||
| 248 | control_guard_inactive(); |
||
| 249 | } else if (char_frame == frame_15_stand || // standing |
||
| 250 | (char_frame>= frame_50_turn && char_frame<53) // end of turning |
||
| 251 | ) { |
||
| 252 | control_standing(); |
||
| 253 | } else if (char_frame == frame_48_turn) { // a frame in turning |
||
| 254 | control_turning(); |
||
| 255 | } else if (char_frame < 4) { // start run |
||
| 256 | control_startrun(); |
||
| 257 | } else if (char_frame >= frame_67_start_jump_up_1 && char_frame < frame_70_jumphang) { // start jump up |
||
| 258 | control_jumpup(); |
||
| 259 | } else if (char_frame < 15) { // running |
||
| 260 | control_running(); |
||
| 261 | } else if (char_frame >= frame_87_hanging_1 && char_frame < 100) { // hanging |
||
| 262 | control_hanging(); |
||
| 263 | } else if (char_frame == frame_109_crouch) { // crouching |
||
| 264 | control_crouched(); |
||
| 265 | } |
||
| 266 | |||
| 267 | #ifdef ALLOW_CROUCH_AFTER_CLIMBING |
||
| 268 | // When ducking with down+forward, give time to release the forward control (prevents unintended crouch-hops) |
||
| 269 | else if (enable_crouch_after_climbing && Char.curr_seq >= seqtbl_offsets[seq_50_crouch] && |
||
| 270 | Char.curr_seq < seqtbl_offsets[seq_49_stand_up_from_crouch]) // while stooping |
||
| 271 | if (control_forward < 1) control_forward = 0; |
||
| 272 | #endif |
||
| 273 | |||
| 274 | #ifdef FIX_MOVE_AFTER_DRINK |
||
| 275 | if (fix_move_after_drink && char_frame >= frame_191_drink && char_frame <= frame_205_drink) |
||
| 276 | release_arrows(); |
||
| 277 | #endif |
||
| 278 | |||
| 279 | #ifdef FIX_MOVE_AFTER_SHEATHE |
||
| 280 | if (fix_move_after_sheathe && |
||
| 281 | Char.curr_seq >= seqtbl_offsets[seq_92_put_sword_away] && |
||
| 282 | Char.curr_seq < seqtbl_offsets[seq_93_put_sword_away_fast] |
||
| 283 | ) |
||
| 284 | release_arrows(); |
||
| 285 | #endif |
||
| 286 | } |
||
| 287 | } |
||
| 288 | |||
| 289 | // seg005:02EB |
||
| 290 | void __pascal far control_crouched() { |
||
| 291 | if (need_level1_music != 0 && current_level == 1) { |
||
| 292 | // Special event: music when crouching |
||
| 293 | if (! check_sound_playing()) { |
||
| 294 | if (need_level1_music == 1) { |
||
| 295 | play_sound(sound_25_presentation); // presentation (level 1 start) |
||
| 296 | need_level1_music = 2; |
||
| 297 | } else { |
||
| 298 | #ifdef USE_REPLAY |
||
| 299 | if (recording) special_move = MOVE_EFFECT_END; |
||
| 300 | if (!replaying) // during replays, crouch immobilization gets cancelled in do_replay_move() |
||
| 301 | #endif |
||
| 302 | need_level1_music = 0; |
||
| 303 | } |
||
| 304 | } |
||
| 305 | } else { |
||
| 306 | need_level1_music = 0; |
||
| 307 | if (control_shift2 < 0 && check_get_item()) return; |
||
| 308 | if (control_y != 1) { |
||
| 309 | seqtbl_offset_char(seq_49_stand_up_from_crouch); // stand up from crouch |
||
| 310 | } else { |
||
| 311 | if (control_forward < 0) { |
||
| 312 | control_forward = 1; // disable automatic repeat |
||
| 313 | seqtbl_offset_char(seq_79_crouch_hop); // crouch-hop |
||
| 314 | } |
||
| 315 | } |
||
| 316 | } |
||
| 317 | } |
||
| 318 | |||
| 319 | // seg005:0358 |
||
| 320 | void __pascal far control_standing() { |
||
| 321 | short var_2; |
||
| 322 | if (control_shift2 < 0 && control_shift < 0 && check_get_item()) { |
||
| 323 | return; |
||
| 324 | } |
||
| 325 | if (Char.charid != charid_0_kid && control_down < 0 && control_forward < 0) { |
||
| 326 | draw_sword(); |
||
| 327 | return; |
||
| 328 | } //else |
||
| 329 | if (have_sword) { |
||
| 330 | if (offguard != 0 && control_shift >= 0) goto loc_6213; |
||
| 331 | if (can_guard_see_kid >= 2) { |
||
| 332 | var_2 = char_opp_dist(); |
||
| 333 | if (var_2 >= -10 && var_2 < 90) { |
||
| 334 | holding_sword = 1; |
||
| 335 | if ((word)var_2 < (word)-6) { |
||
| 336 | if (Opp.charid == charid_1_shadow && |
||
| 337 | (Opp.action == actions_3_in_midair || (Opp.frame >= frame_107_fall_land_1 && Opp.frame < 118)) |
||
| 338 | ) { |
||
| 339 | offguard = 0; |
||
| 340 | } else { |
||
| 341 | draw_sword(); |
||
| 342 | return; |
||
| 343 | } |
||
| 344 | } else { |
||
| 345 | back_pressed(); |
||
| 346 | return; |
||
| 347 | } |
||
| 348 | } |
||
| 349 | } else { |
||
| 350 | offguard = 0; |
||
| 351 | } |
||
| 352 | } |
||
| 353 | if (control_shift < 0) { |
||
| 354 | if (control_backward < 0) { |
||
| 355 | back_pressed(); |
||
| 356 | } else if (control_up < 0) { |
||
| 357 | up_pressed(); |
||
| 358 | } else if (control_down < 0) { |
||
| 359 | down_pressed(); |
||
| 360 | } else if (control_x < 0 && control_forward < 0) { |
||
| 361 | safe_step(); |
||
| 362 | } |
||
| 363 | } else loc_6213: if (control_forward < 0) { |
||
| 364 | if (is_keyboard_mode && control_up < 0) { |
||
| 365 | standing_jump(); |
||
| 366 | } else { |
||
| 367 | forward_pressed(); |
||
| 368 | } |
||
| 369 | } else if (control_backward < 0) { |
||
| 370 | back_pressed(); |
||
| 371 | } else if (control_up < 0) { |
||
| 372 | if (is_keyboard_mode && control_forward < 0) { |
||
| 373 | standing_jump(); |
||
| 374 | } else { |
||
| 375 | up_pressed(); |
||
| 376 | } |
||
| 377 | } else if (control_down < 0) { |
||
| 378 | down_pressed(); |
||
| 379 | } else if (control_x < 0) { |
||
| 380 | forward_pressed(); |
||
| 381 | } |
||
| 382 | } |
||
| 383 | |||
| 384 | // seg005:0482 |
||
| 385 | void __pascal far up_pressed() { |
||
| 386 | int leveldoor_tilepos = -1; |
||
| 387 | if (get_tile_at_char() == tiles_16_level_door_left) leveldoor_tilepos = curr_tilepos; |
||
| 388 | else if (get_tile_behind_char() == tiles_16_level_door_left) leveldoor_tilepos = curr_tilepos; |
||
| 389 | else if (get_tile_infrontof_char() == tiles_16_level_door_left) leveldoor_tilepos = curr_tilepos; |
||
| 390 | if ((leveldoor_tilepos != -1) && |
||
| 391 | level.start_room != drawn_room && |
||
| 392 | curr_room_modif[leveldoor_tilepos] >= 42 // this door must be fully open |
||
| 393 | ){ |
||
| 394 | go_up_leveldoor(); |
||
| 395 | } else { |
||
| 396 | if (control_x < 0) { |
||
| 397 | standing_jump(); |
||
| 398 | } else { |
||
| 399 | check_jump_up(); |
||
| 400 | } |
||
| 401 | } |
||
| 402 | } |
||
| 403 | |||
| 404 | // seg005:04C7 |
||
| 405 | void __pascal far down_pressed() { |
||
| 406 | control_down = 1; // disable automatic repeat |
||
| 407 | if (! tile_is_floor(get_tile_infrontof_char()) && |
||
| 408 | distance_to_edge_weight() < 3 |
||
| 409 | ) { |
||
| 410 | Char.x = char_dx_forward(5); |
||
| 411 | load_fram_det_col(); |
||
| 412 | } else { |
||
| 413 | if (! tile_is_floor(get_tile_behind_char()) && |
||
| 414 | distance_to_edge_weight() >= 8 |
||
| 415 | ) { |
||
| 416 | through_tile = get_tile_behind_char(); |
||
| 417 | get_tile_at_char(); |
||
| 418 | if (can_grab() && |
||
| 419 | #ifdef ALLOW_CROUCH_AFTER_CLIMBING |
||
| 420 | (!(enable_crouch_after_climbing && control_forward == -1)) && |
||
| 421 | #endif |
||
| 422 | (Char.direction >= dir_0_right || |
||
| 423 | get_tile_at_char() != tiles_4_gate || |
||
| 424 | curr_room_modif[curr_tilepos] >> 2 >= 6) |
||
| 425 | ) { |
||
| 426 | Char.x = char_dx_forward(distance_to_edge_weight() - 9); |
||
| 427 | seqtbl_offset_char(seq_68_climb_down); // climb down |
||
| 428 | } else { |
||
| 429 | crouch(); |
||
| 430 | } |
||
| 431 | } else { |
||
| 432 | crouch(); |
||
| 433 | } |
||
| 434 | } |
||
| 435 | } |
||
| 436 | |||
| 437 | // seg005:0574 |
||
| 438 | void __pascal far go_up_leveldoor() { |
||
| 439 | Char.x = x_bump[tile_col + 5] + 10; |
||
| 440 | Char.direction = dir_FF_left; // right |
||
| 441 | seqtbl_offset_char(seq_70_go_up_on_level_door); // go up on level door |
||
| 442 | } |
||
| 443 | |||
| 444 | // seg005:058F |
||
| 445 | void __pascal far control_turning() { |
||
| 446 | if (control_shift >= 0 && control_x < 0 && control_y >= 0) { |
||
| 447 | seqtbl_offset_char(seq_43_start_run_after_turn); // start run and run (after turning) |
||
| 448 | } |
||
| 449 | |||
| 450 | // Added: |
||
| 451 | // When using a joystick, the kid may sometimes jump/duck/turn unintendedly after turning around. |
||
| 452 | // To prevent this: clear the remembered controls, so that if the stick has already moved to another/neutral position, |
||
| 453 | // the kid will not jump, duck, or turn again. |
||
| 454 | if (is_joyst_mode) { |
||
| 455 | if (control_up < 0 && control_y >= 0) { |
||
| 456 | control_up = 0; |
||
| 457 | } |
||
| 458 | if (control_down < 0 && control_y <= 0) { |
||
| 459 | control_down = 0; |
||
| 460 | } |
||
| 461 | if (control_backward < 0 && control_x == 0) { |
||
| 462 | control_backward = 0; |
||
| 463 | } |
||
| 464 | } |
||
| 465 | } |
||
| 466 | |||
| 467 | // seg005:05AD |
||
| 468 | void __pascal far crouch() { |
||
| 469 | seqtbl_offset_char(seq_50_crouch); // crouch |
||
| 470 | control_down = release_arrows(); |
||
| 471 | } |
||
| 472 | |||
| 473 | // seg005:05BE |
||
| 474 | void __pascal far back_pressed() { |
||
| 475 | word seq_id; |
||
| 476 | control_backward = release_arrows(); |
||
| 477 | // After turn, Kid will draw sword if ... |
||
| 478 | if (have_sword == 0 || // if Kid has sword |
||
| 479 | can_guard_see_kid < 2 || // and can see Guard |
||
| 480 | char_opp_dist() > 0 || // and Guard was behind him |
||
| 481 | distance_to_edge_weight() < 2 |
||
| 482 | ) { |
||
| 483 | seq_id = seq_5_turn; // turn |
||
| 484 | } else { |
||
| 485 | Char.sword = sword_2_drawn; |
||
| 486 | offguard = 0; |
||
| 487 | seq_id = seq_89_turn_draw_sword; // turn and draw sword |
||
| 488 | } |
||
| 489 | seqtbl_offset_char(seq_id); |
||
| 490 | } |
||
| 491 | |||
| 492 | // seg005:060F |
||
| 493 | void __pascal far forward_pressed() { |
||
| 494 | short distance; |
||
| 495 | distance = get_edge_distance(); |
||
| 496 | #ifdef ALLOW_CROUCH_AFTER_CLIMBING |
||
| 497 | if (enable_crouch_after_climbing && control_down < 0) { |
||
| 498 | down_pressed(); |
||
| 499 | control_forward = 0; |
||
| 500 | return; |
||
| 501 | } |
||
| 502 | #endif |
||
| 503 | |||
| 504 | if (edge_type == 1 && curr_tile2 != tiles_18_chomper && distance < 8) { |
||
| 505 | // If char is near a wall, step instead of run. |
||
| 506 | if (control_forward < 0) { |
||
| 507 | safe_step(); |
||
| 508 | } |
||
| 509 | } else { |
||
| 510 | seqtbl_offset_char(seq_1_start_run); // start run and run |
||
| 511 | } |
||
| 512 | } |
||
| 513 | |||
| 514 | // seg005:0649 |
||
| 515 | void __pascal far control_running() { |
||
| 516 | if (control_x == 0 && (Char.frame == frame_7_run || Char.frame == frame_11_run)) { |
||
| 517 | control_forward = release_arrows(); |
||
| 518 | seqtbl_offset_char(seq_13_stop_run); // stop run |
||
| 519 | } else if (control_x > 0) { |
||
| 520 | control_backward = release_arrows(); |
||
| 521 | seqtbl_offset_char(seq_6_run_turn); // run-turn |
||
| 522 | } else if (control_y < 0 && control_up < 0) { |
||
| 523 | run_jump(); |
||
| 524 | } else if (control_down < 0) { |
||
| 525 | control_down = 1; // disable automatic repeat |
||
| 526 | seqtbl_offset_char(seq_26_crouch_while_running); // crouch while running |
||
| 527 | } |
||
| 528 | } |
||
| 529 | |||
| 530 | // seg005:06A8 |
||
| 531 | void __pascal far safe_step() { |
||
| 532 | short distance; |
||
| 533 | control_shift2 = 1; // disable automatic repeat |
||
| 534 | control_forward = 1; // disable automatic repeat |
||
| 535 | distance = get_edge_distance(); |
||
| 536 | if (distance) { |
||
| 537 | Char.repeat = 1; |
||
| 538 | seqtbl_offset_char(distance + 28); // 29..42: safe step to edge |
||
| 539 | } else if (edge_type != 1 && Char.repeat != 0) { |
||
| 540 | Char.repeat = 0; |
||
| 541 | seqtbl_offset_char(seq_44_step_on_edge); // step on edge |
||
| 542 | } else { |
||
| 543 | seqtbl_offset_char(seq_39_safe_step_11); // unsafe step (off ledge) |
||
| 544 | } |
||
| 545 | } |
||
| 546 | |||
| 547 | // seg005:06F0 |
||
| 548 | int __pascal far check_get_item() { |
||
| 549 | if (get_tile_at_char() == tiles_10_potion || |
||
| 550 | curr_tile2 == tiles_22_sword |
||
| 551 | ) { |
||
| 552 | if (! tile_is_floor(get_tile_behind_char())) { |
||
| 553 | return 0; |
||
| 554 | } |
||
| 555 | Char.x = char_dx_forward(-14); |
||
| 556 | load_fram_det_col(); |
||
| 557 | } |
||
| 558 | if (get_tile_infrontof_char() == tiles_10_potion || |
||
| 559 | curr_tile2 == tiles_22_sword |
||
| 560 | ) { |
||
| 561 | get_item(); |
||
| 562 | return 1; |
||
| 563 | } |
||
| 564 | return 0; |
||
| 565 | } |
||
| 566 | |||
| 567 | // seg005:073E |
||
| 568 | void __pascal far get_item() { |
||
| 569 | short distance; |
||
| 570 | if (Char.frame != frame_109_crouch) { // crouching |
||
| 571 | distance = get_edge_distance(); |
||
| 572 | if (edge_type != 2) { |
||
| 573 | Char.x = char_dx_forward(distance); |
||
| 574 | } |
||
| 575 | if (Char.direction >= dir_0_right) { |
||
| 576 | Char.x = char_dx_forward((curr_tile2 == tiles_10_potion) - 2); |
||
| 577 | } |
||
| 578 | crouch(); |
||
| 579 | } else if (curr_tile2 == tiles_22_sword) { |
||
| 580 | do_pickup(-1); |
||
| 581 | seqtbl_offset_char(seq_91_get_sword); // get sword |
||
| 582 | } else { // potion |
||
| 583 | do_pickup(curr_room_modif[curr_tilepos] >> 3); |
||
| 584 | seqtbl_offset_char(seq_78_drink); // drink |
||
| 585 | #ifdef USE_COPYPROT |
||
| 586 | if (current_level == 15) { |
||
| 587 | short index; |
||
| 588 | for (index = 0; index < 14; ++index) { |
||
| 589 | // remove letter on potions level |
||
| 590 | if (copyprot_room[index] == curr_room && |
||
| 591 | copyprot_tile[index] == curr_tilepos |
||
| 592 | ) { |
||
| 593 | copyprot_room[index] = 0; |
||
| 594 | break; |
||
| 595 | } |
||
| 596 | } |
||
| 597 | } |
||
| 598 | #endif |
||
| 599 | } |
||
| 600 | } |
||
| 601 | |||
| 602 | // seg005:07FF |
||
| 603 | void __pascal far control_startrun() { |
||
| 604 | if (control_y < 0 && control_x < 0) { |
||
| 605 | standing_jump(); |
||
| 606 | } |
||
| 607 | } |
||
| 608 | |||
| 609 | // seg005:0812 |
||
| 610 | void __pascal far control_jumpup() { |
||
| 611 | if (control_x < 0 || control_forward < 0) { |
||
| 612 | standing_jump(); |
||
| 613 | } |
||
| 614 | } |
||
| 615 | |||
| 616 | // seg005:0825 |
||
| 617 | void __pascal far standing_jump() { |
||
| 618 | control_up = control_forward = 1; // disable automatic repeat |
||
| 619 | seqtbl_offset_char(seq_3_standing_jump); // standing jump |
||
| 620 | } |
||
| 621 | |||
| 622 | // seg005:0836 |
||
| 623 | void __pascal far check_jump_up() { |
||
| 624 | control_up = release_arrows(); |
||
| 625 | through_tile = get_tile_above_char(); |
||
| 626 | get_tile_front_above_char(); |
||
| 627 | if (can_grab()) { |
||
| 628 | grab_up_with_floor_behind(); |
||
| 629 | } else { |
||
| 630 | through_tile = get_tile_behind_above_char(); |
||
| 631 | get_tile_above_char(); |
||
| 632 | if (can_grab()) { |
||
| 633 | jump_up_or_grab(); |
||
| 634 | } else { |
||
| 635 | jump_up(); |
||
| 636 | } |
||
| 637 | } |
||
| 638 | } |
||
| 639 | |||
| 640 | // seg005:087B |
||
| 641 | void __pascal far jump_up_or_grab() { |
||
| 642 | short distance; |
||
| 643 | distance = distance_to_edge_weight(); |
||
| 644 | if (distance < 6) { |
||
| 645 | jump_up(); |
||
| 646 | } else if (! tile_is_floor(get_tile_behind_char())) { |
||
| 647 | // There is not floor behind char. |
||
| 648 | grab_up_no_floor_behind(); |
||
| 649 | } else { |
||
| 650 | // There is floor behind char, go back a bit. |
||
| 651 | Char.x = char_dx_forward(distance - 14); |
||
| 652 | load_fram_det_col(); |
||
| 653 | grab_up_with_floor_behind(); |
||
| 654 | } |
||
| 655 | } |
||
| 656 | |||
| 657 | // seg005:08C7 |
||
| 658 | void __pascal far grab_up_no_floor_behind() { |
||
| 659 | get_tile_above_char(); |
||
| 660 | Char.x = char_dx_forward(distance_to_edge_weight() - 10); |
||
| 661 | seqtbl_offset_char(seq_16_jump_up_and_grab); // jump up and grab (no floor behind) |
||
| 662 | } |
||
| 663 | |||
| 664 | // seg005:08E6 |
||
| 665 | void __pascal far jump_up() { |
||
| 666 | short distance; |
||
| 667 | control_up = release_arrows(); |
||
| 668 | distance = get_edge_distance(); |
||
| 669 | if (distance < 4 && edge_type == 1) { |
||
| 670 | Char.x = char_dx_forward(distance - 3); |
||
| 671 | } |
||
| 672 | #ifdef FIX_JUMP_DISTANCE_AT_EDGE |
||
| 673 | // When climbing up two floors, turning around and jumping upward, the kid falls down. |
||
| 674 | // This fix makes the workaround of Trick 25 unnecessary. |
||
| 675 | if (fix_jump_distance_at_edge && distance == 3 && edge_type == 0) { |
||
| 676 | Char.x = char_dx_forward(-1); |
||
| 677 | } |
||
| 678 | #endif |
||
| 679 | get_tile(Char.room, get_tile_div_mod(back_delta_x(0) + dx_weight() - 6), Char.curr_row - 1); |
||
| 680 | if (curr_tile2 != tiles_20_wall && ! tile_is_floor(curr_tile2)) { |
||
| 681 | seqtbl_offset_char(seq_28_jump_up_with_nothing_above); // jump up with nothing above |
||
| 682 | } else { |
||
| 683 | seqtbl_offset_char(seq_14_jump_up_into_ceiling); // jump up with wall or floor above |
||
| 684 | } |
||
| 685 | } |
||
| 686 | |||
| 687 | // seg005:0968 |
||
| 688 | void __pascal far control_hanging() { |
||
| 689 | if (Char.alive < 0) { |
||
| 690 | if (grab_timer == 0 && control_y < 0) { |
||
| 691 | can_climb_up(); |
||
| 692 | } else if (control_shift < 0) { |
||
| 693 | // hanging against a wall or a doortop |
||
| 694 | if (Char.action != actions_6_hang_straight && |
||
| 695 | (get_tile_at_char() == tiles_20_wall || |
||
| 696 | (Char.direction == dir_FF_left && ( // facing left |
||
| 697 | curr_tile2 == tiles_7_doortop_with_floor || |
||
| 698 | curr_tile2 == tiles_12_doortop |
||
| 699 | ))) |
||
| 700 | ) { |
||
| 701 | if (grab_timer == 0) { |
||
| 702 | play_sound(sound_8_bumped); // touching a wall (hang against wall) |
||
| 703 | } |
||
| 704 | seqtbl_offset_char(seq_25_hang_against_wall); // hang against wall (straight) |
||
| 705 | } else { |
||
| 706 | if (! tile_is_floor(get_tile_above_char())) { |
||
| 707 | hang_fall(); |
||
| 708 | } |
||
| 709 | } |
||
| 710 | } else { |
||
| 711 | hang_fall(); |
||
| 712 | } |
||
| 713 | } else { |
||
| 714 | hang_fall(); |
||
| 715 | } |
||
| 716 | } |
||
| 717 | |||
| 718 | // seg005:09DF |
||
| 719 | void __pascal far can_climb_up() { |
||
| 720 | short seq_id; |
||
| 721 | seq_id = seq_10_climb_up; // climb up |
||
| 722 | control_up = control_shift2 = release_arrows(); |
||
| 723 | get_tile_above_char(); |
||
| 724 | if (((curr_tile2 == tiles_13_mirror || curr_tile2 == tiles_18_chomper) && |
||
| 725 | Char.direction == dir_0_right) || |
||
| 726 | (curr_tile2 == tiles_4_gate && Char.direction != dir_0_right && |
||
| 727 | curr_room_modif[curr_tilepos] >> 2 < 6) |
||
| 728 | ) { |
||
| 729 | seq_id = seq_73_climb_up_to_closed_gate; // climb up to closed gate and down |
||
| 730 | } |
||
| 731 | seqtbl_offset_char(seq_id); |
||
| 732 | } |
||
| 733 | |||
| 734 | // seg005:0A46 |
||
| 735 | void __pascal far hang_fall() { |
||
| 736 | control_down = release_arrows(); |
||
| 737 | if (! tile_is_floor(get_tile_behind_char()) && |
||
| 738 | ! tile_is_floor(get_tile_at_char()) |
||
| 739 | ) { |
||
| 740 | seqtbl_offset_char(seq_23_release_ledge_and_fall); // release ledge and fall |
||
| 741 | } else { |
||
| 742 | if (get_tile_at_char() == tiles_20_wall || |
||
| 743 | (Char.direction < dir_0_right && ( // looking left |
||
| 744 | curr_tile2 == tiles_7_doortop_with_floor || |
||
| 745 | curr_tile2 == tiles_12_doortop |
||
| 746 | )) |
||
| 747 | ) { |
||
| 748 | Char.x = char_dx_forward(-7); |
||
| 749 | } |
||
| 750 | seqtbl_offset_char(seq_11_release_ledge_and_land); // end of climb down |
||
| 751 | } |
||
| 752 | } |
||
| 753 | |||
| 754 | // seg005:0AA8 |
||
| 755 | void __pascal far grab_up_with_floor_behind() { |
||
| 756 | short distance; |
||
| 757 | distance = distance_to_edge_weight(); |
||
| 758 | |||
| 759 | // The global variable edge_type (which we need!) gets set as a side effect of get_edge_distance() |
||
| 760 | short edge_distance = get_edge_distance(); |
||
| 761 | //printf("Distance to edge weight: %d\tedge type: %d\tedge distance: %d\n", distance, edge_type, edge_distance); |
||
| 762 | |||
| 763 | #ifdef FIX_EDGE_DISTANCE_CHECK_WHEN_CLIMBING |
||
| 764 | // When climbing to a higher floor, the game unnecessarily checks how far away the edge below is; |
||
| 765 | // This contributes to sometimes "teleporting" considerable distances when climbing from firm ground |
||
| 766 | #define JUMP_STRAIGHT_CONDITION (fix_edge_distance_check_when_climbing) \ |
||
| 767 | ? (distance < 4 && edge_type != 1) \ |
||
| 768 | : (distance < 4 && edge_distance < 4 && edge_type != 1) |
||
| 769 | #else |
||
| 770 | #define JUMP_STRAIGHT_CONDITION distance < 4 && edge_distance < 4 && edge_type != 1 |
||
| 771 | #endif |
||
| 772 | |||
| 773 | if (JUMP_STRAIGHT_CONDITION) { |
||
| 774 | Char.x = char_dx_forward(distance); |
||
| 775 | seqtbl_offset_char(seq_8_jump_up_and_grab_straight); // jump up and grab (when?) |
||
| 776 | } else { |
||
| 777 | Char.x = char_dx_forward(distance - 4); |
||
| 778 | seqtbl_offset_char(seq_24_jump_up_and_grab_forward); // jump up and grab (with floor behind) |
||
| 779 | } |
||
| 780 | } |
||
| 781 | |||
| 782 | // seg005:0AF7 |
||
| 783 | void __pascal far run_jump() { |
||
| 784 | short var_2; |
||
| 785 | short xpos; |
||
| 786 | short col; |
||
| 787 | short var_8; |
||
| 788 | if (Char.frame >= frame_7_run) { |
||
| 789 | // Align Kid to edge of floor. |
||
| 790 | xpos = char_dx_forward(4); |
||
| 791 | col = get_tile_div_mod_m7(xpos); |
||
| 792 | for (var_2 = 0; var_2 < 2; ++var_2) { |
||
| 793 | col += dir_front[Char.direction + 1]; |
||
| 794 | get_tile(Char.room, col, Char.curr_row); |
||
| 795 | if (curr_tile2 == tiles_2_spike || ! tile_is_floor(curr_tile2)) { |
||
| 796 | var_8 = distance_to_edge(xpos) + 14 * var_2 - 14; |
||
| 797 | if ((word)var_8 < (word)-8 || var_8 >= 2) { |
||
| 798 | if (var_8 < 128) return; |
||
| 799 | var_8 = -3; |
||
| 800 | } |
||
| 801 | Char.x = char_dx_forward(var_8 + 4); |
||
| 802 | break; |
||
| 803 | } |
||
| 804 | } |
||
| 805 | control_up = release_arrows(); // disable automatic repeat |
||
| 806 | seqtbl_offset_char(seq_4_run_jump); // run-jump |
||
| 807 | } |
||
| 808 | } |
||
| 809 | |||
| 810 | // sseg005:0BB5 |
||
| 811 | void __pascal far back_with_sword() { |
||
| 812 | short frame; |
||
| 813 | frame = Char.frame; |
||
| 814 | if (frame == frame_158_stand_with_sword || frame == frame_170_stand_with_sword || frame == frame_171_stand_with_sword) { |
||
| 815 | control_backward = 1; // disable automatic repeat |
||
| 816 | seqtbl_offset_char(seq_57_back_with_sword); // back with sword |
||
| 817 | } |
||
| 818 | } |
||
| 819 | |||
| 820 | // seg005:0BE3 |
||
| 821 | void __pascal far forward_with_sword() { |
||
| 822 | short frame; |
||
| 823 | frame = Char.frame; |
||
| 824 | if (frame == frame_158_stand_with_sword || frame == frame_170_stand_with_sword || frame == frame_171_stand_with_sword) { |
||
| 825 | control_forward = 1; // disable automatic repeat |
||
| 826 | if (Char.charid != charid_0_kid) { |
||
| 827 | seqtbl_offset_char(seq_56_guard_forward_with_sword); // forward with sword (Guard) |
||
| 828 | } else { |
||
| 829 | seqtbl_offset_char(seq_86_forward_with_sword); // forward with sword (Kid) |
||
| 830 | } |
||
| 831 | } |
||
| 832 | } |
||
| 833 | |||
| 834 | // seg005:0C1D |
||
| 835 | void __pascal far draw_sword() { |
||
| 836 | word seq_id; |
||
| 837 | seq_id = seq_55_draw_sword; // draw sword |
||
| 838 | control_forward = control_shift2 = release_arrows(); |
||
| 839 | #ifdef FIX_UNINTENDED_SWORD_STRIKE |
||
| 840 | if (fix_unintended_sword_strike) { |
||
| 841 | ctrl1_shift2 = 1; // prevent restoring control_shift2 to -1 in rest_ctrl_1() |
||
| 842 | } |
||
| 843 | #endif |
||
| 844 | if (Char.charid == charid_0_kid) { |
||
| 845 | play_sound(sound_19_draw_sword); // taking out the sword |
||
| 846 | offguard = 0; |
||
| 847 | } else if (Char.charid != charid_1_shadow) { |
||
| 848 | seq_id = seq_90_en_garde; // stand active |
||
| 849 | } |
||
| 850 | Char.sword = sword_2_drawn; |
||
| 851 | seqtbl_offset_char(seq_id); |
||
| 852 | } |
||
| 853 | |||
| 854 | // seg005:0C67 |
||
| 855 | void __pascal far control_with_sword() { |
||
| 856 | short distance; |
||
| 857 | if (Char.action < actions_2_hang_climb) { |
||
| 858 | if (get_tile_at_char() == tiles_11_loose || can_guard_see_kid >= 2) { |
||
| 859 | distance = char_opp_dist(); |
||
| 860 | if ((word)distance < (word)90) { |
||
| 861 | swordfight(); |
||
| 862 | return; |
||
| 863 | } else if (distance < 0) { |
||
| 864 | if ((word)distance < (word)-4) { |
||
| 865 | seqtbl_offset_char(seq_60_turn_with_sword); // turn with sword (after switching places) |
||
| 866 | return; |
||
| 867 | } else { |
||
| 868 | swordfight(); |
||
| 869 | return; |
||
| 870 | } |
||
| 871 | } |
||
| 872 | } /*else*/ { |
||
| 873 | if (Char.charid == charid_0_kid && Char.alive < 0) { |
||
| 874 | holding_sword = 0; |
||
| 875 | } |
||
| 876 | if (Char.charid < charid_2_guard) { |
||
| 877 | // frame 171: stand with sword |
||
| 878 | if (Char.frame == frame_171_stand_with_sword) { |
||
| 879 | Char.sword = sword_0_sheathed; |
||
| 880 | seqtbl_offset_char(seq_92_put_sword_away); // put sword away (Guard died) |
||
| 881 | } |
||
| 882 | } else { |
||
| 883 | swordfight(); |
||
| 884 | } |
||
| 885 | } |
||
| 886 | } |
||
| 887 | } |
||
| 888 | |||
| 889 | // seg005:0CDB |
||
| 890 | void __pascal far swordfight() { |
||
| 891 | short frame; |
||
| 892 | short seq_id; |
||
| 893 | short charid; |
||
| 894 | frame = Char.frame; |
||
| 895 | charid = Char.charid; |
||
| 896 | // frame 161: parry |
||
| 897 | if (frame == frame_161_parry && control_shift2 >= 0) { |
||
| 898 | seqtbl_offset_char(seq_57_back_with_sword); // back with sword (when parrying) |
||
| 899 | return; |
||
| 900 | } else if (control_shift2 < 0) { |
||
| 901 | if (charid == charid_0_kid) { |
||
| 902 | kid_sword_strike = 15; |
||
| 903 | } |
||
| 904 | sword_strike(); |
||
| 905 | if (control_shift2 == 1) return; |
||
| 906 | } |
||
| 907 | if (control_down < 0) { |
||
| 908 | if (frame == frame_158_stand_with_sword || frame == frame_170_stand_with_sword || frame == frame_171_stand_with_sword) { |
||
| 909 | control_down = 1; // disable automatic repeat |
||
| 910 | Char.sword = sword_0_sheathed; |
||
| 911 | if (charid == charid_0_kid) { |
||
| 912 | offguard = 1; |
||
| 913 | guard_refrac = 9; |
||
| 914 | holding_sword = 0; |
||
| 915 | seq_id = seq_93_put_sword_away_fast; // put sword away fast (down pressed) |
||
| 916 | } else if (charid == charid_1_shadow) { |
||
| 917 | seq_id = seq_92_put_sword_away; // put sword away |
||
| 918 | } else { |
||
| 919 | seq_id = seq_87_guard_become_inactive; // stand inactive (when Kid leaves sight) |
||
| 920 | } |
||
| 921 | seqtbl_offset_char(seq_id); |
||
| 922 | } |
||
| 923 | } else if (control_up < 0) { |
||
| 924 | parry(); |
||
| 925 | } else if (control_forward < 0) { |
||
| 926 | forward_with_sword(); |
||
| 927 | } else if (control_backward < 0) { |
||
| 928 | back_with_sword(); |
||
| 929 | } |
||
| 930 | } |
||
| 931 | |||
| 932 | // seg005:0DB0 |
||
| 933 | void __pascal far sword_strike() { |
||
| 934 | short frame; |
||
| 935 | short seq_id; |
||
| 936 | frame = Char.frame; |
||
| 937 | if (frame == frame_157_walk_with_sword || // walk with sword |
||
| 938 | frame == frame_158_stand_with_sword || // stand with sword |
||
| 939 | frame == frame_170_stand_with_sword || // stand with sword |
||
| 940 | frame == frame_171_stand_with_sword || // stand with sword |
||
| 941 | frame == frame_165_walk_with_sword // walk with sword |
||
| 942 | ) { |
||
| 943 | if (Char.charid == charid_0_kid) { |
||
| 944 | seq_id = seq_75_strike; // strike with sword (Kid) |
||
| 945 | } else { |
||
| 946 | seq_id = seq_58_guard_strike; // strike with sword (Guard) |
||
| 947 | } |
||
| 948 | } else if (frame == frame_150_parry || frame == frame_161_parry) { // parry |
||
| 949 | seq_id = seq_66_strike_after_parry; // strike with sword after parrying |
||
| 950 | } else { |
||
| 951 | return; |
||
| 952 | } |
||
| 953 | control_shift2 = 1; // disable automatic repeat |
||
| 954 | seqtbl_offset_char(seq_id); |
||
| 955 | } |
||
| 956 | |||
| 957 | // seg005:0E0F |
||
| 958 | void __pascal far parry() { |
||
| 959 | short opp_frame; |
||
| 960 | short char_frame; |
||
| 961 | short var_6; |
||
| 962 | short seq_id; |
||
| 963 | short char_charid; |
||
| 964 | char_frame = Char.frame; |
||
| 965 | opp_frame = Opp.frame; |
||
| 966 | char_charid = Char.charid; |
||
| 967 | seq_id = seq_62_parry; // defend (parry) with sword |
||
| 968 | var_6 = 0; |
||
| 969 | if ( |
||
| 970 | char_frame == frame_158_stand_with_sword || // stand with sword |
||
| 971 | char_frame == frame_170_stand_with_sword || // stand with sword |
||
| 972 | char_frame == frame_171_stand_with_sword || // stand with sword |
||
| 973 | char_frame == frame_168_back || // back? |
||
| 974 | char_frame == frame_165_walk_with_sword // walk with sword |
||
| 975 | ) { |
||
| 976 | if (char_opp_dist() >= 32 && char_charid != charid_0_kid) { |
||
| 977 | back_with_sword(); |
||
| 978 | return; |
||
| 979 | } else if (char_charid == charid_0_kid) { |
||
| 980 | if (opp_frame == frame_168_back) return; |
||
| 981 | if (opp_frame != frame_151_strike_1 && |
||
| 982 | opp_frame != frame_152_strike_2 && |
||
| 983 | opp_frame != frame_162_block_to_strike |
||
| 984 | ) { |
||
| 985 | if (opp_frame == frame_153_strike_3) { // strike |
||
| 986 | var_6 = 1; |
||
| 987 | } else |
||
| 988 | if (char_charid != charid_0_kid) { |
||
| 989 | back_with_sword(); |
||
| 990 | return; |
||
| 991 | } |
||
| 992 | } |
||
| 993 | } else { |
||
| 994 | if (opp_frame != frame_152_strike_2) return; |
||
| 995 | } |
||
| 996 | } else { |
||
| 997 | if (char_frame != frame_167_blocked) return; |
||
| 998 | seq_id = seq_61_parry_after_strike; // parry after striking with sword |
||
| 999 | } |
||
| 1000 | control_up = 1; // disable automatic repeat |
||
| 1001 | seqtbl_offset_char(seq_id); |
||
| 1002 | if (var_6) { |
||
| 1003 | play_seq(); |
||
| 1004 | } |
||
| 1005 | } |