tr2/data: fix various softlocks

This fixes softlocks in Temple of Xian, Floating Islands and Vegas.

Resolves #2042.
Resolves #2590.
Resolves #1851.
This commit is contained in:
lahm86 2025-04-13 20:39:15 +01:00
parent 234c339bd2
commit 71b1ce78d2
7 changed files with 47 additions and 5 deletions

View file

@ -141,6 +141,7 @@
"injections": [ "injections": [
"data/injections/common_pickup_meshes.bin", "data/injections/common_pickup_meshes.bin",
"data/injections/guardian_death_commands.bin", "data/injections/guardian_death_commands.bin",
"data/injections/vegas_fd.bin",
], ],
}, },
], ],

Binary file not shown.

View file

@ -10,6 +10,7 @@
- added the ability for custom levels to have up to two of each secret type per level (#2674) - added the ability for custom levels to have up to two of each secret type per level (#2674)
- added BSON savegame support, removing the limits imposed by the OG 8KB file size, so allowing for storing more data and offering improved feature support (legacy save files can still be read, similar to TR1) (#2662) - added BSON savegame support, removing the limits imposed by the OG 8KB file size, so allowing for storing more data and offering improved feature support (legacy save files can still be read, similar to TR1) (#2662)
- added NG+, Japanese, and Japanese NG+ game mode options to the New Game page in the passport (#2731) - added NG+, Japanese, and Japanese NG+ game mode options to the New Game page in the passport (#2731)
- added the ability for spike walls to be reset (antitriggered)
- changed savegame files to be stored in the `saves` directory (#2087) - changed savegame files to be stored in the `saves` directory (#2087)
- changed the default fog distance to 22 tiles cutting off at 30 tiles to match TR1X (#1622) - changed the default fog distance to 22 tiles cutting off at 30 tiles to match TR1X (#1622)
- changed the number of static mesh slots from 50 to 256 (#2734) - changed the number of static mesh slots from 50 to 256 (#2734)
@ -25,6 +26,9 @@
- fixed the scale of several pickup models in The Golden Mask (#2652) - fixed the scale of several pickup models in The Golden Mask (#2652)
- fixed the shark in The Cold War not making any sounds when biting Lara (#2678) - fixed the shark in The Cold War not making any sounds when biting Lara (#2678)
- fixed the in-game cinematic camera at times yielding invalid positions (and hence views) in custom levels (#2754) - fixed the in-game cinematic camera at times yielding invalid positions (and hence views) in custom levels (#2754)
- fixed a softlock in Temple of Xian if the main chamber key is missed (#2042)
- fixed a potential softlock in Floating Islands if returning towards the level start from the gold secret (#2590)
- fixed a potential softlock in Nightmare in Vegas where the bird monster could remain inactive, or the flip map not set (#1851)
- fixed sprites rendering black if no shade value is assigned in the level (#2701, regression from 0.8) - fixed sprites rendering black if no shade value is assigned in the level (#2701, regression from 0.8)
- fixed a crash if an image was missing - fixed a crash if an image was missing
- fixed a crash on level load if an animation has no frames (#2746, regression from 0.8) - fixed a crash on level load if an animation has no frames (#2746, regression from 0.8)

View file

@ -214,8 +214,9 @@ as Notepad.
- **Tibetan Foothills**: added missing triggers for the drawbridge in room 96 (after the flipmap) - **Tibetan Foothills**: added missing triggers for the drawbridge in room 96 (after the flipmap)
- **Catacombs of the Talion**: changed some music triggers to pads near the first yeti, and added missing triggers and ladder in room 116 (after the flipmap) - **Catacombs of the Talion**: changed some music triggers to pads near the first yeti, and added missing triggers and ladder in room 116 (after the flipmap)
- **Ice Palace**: fixed door 143's position to resolve the invisible wall in front of it, and added an extra pickup trigger beside the Gong Hammer in room 29 - **Ice Palace**: fixed door 143's position to resolve the invisible wall in front of it, and added an extra pickup trigger beside the Gong Hammer in room 29
- **Temple of Xian**: fixed missing death tiles in room 91 - **Temple of Xian**: fixed missing death tiles in room 91; adding trigger workarounds to avoid a softlock after (missing) the final key
- **Floating Islands**: fixed door 72's position to resolve the invisible wall in front of it - **Floating Islands**: fixed door 72's position to resolve the invisible wall in front of it; added extra zipline reset triggers to avoid softlock
- **Nightmare in Vegas**: added additional triggers for the bird monster and final flip map to avoid softlock
- fixed the game crashing if a cinematic is triggered but the level contains no cinematic frames - fixed the game crashing if a cinematic is triggered but the level contains no cinematic frames
- fixed smashed windows blocking enemy pathing after loading a save - fixed smashed windows blocking enemy pathing after loading a save
- fixed Lara getting stuck in a T-pose after jumping/falling and then dying before reaching fast fall speed - fixed Lara getting stuck in a T-pose after jumping/falling and then dying before reaching fast fall speed
@ -310,6 +311,7 @@ as Notepad.
- added developer console (accessible with `/`, see [COMMANDS.md](COMMANDS.md) for details) - added developer console (accessible with `/`, see [COMMANDS.md](COMMANDS.md) for details)
- added ability to disable FMVs - added ability to disable FMVs
- added per-level customizable fog distance - added per-level customizable fog distance
- added the ability for spike walls to be reset (antitriggered)
- removed the hard-coded end-level behaviour of the bird guardian for custom levels - removed the hard-coded end-level behaviour of the bird guardian for custom levels
#### Miscellaneous #### Miscellaneous

View file

@ -6,16 +6,30 @@
#include "game/spawn.h" #include "game/spawn.h"
#include "global/vars.h" #include "global/vars.h"
#include <libtrx/game/game_buf.h>
#include <libtrx/game/math.h> #include <libtrx/game/math.h>
#define SPIKE_WALL_DAMAGE 20 #define SPIKE_WALL_DAMAGE 20
#define SPIKE_WALL_SPEED 1 #define SPIKE_WALL_SPEED 1
static void M_Initialise(int16_t item_num);
static void M_Move(int16_t item_num); static void M_Move(int16_t item_num);
static void M_Reset(int16_t item_num);
static void M_HitLara(ITEM *item); static void M_HitLara(ITEM *item);
static void M_Setup(OBJECT *obj); static void M_Setup(OBJECT *obj);
static void M_Control(int16_t item_num); static void M_Control(int16_t item_num);
static void M_Initialise(const int16_t item_num)
{
ITEM *const item = Item_Get(item_num);
GAME_VECTOR *const data =
GameBuf_Alloc(sizeof(GAME_VECTOR), GBUF_ITEM_DATA);
data->pos = item->pos;
data->room_num = item->room_num;
item->data = data;
}
static void M_Move(const int16_t item_num) static void M_Move(const int16_t item_num)
{ {
ITEM *const item = Item_Get(item_num); ITEM *const item = Item_Get(item_num);
@ -25,9 +39,9 @@ static void M_Move(const int16_t item_num)
item->pos.x + (SPIKE_WALL_SPEED * Math_Sin(item->rot.y) >> WALL_SHIFT); item->pos.x + (SPIKE_WALL_SPEED * Math_Sin(item->rot.y) >> WALL_SHIFT);
int16_t room_num = item->room_num; int16_t room_num = item->room_num;
const SECTOR *const Sector = Room_GetSector(x, item->pos.y, z, &room_num); const SECTOR *const sector = Room_GetSector(x, item->pos.y, z, &room_num);
if (Room_GetHeight(Sector, x, item->pos.y, z) != item->pos.y) { if (Room_GetHeight(sector, x, item->pos.y, z) != item->pos.y) {
item->status = IS_DEACTIVATED; item->status = IS_DEACTIVATED;
} else { } else {
item->pos.z = z; item->pos.z = z;
@ -40,6 +54,24 @@ static void M_Move(const int16_t item_num)
Sound_Effect(SFX_DOOR_SLIDE, &item->pos, SPM_NORMAL); Sound_Effect(SFX_DOOR_SLIDE, &item->pos, SPM_NORMAL);
} }
static void M_Reset(const int16_t item_num)
{
ITEM *const item = Item_Get(item_num);
item->status = IS_INACTIVE;
const GAME_VECTOR *const data = item->data;
item->pos = data->pos;
if (item->room_num != data->room_num) {
Item_RemoveDrawn(item_num);
ROOM *const room = Room_Get(data->room_num);
item->next_item = room->item_num;
room->item_num = item_num;
item->room_num = data->room_num;
}
Item_RemoveActive(item_num);
}
static void M_HitLara(ITEM *const item) static void M_HitLara(ITEM *const item)
{ {
Lara_TakeDamage(SPIKE_WALL_DAMAGE, true); Lara_TakeDamage(SPIKE_WALL_DAMAGE, true);
@ -54,6 +86,7 @@ static void M_HitLara(ITEM *const item)
static void M_Setup(OBJECT *const obj) static void M_Setup(OBJECT *const obj)
{ {
obj->initialise_func = M_Initialise;
obj->control_func = M_Control; obj->control_func = M_Control;
obj->collision_func = Object_Collision; obj->collision_func = Object_Collision;
obj->save_position = 1; obj->save_position = 1;
@ -64,7 +97,9 @@ static void M_Control(const int16_t item_num)
{ {
ITEM *const item = Item_Get(item_num); ITEM *const item = Item_Get(item_num);
if (Item_IsTriggerActive(item) && item->status != IS_DEACTIVATED) { if (!Item_IsTriggerActive(item)) {
M_Reset(item_num);
} else if (item->status != IS_DEACTIVATED) {
M_Move(item_num); M_Move(item_num);
} }