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.
This commit is contained in:
lahm86 2025-04-26 10:20:06 +01:00
parent 96b86b1605
commit 83ac9514cb
3 changed files with 47 additions and 14 deletions

View file

@ -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)

View file

@ -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

View file

@ -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);
}