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:432F |
||
| 24 | sbyte bump_col_left_of_wall; |
||
| 25 | // data:436E |
||
| 26 | sbyte bump_col_right_of_wall; |
||
| 27 | // data:4C0A |
||
| 28 | sbyte right_checked_col; |
||
| 29 | // data:408A |
||
| 30 | sbyte left_checked_col; |
||
| 31 | |||
| 32 | |||
| 33 | // data:4C0C |
||
| 34 | short coll_tile_left_xpos; |
||
| 35 | // These two arrays are indexed with the return value of wall_type. |
||
| 36 | // data:24BA |
||
| 37 | const sbyte wall_dist_from_left[] = {0, 10, 0, -1, 0, 0}; |
||
| 38 | // data:24C0 |
||
| 39 | const sbyte wall_dist_from_right[] = {0, 0, 10, 13, 0, 0}; |
||
| 40 | |||
| 41 | // seg004:0004 |
||
| 42 | void __pascal far check_collisions() { |
||
| 43 | short column; |
||
| 44 | bump_col_left_of_wall = bump_col_right_of_wall = -1; |
||
| 45 | if (Char.action == actions_7_turn) return; |
||
| 46 | collision_row = Char.curr_row; |
||
| 47 | move_coll_to_prev(); |
||
| 48 | prev_collision_row = collision_row; |
||
| 49 | right_checked_col = MIN(get_tile_div_mod_m7(char_x_right_coll) + 2, 11); |
||
| 50 | left_checked_col = get_tile_div_mod_m7(char_x_left_coll) - 1; |
||
| 51 | get_row_collision_data(collision_row , curr_row_coll_room, curr_row_coll_flags); |
||
| 52 | get_row_collision_data(collision_row + 1, below_row_coll_room, below_row_coll_flags); |
||
| 53 | get_row_collision_data(collision_row - 1, above_row_coll_room, above_row_coll_flags); |
||
| 54 | for (column = 9; column >= 0; --column) { |
||
| 55 | if (curr_row_coll_room[column] >= 0 && |
||
| 56 | prev_coll_room[column] == curr_row_coll_room[column] |
||
| 57 | ) { |
||
| 58 | // char bumps into left of wall |
||
| 59 | if ( |
||
| 60 | (prev_coll_flags[column] & 0x0F) == 0 && |
||
| 61 | (curr_row_coll_flags[column] & 0x0F) != 0 |
||
| 62 | ) { |
||
| 63 | bump_col_left_of_wall = column; |
||
| 64 | } |
||
| 65 | // char bumps into right of wall |
||
| 66 | if ( |
||
| 67 | (prev_coll_flags[column] & 0xF0) == 0 && |
||
| 68 | (curr_row_coll_flags[column] & 0xF0) != 0 |
||
| 69 | ) { |
||
| 70 | bump_col_right_of_wall = column; |
||
| 71 | } |
||
| 72 | } |
||
| 73 | } |
||
| 74 | } |
||
| 75 | |||
| 76 | // seg004:00DF |
||
| 77 | void __pascal far move_coll_to_prev() { |
||
| 78 | sbyte* row_coll_room_ptr; |
||
| 79 | byte* row_coll_flags_ptr; |
||
| 80 | short column; |
||
| 81 | if (collision_row == prev_collision_row || |
||
| 82 | collision_row + 3 == prev_collision_row || |
||
| 83 | collision_row - 3 == prev_collision_row |
||
| 84 | ) { |
||
| 85 | row_coll_room_ptr = curr_row_coll_room; |
||
| 86 | row_coll_flags_ptr = curr_row_coll_flags; |
||
| 87 | } else if ( |
||
| 88 | collision_row + 1 == prev_collision_row || |
||
| 89 | collision_row - 2 == prev_collision_row |
||
| 90 | ) { |
||
| 91 | row_coll_room_ptr = above_row_coll_room; |
||
| 92 | row_coll_flags_ptr = above_row_coll_flags; |
||
| 93 | } else { |
||
| 94 | row_coll_room_ptr = below_row_coll_room; |
||
| 95 | row_coll_flags_ptr = below_row_coll_flags; |
||
| 96 | } |
||
| 97 | for (column = 0; column < 10; ++column) { |
||
| 98 | prev_coll_room[column] = row_coll_room_ptr[column]; |
||
| 99 | prev_coll_flags[column] = row_coll_flags_ptr[column]; |
||
| 100 | below_row_coll_room[column] = -1; |
||
| 101 | above_row_coll_room[column] = -1; |
||
| 102 | curr_row_coll_room[column] = -1; |
||
| 103 | // bugfix: |
||
| 104 | curr_row_coll_flags[column] = 0; |
||
| 105 | below_row_coll_flags[column] = 0; |
||
| 106 | above_row_coll_flags[column] = 0; |
||
| 107 | } |
||
| 108 | } |
||
| 109 | |||
| 110 | // seg004:0185 |
||
| 111 | void __pascal far get_row_collision_data(short row, sbyte *row_coll_room_ptr, byte *row_coll_flags_ptr) { |
||
| 112 | short right_wall_xpos; |
||
| 113 | byte curr_flags; |
||
| 114 | short room; |
||
| 115 | short column; |
||
| 116 | short left_wall_xpos; |
||
| 117 | room = Char.room; |
||
| 118 | coll_tile_left_xpos = x_bump[left_checked_col + 5] + 7; |
||
| 119 | for (column = left_checked_col; column <= right_checked_col; ++column) { |
||
| 120 | left_wall_xpos = get_left_wall_xpos(room, column, row); |
||
| 121 | right_wall_xpos = get_right_wall_xpos(room, column, row); |
||
| 122 | // char bumps into left of wall |
||
| 123 | curr_flags = (left_wall_xpos < char_x_right_coll) * 0x0F; |
||
| 124 | // char bumps into right of wall |
||
| 125 | curr_flags |= (right_wall_xpos > char_x_left_coll) * 0xF0; |
||
| 126 | row_coll_flags_ptr[tile_col] = curr_flags; |
||
| 127 | row_coll_room_ptr[tile_col] = curr_room; |
||
| 128 | coll_tile_left_xpos += 14; |
||
| 129 | } |
||
| 130 | } |
||
| 131 | |||
| 132 | // seg004:0226 |
||
| 133 | int __pascal far get_left_wall_xpos(int room,int column,int row) { |
||
| 134 | short type; |
||
| 135 | type = wall_type(get_tile(room, column, row)); |
||
| 136 | if (type) { |
||
| 137 | return wall_dist_from_left[type] + coll_tile_left_xpos; |
||
| 138 | } else { |
||
| 139 | return 0xFF; |
||
| 140 | } |
||
| 141 | } |
||
| 142 | |||
| 143 | // seg004:025F |
||
| 144 | int __pascal far get_right_wall_xpos(int room,int column,int row) { |
||
| 145 | short type; |
||
| 146 | type = wall_type(get_tile(room, column, row)); |
||
| 147 | if (type) { |
||
| 148 | return coll_tile_left_xpos - wall_dist_from_right[type] + 13; |
||
| 149 | } else { |
||
| 150 | return 0; |
||
| 151 | } |
||
| 152 | } |
||
| 153 | |||
| 154 | // seg004:029D |
||
| 155 | void __pascal far check_bumped() { |
||
| 156 | if ( |
||
| 157 | Char.action != actions_2_hang_climb && |
||
| 158 | Char.action != actions_6_hang_straight && |
||
| 159 | // frames 135..149: climb up |
||
| 160 | (Char.frame < frame_135_climbing_1 || Char.frame >= 149) |
||
| 161 | ) { |
||
| 162 | #ifdef FIX_TWO_COLL_BUG |
||
| 163 | if (bump_col_left_of_wall >= 0) { |
||
| 164 | check_bumped_look_right(); |
||
| 165 | if (!fix_two_coll_bug) return; // check for the left-oriented collision only with the fix enabled |
||
| 166 | } |
||
| 167 | if (bump_col_right_of_wall >= 0) { |
||
| 168 | check_bumped_look_left(); |
||
| 169 | } |
||
| 170 | #else |
||
| 171 | if (bump_col_left_of_wall >= 0) { |
||
| 172 | check_bumped_look_right(); |
||
| 173 | } |
||
| 174 | else |
||
| 175 | if (bump_col_right_of_wall >= 0) { |
||
| 176 | check_bumped_look_left(); |
||
| 177 | } |
||
| 178 | #endif // FIX_TWO_COLL_BUG |
||
| 179 | |||
| 180 | } |
||
| 181 | } |
||
| 182 | |||
| 183 | // seg004:02D2 |
||
| 184 | void __pascal far check_bumped_look_left() { |
||
| 185 | if ((Char.sword == sword_2_drawn || Char.direction < dir_0_right) && // looking left |
||
| 186 | is_obstacle_at_col(bump_col_right_of_wall) |
||
| 187 | ) { |
||
| 188 | bumped(get_right_wall_xpos(curr_room, tile_col, tile_row) - char_x_left_coll, dir_0_right); |
||
| 189 | } |
||
| 190 | } |
||
| 191 | |||
| 192 | // seg004:030A |
||
| 193 | void __pascal far check_bumped_look_right() { |
||
| 194 | if ((Char.sword == sword_2_drawn || Char.direction == dir_0_right) && // looking right |
||
| 195 | is_obstacle_at_col(bump_col_left_of_wall) |
||
| 196 | ) { |
||
| 197 | bumped(get_left_wall_xpos(curr_room, tile_col, tile_row) - char_x_right_coll, dir_FF_left); |
||
| 198 | } |
||
| 199 | } |
||
| 200 | |||
| 201 | // seg004:0343 |
||
| 202 | int __pascal far is_obstacle_at_col(int tile_col) { |
||
| 203 | short tile_row; |
||
| 204 | tile_row = Char.curr_row; |
||
| 205 | if (tile_row < 0) { |
||
| 206 | tile_row += 3; |
||
| 207 | } |
||
| 208 | if (tile_row >= 3) { |
||
| 209 | tile_row -= 3; |
||
| 210 | } |
||
| 211 | get_tile(curr_row_coll_room[tile_col], tile_col, tile_row); |
||
| 212 | return is_obstacle(); |
||
| 213 | } |
||
| 214 | |||
| 215 | // seg004:037E |
||
| 216 | int __pascal far is_obstacle() { |
||
| 217 | if (curr_tile2 == tiles_10_potion) { |
||
| 218 | return 0; |
||
| 219 | } else if (curr_tile2 == tiles_4_gate) { |
||
| 220 | if (! can_bump_into_gate()) return 0; |
||
| 221 | } else if (curr_tile2 == tiles_18_chomper) { |
||
| 222 | // is the chomper closed? |
||
| 223 | if (curr_room_modif[curr_tilepos] != 2) return 0; |
||
| 224 | } else if ( |
||
| 225 | curr_tile2 == tiles_13_mirror && |
||
| 226 | Char.charid == charid_0_kid && |
||
| 227 | Char.frame >= frame_39_start_run_jump_6 && Char.frame < frame_44_running_jump_5 && // run-jump |
||
| 228 | Char.direction < dir_0_right // right-to-left only |
||
| 229 | ) { |
||
| 230 | curr_room_modif[curr_tilepos] = 0x56; // broken mirror or what? |
||
| 231 | jumped_through_mirror = -1; |
||
| 232 | return 0; |
||
| 233 | } |
||
| 234 | coll_tile_left_xpos = xpos_in_drawn_room(x_bump[tile_col + 5]) + 7; |
||
| 235 | return 1; |
||
| 236 | } |
||
| 237 | |||
| 238 | // seg004:0405 |
||
| 239 | int __pascal far xpos_in_drawn_room(int xpos) { |
||
| 240 | if (curr_room != drawn_room) { |
||
| 241 | if (curr_room == room_L || curr_room == room_BL) { |
||
| 242 | xpos -= 140; |
||
| 243 | } else if (curr_room == room_R || curr_room == room_BR) { |
||
| 244 | xpos += 140; |
||
| 245 | } |
||
| 246 | } |
||
| 247 | return xpos; |
||
| 248 | } |
||
| 249 | |||
| 250 | // seg004:0448 |
||
| 251 | void __pascal far bumped(sbyte delta_x,sbyte push_direction) { |
||
| 252 | // frame 177: spiked |
||
| 253 | if (Char.alive < 0 && Char.frame != frame_177_spiked) { |
||
| 254 | Char.x += delta_x; |
||
| 255 | if (push_direction < dir_0_right) { |
||
| 256 | // pushing left |
||
| 257 | if (curr_tile2 == tiles_20_wall) { |
||
| 258 | get_tile(curr_room, --tile_col, tile_row); |
||
| 259 | } |
||
| 260 | } else { |
||
| 261 | // pushing right |
||
| 262 | if (curr_tile2 == tiles_12_doortop || |
||
| 263 | curr_tile2 == tiles_7_doortop_with_floor || |
||
| 264 | curr_tile2 == tiles_20_wall |
||
| 265 | ) { |
||
| 266 | ++tile_col; |
||
| 267 | if (curr_room == 0 && tile_col == 10) { |
||
| 268 | curr_room = Char.room; |
||
| 269 | tile_col = 0; |
||
| 270 | } |
||
| 271 | get_tile(curr_room, tile_col, tile_row); |
||
| 272 | } |
||
| 273 | } |
||
| 274 | if (tile_is_floor(curr_tile2)) { |
||
| 275 | bumped_floor(push_direction); |
||
| 276 | } else { |
||
| 277 | bumped_fall(); |
||
| 278 | } |
||
| 279 | } |
||
| 280 | } |
||
| 281 | |||
| 282 | // seg004:04E4 |
||
| 283 | void __pascal far bumped_fall() { |
||
| 284 | short action; |
||
| 285 | action = Char.action; |
||
| 286 | Char.x = char_dx_forward(-4); |
||
| 287 | if (action == actions_4_in_freefall) { |
||
| 288 | Char.fall_x = 0; |
||
| 289 | } else { |
||
| 290 | seqtbl_offset_char(seq_45_bumpfall); // fall after bumped |
||
| 291 | play_seq(); |
||
| 292 | } |
||
| 293 | bumped_sound(); |
||
| 294 | } |
||
| 295 | |||
| 296 | // seg004:0520 |
||
| 297 | void __pascal far bumped_floor(sbyte push_direction) { |
||
| 298 | short frame; |
||
| 299 | short seq_index; |
||
| 300 | if (Char.sword != sword_2_drawn && (word)(y_land[Char.curr_row + 1] - Char.y) >= (word)15) { |
||
| 301 | bumped_fall(); |
||
| 302 | } else { |
||
| 303 | Char.y = y_land[Char.curr_row + 1]; |
||
| 304 | if (Char.fall_y >= 22) { |
||
| 305 | Char.x = char_dx_forward(-5); |
||
| 306 | } else { |
||
| 307 | Char.fall_y = 0; |
||
| 308 | if (Char.alive) { |
||
| 309 | if (Char.sword == sword_2_drawn) { |
||
| 310 | if (push_direction == Char.direction) { |
||
| 311 | seqtbl_offset_char(seq_65_bump_forward_with_sword); // pushed forward with sword (Kid) |
||
| 312 | play_seq(); |
||
| 313 | Char.x = char_dx_forward(1); |
||
| 314 | return; |
||
| 315 | } else { |
||
| 316 | seq_index = seq_64_pushed_back_with_sword; // pushed back with sword |
||
| 317 | } |
||
| 318 | } else { |
||
| 319 | frame = Char.frame; |
||
| 320 | if (frame == 24 || frame == 25 || |
||
| 321 | (frame >= 40 && frame < 43) || |
||
| 322 | (frame >= frame_102_start_fall_1 && frame < 107) |
||
| 323 | ) { |
||
| 324 | seq_index = seq_46_hardbump; // bump into wall after run-jump (crouch) |
||
| 325 | } else { |
||
| 326 | seq_index = seq_47_bump; // bump into wall |
||
| 327 | } |
||
| 328 | } |
||
| 329 | seqtbl_offset_char(seq_index); |
||
| 330 | play_seq(); |
||
| 331 | bumped_sound(); |
||
| 332 | } |
||
| 333 | } |
||
| 334 | } |
||
| 335 | } |
||
| 336 | |||
| 337 | // seg004:05F1 |
||
| 338 | void __pascal far bumped_sound() { |
||
| 339 | is_guard_notice = 1; |
||
| 340 | play_sound(sound_8_bumped); // touching a wall |
||
| 341 | } |
||
| 342 | |||
| 343 | // seg004:0601 |
||
| 344 | void __pascal far clear_coll_rooms() { |
||
| 345 | memset_near(prev_coll_room, -1, sizeof(prev_coll_room)); |
||
| 346 | memset_near(curr_row_coll_room, -1, sizeof(curr_row_coll_room)); |
||
| 347 | memset_near(below_row_coll_room, -1, sizeof(below_row_coll_room)); |
||
| 348 | memset_near(above_row_coll_room, -1, sizeof(above_row_coll_room)); |
||
| 349 | // workaround |
||
| 350 | memset_near(prev_coll_flags, 0, sizeof(prev_coll_flags)); |
||
| 351 | memset_near(curr_row_coll_flags, 0, sizeof(curr_row_coll_flags)); |
||
| 352 | memset_near(below_row_coll_flags, 0, sizeof(below_row_coll_flags)); |
||
| 353 | memset_near(above_row_coll_flags, 0, sizeof(above_row_coll_flags)); |
||
| 354 | prev_collision_row = -1; |
||
| 355 | } |
||
| 356 | |||
| 357 | // seg004:0657 |
||
| 358 | int __pascal far can_bump_into_gate() { |
||
| 359 | return (curr_room_modif[curr_tilepos] >> 2) + 6 < char_height; |
||
| 360 | } |
||
| 361 | |||
| 362 | // seg004:067C |
||
| 363 | int __pascal far get_edge_distance() { |
||
| 364 | /* |
||
| 365 | Possible results in edge_type: |
||
| 366 | 0: closer/sword/potion |
||
| 367 | 1: edge |
||
| 368 | 2: floor (nothing near char) |
||
| 369 | */ |
||
| 370 | short distance; |
||
| 371 | byte tiletype; |
||
| 372 | determine_col(); |
||
| 373 | load_frame_to_obj(); |
||
| 374 | set_char_collision(); |
||
| 375 | tiletype = get_tile_at_char(); |
||
| 376 | if (wall_type(tiletype) != 0) { |
||
| 377 | tile_col = Char.curr_col; |
||
| 378 | distance = dist_from_wall_forward(tiletype); |
||
| 379 | if (distance >= 0) { |
||
| 380 | loc_59DD: |
||
| 381 | if (distance < 14) { |
||
| 382 | edge_type = 1; |
||
| 383 | } else { |
||
| 384 | edge_type = 2; |
||
| 385 | distance = 11; |
||
| 386 | } |
||
| 387 | } else { |
||
| 388 | goto loc_59E8; |
||
| 389 | } |
||
| 390 | } else { |
||
| 391 | loc_59E8: |
||
| 392 | tiletype = get_tile_infrontof_char(); |
||
| 393 | if (tiletype == tiles_12_doortop && Char.direction >= dir_0_right) { |
||
| 394 | loc_59FB: |
||
| 395 | edge_type = 0; |
||
| 396 | distance = distance_to_edge_weight(); |
||
| 397 | } else { |
||
| 398 | if (wall_type(tiletype) != 0) { |
||
| 399 | tile_col = infrontx; |
||
| 400 | distance = dist_from_wall_forward(tiletype); |
||
| 401 | if (distance >= 0) goto loc_59DD; |
||
| 402 | } |
||
| 403 | if (tiletype == tiles_11_loose) goto loc_59FB; |
||
| 404 | if ( |
||
| 405 | tiletype == tiles_6_closer || |
||
| 406 | tiletype == tiles_22_sword || |
||
| 407 | tiletype == tiles_10_potion |
||
| 408 | ) { |
||
| 409 | distance = distance_to_edge_weight(); |
||
| 410 | if (distance != 0) { |
||
| 411 | edge_type = 0; |
||
| 412 | } else { |
||
| 413 | edge_type = 2; |
||
| 414 | distance = 11; |
||
| 415 | } |
||
| 416 | } else { |
||
| 417 | if (tile_is_floor(tiletype)) { |
||
| 418 | edge_type = 2; |
||
| 419 | distance = 11; |
||
| 420 | } else { |
||
| 421 | goto loc_59FB; |
||
| 422 | } |
||
| 423 | } |
||
| 424 | } |
||
| 425 | } |
||
| 426 | curr_tile2 = tiletype; |
||
| 427 | return distance; |
||
| 428 | } |
||
| 429 | |||
| 430 | // seg004:076B |
||
| 431 | void __pascal far check_chomped_kid() { |
||
| 432 | short tile_col; |
||
| 433 | short tile_row; |
||
| 434 | tile_row = Char.curr_row; |
||
| 435 | for (tile_col = 0; tile_col < 10; ++tile_col) { |
||
| 436 | if (curr_row_coll_flags[tile_col] == 0xFF && |
||
| 437 | get_tile(curr_row_coll_room[tile_col], tile_col, tile_row) == tiles_18_chomper && |
||
| 438 | (curr_room_modif[curr_tilepos] & 0x7F) == 2 // closed chomper |
||
| 439 | ) { |
||
| 440 | chomped(); |
||
| 441 | } |
||
| 442 | } |
||
| 443 | } |
||
| 444 | |||
| 445 | // seg004:07BF |
||
| 446 | void __pascal far chomped() { |
||
| 447 | #ifdef FIX_SKELETON_CHOMPER_BLOOD |
||
| 448 | if (!(fix_skeleton_chomper_blood && Char.charid == charid_4_skeleton)) |
||
| 449 | #endif |
||
| 450 | curr_room_modif[curr_tilepos] |= 0x80; // put blood |
||
| 451 | if (Char.frame != frame_178_chomped && Char.room == curr_room) { |
||
| 452 | Char.x = x_bump[tile_col + 5] + 7; |
||
| 453 | Char.x = char_dx_forward(7 - !Char.direction); |
||
| 454 | Char.y = y_land[Char.curr_row + 1]; |
||
| 455 | take_hp(100); |
||
| 456 | play_sound(sound_46_chomped); // something chomped |
||
| 457 | seqtbl_offset_char(seq_54_chomped); // chomped |
||
| 458 | play_seq(); |
||
| 459 | } |
||
| 460 | } |
||
| 461 | |||
| 462 | // seg004:0833 |
||
| 463 | void __pascal far check_gate_push() { |
||
| 464 | // Closing gate pushes Kid |
||
| 465 | short frame; |
||
| 466 | short var_4; |
||
| 467 | frame = Char.frame; |
||
| 468 | if (Char.action == actions_7_turn || |
||
| 469 | frame == frame_15_stand || // stand |
||
| 470 | (frame >= frame_108_fall_land_2 && frame < 111) // crouch |
||
| 471 | ) { |
||
| 472 | get_tile_at_char(); |
||
| 473 | var_4 = tile_col; |
||
| 474 | if ((curr_tile2 == tiles_4_gate || |
||
| 475 | get_tile(curr_room, --tile_col, tile_row) == tiles_4_gate) && |
||
| 476 | (curr_row_coll_flags[tile_col] & prev_coll_flags[tile_col]) == 0xFF && |
||
| 477 | can_bump_into_gate() |
||
| 478 | ) { |
||
| 479 | bumped_sound(); |
||
| 480 | // push Kid left if var_4 <= tile_col, gate at char's tile |
||
| 481 | // push Kid right if var_4 > tile_col, gate is left from char's tile |
||
| 482 | Char.x += 5 - (var_4 <= tile_col) * 10; |
||
| 483 | } |
||
| 484 | } |
||
| 485 | } |
||
| 486 | |||
| 487 | // seg004:08C3 |
||
| 488 | void __pascal far check_guard_bumped() { |
||
| 489 | if ( |
||
| 490 | Char.action == actions_1_run_jump && |
||
| 491 | Char.alive < 0 && |
||
| 492 | Char.sword >= sword_2_drawn |
||
| 493 | ) { |
||
| 494 | if ( |
||
| 495 | |||
| 496 | #ifdef FIX_PUSH_GUARD_INTO_WALL |
||
| 497 | // Should also check for a wall BEHIND the guard, instead of only the current tile |
||
| 498 | (fix_push_guard_into_wall && get_tile_behind_char() == tiles_20_wall) || |
||
| 499 | #endif |
||
| 500 | |||
| 501 | get_tile_at_char() == tiles_20_wall || |
||
| 502 | curr_tile2 == tiles_7_doortop_with_floor || |
||
| 503 | (curr_tile2 == tiles_4_gate && can_bump_into_gate()) || |
||
| 504 | (Char.direction >= dir_0_right && ( |
||
| 505 | get_tile(curr_room, --tile_col, tile_row) == tiles_7_doortop_with_floor || |
||
| 506 | (curr_tile2 == tiles_4_gate && can_bump_into_gate()) |
||
| 507 | )) |
||
| 508 | ) { |
||
| 509 | load_frame_to_obj(); |
||
| 510 | set_char_collision(); |
||
| 511 | if (is_obstacle()) { |
||
| 512 | short delta_x; |
||
| 513 | delta_x = dist_from_wall_behind(curr_tile2); |
||
| 514 | if (delta_x < 0 && delta_x > -13) { |
||
| 515 | Char.x = char_dx_forward(-delta_x); |
||
| 516 | seqtbl_offset_char(seq_65_bump_forward_with_sword); // pushed to wall with sword (Guard) |
||
| 517 | play_seq(); |
||
| 518 | load_fram_det_col(); |
||
| 519 | } |
||
| 520 | } |
||
| 521 | } |
||
| 522 | } |
||
| 523 | } |
||
| 524 | |||
| 525 | // seg004:0989 |
||
| 526 | void __pascal far check_chomped_guard() { |
||
| 527 | get_tile_at_char(); |
||
| 528 | if ( ! check_chomped_here()) { |
||
| 529 | get_tile(curr_room, ++tile_col, tile_row); |
||
| 530 | check_chomped_here(); |
||
| 531 | } |
||
| 532 | } |
||
| 533 | |||
| 534 | // seg004:09B0 |
||
| 535 | int __pascal far check_chomped_here() { |
||
| 536 | if (curr_tile2 == tiles_18_chomper && |
||
| 537 | (curr_room_modif[curr_tilepos] & 0x7F) == 2 |
||
| 538 | ) { |
||
| 539 | coll_tile_left_xpos = x_bump[tile_col + 5] + 7; |
||
| 540 | if (get_left_wall_xpos(curr_room, tile_col, tile_row) < char_x_right_coll && |
||
| 541 | get_right_wall_xpos(curr_room, tile_col, tile_row) > char_x_left_coll |
||
| 542 | ) { |
||
| 543 | chomped(); |
||
| 544 | return 1; |
||
| 545 | } else { |
||
| 546 | return 0; |
||
| 547 | } |
||
| 548 | } else { |
||
| 549 | return 0; |
||
| 550 | } |
||
| 551 | } |
||
| 552 | |||
| 553 | // seg004:0A10 |
||
| 554 | int __pascal far dist_from_wall_forward(byte tiletype) { |
||
| 555 | short type; |
||
| 556 | if (tiletype == tiles_4_gate && ! can_bump_into_gate()) { |
||
| 557 | return -1; |
||
| 558 | } else { |
||
| 559 | coll_tile_left_xpos = x_bump[tile_col + 5] + 7; |
||
| 560 | type = wall_type(tiletype); |
||
| 561 | if (type == 0) return -1; |
||
| 562 | if (Char.direction < dir_0_right) { |
||
| 563 | // looking left |
||
| 564 | //return wall_dist_from_right[type] + char_x_left_coll - coll_tile_left_xpos - 13; |
||
| 565 | return char_x_left_coll - (coll_tile_left_xpos + 13 - wall_dist_from_right[type]); |
||
| 566 | } else { |
||
| 567 | // looking right |
||
| 568 | return wall_dist_from_left[type] + coll_tile_left_xpos - char_x_right_coll; |
||
| 569 | } |
||
| 570 | } |
||
| 571 | } |
||
| 572 | |||
| 573 | // seg004:0A7B |
||
| 574 | int __pascal far dist_from_wall_behind(byte tiletype) { |
||
| 575 | short type; |
||
| 576 | type = wall_type(tiletype); |
||
| 577 | if (type == 0) { |
||
| 578 | return 99; |
||
| 579 | } else { |
||
| 580 | if (Char.direction >= dir_0_right) { |
||
| 581 | // looking right |
||
| 582 | //return wall_dist_from_right[type] + char_x_left_coll - coll_tile_left_xpos - 13; |
||
| 583 | return char_x_left_coll - (coll_tile_left_xpos + 13 - wall_dist_from_right[type]); |
||
| 584 | } else { |
||
| 585 | // looking left |
||
| 586 | return wall_dist_from_left[type] + coll_tile_left_xpos - char_x_right_coll; |
||
| 587 | } |
||
| 588 | } |
||
| 589 | } |