From 83ac9514cbc8b5f866d2dd02a4ffc05e2525fbcb Mon Sep 17 00:00:00 2001 From: lahm86 <33758420+lahm86@users.noreply.github.com> Date: Sat, 26 Apr 2025 10:20:06 +0100 Subject: [PATCH] tr2/objects/door: prevent Lara voiding in closed doors This uses the same approach as TR1 to avoid Lara voiding in closing/ closed doors that are not placed on portals. Resovles #2848. --- docs/tr2/CHANGELOG.md | 1 + docs/tr2/README.md | 1 + src/tr2/game/objects/general/door.c | 59 ++++++++++++++++++++++------- 3 files changed, 47 insertions(+), 14 deletions(-) diff --git a/docs/tr2/CHANGELOG.md b/docs/tr2/CHANGELOG.md index b3b0c1eb2..fa31d551c 100644 --- a/docs/tr2/CHANGELOG.md +++ b/docs/tr2/CHANGELOG.md @@ -1,5 +1,6 @@ ## [Unreleased](https://github.com/LostArtefacts/TRX/compare/tr2-1.0.1...develop) - ××××-××-×× - changed the sound dialog appearance (repositioned, added text labels and arrows) +- fixed Lara voiding if she stops on a tile with a closing door, and the door isn't on a portal (#2848) - fixed guns carried by enemies not being converted to ammo if Lara has picked up the same gun elsewhere in the same level (#2856) - fixed guns carried by enemies not being converted to ammo if Lara starts the level with the gun and the game has later been reloaded (#2850, regression from 1.0) - fixed 1920x1080 screenshots in 16:9 aspect mode being saved as 1919x1080 (#2845, regression from 0.8) diff --git a/docs/tr2/README.md b/docs/tr2/README.md index d0fe8a2f2..54d53df6a 100644 --- a/docs/tr2/README.md +++ b/docs/tr2/README.md @@ -256,6 +256,7 @@ However, you can easily download them manually from these urls: - fixed being able to use hotkeys in the end-level statistics screen - fixed guns carried by enemies not being converted to ammo if Lara has picked up the same gun elsewhere in the same level - fixed destroyed gondolas appearing embedded in the ground after loading a save +- fixed Lara voiding if she stops on a tile with a closing door, and the door isn't on a portal - improved the animation of Lara's braid #### Cheats diff --git a/src/tr2/game/objects/general/door.c b/src/tr2/game/objects/general/door.c index 819c8fb5f..e97ec0cd5 100644 --- a/src/tr2/game/objects/general/door.c +++ b/src/tr2/game/objects/general/door.c @@ -21,6 +21,8 @@ static SECTOR *M_GetRoomRelSector( static void M_InitialisePortal( const ROOM *room, const ITEM *item, int32_t sector_dx, int32_t sector_dz, DOORPOS_DATA *door_pos); +static bool M_LaraDoorCollision(const SECTOR *sector); +static void M_Check(DOORPOS_DATA *d); static void M_Shut(DOORPOS_DATA *d); static void M_Open(DOORPOS_DATA *d); static void M_Setup(OBJECT *obj); @@ -38,7 +40,32 @@ static SECTOR *M_GetRoomRelSector( return Room_GetUnitSector(room, sector.x, sector.z); } -static void Door_Shut(DOORPOS_DATA *const d) +static bool M_LaraDoorCollision(const SECTOR *const sector) +{ + // Check if Lara is on the same tile as the invisible block. + const ITEM *const lara = Lara_GetItem(); + if (lara == nullptr) { + return false; + } + + int16_t room_num = lara->room_num; + const SECTOR *const lara_sector = + Room_GetSector(lara->pos.x, lara->pos.y, lara->pos.z, &room_num); + return lara_sector == sector; +} + +static void M_Check(DOORPOS_DATA *const d) +{ + // Forcefully remove the invisible block if Lara happens to occupy the same + // tile. This ensures that Lara doesn't void if a timed door happens to + // close right on her, or the player loads the game while standing on a + // closed door's block tile. + if (M_LaraDoorCollision(d->sector)) { + M_Open(d); + } +} + +static void M_Shut(DOORPOS_DATA *const d) { SECTOR *const sector = d->sector; if (d->sector == nullptr) { @@ -61,7 +88,7 @@ static void Door_Shut(DOORPOS_DATA *const d) } } -static void Door_Open(DOORPOS_DATA *const d) +static void M_Open(DOORPOS_DATA *const d) { if (d->sector == nullptr) { return; @@ -137,8 +164,8 @@ static void M_Initialise(const int16_t item_num) } room_num = door->d1.sector->portal_room.wall; - Door_Shut(&door->d1); - Door_Shut(&door->d1flip); + M_Shut(&door->d1); + M_Shut(&door->d1flip); if (room_num == NO_ROOM) { door->d2.sector = nullptr; @@ -153,8 +180,8 @@ static void M_Initialise(const int16_t item_num) M_InitialisePortal(room, item, 0, 0, &door->d2flip); } - Door_Shut(&door->d2); - Door_Shut(&door->d2flip); + M_Shut(&door->d2); + M_Shut(&door->d2flip); const int16_t prev_room = item->room_num; Item_NewRoom(item_num, room_num); @@ -171,22 +198,26 @@ static void M_Control(const int16_t item_num) if (item->current_anim_state == DOOR_STATE_CLOSED) { item->goal_anim_state = DOOR_STATE_OPEN; } else { - Door_Open(&data->d1); - Door_Open(&data->d2); - Door_Open(&data->d1flip); - Door_Open(&data->d2flip); + M_Open(&data->d1); + M_Open(&data->d2); + M_Open(&data->d1flip); + M_Open(&data->d2flip); } } else { if (item->current_anim_state == DOOR_STATE_OPEN) { item->goal_anim_state = DOOR_STATE_CLOSED; } else { - Door_Shut(&data->d1); - Door_Shut(&data->d2); - Door_Shut(&data->d1flip); - Door_Shut(&data->d2flip); + M_Shut(&data->d1); + M_Shut(&data->d2); + M_Shut(&data->d1flip); + M_Shut(&data->d2flip); } } + M_Check(&data->d1); + M_Check(&data->d2); + M_Check(&data->d1flip); + M_Check(&data->d2flip); Item_Animate(item); }