diff --git a/data/tr2/ship/cfg/TR2X_gameflow_gm.json5 b/data/tr2/ship/cfg/TR2X_gameflow_gm.json5 index 03a7f0eda..1b2f2b624 100644 --- a/data/tr2/ship/cfg/TR2X_gameflow_gm.json5 +++ b/data/tr2/ship/cfg/TR2X_gameflow_gm.json5 @@ -141,6 +141,7 @@ "injections": [ "data/injections/common_pickup_meshes.bin", "data/injections/guardian_death_commands.bin", + "data/injections/vegas_fd.bin", ], }, ], diff --git a/data/tr2/ship/data/injections/floating_fd.bin b/data/tr2/ship/data/injections/floating_fd.bin index d1f98768a..044a0d4e8 100644 Binary files a/data/tr2/ship/data/injections/floating_fd.bin and b/data/tr2/ship/data/injections/floating_fd.bin differ diff --git a/data/tr2/ship/data/injections/vegas_fd.bin b/data/tr2/ship/data/injections/vegas_fd.bin new file mode 100644 index 000000000..ee24306c2 Binary files /dev/null and b/data/tr2/ship/data/injections/vegas_fd.bin differ diff --git a/data/tr2/ship/data/injections/xian_fd.bin b/data/tr2/ship/data/injections/xian_fd.bin index d98701465..258aac7dc 100644 Binary files a/data/tr2/ship/data/injections/xian_fd.bin and b/data/tr2/ship/data/injections/xian_fd.bin differ diff --git a/docs/tr2/CHANGELOG.md b/docs/tr2/CHANGELOG.md index 72a3bc155..4a473c338 100644 --- a/docs/tr2/CHANGELOG.md +++ b/docs/tr2/CHANGELOG.md @@ -10,6 +10,7 @@ - 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 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 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) @@ -25,6 +26,9 @@ - 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 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 a crash if an image was missing - fixed a crash on level load if an animation has no frames (#2746, regression from 0.8) diff --git a/docs/tr2/README.md b/docs/tr2/README.md index de9732e7d..8456a0ce1 100644 --- a/docs/tr2/README.md +++ b/docs/tr2/README.md @@ -214,8 +214,9 @@ as Notepad. - **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) - **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 - - **Floating Islands**: fixed door 72's position to resolve the invisible wall in front of it + - **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; 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 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 @@ -310,6 +311,7 @@ as Notepad. - added developer console (accessible with `/`, see [COMMANDS.md](COMMANDS.md) for details) - added ability to disable FMVs - 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 #### Miscellaneous diff --git a/src/tr2/game/objects/traps/spike_wall.c b/src/tr2/game/objects/traps/spike_wall.c index 9a3784a4c..fa6a8ceee 100644 --- a/src/tr2/game/objects/traps/spike_wall.c +++ b/src/tr2/game/objects/traps/spike_wall.c @@ -6,16 +6,30 @@ #include "game/spawn.h" #include "global/vars.h" +#include #include #define SPIKE_WALL_DAMAGE 20 #define SPIKE_WALL_SPEED 1 +static void M_Initialise(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_Setup(OBJECT *obj); 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) { 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); 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; } else { 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); } +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) { Lara_TakeDamage(SPIKE_WALL_DAMAGE, true); @@ -54,6 +86,7 @@ static void M_HitLara(ITEM *const item) static void M_Setup(OBJECT *const obj) { + obj->initialise_func = M_Initialise; obj->control_func = M_Control; obj->collision_func = Object_Collision; obj->save_position = 1; @@ -64,7 +97,9 @@ static void M_Control(const int16_t 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); }