diff --git a/docs/GAME_FLOW.md b/docs/GAME_FLOW.md index fe25e2ea1..24226714a 100644 --- a/docs/GAME_FLOW.md +++ b/docs/GAME_FLOW.md @@ -841,7 +841,7 @@ default game flow for examples. - disable_floor² + disable_floor value Integer diff --git a/docs/tr1/CHANGELOG.md b/docs/tr1/CHANGELOG.md index dea5a5b2d..228644cee 100644 --- a/docs/tr1/CHANGELOG.md +++ b/docs/tr1/CHANGELOG.md @@ -1,4 +1,5 @@ ## [Unreleased](https://github.com/LostArtefacts/TRX/compare/tr1-4.8.3...develop) - ××××-××-×× +- added support for custom levels to use `disable_floor` in the gameflow, similar to TR2's Floating Islands (#2541) ## [4.8.3](https://github.com/LostArtefacts/TRX/compare/tr1-4.8.2...tr1-4.8.3) - 2025-02-17 - fixed some of Lara's speech in the gym not playing in response to player action (#2514, regression from 4.8) diff --git a/docs/tr1/README.md b/docs/tr1/README.md index da3a70707..d1570c335 100644 --- a/docs/tr1/README.md +++ b/docs/tr1/README.md @@ -402,6 +402,7 @@ Not all options are turned on by default. Refer to `TR1X_ConfigTool.exe` for det - added a photo mode feature - added optional automatic key/puzzle inventory item pre-selection - added ability for falling pushblocks to kill Lara outright if one lands directly on her +- added support for custom levels to define "no floor", to create an abyss like in TR2's Floating Islands - changed weapon pickup behavior when unarmed to set any weapon as the default weapon, not just pistols - fixed keys and items not working when drawing guns immediately after using them - fixed counting the secret in The Great Pyramid diff --git a/src/libtrx/game/game_flow/reader_tr1.def.c b/src/libtrx/game/game_flow/reader_tr1.def.c index 4ae7d8191..34944fe87 100644 --- a/src/libtrx/game/game_flow/reader_tr1.def.c +++ b/src/libtrx/game/game_flow/reader_tr1.def.c @@ -32,6 +32,7 @@ static M_SEQUENCE_EVENT_HANDLER m_SequenceEventHandlers[] = { { GFS_PLAY_MUSIC, M_HandleIntEvent, "music_track" }, { GFS_SET_CAMERA_ANGLE, M_HandleIntEvent, "value" }, { GFS_SETUP_BACON_LARA, M_HandleIntEvent, "anchor_room" }, + { GFS_DISABLE_FLOOR, M_HandleIntEvent, "height" }, // Special cases with custom handlers { GFS_LOADING_SCREEN, M_HandlePictureEvent, nullptr }, diff --git a/src/libtrx/game/rooms/common.c b/src/libtrx/game/rooms/common.c index 7bb107ba6..a2fd63f9d 100644 --- a/src/libtrx/game/rooms/common.c +++ b/src/libtrx/game/rooms/common.c @@ -1,6 +1,7 @@ #include "game/rooms/common.h" #include "debug.h" +#include "game/camera.h" #include "game/const.h" #include "game/game_buf.h" #include "game/items.h" @@ -32,11 +33,17 @@ static bool m_FlipStatus = false; static int32_t m_FlipEffect = -1; static int32_t m_FlipTimer = 0; static int32_t m_FlipSlotFlags[MAX_FLIP_MAPS] = {}; +static int16_t m_AbyssMinHeight = 0; +static int32_t m_AbyssMaxHeight = 0; +static HEIGHT_TYPE m_HeightType = HT_WALL; static const int16_t *M_ReadTrigger( const int16_t *data, int16_t fd_entry, SECTOR *sector); static void M_AddFlipItems(const ROOM *room); static void M_RemoveFlipItems(const ROOM *room); +static int16_t M_GetFloorTiltHeight(const SECTOR *sector, int32_t x, int32_t z); +static int16_t M_GetCeilingTiltHeight( + const SECTOR *sector, int32_t x, int32_t z); static const int16_t *M_ReadTrigger( const int16_t *data, const int16_t fd_entry, SECTOR *const sector) @@ -145,6 +152,70 @@ static void M_RemoveFlipItems(const ROOM *const room) } } +static int16_t M_GetFloorTiltHeight( + const SECTOR *const sector, const int32_t x, const int32_t z) +{ + int16_t height = sector->floor.height; + if (sector->floor.tilt == 0) { + return height; + } + + const int32_t z_off = sector->floor.tilt >> 8; + const int32_t x_off = (int8_t)sector->floor.tilt; + + const HEIGHT_TYPE slope_type = + (ABS(z_off) > 2 || ABS(x_off) > 2) ? HT_BIG_SLOPE : HT_SMALL_SLOPE; + if (Camera_IsChunky() && slope_type == HT_BIG_SLOPE) { + return height; + } + + m_HeightType = slope_type; + + if (z_off < 0) { + height -= (int16_t)NEG_TILT(z_off, z); + } else { + height += (int16_t)POS_TILT(z_off, z); + } + + if (x_off < 0) { + height -= (int16_t)NEG_TILT(x_off, x); + } else { + height += (int16_t)POS_TILT(x_off, x); + } + + return height; +} + +static int16_t M_GetCeilingTiltHeight( + const SECTOR *sector, const int32_t x, const int32_t z) +{ + int16_t height = sector->ceiling.height; + if (sector->ceiling.tilt == 0) { + return height; + } + + const int32_t z_off = sector->ceiling.tilt >> 8; + const int32_t x_off = (int8_t)sector->ceiling.tilt; + + if (Camera_IsChunky() && (ABS(z_off) > 2 || ABS(x_off) > 2)) { + return height; + } + + if (z_off < 0) { + height += (int16_t)NEG_TILT(z_off, z); + } else { + height -= (int16_t)POS_TILT(z_off, z); + } + + if (x_off < 0) { + height += (int16_t)POS_TILT(x_off, x); + } else { + height -= (int16_t)NEG_TILT(x_off, x); + } + + return height; +} + void Room_InitialiseRooms(const int32_t num_rooms) { m_RoomCount = num_rooms; @@ -416,3 +487,107 @@ SECTOR *Room_GetUnitSector( { return &room->sectors[z_sector + x_sector * room->size.z]; } + +SECTOR *Room_GetPitSector( + const SECTOR *sector, const int32_t x, const int32_t z) +{ + while (sector->portal_room.pit != NO_ROOM) { + const ROOM *const room = Room_Get(sector->portal_room.pit); + sector = Room_GetWorldSector(room, x, z); + } + + return (SECTOR *)sector; +} + +SECTOR *Room_GetSkySector( + const SECTOR *sector, const int32_t x, const int32_t z) +{ + while (sector->portal_room.sky != NO_ROOM) { + const ROOM *const room = Room_Get(sector->portal_room.sky); + sector = Room_GetWorldSector(room, x, z); + } + + return (SECTOR *)sector; +} + +void Room_SetAbyssHeight(const int16_t height) +{ + // Once Lara reaches the min abyss height, she will be killed; she will + // continue to fall however, so the max height is needed until the inventory + // is shown, otherwise Lara will hit the floor. + m_AbyssMinHeight = height; + m_AbyssMaxHeight = height == 0 ? 0 : m_AbyssMinHeight + 26 * STEP_L; + CLAMPG(m_AbyssMaxHeight, MAX_HEIGHT - STEP_L); +} + +bool Room_IsAbyssHeight(const int16_t height) +{ + return m_AbyssMinHeight != 0 && height >= m_AbyssMinHeight; +} + +HEIGHT_TYPE Room_GetHeightType(void) +{ + return m_HeightType; +} + +int16_t Room_GetHeight( + const SECTOR *sector, const int32_t x, const int32_t y, const int32_t z) +{ + m_HeightType = HT_WALL; + + const SECTOR *const pit_sector = Room_GetPitSector(sector, x, z); + int32_t height = pit_sector->floor.height; + + if (Room_IsAbyssHeight(height)) { + height = m_AbyssMaxHeight; + } else { + height = M_GetFloorTiltHeight(pit_sector, x, z); + } + + if (pit_sector->trigger == nullptr) { + return height; + } + + const TRIGGER_CMD *cmd = pit_sector->trigger->command; + for (; cmd != nullptr; cmd = cmd->next_cmd) { + if (cmd->type != TO_OBJECT) { + continue; + } + + const ITEM *const item = Item_Get((int16_t)(intptr_t)cmd->parameter); + const OBJECT *const obj = Object_Get(item->object_id); + if (obj->floor_height_func != nullptr) { + height = obj->floor_height_func(item, x, y, z, height); + } + } + + return height; +} + +int16_t Room_GetCeiling( + const SECTOR *const sector, const int32_t x, const int32_t y, + const int32_t z) +{ + const SECTOR *const sky_sector = Room_GetSkySector(sector, x, z); + int16_t height = M_GetCeilingTiltHeight(sky_sector, x, z); + + const SECTOR *const pit_sector = Room_GetPitSector(sector, x, z); + if (pit_sector->trigger == nullptr) { + return height; + } + + const TRIGGER_CMD *cmd = pit_sector->trigger->command; + for (; cmd != nullptr; cmd = cmd->next_cmd) { + if (cmd->type != TO_OBJECT) { + continue; + } + + const ITEM *const item = Item_Get((int16_t)(intptr_t)cmd->parameter); + const OBJECT *const obj = Object_Get(item->object_id); + if (obj->ceiling_height_func != nullptr) { + height = obj->ceiling_height_func(item, x, y, z, height); + } + } + + return height; +} diff --git a/src/libtrx/include/libtrx/game/enum_map.def b/src/libtrx/include/libtrx/game/enum_map.def index 6d37d0ec5..48b3ac199 100644 --- a/src/libtrx/include/libtrx/game/enum_map.def +++ b/src/libtrx/include/libtrx/game/enum_map.def @@ -79,6 +79,7 @@ ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_ADD_ITEM, "give_item") ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_REMOVE_WEAPONS, "remove_weapons") ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_REMOVE_AMMO, "remove_ammo") ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_REMOVE_MEDIPACKS, "remove_medipacks") +ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_DISABLE_FLOOR, "disable_floor") #if TR_VERSION == 1 ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_REMOVE_SCIONS, "remove_scions") ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_MESH_SWAP, "mesh_swap") @@ -88,7 +89,6 @@ ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_REMOVE_FLARES, "remove_flares") ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_ENABLE_SUNSET, "enable_sunset") ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_SET_NUM_SECRETS, "set_secret_count") ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_SET_START_ANIM, "set_lara_start_anim") -ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_DISABLE_FLOOR, "disable_floor") ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_ADD_SECRET_REWARD, "add_secret_reward") #endif diff --git a/src/libtrx/include/libtrx/game/game_flow/enum.h b/src/libtrx/include/libtrx/game/game_flow/enum.h index 02e5bd561..4c51c5963 100644 --- a/src/libtrx/include/libtrx/game/game_flow/enum.h +++ b/src/libtrx/include/libtrx/game/game_flow/enum.h @@ -73,6 +73,7 @@ typedef enum { GFS_REMOVE_WEAPONS, GFS_REMOVE_AMMO, GFS_REMOVE_MEDIPACKS, + GFS_DISABLE_FLOOR, #if TR_VERSION == 1 GFS_REMOVE_SCIONS, GFS_FLIP_MAP, @@ -82,7 +83,6 @@ typedef enum { GFS_REMOVE_FLARES, GFS_SET_START_ANIM, GFS_SET_NUM_SECRETS, - GFS_DISABLE_FLOOR, GFS_ENABLE_SUNSET, GFS_ADD_SECRET_REWARD, #endif diff --git a/src/libtrx/include/libtrx/game/rooms/common.h b/src/libtrx/include/libtrx/game/rooms/common.h index be704fe11..43f483665 100644 --- a/src/libtrx/include/libtrx/game/rooms/common.h +++ b/src/libtrx/include/libtrx/game/rooms/common.h @@ -35,3 +35,11 @@ BOUNDS_32 Room_GetWorldBounds(void); SECTOR *Room_GetWorldSector(const ROOM *room, int32_t x_pos, int32_t z_pos); SECTOR *Room_GetUnitSector( const ROOM *room, int32_t x_sector, int32_t z_sector); +SECTOR *Room_GetPitSector(const SECTOR *sector, int32_t x, int32_t z); +SECTOR *Room_GetSkySector(const SECTOR *sector, int32_t x, int32_t z); + +void Room_SetAbyssHeight(int16_t height); +bool Room_IsAbyssHeight(int16_t height); +HEIGHT_TYPE Room_GetHeightType(void); +int16_t Room_GetHeight(const SECTOR *sector, int32_t x, int32_t y, int32_t z); +int16_t Room_GetCeiling(const SECTOR *sector, int32_t x, int32_t y, int32_t z); diff --git a/src/libtrx/include/libtrx/game/rooms/enum.h b/src/libtrx/include/libtrx/game/rooms/enum.h index 0f85e8799..8dcbab259 100644 --- a/src/libtrx/include/libtrx/game/rooms/enum.h +++ b/src/libtrx/include/libtrx/game/rooms/enum.h @@ -1,5 +1,11 @@ #pragma once +typedef enum { + HT_WALL = 0, + HT_SMALL_SLOPE = 1, + HT_BIG_SLOPE = 2, +} HEIGHT_TYPE; + typedef enum { RF_UNDERWATER = 0x01, RF_OUTSIDE = 0x08, diff --git a/src/tr1/game/collide.c b/src/tr1/game/collide.c index b21f04adf..35c64fb16 100644 --- a/src/tr1/game/collide.c +++ b/src/tr1/game/collide.c @@ -41,7 +41,7 @@ void Collide_GetCollisionInfo( coll->mid_floor = height; coll->mid_ceiling = ceiling; - coll->mid_type = g_HeightType; + coll->mid_type = Room_GetHeightType(); if (!g_Config.gameplay.fix_bridge_collision || !Room_IsOnWalkable(sector, x, ytop, z, room_height)) { @@ -123,7 +123,7 @@ void Collide_GetCollisionInfo( coll->front_floor = height; coll->front_ceiling = ceiling; - coll->front_type = g_HeightType; + coll->front_type = Room_GetHeightType(); if (!g_Config.gameplay.fix_bridge_collision || !Room_IsOnWalkable(sector, x, ytop, z, room_height)) { @@ -158,7 +158,7 @@ void Collide_GetCollisionInfo( coll->left_floor = height; coll->left_ceiling = ceiling; - coll->left_type = g_HeightType; + coll->left_type = Room_GetHeightType(); if (!g_Config.gameplay.fix_bridge_collision || !Room_IsOnWalkable(sector, x, ytop, z, room_height)) { @@ -193,7 +193,7 @@ void Collide_GetCollisionInfo( coll->right_floor = height; coll->right_ceiling = ceiling; - coll->right_type = g_HeightType; + coll->right_type = Room_GetHeightType(); if (!g_Config.gameplay.fix_bridge_collision || !Room_IsOnWalkable(sector, x, ytop, z, room_height)) { diff --git a/src/tr1/game/game_flow/sequencer_events.c b/src/tr1/game/game_flow/sequencer_events.c index d0ff9fc9d..00f66fced 100644 --- a/src/tr1/game/game_flow/sequencer_events.c +++ b/src/tr1/game/game_flow/sequencer_events.c @@ -22,6 +22,7 @@ static DECLARE_GF_EVENT_HANDLER(M_HandlePlayMusic); static DECLARE_GF_EVENT_HANDLER(M_HandleLevelComplete); static DECLARE_GF_EVENT_HANDLER(M_HandleSetCameraPos); static DECLARE_GF_EVENT_HANDLER(M_HandleSetCameraAngle); +static DECLARE_GF_EVENT_HANDLER(M_HandleDisableFloor); static DECLARE_GF_EVENT_HANDLER(M_HandleFlipMap); static DECLARE_GF_EVENT_HANDLER(M_HandleAddItem); static DECLARE_GF_EVENT_HANDLER(M_HandleRemoveWeapons); @@ -33,11 +34,12 @@ static DECLARE_GF_EVENT_HANDLER(M_HandleSetupBaconLara); static DECLARE_GF_EVENT_HANDLER((*m_EventHandlers[GFS_NUMBER_OF])) = { // clang-format off - [GFS_LOOP_GAME] = M_HandlePlayLevel, + [GFS_LOOP_GAME] = M_HandlePlayLevel, [GFS_PLAY_MUSIC] = M_HandlePlayMusic, [GFS_LEVEL_COMPLETE] = M_HandleLevelComplete, [GFS_SET_CAMERA_POS] = M_HandleSetCameraPos, [GFS_SET_CAMERA_ANGLE] = M_HandleSetCameraAngle, + [GFS_DISABLE_FLOOR] = M_HandleDisableFloor, [GFS_FLIP_MAP] = M_HandleFlipMap, [GFS_ADD_ITEM] = M_HandleAddItem, [GFS_REMOVE_WEAPONS] = M_HandleRemoveWeapons, @@ -272,6 +274,15 @@ static DECLARE_GF_EVENT_HANDLER(M_HandleSetCameraAngle) return (GF_COMMAND) { .action = GF_NOOP }; } +static DECLARE_GF_EVENT_HANDLER(M_HandleDisableFloor) +{ + GF_COMMAND gf_cmd = { .action = GF_NOOP }; + if (seq_ctx != GFSC_STORY) { + Room_SetAbyssHeight((int16_t)(intptr_t)event->data); + } + return gf_cmd; +} + static DECLARE_GF_EVENT_HANDLER(M_HandleFlipMap) { if (seq_ctx != GFSC_STORY) { @@ -349,6 +360,7 @@ static DECLARE_GF_EVENT_HANDLER(M_HandleSetupBaconLara) void GF_PreSequenceHook( const GF_SEQUENCE_CONTEXT seq_ctx, void *const seq_ctx_arg) { + Room_SetAbyssHeight(0); g_GameInfo.remove_guns = false; g_GameInfo.remove_scions = false; g_GameInfo.remove_ammo = false; diff --git a/src/tr1/game/lara/common.c b/src/tr1/game/lara/common.c index f5b91ac86..7897a9fab 100644 --- a/src/tr1/game/lara/common.c +++ b/src/tr1/game/lara/common.c @@ -285,6 +285,9 @@ void Lara_Control(void) if (g_LaraItem->flags & IF_INVISIBLE) { return; } + } else if (Room_IsAbyssHeight(item->pos.y)) { + item->hit_points = -1; + g_Lara.death_timer = 9 * LOGIC_FPS; } Camera_MoveManual(); diff --git a/src/tr1/game/room.c b/src/tr1/game/room.c index f223afa9e..56784c9e0 100644 --- a/src/tr1/game/room.c +++ b/src/tr1/game/room.c @@ -21,11 +21,6 @@ static void M_TriggerMusicTrack(int16_t track, const TRIGGER *const trigger); -static int16_t M_GetFloorTiltHeight( - const SECTOR *sector, const int32_t x, const int32_t z); -static int16_t M_GetCeilingTiltHeight( - const SECTOR *sector, const int32_t x, const int32_t z); -static SECTOR *M_GetSkySector(const SECTOR *sector, int32_t x, int32_t z); static bool M_TestLava(const ITEM *const item); static void M_TriggerMusicTrack(int16_t track, const TRIGGER *const trigger) @@ -162,28 +157,6 @@ void Room_GetNewRoom(int32_t x, int32_t y, int32_t z, int16_t room_num) Room_MarkToBeDrawn(room_num); } -SECTOR *Room_GetPitSector( - const SECTOR *sector, const int32_t x, const int32_t z) -{ - while (sector->portal_room.pit != NO_ROOM) { - const ROOM *const room = Room_Get(sector->portal_room.pit); - sector = Room_GetWorldSector(room, x, z); - } - - return (SECTOR *)sector; -} - -static SECTOR *M_GetSkySector( - const SECTOR *sector, const int32_t x, const int32_t z) -{ - while (sector->portal_room.sky != NO_ROOM) { - const ROOM *const room = Room_Get(sector->portal_room.sky); - sector = Room_GetWorldSector(room, x, z); - } - - return (SECTOR *)sector; -} - SECTOR *Room_GetSector(int32_t x, int32_t y, int32_t z, int16_t *room_num) { int16_t portal_room; @@ -246,127 +219,6 @@ SECTOR *Room_GetSector(int32_t x, int32_t y, int32_t z, int16_t *room_num) return sector; } -int16_t Room_GetCeiling(const SECTOR *sector, int32_t x, int32_t y, int32_t z) -{ - int16_t *data; - int16_t type; - int16_t trigger; - - const SECTOR *const sky_sector = M_GetSkySector(sector, x, z); - int16_t height = M_GetCeilingTiltHeight(sky_sector, x, z); - - sector = Room_GetPitSector(sector, x, z); - if (sector->trigger == nullptr) { - return height; - } - - const TRIGGER_CMD *cmd = sector->trigger->command; - for (; cmd != nullptr; cmd = cmd->next_cmd) { - if (cmd->type != TO_OBJECT) { - continue; - } - - const ITEM *const item = Item_Get((int16_t)(intptr_t)cmd->parameter); - const OBJECT *const obj = Object_Get(item->object_id); - if (obj->ceiling_height_func != nullptr) { - height = obj->ceiling_height_func(item, x, y, z, height); - } - } - - return height; -} - -int16_t Room_GetHeight(const SECTOR *sector, int32_t x, int32_t y, int32_t z) -{ - g_HeightType = HT_WALL; - sector = Room_GetPitSector(sector, x, z); - - int16_t height = M_GetFloorTiltHeight(sector, x, z); - - if (sector->trigger == nullptr) { - return height; - } - - const TRIGGER_CMD *cmd = sector->trigger->command; - for (; cmd != nullptr; cmd = cmd->next_cmd) { - if (cmd->type != TO_OBJECT) { - continue; - } - - const ITEM *const item = Item_Get((int16_t)(intptr_t)cmd->parameter); - const OBJECT *const obj = Object_Get(item->object_id); - if (obj->floor_height_func != nullptr) { - height = obj->floor_height_func(item, x, y, z, height); - } - } - - return height; -} - -static int16_t M_GetFloorTiltHeight( - const SECTOR *sector, const int32_t x, const int32_t z) -{ - int16_t height = sector->floor.height; - if (sector->floor.tilt == 0) { - return height; - } - - const int32_t z_off = sector->floor.tilt >> 8; - const int32_t x_off = (int8_t)sector->floor.tilt; - - const HEIGHT_TYPE slope_type = - (ABS(z_off) > 2 || ABS(x_off) > 2) ? HT_BIG_SLOPE : HT_SMALL_SLOPE; - if (Camera_IsChunky() && slope_type == HT_BIG_SLOPE) { - return height; - } - - g_HeightType = slope_type; - - if (z_off < 0) { - height -= (int16_t)NEG_TILT(z_off, z); - } else { - height += (int16_t)POS_TILT(z_off, z); - } - - if (x_off < 0) { - height -= (int16_t)NEG_TILT(x_off, x); - } else { - height += (int16_t)POS_TILT(x_off, x); - } - - return height; -} - -static int16_t M_GetCeilingTiltHeight( - const SECTOR *sector, const int32_t x, const int32_t z) -{ - int16_t height = sector->ceiling.height; - if (sector->ceiling.tilt == 0) { - return height; - } - - const int32_t z_off = sector->ceiling.tilt >> 8; - const int32_t x_off = (int8_t)sector->ceiling.tilt; - - if (Camera_IsChunky() && (ABS(z_off) > 2 || ABS(x_off) > 2)) { - return height; - } - - if (z_off < 0) { - height += (int16_t)NEG_TILT(z_off, z); - } else { - height -= (int16_t)POS_TILT(z_off, z); - } - - if (x_off < 0) { - height += (int16_t)POS_TILT(x_off, x); - } else { - height -= (int16_t)NEG_TILT(x_off, x); - } - - return height; -} - int16_t Room_GetWaterHeight(int32_t x, int32_t y, int32_t z, int16_t room_num) { const ROOM *room = Room_Get(room_num); @@ -459,7 +311,7 @@ void Room_AlterFloorHeight(const ITEM *const item, const int32_t height) } while (portal_room != NO_ROOM); const SECTOR *const sky_sector = - M_GetSkySector(sector, item->pos.x, item->pos.z); + Room_GetSkySector(sector, item->pos.x, item->pos.z); sector = Room_GetPitSector(sector, item->pos.x, item->pos.z); if (sector->floor.height != NO_HEIGHT) { diff --git a/src/tr1/game/room.h b/src/tr1/game/room.h index c12aeb3d0..ab41fb4d7 100644 --- a/src/tr1/game/room.h +++ b/src/tr1/game/room.h @@ -13,9 +13,6 @@ void Room_GetNewRoom(int32_t x, int32_t y, int32_t z, int16_t room_num); void Room_GetNearByRooms( int32_t x, int32_t y, int32_t z, int32_t r, int32_t h, int16_t room_num); SECTOR *Room_GetSector(int32_t x, int32_t y, int32_t z, int16_t *room_num); -SECTOR *Room_GetPitSector(const SECTOR *sector, int32_t x, int32_t z); -int16_t Room_GetCeiling(const SECTOR *sector, int32_t x, int32_t y, int32_t z); -int16_t Room_GetHeight(const SECTOR *sector, int32_t x, int32_t y, int32_t z); int16_t Room_GetWaterHeight(int32_t x, int32_t y, int32_t z, int16_t room_num); void Room_TestTriggers(const ITEM *item); diff --git a/src/tr1/global/types.h b/src/tr1/global/types.h index 09505a9c4..316a4cdd8 100644 --- a/src/tr1/global/types.h +++ b/src/tr1/global/types.h @@ -58,12 +58,6 @@ typedef enum { COLL_CLAMP = 32, } COLL_TYPE; -typedef enum { - HT_WALL = 0, - HT_SMALL_SLOPE = 1, - HT_BIG_SLOPE = 2, -} HEIGHT_TYPE; - typedef enum { IC_BLACK = 0, IC_GREY = 1, diff --git a/src/tr1/global/vars.c b/src/tr1/global/vars.c index 8d914491d..d15f20fdb 100644 --- a/src/tr1/global/vars.c +++ b/src/tr1/global/vars.c @@ -19,7 +19,6 @@ int32_t g_SavedGamesCount = 0; int32_t g_SaveCounter = 0; bool g_LevelComplete = false; int32_t g_OverlayFlag = 0; -int32_t g_HeightType = 0; INVENTORY_MODE g_InvMode; diff --git a/src/tr1/global/vars.h b/src/tr1/global/vars.h index a2ee2ca45..b0d83e4e5 100644 --- a/src/tr1/global/vars.h +++ b/src/tr1/global/vars.h @@ -27,7 +27,6 @@ extern int32_t g_SavedGamesCount; extern int32_t g_SaveCounter; extern bool g_LevelComplete; extern int32_t g_OverlayFlag; -extern int32_t g_HeightType; extern REQUEST_INFO g_SavegameRequester; diff --git a/src/tr2/decomp/skidoo.c b/src/tr2/decomp/skidoo.c index 045340d7a..5b511397f 100644 --- a/src/tr2/decomp/skidoo.c +++ b/src/tr2/decomp/skidoo.c @@ -559,7 +559,7 @@ int32_t Skidoo_CheckGetOffOK(int32_t direction) const SECTOR *const sector = Room_GetSector(x, y, z, &room_num); const int32_t height = Room_GetHeight(sector, x, y, z); - if (g_HeightType == HT_BIG_SLOPE || height == NO_HEIGHT) { + if (Room_GetHeightType() == HT_BIG_SLOPE || height == NO_HEIGHT) { return false; } diff --git a/src/tr2/game/collide.c b/src/tr2/game/collide.c index 568e1b383..1aeeb5ae8 100644 --- a/src/tr2/game/collide.c +++ b/src/tr2/game/collide.c @@ -40,7 +40,7 @@ void Collide_GetCollisionInfo( coll->side_mid.floor = height; coll->side_mid.ceiling = ceiling; - coll->side_mid.type = g_HeightType; + coll->side_mid.type = Room_GetHeightType(); const int16_t tilt = Room_GetTiltType(sector, x, g_LaraItem->pos.y, z); coll->z_tilt = tilt >> 8; @@ -113,7 +113,7 @@ void Collide_GetCollisionInfo( coll->side_front.floor = height; coll->side_front.ceiling = ceiling; - coll->side_front.type = g_HeightType; + coll->side_front.type = Room_GetHeightType(); if (coll->slopes_are_walls && coll->side_front.type == HT_BIG_SLOPE && coll->side_front.floor < 0) { coll->side_front.floor = -32767; @@ -141,7 +141,7 @@ void Collide_GetCollisionInfo( coll->side_left.floor = height; coll->side_left.ceiling = ceiling; - coll->side_left.type = g_HeightType; + coll->side_left.type = Room_GetHeightType(); if (coll->slopes_are_walls && coll->side_left.type == HT_BIG_SLOPE && coll->side_left.floor < 0) { coll->side_left.floor = -32767; @@ -169,7 +169,7 @@ void Collide_GetCollisionInfo( coll->side_right.floor = height; coll->side_right.ceiling = ceiling; - coll->side_right.type = g_HeightType; + coll->side_right.type = Room_GetHeightType(); if (coll->slopes_are_walls && coll->side_right.type == HT_BIG_SLOPE && coll->side_right.floor < 0) { coll->side_right.floor = -32767; diff --git a/src/tr2/game/game_flow/sequencer_events.c b/src/tr2/game/game_flow/sequencer_events.c index b8d1ca9e2..595a5b609 100644 --- a/src/tr2/game/game_flow/sequencer_events.c +++ b/src/tr2/game/game_flow/sequencer_events.c @@ -31,7 +31,7 @@ static DECLARE_GF_EVENT_HANDLER(M_HandleSetNumSecrets); static DECLARE_GF_EVENT_HANDLER((*m_EventHandlers[GFS_NUMBER_OF])) = { // clang-format off - [GFS_LOOP_GAME] = M_HandlePlayLevel, + [GFS_LOOP_GAME] = M_HandlePlayLevel, [GFS_PLAY_MUSIC] = M_HandlePlayMusic, [GFS_LEVEL_COMPLETE] = M_HandleLevelComplete, [GFS_ENABLE_SUNSET] = M_HandleEnableSunset, @@ -200,7 +200,7 @@ static DECLARE_GF_EVENT_HANDLER(M_HandleDisableFloor) { GF_COMMAND gf_cmd = { .action = GF_NOOP }; if (seq_ctx != GFSC_STORY) { - g_GF_NoFloor = (int16_t)(intptr_t)event->data; + Room_SetAbyssHeight((int16_t)(intptr_t)event->data); } return gf_cmd; } @@ -262,7 +262,7 @@ static DECLARE_GF_EVENT_HANDLER(M_HandleSetNumSecrets) void GF_PreSequenceHook( const GF_SEQUENCE_CONTEXT seq_ctx, void *const seq_ctx_arg) { - g_GF_NoFloor = 0; + Room_SetAbyssHeight(0); Output_SetSunsetEnabled(false); g_GF_LaraStartAnim = 0; g_GF_RemoveAmmo = false; diff --git a/src/tr2/game/lara/control.c b/src/tr2/game/lara/control.c index 0d9e53592..702445db1 100644 --- a/src/tr2/game/lara/control.c +++ b/src/tr2/game/lara/control.c @@ -633,7 +633,7 @@ void Lara_Control(const int16_t item_num) g_Lara.death_timer++; return; } - } else if (g_GF_NoFloor && item->pos.y >= g_GF_NoFloor) { + } else if (Room_IsAbyssHeight(item->pos.y)) { item->hit_points = -1; g_Lara.death_timer = 9 * FRAMES_PER_SECOND; } diff --git a/src/tr2/game/objects/general/movable_block.c b/src/tr2/game/objects/general/movable_block.c index 5c3a63ca8..bf48ed9a4 100644 --- a/src/tr2/game/objects/general/movable_block.c +++ b/src/tr2/game/objects/general/movable_block.c @@ -103,7 +103,7 @@ static bool M_TestPush( } Room_GetHeight(sector, x, y, z); - if (g_HeightType != HT_WALL) { + if (Room_GetHeightType() != HT_WALL) { return false; } diff --git a/src/tr2/game/room.c b/src/tr2/game/room.c index e9d5f7a62..d7c6ee006 100644 --- a/src/tr2/game/room.c +++ b/src/tr2/game/room.c @@ -20,77 +20,10 @@ #include void Room_MarkToBeDrawn(int16_t room_num); -static int16_t M_GetFloorTiltHeight(const SECTOR *sector, int32_t x, int32_t z); -static int16_t M_GetCeilingTiltHeight( - const SECTOR *sector, int32_t x, int32_t z); static void M_TriggerMusicTrack(int16_t track, const TRIGGER *trigger); static bool M_TestLava(const ITEM *item); -static int16_t M_GetFloorTiltHeight( - const SECTOR *sector, const int32_t x, const int32_t z) -{ - int16_t height = sector->floor.height; - if (sector->floor.tilt == 0) { - return height; - } - - const int32_t z_off = sector->floor.tilt >> 8; - const int32_t x_off = (int8_t)sector->floor.tilt; - - const HEIGHT_TYPE slope_type = - (ABS(z_off) > 2 || ABS(x_off) > 2) ? HT_BIG_SLOPE : HT_SMALL_SLOPE; - if (Camera_IsChunky() && slope_type == HT_BIG_SLOPE) { - return height; - } - - g_HeightType = slope_type; - - if (z_off < 0) { - height -= (int16_t)NEG_TILT(z_off, z); - } else { - height += (int16_t)POS_TILT(z_off, z); - } - - if (x_off < 0) { - height -= (int16_t)NEG_TILT(x_off, x); - } else { - height += (int16_t)POS_TILT(x_off, x); - } - - return height; -} - -static int16_t M_GetCeilingTiltHeight( - const SECTOR *sector, const int32_t x, const int32_t z) -{ - int16_t height = sector->ceiling.height; - if (sector->ceiling.tilt == 0) { - return height; - } - - const int32_t z_off = sector->ceiling.tilt >> 8; - const int32_t x_off = (int8_t)sector->ceiling.tilt; - - if (Camera_IsChunky() && (ABS(z_off) > 2 || ABS(x_off) > 2)) { - return height; - } - - if (z_off < 0) { - height += (int16_t)NEG_TILT(z_off, z); - } else { - height -= (int16_t)POS_TILT(z_off, z); - } - - if (x_off < 0) { - height += (int16_t)POS_TILT(x_off, x); - } else { - height -= (int16_t)NEG_TILT(x_off, x); - } - - return height; -} - static void M_TriggerMusicTrack( const int16_t track, const TRIGGER *const trigger) { @@ -496,28 +429,6 @@ int16_t Room_GetTiltType( return sector->floor.tilt; } -SECTOR *Room_GetPitSector( - const SECTOR *sector, const int32_t x, const int32_t z) -{ - while (sector->portal_room.pit != NO_ROOM) { - const ROOM *const room = Room_Get(sector->portal_room.pit); - sector = Room_GetWorldSector(room, x, z); - } - - return (SECTOR *)sector; -} - -SECTOR *Room_GetSkySector( - const SECTOR *sector, const int32_t x, const int32_t z) -{ - while (sector->portal_room.sky != NO_ROOM) { - const ROOM *const room = Room_Get(sector->portal_room.sky); - sector = Room_GetWorldSector(room, x, z); - } - - return (SECTOR *)sector; -} - SECTOR *Room_GetSector( const int32_t x, const int32_t y, const int32_t z, int16_t *const room_num) { @@ -636,40 +547,6 @@ int32_t Room_GetWaterHeight( } } -int32_t Room_GetHeight( - const SECTOR *sector, const int32_t x, const int32_t y, const int32_t z) -{ - g_HeightType = 0; - - const SECTOR *const pit_sector = Room_GetPitSector(sector, x, z); - int32_t height = pit_sector->floor.height; - - if (g_GF_NoFloor && g_GF_NoFloor == height) { - height = 0x4000; - } else { - height = M_GetFloorTiltHeight(pit_sector, x, z); - } - - if (pit_sector->trigger == nullptr) { - return height; - } - - const TRIGGER_CMD *cmd = pit_sector->trigger->command; - for (; cmd != nullptr; cmd = cmd->next_cmd) { - if (cmd->type != TO_OBJECT) { - continue; - } - - const ITEM *const item = Item_Get((int16_t)(intptr_t)cmd->parameter); - const OBJECT *const obj = Object_Get(item->object_id); - if (obj->floor_height_func != nullptr) { - height = obj->floor_height_func(item, x, y, z, height); - } - } - - return height; -} - void Room_TestTriggers(const ITEM *const item) { int16_t room_num = item->room_num; @@ -679,34 +556,6 @@ void Room_TestTriggers(const ITEM *const item) Room_TestSectorTrigger(item, sector); } -int32_t Room_GetCeiling( - const SECTOR *const sector, const int32_t x, const int32_t y, - const int32_t z) -{ - const SECTOR *const sky_sector = Room_GetSkySector(sector, x, z); - int32_t height = M_GetCeilingTiltHeight(sky_sector, x, z); - - const SECTOR *const pit_sector = Room_GetPitSector(sector, x, z); - if (pit_sector->trigger == nullptr) { - return height; - } - - const TRIGGER_CMD *cmd = pit_sector->trigger->command; - for (; cmd != nullptr; cmd = cmd->next_cmd) { - if (cmd->type != TO_OBJECT) { - continue; - } - - const ITEM *const item = Item_Get((int16_t)(intptr_t)cmd->parameter); - const OBJECT *const obj = Object_Get(item->object_id); - if (obj->ceiling_height_func != nullptr) { - height = obj->ceiling_height_func(item, x, y, z, height); - } - } - - return height; -} - void Room_AlterFloorHeight(const ITEM *const item, const int32_t height) { int16_t room_num = item->room_num; diff --git a/src/tr2/game/room.h b/src/tr2/game/room.h index ecdda372d..460ec9732 100644 --- a/src/tr2/game/room.h +++ b/src/tr2/game/room.h @@ -15,13 +15,9 @@ int16_t Room_GetTiltType(const SECTOR *sector, int32_t x, int32_t y, int32_t z); // TODO: poor abstraction void Room_InitCinematic(void); -SECTOR *Room_GetPitSector(const SECTOR *sector, int32_t x, int32_t z); -SECTOR *Room_GetSkySector(const SECTOR *sector, int32_t x, int32_t z); SECTOR *Room_GetSector(int32_t x, int32_t y, int32_t z, int16_t *room_num); int32_t Room_GetWaterHeight(int32_t x, int32_t y, int32_t z, int16_t room_num); -int32_t Room_GetHeight(const SECTOR *sector, int32_t x, int32_t y, int32_t z); -int32_t Room_GetCeiling(const SECTOR *sector, int32_t x, int32_t y, int32_t z); void Room_TestTriggers(const ITEM *item); void Room_TestSectorTrigger(const ITEM *item, const SECTOR *sector); diff --git a/src/tr2/global/types_decomp.h b/src/tr2/global/types_decomp.h index 0ebd67542..83949787c 100644 --- a/src/tr2/global/types_decomp.h +++ b/src/tr2/global/types_decomp.h @@ -232,12 +232,6 @@ typedef enum { COLL_CLAMP = 0x20, } COLL_TYPE; -typedef enum { - HT_WALL = 0, - HT_SMALL_SLOPE = 1, - HT_BIG_SLOPE = 2, -} HEIGHT_TYPE; - typedef struct { int32_t boat_turn; int32_t left_fallspeed; diff --git a/src/tr2/global/vars.c b/src/tr2/global/vars.c index d5dfc9603..bda567bfd 100644 --- a/src/tr2/global/vars.c +++ b/src/tr2/global/vars.c @@ -64,7 +64,6 @@ LARA_INFO g_Lara; ITEM *g_LaraItem = nullptr; CREATURE *g_BaddieSlots = nullptr; -int32_t g_HeightType; bool g_CameraUnderwater; char g_LevelFileName[256]; @@ -265,7 +264,6 @@ REQUEST_INFO g_SaveGameRequester = { bool g_GF_RemoveAmmo = false; bool g_GF_RemoveWeapons = false; -int16_t g_GF_NoFloor = 0; int16_t g_GF_NumSecrets = 3; int32_t g_GF_LaraStartAnim; int32_t g_GF_ScriptVersion; diff --git a/src/tr2/global/vars.h b/src/tr2/global/vars.h index d966f5411..8d7b5c582 100644 --- a/src/tr2/global/vars.h +++ b/src/tr2/global/vars.h @@ -64,7 +64,6 @@ extern SAVEGAME_INFO g_SaveGame; extern LARA_INFO g_Lara; extern ITEM *g_LaraItem; extern CREATURE *g_BaddieSlots; -extern int32_t g_HeightType; extern bool g_CameraUnderwater; extern char g_LevelFileName[256]; extern WEAPON_INFO g_Weapons[]; @@ -77,7 +76,6 @@ extern REQUEST_INFO g_SaveGameRequester; extern bool g_GF_RemoveAmmo; extern bool g_GF_RemoveWeapons; -extern int16_t g_GF_NoFloor; extern int16_t g_GF_NumSecrets; extern int32_t g_GF_LaraStartAnim;