diff --git a/CHANGELOG.md b/CHANGELOG.md index 0227c9f97..813764698 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - fixed `/tp` console command reporting teleport fails as success (#1484, regression from 4.1) - fixed console commands causing improper ring shutdown with selected inventory item (#1460, regression from 3.0) - fixed console input immediately ending demo (#1480, regression from 4.1) +- fixed a potential softlock when killing the Torso boss in Great Pyramid (#1236) - changed `/tp` console command to look for the closest place to teleport to when targeting items (#1484) - improved appearance of textures around edges when bilinear filter is off (#1483) Since this removes the seams on pushblocks, this was made optional. diff --git a/GAMEFLOW.md b/GAMEFLOW.md index 4e95e2b5e..7fbc1d4c1 100644 --- a/GAMEFLOW.md +++ b/GAMEFLOW.md @@ -189,6 +189,19 @@ various pieces of global behaviour. only. + + + use_extended_triggers + + Boolean + No + + When enabled, triggers will be tested for heavy items larger than 1.5 + tiles in each immediately neighbouring tile on which the item dies. This + primarily applies to the Torso boss in Great Pyramid to avoid softlock; it + should generally not be required for custom levels. + + diff --git a/README.md b/README.md index 335f58835..ee25a9e56 100644 --- a/README.md +++ b/README.md @@ -516,6 +516,7 @@ Not all options are turned on by default. Refer to `TR1X_ConfigTool.exe` for det - fixed looking forward too far causing an upside down camera frame - fixed the Scion being extremely difficult to shoot with the shotgun - fixed collision issues with drawbridges, trapdoors, and bridges when stacked over each other, over slopes, and near the ground +- fixed a potential softlock when killing the Torso boss in Great Pyramid #### Cheats - added a fly cheat diff --git a/data/ship/cfg/TR1X_gameflow.json5 b/data/ship/cfg/TR1X_gameflow.json5 index 1a586c615..8652fcd36 100644 --- a/data/ship/cfg/TR1X_gameflow.json5 +++ b/data/ship/cfg/TR1X_gameflow.json5 @@ -21,6 +21,7 @@ "data/injections/uzi_sfx.bin", ], "convert_dropped_guns": false, + "use_extended_triggers": true, "levels": [ // Level 0 diff --git a/src/game/gameflow.c b/src/game/gameflow.c index 44bb1312b..36d8239d9 100644 --- a/src/game/gameflow.c +++ b/src/game/gameflow.c @@ -229,6 +229,8 @@ static bool GameFlow_LoadScriptMeta(struct json_object_s *obj) g_GameFlow.convert_dropped_guns = json_object_get_bool(obj, "convert_dropped_guns", false); + g_GameFlow.use_extended_triggers = + json_object_get_bool(obj, "use_extended_triggers", true); return true; } diff --git a/src/game/gameflow.h b/src/game/gameflow.h index 46c2a9467..acb5eabf4 100644 --- a/src/game/gameflow.h +++ b/src/game/gameflow.h @@ -83,6 +83,7 @@ typedef struct GAMEFLOW { char **data_paths; } injections; bool convert_dropped_guns; + bool use_extended_triggers; } GAMEFLOW; extern GAMEFLOW g_GameFlow; diff --git a/src/game/room.c b/src/game/room.c index 651509691..65a0ef24c 100644 --- a/src/game/room.c +++ b/src/game/room.c @@ -1,5 +1,6 @@ #include "game/room.h" +#include "gameflow.h" #include "game/camera.h" #include "game/gamebuf.h" #include "game/items.h" @@ -40,6 +41,8 @@ static int16_t Room_GetCeilingTiltHeight( const SECTOR_INFO *sector, const int32_t x, const int32_t z); static SECTOR_INFO *Room_GetSkySector( const SECTOR_INFO *sector, int32_t x, int32_t z); +static void Room_TestSectorTrigger( + const ITEM_INFO *item, const SECTOR_INFO *sector); static void Room_TriggerMusicTrack(int16_t track, const TRIGGER *const trigger) { @@ -736,11 +739,41 @@ void Room_PopulateSectorData( void Room_TestTriggers(const ITEM_INFO *const item) { - const bool is_heavy = item->object_id != O_LARA; int16_t room_num = item->room_num; - const SECTOR_INFO *const sector = + const SECTOR_INFO *sector = Room_GetSector(item->pos.x, MAX_HEIGHT, item->pos.z, &room_num); + Room_TestSectorTrigger(item, sector); + if (item->object_id == O_LARA || !g_GameFlow.use_extended_triggers) { + return; + } + + const BOUNDS_16 *const bounds = Item_GetBoundsAccurate(item); + const int32_t x_size = ABS(bounds->max.x - bounds->min.x) / (WALL_L * 1.5); + const int32_t z_size = ABS(bounds->max.z - bounds->min.z) / (WALL_L * 1.5); + if (!x_size && !z_size) { + return; + } + + for (int32_t dx = -1; dx < 2; dx++) { + for (int32_t dz = -1; dz < 2; dz++) { + if (!dx && !dz) { + continue; + } + + room_num = item->room_num; + sector = Room_GetSector( + item->pos.x + dx * WALL_L, MAX_HEIGHT, + item->pos.z + dz * WALL_L, &room_num); + Room_TestSectorTrigger(item, sector); + } + } +} + +static void Room_TestSectorTrigger( + const ITEM_INFO *const item, const SECTOR_INFO *const sector) +{ + const bool is_heavy = item->object_id != O_LARA; if (!is_heavy && sector->is_death_sector && Lava_TestFloor(item)) { Lava_Burn(g_LaraItem); }