From 5de236b76e6e2f43fc1cc9a3c15816886f141f5f Mon Sep 17 00:00:00 2001
From: Sezz
Date: Mon, 14 Aug 2023 02:20:41 +1000
Subject: [PATCH 001/410] Prototype PointCollision class
---
TombEngine/Game/collision/PointCollision.cpp | 266 +++++++++++++++++++
TombEngine/Game/collision/PointCollision.h | 67 +++++
TombEngine/Game/collision/collide_room.cpp | 230 +++++++++-------
TombEngine/Game/collision/collide_room.h | 4 +
TombEngine/TombEngine.vcxproj | 2 +
5 files changed, 477 insertions(+), 92 deletions(-)
create mode 100644 TombEngine/Game/collision/PointCollision.cpp
create mode 100644 TombEngine/Game/collision/PointCollision.h
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
new file mode 100644
index 000000000..6b95ec912
--- /dev/null
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -0,0 +1,266 @@
+#include "framework.h"
+#include "Game/collision/PointCollision.h"
+
+#include "Game/collision/collide_room.h"
+#include "Game/collision/floordata.h"
+#include "Game/items.h"
+#include "Game/room.h"
+#include "Math/Math.h"
+#include "Specific/level.h"
+
+using namespace TEN::Collision::Floordata;
+using namespace TEN::Math;
+
+namespace TEN::Collision
+{
+ PointCollision::PointCollision(const Vector3i& pos, int roomNumber) :
+ Position(pos),
+ RoomNumber(roomNumber)
+ {
+ }
+
+ FloorInfo& PointCollision::nGetSector()
+ {
+ if (SectorPtr != nullptr)
+ return *SectorPtr;
+
+ // Set current sector pointer.
+ short probedRoomNumber = RoomNumber;
+ auto* sectorPtr = GetFloor(Position.x, Position.y, Position.z, &probedRoomNumber);
+ SectorPtr = sectorPtr;
+
+ return *SectorPtr;
+ }
+
+ FloorInfo& PointCollision::GetTopSector()
+ {
+ if (TopSectorPtr != nullptr)
+ return *TopSectorPtr;
+
+ // Set top sector pointer.
+ auto* topSectorPtr = &nGetSector();
+ while (topSectorPtr->GetRoomNumberAbove(Position.x, Position.y, Position.z).has_value())
+ {
+ auto roomNumberAbove = topSectorPtr->GetRoomNumberAbove(Position.x, Position.y, Position.z);
+ auto& room = g_Level.Rooms[roomNumberAbove.value_or(topSectorPtr->Room)];
+
+ topSectorPtr = GetSector(&room, Position.x - room.x, Position.z - room.z);
+ }
+ TopSectorPtr = topSectorPtr;
+
+ return *TopSectorPtr;
+ }
+
+ FloorInfo& PointCollision::GetBottomSector()
+ {
+ if (BottomSectorPtr != nullptr)
+ return *BottomSectorPtr;
+
+ // Set bottom sector pointer.
+ auto* bottomSectorPtr = &nGetSector();
+ while (bottomSectorPtr->GetRoomNumberBelow(Position.x, Position.y, Position.z).has_value())
+ {
+ auto roomNumberBelow = bottomSectorPtr->GetRoomNumberBelow(Position.x, Position.y, Position.z);
+ auto& room = g_Level.Rooms[roomNumberBelow.value_or(bottomSectorPtr->Room)];
+
+ bottomSectorPtr = GetSector(&room, Position.x - room.x, Position.z - room.z);
+ }
+ BottomSectorPtr = bottomSectorPtr;
+
+ return *BottomSectorPtr;
+ }
+
+ int PointCollision::nGetFloorHeight()
+ {
+ if (FloorHeight.has_value())
+ return *FloorHeight;
+
+ // Set floor height.
+ auto roomVector = ROOM_VECTOR{ SectorPtr->Room, Position.y };
+ FloorHeight = GetFloorHeight(roomVector, Position.x, Position.z).value_or(NO_HEIGHT);
+
+ return *FloorHeight;
+ }
+
+ int PointCollision::nGetCeilingHeight()
+ {
+ if (CeilingHeight.has_value())
+ return *CeilingHeight;
+
+ // Set ceiling height.
+ auto roomVector = ROOM_VECTOR{ SectorPtr->Room, Position.y };
+ CeilingHeight = GetCeilingHeight(roomVector, Position.x, Position.z).value_or(NO_HEIGHT);
+
+ return *CeilingHeight;
+ }
+
+ Vector3 PointCollision::GetFloorNormal()
+ {
+ if (FloorNormal.has_value())
+ return *FloorNormal;
+
+ // Set floor normal.
+ auto floorTilt = GetBottomSector().GetSurfaceTilt(Position.x, Position.z, true);
+ auto floorNormal = GetSurfaceNormal(floorTilt, true);
+ FloorNormal = floorNormal;
+
+ return *FloorNormal;
+ }
+
+ Vector3 PointCollision::GetCeilingNormal()
+ {
+ if (CeilingNormal.has_value())
+ return *CeilingNormal;
+
+ // Set ceiling normal.
+ auto ceilingTilt = GetTopSector().GetSurfaceTilt(Position.x, Position.z, false); // TODO: Check GetTopSector().
+ auto ceilingNormal = GetSurfaceNormal(ceilingTilt, false);
+ CeilingNormal = ceilingNormal;
+
+ return *CeilingNormal;
+ }
+
+ int PointCollision::GetBridgeItemNumber()
+ {
+ if (BridgeItemNumber.has_value())
+ return *BridgeItemNumber;
+
+ // Set bridge item number.
+ int floorHeight = nGetFloorHeight();
+ int bridgItemNumber = GetBottomSector().GetInsideBridgeItemNumber(Position.x, floorHeight, Position.z, true, false);
+ BridgeItemNumber = bridgItemNumber;
+
+ return *BridgeItemNumber;
+ }
+
+ float PointCollision::GetSplitAngle()
+ {
+ return GetBottomSector().FloorCollision.SplitAngle;
+ }
+
+ int PointCollision::GetWaterSurfaceHeight()
+ {
+ if (WaterSurfaceHeight.has_value())
+ return *WaterSurfaceHeight;
+
+ // Set water surface height.
+ WaterSurfaceHeight = GetWaterSurface(Position.x, Position.y, Position.z, RoomNumber);
+
+ return *WaterSurfaceHeight;
+ }
+
+ int PointCollision::GetWaterTopHeight()
+ {
+ if (WaterTopHeight.has_value())
+ return *WaterTopHeight;
+
+ // Set water top height.
+ WaterTopHeight = GetWaterHeight(Position.x, Position.y, Position.z, RoomNumber);
+
+ return *WaterTopHeight;
+ }
+
+ int PointCollision::GetWaterBottomHeight()
+ {
+ if (WaterBottomHeight.has_value())
+ return *WaterBottomHeight;
+
+ // Set water bottom height.
+ WaterBottomHeight = GetWaterDepth(Position.x, Position.y, Position.z, RoomNumber);
+
+ return *WaterBottomHeight;
+ }
+
+ bool PointCollision::IsWall()
+ {
+ return ((nGetFloorHeight() == NO_HEIGHT) || (nGetCeilingHeight() == NO_HEIGHT));
+ }
+
+ bool PointCollision::IsFloorSlope()
+ {
+ // Get floor slope angle.
+ auto floorNormal = GetFloorNormal();
+ auto slopeAngle = Geometry::GetSurfaceSlopeAngle(floorNormal);
+
+ return (GetBridgeItemNumber() == NO_ITEM && abs(slopeAngle) >= SLIPPERY_FLOOR_SLOPE_ANGLE);
+ }
+
+ bool PointCollision::IsCeilingSlope()
+ {
+ // Get ceiling slope angle.
+ auto ceilingNormal = GetCeilingNormal();
+ auto slopeAngle = Geometry::GetSurfaceSlopeAngle(ceilingNormal, -Vector3::UnitY);
+
+ return (abs(slopeAngle) >= SLIPPERY_CEILING_SLOPE_ANGLE);
+ }
+
+ bool PointCollision::IsDiagonalStep()
+ {
+ return GetBottomSector().IsSurfaceDiagonalStep(true);
+ }
+
+ bool PointCollision::HasDiagonalSplit()
+ {
+ constexpr auto DIAGONAL_SPLIT_0 = 45.0f * RADIAN;
+ constexpr auto DIAGONAL_SPLIT_1 = 135.0f * RADIAN;
+
+ return ((GetSplitAngle() == DIAGONAL_SPLIT_0) || (GetSplitAngle() == DIAGONAL_SPLIT_1));
+ }
+
+ bool PointCollision::HasFlippedDiagonalSplit()
+ {
+ constexpr auto DIAGONAL_SPLIT_0 = 45.0f * RADIAN;
+
+ return (HasDiagonalSplit() && (GetSplitAngle() != DIAGONAL_SPLIT_0));
+ }
+
+ bool PointCollision::HasEnvironmentFlag(RoomEnvFlags envFlag)
+ {
+ const auto& room = g_Level.Rooms[RoomNumber];
+ return ((room.flags & envFlag) == envFlag);
+ }
+
+ PointCollision GetPointCollision(const Vector3i& pos, int roomNumber)
+ {
+ return PointCollision(pos, roomNumber);
+ }
+
+ PointCollision GetPointCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down, float right)
+ {
+ short tempRoomNumber = roomNumber;
+ const auto& sector = *GetFloor(pos.x, pos.y, pos.z, &tempRoomNumber);
+
+ auto roomVector = ROOM_VECTOR{ sector.Room, pos.y };
+
+ auto probePos = Geometry::TranslatePoint(pos, headingAngle, forward, down, right);
+ int adjacentRoomNumber = GetRoom(roomVector, pos.x, probePos.y, pos.z).roomNumber;
+ return PointCollision(probePos, adjacentRoomNumber);
+ }
+
+ PointCollision GetPointCollision(const ItemInfo& item)
+ {
+ return PointCollision(item.Pose.Position, item.RoomNumber);
+ }
+
+ // TODO: Find cleaner solution. Constructing a room vector (sometimes dubbed "Location")
+ // on the spot for the player can result in a stumble when climbing onto thin platforms. -- Sezz 2022.06.14
+ static ROOM_VECTOR GetEntityRoomVector(const ItemInfo& item)
+ {
+ if (item.IsLara())
+ return item.Location;
+
+ short tempRoomNumber = item.RoomNumber;
+ const auto& sector = *GetFloor(item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z, &tempRoomNumber);
+
+ return ROOM_VECTOR{ sector.Room, item.Pose.Position.y };
+ }
+
+ PointCollision GetPointCollision(const ItemInfo& item, short headingAngle, float forward, float down, float right)
+ {
+ auto roomVector = GetEntityRoomVector(item);
+
+ auto probePos = Geometry::TranslatePoint(item.Pose.Position, headingAngle, forward, down, right);
+ int adjacentRoomNumber = GetRoom(roomVector, item.Pose.Position.x, probePos.y, item.Pose.Position.z).roomNumber;
+ return PointCollision(probePos, adjacentRoomNumber);
+ }
+}
diff --git a/TombEngine/Game/collision/PointCollision.h b/TombEngine/Game/collision/PointCollision.h
new file mode 100644
index 000000000..cf6b76c3b
--- /dev/null
+++ b/TombEngine/Game/collision/PointCollision.h
@@ -0,0 +1,67 @@
+#pragma once
+#include "Math/Math.h"
+
+enum RoomEnvFlags;
+class FloorInfo;
+
+using namespace TEN::Math;
+
+namespace TEN::Collision
+{
+ class PointCollision
+ {
+ public:
+ // Members
+ const Vector3i Position = Vector3i::Zero;
+ const int RoomNumber = 0;
+
+ private:
+ FloorInfo* SectorPtr = nullptr;
+ FloorInfo* TopSectorPtr = nullptr;
+ FloorInfo* BottomSectorPtr = nullptr;
+
+ std::optional FloorHeight = std::nullopt;
+ std::optional CeilingHeight = std::nullopt;
+ std::optional FloorNormal = std::nullopt;
+ std::optional CeilingNormal = std::nullopt;
+ std::optional BridgeItemNumber = std::nullopt;
+
+ std::optional WaterSurfaceHeight = std::nullopt;
+ std::optional WaterTopHeight = std::nullopt;
+ std::optional WaterBottomHeight = std::nullopt;
+
+ public:
+ // Constructors
+ PointCollision(const Vector3i& pos, int roomNumber);
+
+ // Getters
+ FloorInfo& nGetSector();
+ FloorInfo& GetTopSector();
+ FloorInfo& GetBottomSector();
+
+ int nGetFloorHeight();
+ int nGetCeilingHeight();
+ Vector3 GetFloorNormal();
+ Vector3 GetCeilingNormal();
+ int GetBridgeItemNumber();
+ float GetSplitAngle();
+
+ int GetWaterSurfaceHeight();
+ int GetWaterTopHeight();
+ int GetWaterBottomHeight();
+
+ // Inquirers
+ bool IsWall();
+ bool IsFloorSlope();
+ bool IsCeilingSlope();
+ bool IsDiagonalStep();
+ bool HasDiagonalSplit();
+ bool HasFlippedDiagonalSplit();
+ bool HasEnvironmentFlag(RoomEnvFlags envFlag);
+ };
+
+ PointCollision GetPointCollision(const Vector3i& pos, int roomNumber);
+ PointCollision GetPointCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down = 0.0f, float right = 0.0f);
+ PointCollision GetPointCollision(const ItemInfo& item);
+ PointCollision GetPointCollision(const ItemInfo& item, short headingAngle, float forward, float down = 0.0f, float right = 0.0f);
+}
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index f7b5f82da..3979e6ec9 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -4,6 +4,7 @@
#include "Game/control/box.h"
#include "Game/control/los.h"
#include "Game/collision/collide_item.h"
+#include "Game/collision/PointCollision.h"
#include "Game/animation.h"
#include "Game/Lara/lara.h"
#include "Game/items.h"
@@ -12,6 +13,7 @@
#include "Sound/sound.h"
#include "Renderer/Renderer11.h"
+using namespace TEN::Collision;
using namespace TEN::Collision::Floordata;
using namespace TEN::Math;
using namespace TEN::Renderer;
@@ -180,11 +182,26 @@ CollisionResult GetCollision(const Vector3i& pos, int roomNumber)
// Deprecated.
CollisionResult GetCollision(int x, int y, int z, short roomNumber)
{
- auto room = roomNumber;
- auto floor = GetFloor(x, y, z, &room);
- auto result = GetCollision(floor, x, y, z);
+ auto pointColl = GetPointCollision(Vector3i(x, y, z), roomNumber);
+
+ auto result = CollisionResult{};
+
+ result.Coordinates = pointColl.Position;
+ result.RoomNumber = pointColl.RoomNumber;
+ result.Block = &pointColl.nGetSector();
+ result.BottomBlock = &pointColl.GetBottomSector();
+
+ result.Position.Floor = pointColl.nGetFloorHeight();
+ result.Position.Ceiling = pointColl.nGetCeilingHeight();
+ result.Position.Bridge = pointColl.GetBridgeItemNumber();
+ result.Position.SplitAngle = pointColl.GetSplitAngle();
+ result.Position.FloorSlope = pointColl.IsFloorSlope();
+ result.Position.CeilingSlope = pointColl.IsCeilingSlope();
+ result.Position.DiagonalStep = pointColl.IsDiagonalStep();
+
+ result.FloorTilt = result.BottomBlock->GetSurfaceTilt(x, z, true);
+ result.CeilingTilt = result.BottomBlock->GetSurfaceTilt(x, z, false);
- result.RoomNumber = room;
return result;
}
@@ -207,7 +224,7 @@ CollisionResult GetCollision(FloorInfo* floor, int x, int y, int z)
// Return provided collision block into result as itself.
result.Block = floor;
-
+
// Floor and ceiling heights are borrowed directly from floordata.
result.Position.Floor = GetFloorHeight(ROOM_VECTOR{ floor->Room, y }, x, z).value_or(NO_HEIGHT);
result.Position.Ceiling = GetCeilingHeight(ROOM_VECTOR{ floor->Room, y }, x, z).value_or(NO_HEIGHT);
@@ -1193,31 +1210,31 @@ void AlterFloorHeight(ItemInfo* item, int height)
int GetWaterSurface(int x, int y, int z, short roomNumber)
{
- auto* room = &g_Level.Rooms[roomNumber];
- FloorInfo* floor = GetSector(room, x - room->x, z - room->z);
+ auto* roomPtr = &g_Level.Rooms[roomNumber];
+ auto* sectorPtr = GetSector(roomPtr, x - roomPtr->x, z - roomPtr->z);
- if (TestEnvironment(ENV_FLAG_WATER, room))
+ if (TestEnvironment(ENV_FLAG_WATER, roomPtr))
{
- while (floor->GetRoomNumberAbove(x, y, z).value_or(NO_ROOM) != NO_ROOM)
+ while (sectorPtr->GetRoomNumberAbove(x, y, z).value_or(NO_ROOM) != NO_ROOM)
{
- room = &g_Level.Rooms[floor->GetRoomNumberAbove(x, y, z).value_or(floor->Room)];
- if (!TestEnvironment(ENV_FLAG_WATER, room))
- return (floor->GetSurfaceHeight(x, z, false));
+ roomPtr = &g_Level.Rooms[sectorPtr->GetRoomNumberAbove(x, y, z).value_or(sectorPtr->Room)];
+ if (!TestEnvironment(ENV_FLAG_WATER, roomPtr))
+ return (sectorPtr->GetSurfaceHeight(x, z, false));
- floor = GetSector(room, x - room->x, z - room->z);
+ sectorPtr = GetSector(roomPtr, x - roomPtr->x, z - roomPtr->z);
}
return NO_HEIGHT;
}
else
{
- while (floor->GetRoomNumberBelow(x, y, z).value_or(NO_ROOM) != NO_ROOM)
+ while (sectorPtr->GetRoomNumberBelow(x, y, z).value_or(NO_ROOM) != NO_ROOM)
{
- room = &g_Level.Rooms[floor->GetRoomNumberBelow(x, y, z).value_or(floor->Room)];
- if (TestEnvironment(ENV_FLAG_WATER, room))
- return (floor->GetSurfaceHeight(x, z, true));
+ roomPtr = &g_Level.Rooms[sectorPtr->GetRoomNumberBelow(x, y, z).value_or(sectorPtr->Room)];
+ if (TestEnvironment(ENV_FLAG_WATER, roomPtr))
+ return (sectorPtr->GetSurfaceHeight(x, z, true));
- floor = GetSector(room, x - room->x, z - room->z);
+ sectorPtr = GetSector(roomPtr, x - roomPtr->x, z - roomPtr->z);
}
}
@@ -1231,81 +1248,93 @@ int GetWaterSurface(ItemInfo* item)
int GetWaterDepth(int x, int y, int z, short roomNumber)
{
- FloorInfo* floor;
- auto* room = &g_Level.Rooms[roomNumber];
+ FloorInfo* sectorPtr = nullptr;
+ auto* roomPtr = &g_Level.Rooms[roomNumber];
- short roomIndex = NO_ROOM;
+ int adjoiningRoomNumber = NO_ROOM;
do
{
- int zFloor = (z - room->z) / BLOCK(1);
- int xFloor = (x - room->x) / BLOCK(1);
+ int xFloor = (x - roomPtr->x) / BLOCK(1);
+ int zFloor = (z - roomPtr->z) / BLOCK(1);
if (zFloor <= 0)
{
zFloor = 0;
if (xFloor < 1)
+ {
xFloor = 1;
- else if (xFloor > room->xSize - 2)
- xFloor = room->xSize - 2;
+ }
+ else if (xFloor > (roomPtr->xSize - 2))
+ {
+ xFloor = roomPtr->xSize - 2;
+ }
}
- else if (zFloor >= room->zSize - 1)
+ else if (zFloor >= (roomPtr->zSize - 1))
{
- zFloor = room->zSize - 1;
+ zFloor = roomPtr->zSize - 1;
if (xFloor < 1)
+ {
xFloor = 1;
- else if (xFloor > room->xSize - 2)
- xFloor = room->xSize - 2;
+ }
+ else if (xFloor > (roomPtr->xSize - 2))
+ {
+ xFloor = roomPtr->xSize - 2;
+ }
}
else if (xFloor < 0)
- xFloor = 0;
- else if (xFloor >= room->xSize)
- xFloor = room->xSize - 1;
-
- floor = &room->floor[zFloor + xFloor * room->zSize];
- roomIndex = floor->WallPortal;
- if (roomIndex != NO_ROOM)
{
- roomNumber = roomIndex;
- room = &g_Level.Rooms[roomIndex];
+ xFloor = 0;
+ }
+ else if (xFloor >= roomPtr->xSize)
+ {
+ xFloor = roomPtr->xSize - 1;
+ }
+
+ sectorPtr = &roomPtr->floor[zFloor + (xFloor * roomPtr->zSize)];
+ adjoiningRoomNumber = sectorPtr->WallPortal;
+ if (adjoiningRoomNumber != NO_ROOM)
+ {
+ roomNumber = adjoiningRoomNumber;
+ roomPtr = &g_Level.Rooms[adjoiningRoomNumber];
}
}
- while (roomIndex != NO_ROOM);
+ while (adjoiningRoomNumber != NO_ROOM);
- if (TestEnvironment(ENV_FLAG_WATER, room) ||
- TestEnvironment(ENV_FLAG_SWAMP, room))
+ if (TestEnvironment(ENV_FLAG_WATER, roomPtr) ||
+ TestEnvironment(ENV_FLAG_SWAMP, roomPtr))
{
- while (floor->GetRoomNumberAbove(x, y, z).value_or(NO_ROOM) != NO_ROOM)
+ while (sectorPtr->GetRoomNumberAbove(x, y, z).value_or(NO_ROOM) != NO_ROOM)
{
- room = &g_Level.Rooms[floor->GetRoomNumberAbove(x, y, z).value_or(floor->Room)];
+ roomPtr = &g_Level.Rooms[sectorPtr->GetRoomNumberAbove(x, y, z).value_or(sectorPtr->Room)];
- if (!TestEnvironment(ENV_FLAG_WATER, room) &&
- !TestEnvironment(ENV_FLAG_SWAMP, room))
+ if (!TestEnvironment(ENV_FLAG_WATER, roomPtr) &&
+ !TestEnvironment(ENV_FLAG_SWAMP, roomPtr))
{
- int waterHeight = floor->GetSurfaceHeight(x, z, false);
- int floorHeight = GetCollision(floor, x, y, z).BottomBlock->GetSurfaceHeight(x, z, true);
+ int waterHeight = sectorPtr->GetSurfaceHeight(x, z, false);
+ int floorHeight = GetCollision(sectorPtr, x, y, z).BottomBlock->GetSurfaceHeight(x, z, true);
return (floorHeight - waterHeight);
}
- floor = GetSector(room, x - room->x, z - room->z);
+ sectorPtr = GetSector(roomPtr, x - roomPtr->x, z - roomPtr->z);
}
return DEEP_WATER;
}
else
{
- while (floor->GetRoomNumberBelow(x, y, z).value_or(NO_ROOM) != NO_ROOM)
+ while (sectorPtr->GetRoomNumberBelow(x, y, z).value_or(NO_ROOM) != NO_ROOM)
{
- room = &g_Level.Rooms[floor->GetRoomNumberBelow(x, y, z).value_or(floor->Room)];
+ roomPtr = &g_Level.Rooms[sectorPtr->GetRoomNumberBelow(x, y, z).value_or(sectorPtr->Room)];
- if (TestEnvironment(ENV_FLAG_WATER, room) ||
- TestEnvironment(ENV_FLAG_SWAMP, room))
+ if (TestEnvironment(ENV_FLAG_WATER, roomPtr) ||
+ TestEnvironment(ENV_FLAG_SWAMP, roomPtr))
{
- int waterHeight = floor->GetSurfaceHeight(x, z, true);
- floor = GetFloor(x, y, z, &roomNumber);
- return (GetFloorHeight(floor, x, y, z) - waterHeight);
+ int waterHeight = sectorPtr->GetSurfaceHeight(x, z, true);
+ sectorPtr = GetFloor(x, y, z, &roomNumber);
+ return (GetFloorHeight(sectorPtr, x, y, z) - waterHeight);
}
- floor = GetSector(room, x - room->x, z - room->z);
+ sectorPtr = GetSector(roomPtr, x - roomPtr->x, z - roomPtr->z);
}
return NO_HEIGHT;
@@ -1319,79 +1348,96 @@ int GetWaterDepth(ItemInfo* item)
int GetWaterHeight(int x, int y, int z, short roomNumber)
{
- auto* room = &g_Level.Rooms[roomNumber];
- FloorInfo* floor;
+ FloorInfo* sectorPtr = nullptr;
+ auto* roomPtr = &g_Level.Rooms[roomNumber];
- short adjoiningRoom = NO_ROOM;
+ int adjoiningRoomNumber = NO_ROOM;
do
{
- int xBlock = (x - room->x) / BLOCK(1);
- int zBlock = (z - room->z) / BLOCK(1);
+ int xBlock = (x - roomPtr->x) / BLOCK(1);
+ int zBlock = (z - roomPtr->z) / BLOCK(1);
if (zBlock <= 0)
{
zBlock = 0;
if (xBlock < 1)
+ {
xBlock = 1;
- else if (xBlock > room->xSize - 2)
- xBlock = room->xSize - 2;
+ }
+ else if (xBlock > (roomPtr->xSize - 2))
+ {
+ xBlock = roomPtr->xSize - 2;
+ }
}
- else if (zBlock >= room->zSize - 1)
+ else if (zBlock >= (roomPtr->zSize - 1))
{
- zBlock = room->zSize - 1;
+ zBlock = roomPtr->zSize - 1;
if (xBlock < 1)
+ {
xBlock = 1;
- else if (xBlock > room->xSize - 2)
- xBlock = room->xSize - 2;
+ }
+ else if (xBlock > (roomPtr->xSize - 2))
+ {
+ xBlock = roomPtr->xSize - 2;
+ }
}
else if (xBlock < 0)
- xBlock = 0;
- else if (xBlock >= room->xSize)
- xBlock = room->xSize - 1;
-
- floor = &room->floor[zBlock + xBlock * room->zSize];
- adjoiningRoom = floor->WallPortal;
-
- if (adjoiningRoom != NO_ROOM)
{
- roomNumber = adjoiningRoom;
- room = &g_Level.Rooms[adjoiningRoom];
+ xBlock = 0;
+ }
+ else if (xBlock >= roomPtr->xSize)
+ {
+ xBlock = roomPtr->xSize - 1;
}
- } while (adjoiningRoom != NO_ROOM);
- if (floor->IsWall(x, z))
+ sectorPtr = &roomPtr->floor[zBlock + (xBlock * roomPtr->zSize)];
+ adjoiningRoomNumber = sectorPtr->WallPortal;
+
+ if (adjoiningRoomNumber != NO_ROOM)
+ {
+ roomNumber = adjoiningRoomNumber;
+ roomPtr = &g_Level.Rooms[adjoiningRoomNumber];
+ }
+ }
+ while (adjoiningRoomNumber != NO_ROOM);
+
+ if (sectorPtr->IsWall(x, z))
return NO_HEIGHT;
- if (TestEnvironment(ENV_FLAG_WATER, room) ||
- TestEnvironment(ENV_FLAG_SWAMP, room))
+ if (TestEnvironment(ENV_FLAG_WATER, roomPtr) ||
+ TestEnvironment(ENV_FLAG_SWAMP, roomPtr))
{
- while (floor->GetRoomNumberAbove(x, y, z).value_or(NO_ROOM) != NO_ROOM)
+ while (sectorPtr->GetRoomNumberAbove(x, y, z).value_or(NO_ROOM) != NO_ROOM)
{
- auto* room = &g_Level.Rooms[floor->GetRoomNumberAbove(x, y, z).value_or(floor->Room)];
+ auto* room = &g_Level.Rooms[sectorPtr->GetRoomNumberAbove(x, y, z).value_or(sectorPtr->Room)];
if (!TestEnvironment(ENV_FLAG_WATER, room) &&
!TestEnvironment(ENV_FLAG_SWAMP, room))
+ {
break;
+ }
- floor = GetSector(room, x - room->x, z - room->z);
+ sectorPtr = GetSector(room, x - room->x, z - room->z);
}
- return GetCollision(floor, x, y, z).Block->GetSurfaceHeight(x, y, z, false);
+ return GetCollision(sectorPtr, x, y, z).Block->GetSurfaceHeight(x, y, z, false);
}
- else if (floor->GetRoomNumberBelow(x, y, z).value_or(NO_ROOM) != NO_ROOM)
+ else if (sectorPtr->GetRoomNumberBelow(x, y, z).value_or(NO_ROOM) != NO_ROOM)
{
- while (floor->GetRoomNumberBelow(x, y, z).value_or(NO_ROOM) != NO_ROOM)
+ while (sectorPtr->GetRoomNumberBelow(x, y, z).value_or(NO_ROOM) != NO_ROOM)
{
- auto* room2 = &g_Level.Rooms[floor->GetRoomNumberBelow(x, y, z).value_or(floor->Room)];
+ auto* roomPtr2 = &g_Level.Rooms[sectorPtr->GetRoomNumberBelow(x, y, z).value_or(sectorPtr->Room)];
- if (TestEnvironment(ENV_FLAG_WATER, room2) ||
- TestEnvironment(ENV_FLAG_SWAMP, room2))
+ if (TestEnvironment(ENV_FLAG_WATER, roomPtr2) ||
+ TestEnvironment(ENV_FLAG_SWAMP, roomPtr2))
+ {
break;
+ }
- floor = GetSector(room2, x - room2->x, z - room2->z);
+ sectorPtr = GetSector(roomPtr2, x - roomPtr2->x, z - roomPtr2->z);
}
- return GetCollision(floor, x, y, z).Block->GetSurfaceHeight(x, y, z, true);
+ return GetCollision(sectorPtr, x, y, z).Block->GetSurfaceHeight(x, y, z, true);
}
return NO_HEIGHT;
diff --git a/TombEngine/Game/collision/collide_room.h b/TombEngine/Game/collision/collide_room.h
index e13c8c6f3..5f286d8b9 100644
--- a/TombEngine/Game/collision/collide_room.h
+++ b/TombEngine/Game/collision/collide_room.h
@@ -13,6 +13,9 @@ constexpr auto NO_LOWER_BOUND = -NO_HEIGHT; // Used by coll->Setup.LowerFloorBou
constexpr auto NO_UPPER_BOUND = NO_HEIGHT; // Used by coll->Setup.UpperFloorBound.
constexpr auto COLLISION_CHECK_DISTANCE = BLOCK(8);
+constexpr auto SLIPPERY_FLOOR_SLOPE_ANGLE = short(ANGLE(45.0f) * 0.75f);
+constexpr auto SLIPPERY_CEILING_SLOPE_ANGLE = ANGLE(45.0f);
+
enum CollisionType
{
CT_NONE = 0,
@@ -126,6 +129,7 @@ struct CollisionInfo
[[nodiscard]] bool TestItemRoomCollisionAABB(ItemInfo* item);
+// All deprecated. Use GetPointCollision() instead.
CollisionResult GetCollision(const ItemInfo& item);
CollisionResult GetCollision(ItemInfo* item);
CollisionResult GetCollision(ItemInfo* item, short headingAngle, float forward, float down = 0.0f, float right = 0.0f);
diff --git a/TombEngine/TombEngine.vcxproj b/TombEngine/TombEngine.vcxproj
index 0d5ad7b92..90c5d8dc8 100644
--- a/TombEngine/TombEngine.vcxproj
+++ b/TombEngine/TombEngine.vcxproj
@@ -323,6 +323,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
+
@@ -786,6 +787,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
+
From de3ef5137863d916edc512dbcb54d493b6b16746 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Mon, 14 Aug 2023 02:28:54 +1000
Subject: [PATCH 002/410] Remove unneeded method
---
TombEngine/Game/collision/PointCollision.cpp | 11 ++++-------
TombEngine/Game/collision/PointCollision.h | 1 -
2 files changed, 4 insertions(+), 8 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 6b95ec912..1902b48e3 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -133,11 +133,6 @@ namespace TEN::Collision
return *BridgeItemNumber;
}
- float PointCollision::GetSplitAngle()
- {
- return GetBottomSector().FloorCollision.SplitAngle;
- }
-
int PointCollision::GetWaterSurfaceHeight()
{
if (WaterSurfaceHeight.has_value())
@@ -204,14 +199,16 @@ namespace TEN::Collision
constexpr auto DIAGONAL_SPLIT_0 = 45.0f * RADIAN;
constexpr auto DIAGONAL_SPLIT_1 = 135.0f * RADIAN;
- return ((GetSplitAngle() == DIAGONAL_SPLIT_0) || (GetSplitAngle() == DIAGONAL_SPLIT_1));
+ float splitAngle = GetBottomSector().FloorCollision.SplitAngle;
+ return ((splitAngle == DIAGONAL_SPLIT_0) || (splitAngle == DIAGONAL_SPLIT_1));
}
bool PointCollision::HasFlippedDiagonalSplit()
{
constexpr auto DIAGONAL_SPLIT_0 = 45.0f * RADIAN;
- return (HasDiagonalSplit() && (GetSplitAngle() != DIAGONAL_SPLIT_0));
+ float splitAngle = GetBottomSector().FloorCollision.SplitAngle;
+ return (HasDiagonalSplit() && (splitAngle != DIAGONAL_SPLIT_0));
}
bool PointCollision::HasEnvironmentFlag(RoomEnvFlags envFlag)
diff --git a/TombEngine/Game/collision/PointCollision.h b/TombEngine/Game/collision/PointCollision.h
index cf6b76c3b..327868692 100644
--- a/TombEngine/Game/collision/PointCollision.h
+++ b/TombEngine/Game/collision/PointCollision.h
@@ -44,7 +44,6 @@ namespace TEN::Collision
Vector3 GetFloorNormal();
Vector3 GetCeilingNormal();
int GetBridgeItemNumber();
- float GetSplitAngle();
int GetWaterSurfaceHeight();
int GetWaterTopHeight();
From a0aa4548b3837399ff6cea6705fad9db615dc948 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Mon, 14 Aug 2023 02:52:30 +1000
Subject: [PATCH 003/410] Move function into namespace to avoid name clash
---
TombEngine/Game/collision/PointCollision.cpp | 38 ++++++++++++-------
TombEngine/Game/collision/PointCollision.h | 6 +--
TombEngine/Game/collision/collide_room.cpp | 1 +
TombEngine/Game/control/box.cpp | 1 +
TombEngine/Game/control/lot.cpp | 2 +
TombEngine/Game/items.cpp | 3 +-
TombEngine/Game/room.cpp | 19 ++++++----
TombEngine/Game/room.h | 6 ++-
.../Objects/Generic/Doors/generic_doors.cpp | 1 +
.../Objects/TR5/Entity/tr5_gladiator.cpp | 1 +
.../Objects/TR5/Entity/tr5_roman_statue.cpp | 1 +
.../Objects/TR5/Object/tr5_pushableblock.cpp | 1 +
.../Objects/TR5/Shatter/tr5_smashobject.cpp | 2 +
13 files changed, 56 insertions(+), 26 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 1902b48e3..a3f140079 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -10,16 +10,28 @@
using namespace TEN::Collision::Floordata;
using namespace TEN::Math;
+using namespace TEN::Room;
namespace TEN::Collision
{
+ // TEMP: Wrappers to avoid name clashes.
+ static std::optional WrapGetFloorHeight(const ROOM_VECTOR& roomVector, int x, int z)
+ {
+ return GetFloorHeight(roomVector, x, z);
+ }
+
+ static std::optional WrapGetCeilingHeight(const ROOM_VECTOR& roomVector, int x, int z)
+ {
+ return GetCeilingHeight(roomVector, x, z);
+ }
+
PointCollision::PointCollision(const Vector3i& pos, int roomNumber) :
Position(pos),
RoomNumber(roomNumber)
{
}
- FloorInfo& PointCollision::nGetSector()
+ FloorInfo& PointCollision::GetSector()
{
if (SectorPtr != nullptr)
return *SectorPtr;
@@ -38,13 +50,13 @@ namespace TEN::Collision
return *TopSectorPtr;
// Set top sector pointer.
- auto* topSectorPtr = &nGetSector();
+ auto* topSectorPtr = &GetSector();
while (topSectorPtr->GetRoomNumberAbove(Position.x, Position.y, Position.z).has_value())
{
auto roomNumberAbove = topSectorPtr->GetRoomNumberAbove(Position.x, Position.y, Position.z);
auto& room = g_Level.Rooms[roomNumberAbove.value_or(topSectorPtr->Room)];
- topSectorPtr = GetSector(&room, Position.x - room.x, Position.z - room.z);
+ topSectorPtr = TEN::Room::GetSector(&room, Position.x - room.x, Position.z - room.z);
}
TopSectorPtr = topSectorPtr;
@@ -57,39 +69,39 @@ namespace TEN::Collision
return *BottomSectorPtr;
// Set bottom sector pointer.
- auto* bottomSectorPtr = &nGetSector();
+ auto* bottomSectorPtr = &GetSector();
while (bottomSectorPtr->GetRoomNumberBelow(Position.x, Position.y, Position.z).has_value())
{
auto roomNumberBelow = bottomSectorPtr->GetRoomNumberBelow(Position.x, Position.y, Position.z);
auto& room = g_Level.Rooms[roomNumberBelow.value_or(bottomSectorPtr->Room)];
- bottomSectorPtr = GetSector(&room, Position.x - room.x, Position.z - room.z);
+ bottomSectorPtr = TEN::Room::GetSector(&room, Position.x - room.x, Position.z - room.z);
}
BottomSectorPtr = bottomSectorPtr;
return *BottomSectorPtr;
}
- int PointCollision::nGetFloorHeight()
+ int PointCollision::GetFloorHeight()
{
if (FloorHeight.has_value())
return *FloorHeight;
// Set floor height.
- auto roomVector = ROOM_VECTOR{ SectorPtr->Room, Position.y };
- FloorHeight = GetFloorHeight(roomVector, Position.x, Position.z).value_or(NO_HEIGHT);
+ auto roomVector = ROOM_VECTOR{ GetSector().Room, Position.y };
+ FloorHeight = WrapGetFloorHeight(roomVector, Position.x, Position.z).value_or(NO_HEIGHT);
return *FloorHeight;
}
- int PointCollision::nGetCeilingHeight()
+ int PointCollision::GetCeilingHeight()
{
if (CeilingHeight.has_value())
return *CeilingHeight;
// Set ceiling height.
- auto roomVector = ROOM_VECTOR{ SectorPtr->Room, Position.y };
- CeilingHeight = GetCeilingHeight(roomVector, Position.x, Position.z).value_or(NO_HEIGHT);
+ auto roomVector = ROOM_VECTOR{ GetSector().Room, Position.y};
+ CeilingHeight = WrapGetCeilingHeight(roomVector, Position.x, Position.z).value_or(NO_HEIGHT);
return *CeilingHeight;
}
@@ -126,7 +138,7 @@ namespace TEN::Collision
return *BridgeItemNumber;
// Set bridge item number.
- int floorHeight = nGetFloorHeight();
+ int floorHeight = GetFloorHeight();
int bridgItemNumber = GetBottomSector().GetInsideBridgeItemNumber(Position.x, floorHeight, Position.z, true, false);
BridgeItemNumber = bridgItemNumber;
@@ -168,7 +180,7 @@ namespace TEN::Collision
bool PointCollision::IsWall()
{
- return ((nGetFloorHeight() == NO_HEIGHT) || (nGetCeilingHeight() == NO_HEIGHT));
+ return ((GetFloorHeight() == NO_HEIGHT) || (GetCeilingHeight() == NO_HEIGHT));
}
bool PointCollision::IsFloorSlope()
diff --git a/TombEngine/Game/collision/PointCollision.h b/TombEngine/Game/collision/PointCollision.h
index 327868692..fef3952d8 100644
--- a/TombEngine/Game/collision/PointCollision.h
+++ b/TombEngine/Game/collision/PointCollision.h
@@ -35,12 +35,12 @@ namespace TEN::Collision
PointCollision(const Vector3i& pos, int roomNumber);
// Getters
- FloorInfo& nGetSector();
+ FloorInfo& GetSector();
FloorInfo& GetTopSector();
FloorInfo& GetBottomSector();
- int nGetFloorHeight();
- int nGetCeilingHeight();
+ int GetFloorHeight();
+ int GetCeilingHeight();
Vector3 GetFloorNormal();
Vector3 GetCeilingNormal();
int GetBridgeItemNumber();
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index 3979e6ec9..bfc959d44 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -17,6 +17,7 @@ using namespace TEN::Collision;
using namespace TEN::Collision::Floordata;
using namespace TEN::Math;
using namespace TEN::Renderer;
+using namespace TEN::Room;
void ShiftItem(ItemInfo* item, CollisionInfo* coll)
{
diff --git a/TombEngine/Game/control/box.cpp b/TombEngine/Game/control/box.cpp
index 37b44690d..e265e53eb 100644
--- a/TombEngine/Game/control/box.cpp
+++ b/TombEngine/Game/control/box.cpp
@@ -23,6 +23,7 @@
#include "Renderer/Renderer11.h"
using namespace TEN::Effects::Smoke;
+using namespace TEN::Room;
constexpr auto ESCAPE_DIST = BLOCK(5);
constexpr auto STALK_DIST = BLOCK(3);
diff --git a/TombEngine/Game/control/lot.cpp b/TombEngine/Game/control/lot.cpp
index 66e06c183..373d70a76 100644
--- a/TombEngine/Game/control/lot.cpp
+++ b/TombEngine/Game/control/lot.cpp
@@ -10,6 +10,8 @@
#include "Game/Setup.h"
#include "Specific/level.h"
+using namespace TEN::Room;
+
#define DEFAULT_FLY_UPDOWN_SPEED 16
#define DEFAULT_SWIM_UPDOWN_SPEED 32
diff --git a/TombEngine/Game/items.cpp b/TombEngine/Game/items.cpp
index e574205be..7bd42c6f7 100644
--- a/TombEngine/Game/items.cpp
+++ b/TombEngine/Game/items.cpp
@@ -21,11 +21,12 @@
#include "Specific/level.h"
#include "Scripting/Internal/TEN/Objects/ObjectIDs.h"
+using namespace TEN::Collision::Floordata;
using namespace TEN::Control::Volumes;
using namespace TEN::Effects::Items;
-using namespace TEN::Collision::Floordata;
using namespace TEN::Input;
using namespace TEN::Math;
+using namespace TEN::Room;
constexpr int ITEM_DEATH_TIMEOUT = 4 * FPS;
diff --git a/TombEngine/Game/room.cpp b/TombEngine/Game/room.cpp
index ebc8f615b..aef5da31e 100644
--- a/TombEngine/Game/room.cpp
+++ b/TombEngine/Game/room.cpp
@@ -159,16 +159,19 @@ int IsRoomOutside(int x, int y, int z)
return NO_ROOM;
}
-FloorInfo* GetSector(ROOM_INFO* room, int x, int z)
+namespace TEN::Room
{
- int sectorX = std::clamp(x / BLOCK(1), 0, room->xSize - 1);
- int sectorZ = std::clamp(z / BLOCK(1), 0, room->zSize - 1);
+ FloorInfo* GetSector(ROOM_INFO* room, int x, int z)
+ {
+ int sectorX = std::clamp(x / BLOCK(1), 0, room->xSize - 1);
+ int sectorZ = std::clamp(z / BLOCK(1), 0, room->zSize - 1);
- int index = sectorZ + sectorX * room->zSize;
- if (index > room->floor.size())
- return nullptr;
-
- return &room->floor[index];
+ int index = sectorZ + sectorX * room->zSize;
+ if (index > room->floor.size())
+ return nullptr;
+
+ return &room->floor[index];
+ }
}
GameBoundingBox& GetBoundsAccurate(const MESH_INFO& mesh, bool visibility)
diff --git a/TombEngine/Game/room.h b/TombEngine/Game/room.h
index bb11ddc96..81a0570d0 100644
--- a/TombEngine/Game/room.h
+++ b/TombEngine/Game/room.h
@@ -155,4 +155,8 @@ std::set GetRoomList(int roomNumber);
void InitializeNeighborRoomList();
GameBoundingBox& GetBoundsAccurate(const MESH_INFO& mesh, bool visibility);
-FloorInfo* GetSector(ROOM_INFO* room, int x, int z);
+
+namespace TEN::Room
+{
+ FloorInfo* GetSector(ROOM_INFO* room, int x, int z);
+}
diff --git a/TombEngine/Objects/Generic/Doors/generic_doors.cpp b/TombEngine/Objects/Generic/Doors/generic_doors.cpp
index ec0fd8d29..94f6f3769 100644
--- a/TombEngine/Objects/Generic/Doors/generic_doors.cpp
+++ b/TombEngine/Objects/Generic/Doors/generic_doors.cpp
@@ -25,6 +25,7 @@
using namespace TEN::Gui;
using namespace TEN::Input;
+using namespace TEN::Room;
namespace TEN::Entities::Doors
{
diff --git a/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp b/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp
index 8b56bacc2..62efd7a60 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp
@@ -16,6 +16,7 @@
#include "Specific/level.h"
using namespace TEN::Math;
+using namespace TEN::Room;
namespace TEN::Entities::Creatures::TR5
{
diff --git a/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp b/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp
index 73be0c039..e94e48405 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp
@@ -23,6 +23,7 @@
using namespace TEN::Effects::Electricity;
using namespace TEN::Effects::Spark;
using namespace TEN::Math;
+using namespace TEN::Room;
namespace TEN::Entities::Creatures::TR5
{
diff --git a/TombEngine/Objects/TR5/Object/tr5_pushableblock.cpp b/TombEngine/Objects/TR5/Object/tr5_pushableblock.cpp
index fa4ecb2ae..aa629e109 100644
--- a/TombEngine/Objects/TR5/Object/tr5_pushableblock.cpp
+++ b/TombEngine/Objects/TR5/Object/tr5_pushableblock.cpp
@@ -17,6 +17,7 @@
using namespace TEN::Collision::Floordata;
using namespace TEN::Input;
+using namespace TEN::Room;
namespace TEN::Entities::Generic
{
diff --git a/TombEngine/Objects/TR5/Shatter/tr5_smashobject.cpp b/TombEngine/Objects/TR5/Shatter/tr5_smashobject.cpp
index 8ff5953de..4ed96e273 100644
--- a/TombEngine/Objects/TR5/Shatter/tr5_smashobject.cpp
+++ b/TombEngine/Objects/TR5/Shatter/tr5_smashobject.cpp
@@ -6,6 +6,8 @@
#include "Game/effects/tomb4fx.h"
#include "Game/items.h"
+using namespace TEN::Room;
+
void InitializeSmashObject(short itemNumber)
{
auto* item = &g_Level.Items[itemNumber];
From cf4429f7d72c0959f17fbfe0b38c0972be0e13b0 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Mon, 14 Aug 2023 03:01:04 +1000
Subject: [PATCH 004/410] Update collide_room.cpp
---
TombEngine/Game/collision/collide_room.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index bfc959d44..0be68e1e2 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -189,13 +189,13 @@ CollisionResult GetCollision(int x, int y, int z, short roomNumber)
result.Coordinates = pointColl.Position;
result.RoomNumber = pointColl.RoomNumber;
- result.Block = &pointColl.nGetSector();
+ result.Block = &pointColl.GetSector();
result.BottomBlock = &pointColl.GetBottomSector();
- result.Position.Floor = pointColl.nGetFloorHeight();
- result.Position.Ceiling = pointColl.nGetCeilingHeight();
+ result.Position.Floor = pointColl.GetFloorHeight();
+ result.Position.Ceiling = pointColl.GetCeilingHeight();
result.Position.Bridge = pointColl.GetBridgeItemNumber();
- result.Position.SplitAngle = pointColl.GetSplitAngle();
+ result.Position.SplitAngle = pointColl.GetBottomSector().FloorCollision.SplitAngle;
result.Position.FloorSlope = pointColl.IsFloorSlope();
result.Position.CeilingSlope = pointColl.IsCeilingSlope();
result.Position.DiagonalStep = pointColl.IsDiagonalStep();
From ffe819e4a68bf5890d1a55c6dbedda74132a9c70 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Mon, 14 Aug 2023 18:39:02 +1000
Subject: [PATCH 005/410] Update methods
---
TombEngine/Game/collision/PointCollision.cpp | 31 +++++++++++++++-----
1 file changed, 24 insertions(+), 7 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index a3f140079..7531bb10a 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -112,9 +112,17 @@ namespace TEN::Collision
return *FloorNormal;
// Set floor normal.
- auto floorTilt = GetBottomSector().GetSurfaceTilt(Position.x, Position.z, true);
- auto floorNormal = GetSurfaceNormal(floorTilt, true);
- FloorNormal = floorNormal;
+ if (GetBridgeItemNumber() != NO_ITEM)
+ {
+ // TODO: Get bridge normal.
+ FloorNormal = -Vector3::UnitY;
+ }
+ else
+ {
+ auto floorTilt = GetBottomSector().GetSurfaceTilt(Position.x, Position.z, true);
+ auto floorNormal = GetSurfaceNormal(floorTilt, true);
+ FloorNormal = floorNormal;
+ }
return *FloorNormal;
}
@@ -125,9 +133,18 @@ namespace TEN::Collision
return *CeilingNormal;
// Set ceiling normal.
- auto ceilingTilt = GetTopSector().GetSurfaceTilt(Position.x, Position.z, false); // TODO: Check GetTopSector().
- auto ceilingNormal = GetSurfaceNormal(ceilingTilt, false);
- CeilingNormal = ceilingNormal;
+ if (GetBridgeItemNumber() != NO_ITEM)
+ {
+ // TODO: Get bridge normal.
+ CeilingNormal = Vector3::UnitY;
+ }
+ else
+ {
+ // TODO: Check GetTopSector().
+ auto ceilingTilt = GetTopSector().GetSurfaceTilt(Position.x, Position.z, false);
+ auto ceilingNormal = GetSurfaceNormal(ceilingTilt, false);
+ CeilingNormal = ceilingNormal;
+ }
return *CeilingNormal;
}
@@ -189,7 +206,7 @@ namespace TEN::Collision
auto floorNormal = GetFloorNormal();
auto slopeAngle = Geometry::GetSurfaceSlopeAngle(floorNormal);
- return (GetBridgeItemNumber() == NO_ITEM && abs(slopeAngle) >= SLIPPERY_FLOOR_SLOPE_ANGLE);
+ return ((GetBridgeItemNumber() == NO_ITEM) && (abs(slopeAngle) >= SLIPPERY_FLOOR_SLOPE_ANGLE));
}
bool PointCollision::IsCeilingSlope()
From 5433a11297a70355cd06796f5844f7a158713a7f Mon Sep 17 00:00:00 2001
From: Sezz
Date: Mon, 14 Aug 2023 19:26:59 +1000
Subject: [PATCH 006/410] Move RoomVector struct
---
TombEngine/Game/Lara/lara.cpp | 4 +-
TombEngine/Game/Lara/lara_helpers.cpp | 4 +-
TombEngine/Game/Lara/lara_initialise.cpp | 4 +-
TombEngine/Game/Lara/lara_tests.cpp | 8 +-
TombEngine/Game/collision/PointCollision.cpp | 18 +--
TombEngine/Game/collision/collide_room.cpp | 40 +++----
TombEngine/Game/collision/collide_room.h | 1 -
TombEngine/Game/collision/floordata.cpp | 110 +++++++++---------
TombEngine/Game/collision/floordata.h | 24 +++-
TombEngine/Game/effects/bubble.cpp | 4 +-
TombEngine/Game/items.h | 2 +-
TombEngine/Game/savegame.cpp | 4 +-
TombEngine/Renderer/Renderer11DrawMenu.cpp | 2 +-
.../TEN/Objects/Moveable/MoveableObject.cpp | 2 +-
TombEngine/Specific/newtypes.h | 6 -
15 files changed, 120 insertions(+), 113 deletions(-)
diff --git a/TombEngine/Game/Lara/lara.cpp b/TombEngine/Game/Lara/lara.cpp
index 0f95a18df..9608309f1 100644
--- a/TombEngine/Game/Lara/lara.cpp
+++ b/TombEngine/Game/Lara/lara.cpp
@@ -1186,9 +1186,9 @@ bool UpdateLaraRoom(ItemInfo* item, int height, int xOffset, int zOffset)
item->Location = GetRoom(item->Location, item->Pose.Position.x, point.y, item->Pose.Position.z);
item->Floor = GetFloorHeight(item->Location, item->Pose.Position.x, item->Pose.Position.z).value_or(NO_HEIGHT);
- if (item->RoomNumber != item->Location.roomNumber)
+ if (item->RoomNumber != item->Location.RoomNumber)
{
- ItemNewRoom(item->Index, item->Location.roomNumber);
+ ItemNewRoom(item->Index, item->Location.RoomNumber);
return true;
}
diff --git a/TombEngine/Game/Lara/lara_helpers.cpp b/TombEngine/Game/Lara/lara_helpers.cpp
index ffd2da09f..75ed0e3d5 100644
--- a/TombEngine/Game/Lara/lara_helpers.cpp
+++ b/TombEngine/Game/Lara/lara_helpers.cpp
@@ -534,7 +534,7 @@ void HandlePlayerWetnessDrips(ItemInfo& item)
for (auto& node : player.Effect.DripNodes)
{
auto pos = GetJointPosition(&item, jointIndex).ToVector3();
- int roomNumber = GetRoom(item.Location, pos.x, pos.y, pos.z).roomNumber;
+ int roomNumber = GetRoom(item.Location, pos.x, pos.y, pos.z).RoomNumber;
jointIndex++;
// Node underwater; set max wetness value.
@@ -571,7 +571,7 @@ void HandlePlayerDiveBubbles(ItemInfo& item)
for (auto& node : player.Effect.BubbleNodes)
{
auto pos = GetJointPosition(&item, jointIndex).ToVector3();
- int roomNumber = GetRoom(item.Location, pos.x, pos.y, pos.z).roomNumber;
+ int roomNumber = GetRoom(item.Location, pos.x, pos.y, pos.z).RoomNumber;
jointIndex++;
// Node inactive; continue.
diff --git a/TombEngine/Game/Lara/lara_initialise.cpp b/TombEngine/Game/Lara/lara_initialise.cpp
index e6cef9199..752b3a615 100644
--- a/TombEngine/Game/Lara/lara_initialise.cpp
+++ b/TombEngine/Game/Lara/lara_initialise.cpp
@@ -33,8 +33,8 @@ void InitializeLara(bool restore)
LaraItem->Data = &Lara;
LaraItem->Collidable = false;
- LaraItem->Location.roomNumber = LaraItem->RoomNumber;
- LaraItem->Location.yNumber = LaraItem->Pose.Position.y;
+ LaraItem->Location.RoomNumber = LaraItem->RoomNumber;
+ LaraItem->Location.Height = LaraItem->Pose.Position.y;
Lara.Status.Air = LARA_AIR_MAX;
Lara.Status.Exposure = LARA_EXPOSURE_MAX;
diff --git a/TombEngine/Game/Lara/lara_tests.cpp b/TombEngine/Game/Lara/lara_tests.cpp
index 6e172c83c..6e3ab8e27 100644
--- a/TombEngine/Game/Lara/lara_tests.cpp
+++ b/TombEngine/Game/Lara/lara_tests.cpp
@@ -43,8 +43,8 @@ bool TestValidLedge(ItemInfo* item, CollisionInfo* coll, bool ignoreHeadroom, bo
int y = item->Pose.Position.y - coll->Setup.Height;
// Get frontal collision data
- auto frontLeft = GetCollision(item->Pose.Position.x + xl, y, item->Pose.Position.z + zl, GetRoom(item->Location, item->Pose.Position.x, y, item->Pose.Position.z).roomNumber);
- auto frontRight = GetCollision(item->Pose.Position.x + xr, y, item->Pose.Position.z + zr, GetRoom(item->Location, item->Pose.Position.x, y, item->Pose.Position.z).roomNumber);
+ auto frontLeft = GetCollision(item->Pose.Position.x + xl, y, item->Pose.Position.z + zl, GetRoom(item->Location, item->Pose.Position.x, y, item->Pose.Position.z).RoomNumber);
+ auto frontRight = GetCollision(item->Pose.Position.x + xr, y, item->Pose.Position.z + zr, GetRoom(item->Location, item->Pose.Position.x, y, item->Pose.Position.z).RoomNumber);
// If any of the frontal collision results intersects item bounds, return false, because there is material intersection.
// This check helps to filter out cases when Lara is formally facing corner but ledge check returns true because probe distance is fixed.
@@ -63,8 +63,8 @@ bool TestValidLedge(ItemInfo* item, CollisionInfo* coll, bool ignoreHeadroom, bo
int zf = phd_cos(coll->NearestLedgeAngle) * (coll->Setup.Radius * 1.2f);
// Get floor heights at both points
- auto left = GetCollision(item->Pose.Position.x + xf + xl, y, item->Pose.Position.z + zf + zl, GetRoom(item->Location, item->Pose.Position.x, y, item->Pose.Position.z).roomNumber).Position.Floor;
- auto right = GetCollision(item->Pose.Position.x + xf + xr, y, item->Pose.Position.z + zf + zr, GetRoom(item->Location, item->Pose.Position.x, y, item->Pose.Position.z).roomNumber).Position.Floor;
+ auto left = GetCollision(item->Pose.Position.x + xf + xl, y, item->Pose.Position.z + zf + zl, GetRoom(item->Location, item->Pose.Position.x, y, item->Pose.Position.z).RoomNumber).Position.Floor;
+ auto right = GetCollision(item->Pose.Position.x + xf + xr, y, item->Pose.Position.z + zf + zr, GetRoom(item->Location, item->Pose.Position.x, y, item->Pose.Position.z).RoomNumber).Position.Floor;
// If specified, limit vertical search zone only to nearest height
if (heightLimit && (abs(left - y) > CLICK(0.5f) || abs(right - y) > CLICK(0.5f)))
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 7531bb10a..24709da29 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -15,12 +15,12 @@ using namespace TEN::Room;
namespace TEN::Collision
{
// TEMP: Wrappers to avoid name clashes.
- static std::optional WrapGetFloorHeight(const ROOM_VECTOR& roomVector, int x, int z)
+ static std::optional WrapGetFloorHeight(const RoomVector& roomVector, int x, int z)
{
return GetFloorHeight(roomVector, x, z);
}
- static std::optional WrapGetCeilingHeight(const ROOM_VECTOR& roomVector, int x, int z)
+ static std::optional WrapGetCeilingHeight(const RoomVector& roomVector, int x, int z)
{
return GetCeilingHeight(roomVector, x, z);
}
@@ -88,7 +88,7 @@ namespace TEN::Collision
return *FloorHeight;
// Set floor height.
- auto roomVector = ROOM_VECTOR{ GetSector().Room, Position.y };
+ auto roomVector = RoomVector(GetSector().Room, Position.y);
FloorHeight = WrapGetFloorHeight(roomVector, Position.x, Position.z).value_or(NO_HEIGHT);
return *FloorHeight;
@@ -100,7 +100,7 @@ namespace TEN::Collision
return *CeilingHeight;
// Set ceiling height.
- auto roomVector = ROOM_VECTOR{ GetSector().Room, Position.y};
+ auto roomVector = RoomVector(GetSector().Room, Position.y);
CeilingHeight = WrapGetCeilingHeight(roomVector, Position.x, Position.z).value_or(NO_HEIGHT);
return *CeilingHeight;
@@ -256,10 +256,10 @@ namespace TEN::Collision
short tempRoomNumber = roomNumber;
const auto& sector = *GetFloor(pos.x, pos.y, pos.z, &tempRoomNumber);
- auto roomVector = ROOM_VECTOR{ sector.Room, pos.y };
+ auto roomVector = RoomVector(sector.Room, pos.y);
auto probePos = Geometry::TranslatePoint(pos, headingAngle, forward, down, right);
- int adjacentRoomNumber = GetRoom(roomVector, pos.x, probePos.y, pos.z).roomNumber;
+ int adjacentRoomNumber = GetRoom(roomVector, pos.x, probePos.y, pos.z).RoomNumber;
return PointCollision(probePos, adjacentRoomNumber);
}
@@ -270,7 +270,7 @@ namespace TEN::Collision
// TODO: Find cleaner solution. Constructing a room vector (sometimes dubbed "Location")
// on the spot for the player can result in a stumble when climbing onto thin platforms. -- Sezz 2022.06.14
- static ROOM_VECTOR GetEntityRoomVector(const ItemInfo& item)
+ static RoomVector GetEntityRoomVector(const ItemInfo& item)
{
if (item.IsLara())
return item.Location;
@@ -278,7 +278,7 @@ namespace TEN::Collision
short tempRoomNumber = item.RoomNumber;
const auto& sector = *GetFloor(item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z, &tempRoomNumber);
- return ROOM_VECTOR{ sector.Room, item.Pose.Position.y };
+ return RoomVector(sector.Room, item.Pose.Position.y);
}
PointCollision GetPointCollision(const ItemInfo& item, short headingAngle, float forward, float down, float right)
@@ -286,7 +286,7 @@ namespace TEN::Collision
auto roomVector = GetEntityRoomVector(item);
auto probePos = Geometry::TranslatePoint(item.Pose.Position, headingAngle, forward, down, right);
- int adjacentRoomNumber = GetRoom(roomVector, item.Pose.Position.x, probePos.y, item.Pose.Position.z).roomNumber;
+ int adjacentRoomNumber = GetRoom(roomVector, item.Pose.Position.x, probePos.y, item.Pose.Position.z).RoomNumber;
return PointCollision(probePos, adjacentRoomNumber);
}
}
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index 0be68e1e2..0b91a8356 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -142,10 +142,10 @@ CollisionResult GetCollision(ItemInfo* item, short headingAngle, float forward,
// TODO: Find cleaner solution. Constructing a Location for Lara on the spot can result in a stumble when climbing onto thin platforms. -- Sezz 2022.06.14
auto location = item->IsLara() ?
item->Location :
- ROOM_VECTOR{ GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &tempRoomNumber)->Room, item->Pose.Position.y };
+ RoomVector(GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &tempRoomNumber)->Room, item->Pose.Position.y);
auto point = Geometry::TranslatePoint(item->Pose.Position, headingAngle, forward, down, right);
- int adjacentRoomNumber = GetRoom(location, item->Pose.Position.x, point.y, item->Pose.Position.z).roomNumber;
+ int adjacentRoomNumber = GetRoom(location, item->Pose.Position.x, point.y, item->Pose.Position.z).RoomNumber;
return GetCollision(point.x, point.y, point.z, adjacentRoomNumber);
}
@@ -153,10 +153,10 @@ CollisionResult GetCollision(ItemInfo* item, short headingAngle, float forward,
CollisionResult GetCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down, float right)
{
short tempRoomNumber = roomNumber;
- auto location = ROOM_VECTOR{ GetFloor(pos.x, pos.y, pos.z, &tempRoomNumber)->Room, pos.y };
+ auto location = RoomVector(GetFloor(pos.x, pos.y, pos.z, &tempRoomNumber)->Room, pos.y);
auto point = Geometry::TranslatePoint(pos, headingAngle, forward, down, right);
- int adjacentRoomNumber = GetRoom(location, pos.x, point.y, pos.z).roomNumber;
+ int adjacentRoomNumber = GetRoom(location, pos.x, point.y, pos.z).RoomNumber;
return GetCollision(point.x, point.y, point.z, adjacentRoomNumber);
}
@@ -165,8 +165,8 @@ CollisionResult GetCollision(const Vector3i& pos, int roomNumber, const EulerAng
auto point = Geometry::TranslatePoint(pos, orient, dist);
short tempRoomNumber = roomNumber;
- auto location = ROOM_VECTOR{ GetFloor(pos.x, pos.y, pos.z, &tempRoomNumber)->Room, pos.y };
- int adjacentRoomNumber = GetRoom(location, pos.x, point.y, pos.z).roomNumber;
+ auto location = RoomVector{ GetFloor(pos.x, pos.y, pos.z, &tempRoomNumber)->Room, pos.y };
+ int adjacentRoomNumber = GetRoom(location, pos.x, point.y, pos.z).RoomNumber;
return GetCollision(point.x, point.y, point.z, adjacentRoomNumber);
}
@@ -227,8 +227,8 @@ CollisionResult GetCollision(FloorInfo* floor, int x, int y, int z)
result.Block = floor;
// Floor and ceiling heights are borrowed directly from floordata.
- result.Position.Floor = GetFloorHeight(ROOM_VECTOR{ floor->Room, y }, x, z).value_or(NO_HEIGHT);
- result.Position.Ceiling = GetCeilingHeight(ROOM_VECTOR{ floor->Room, y }, x, z).value_or(NO_HEIGHT);
+ result.Position.Floor = GetFloorHeight(RoomVector(floor->Room, y), x, z).value_or(NO_HEIGHT);
+ result.Position.Ceiling = GetCeilingHeight(RoomVector(floor->Room, y), x, z).value_or(NO_HEIGHT);
// Probe bottom collision block through portals.
while (floor->GetRoomNumberBelow(x, y, z).value_or(NO_ROOM) != NO_ROOM)
@@ -377,19 +377,19 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
}
// Define generic variables used for later object-specific position test shifts.
- ROOM_VECTOR tfLocation{}, tcLocation{}, lrfLocation{}, lrcLocation{};
+ RoomVector tfLocation, tcLocation, lrfLocation, lrcLocation;
int height, ceiling;
// Parameter definition ends here, now process to actual collision tests...
// HACK: when using SetPosition animcommand, item->RoomNumber does not immediately
// update, but only at the end of control loop. This may cause bugs when Lara is
- // climbing or vaulting ledges under slopes. Using Location->roomNumber solves
- // these bugs, as it is updated immediately. But since Location->roomNumber is ONLY
+ // climbing or vaulting ledges under slopes. Using Location->RoomNumber solves
+ // these bugs, as it is updated immediately. But since Location->RoomNumber is ONLY
// updated for Lara, we can't use it for all objects for now. In future, we should
// either update Location field for all objects or use this value as it is now.
- int realRoomNumber = doPlayerCollision ? item->Location.roomNumber : item->RoomNumber;
+ int realRoomNumber = doPlayerCollision ? item->Location.RoomNumber : item->RoomNumber;
// TEST 1: TILT AND NEAREST LEDGE CALCULATION
@@ -921,12 +921,12 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance)
float maxZ = ceil(ffpZ / BLOCK(1)) * BLOCK(1) + 1.0f;
// Get front floor block
- auto room = GetRoom(item->Location, ffpX, y, ffpZ).roomNumber;
+ auto room = GetRoom(item->Location, ffpX, y, ffpZ).RoomNumber;
auto block = GetCollision(ffpX, y, ffpZ, room).Block;
// Get front floor surface heights
- auto floorHeight = GetFloorHeight(ROOM_VECTOR{ block->Room, y }, ffpX, ffpZ).value_or(NO_HEIGHT);
- auto ceilingHeight = GetCeilingHeight(ROOM_VECTOR{ block->Room, y }, ffpX, ffpZ).value_or(NO_HEIGHT);
+ auto floorHeight = GetFloorHeight(RoomVector(block->Room, y), ffpX, ffpZ).value_or(NO_HEIGHT);
+ auto ceilingHeight = GetCeilingHeight(RoomVector(block->Room, y), ffpX, ffpZ).value_or(NO_HEIGHT);
// If probe landed inside wall (i.e. both floor/ceiling heights are NO_HEIGHT), make a fake
// ledge for algorithm to further succeed.
@@ -951,7 +951,7 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance)
// g_Renderer.AddDebugSphere(Vector3(fpX, y, fpZ), 16, Vector4(0, 1, 0, 1), RendererDebugPage::CollisionStats);
// Get true room number and block, based on derived height
- room = GetRoom(item->Location, fpX, height, fpZ).roomNumber;
+ room = GetRoom(item->Location, fpX, height, fpZ).RoomNumber;
block = GetCollision(fpX, height, fpZ, room).Block;
// We don't need actual corner heights to build planes, so just use normalized value here.
@@ -1150,19 +1150,19 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance)
FloorInfo* GetFloor(int x, int y, int z, short* roomNumber)
{
- const auto location = GetRoom(ROOM_VECTOR{ *roomNumber, y }, x, y, z);
- *roomNumber = location.roomNumber;
+ const auto location = GetRoom(RoomVector{ *roomNumber, y }, x, y, z);
+ *roomNumber = location.RoomNumber;
return &GetFloor(*roomNumber, x, z);
}
int GetFloorHeight(FloorInfo* floor, int x, int y, int z)
{
- return GetFloorHeight(ROOM_VECTOR{ floor->Room, y }, x, z).value_or(NO_HEIGHT);
+ return GetFloorHeight(RoomVector(floor->Room, y), x, z).value_or(NO_HEIGHT);
}
int GetCeiling(FloorInfo* floor, int x, int y, int z)
{
- return GetCeilingHeight(ROOM_VECTOR{ floor->Room, y }, x, z).value_or(NO_HEIGHT);
+ return GetCeilingHeight(RoomVector(floor->Room, y), x, z).value_or(NO_HEIGHT);
}
int GetDistanceToFloor(int itemNumber, bool precise)
diff --git a/TombEngine/Game/collision/collide_room.h b/TombEngine/Game/collision/collide_room.h
index 5f286d8b9..74cd6fd0e 100644
--- a/TombEngine/Game/collision/collide_room.h
+++ b/TombEngine/Game/collision/collide_room.h
@@ -172,4 +172,3 @@ bool TestEnvironment(RoomEnvFlags environmentType, ItemInfo* item);
bool TestEnvironment(RoomEnvFlags environmentType, int roomNumber);
bool TestEnvironment(RoomEnvFlags environmentType, ROOM_INFO* room);
bool TestEnvironmentFlags(RoomEnvFlags environmentType, int flags);
-
diff --git a/TombEngine/Game/collision/floordata.cpp b/TombEngine/Game/collision/floordata.cpp
index cbe2cdbbc..b03d921d3 100644
--- a/TombEngine/Game/collision/floordata.cpp
+++ b/TombEngine/Game/collision/floordata.cpp
@@ -484,15 +484,15 @@ namespace TEN::Collision::Floordata
return pos.y;
}
- std::optional GetFloorHeight(const ROOM_VECTOR& location, int x, int z)
+ std::optional GetFloorHeight(const RoomVector& location, int x, int z)
{
- auto floor = &GetFloorSide(location.roomNumber, x, z);
- auto y = location.yNumber;
+ auto floor = &GetFloorSide(location.RoomNumber, x, z);
+ auto y = location.Height;
auto direction = 0;
if (floor->IsWall(x, z))
{
- floor = &GetTopFloor(location.roomNumber, x, z);
+ floor = &GetTopFloor(location.RoomNumber, x, z);
if (!floor->IsWall(x, z))
{
@@ -501,7 +501,7 @@ namespace TEN::Collision::Floordata
}
else
{
- floor = &GetBottomFloor(location.roomNumber, x, z);
+ floor = &GetBottomFloor(location.RoomNumber, x, z);
if (!floor->IsWall(x, z))
{
@@ -550,15 +550,15 @@ namespace TEN::Collision::Floordata
return std::optional{floor->GetSurfaceHeight(x, y, z, true)};
}
- std::optional GetCeilingHeight(const ROOM_VECTOR& location, int x, int z)
+ std::optional GetCeilingHeight(const RoomVector& location, int x, int z)
{
- auto floor = &GetFloorSide(location.roomNumber, x, z);
- auto y = location.yNumber;
+ auto floor = &GetFloorSide(location.RoomNumber, x, z);
+ auto y = location.Height;
auto direction = 0;
if (floor->IsWall(x, z))
{
- floor = &GetBottomFloor(location.roomNumber, x, z);
+ floor = &GetBottomFloor(location.RoomNumber, x, z);
if (!floor->IsWall(x, z))
{
@@ -567,7 +567,7 @@ namespace TEN::Collision::Floordata
}
else
{
- floor = &GetTopFloor(location.roomNumber, x, z);
+ floor = &GetTopFloor(location.RoomNumber, x, z);
if (!floor->IsWall(x, z))
{
@@ -616,131 +616,131 @@ namespace TEN::Collision::Floordata
return std::optional{floor->GetSurfaceHeight(x, y, z, false)};
}
- std::optional GetBottomRoom(ROOM_VECTOR location, int x, int y, int z)
+ std::optional GetBottomRoom(RoomVector location, int x, int y, int z)
{
- auto floor = &GetFloorSide(location.roomNumber, x, z, &location.roomNumber);
+ auto floor = &GetFloorSide(location.RoomNumber, x, z, &location.RoomNumber);
if (floor->IsWall(x, z))
{
- floor = &GetBottomFloor(location.roomNumber, x, z, &location.roomNumber);
+ floor = &GetBottomFloor(location.RoomNumber, x, z, &location.RoomNumber);
if (floor->IsWall(x, z))
return std::nullopt;
- location.yNumber = floor->GetSurfaceHeight(x, z, false);
+ location.Height = floor->GetSurfaceHeight(x, z, false);
}
- auto floorHeight = floor->GetSurfaceHeight(x, location.yNumber, z, true);
- auto ceilingHeight = floor->GetSurfaceHeight(x, location.yNumber, z, false);
+ auto floorHeight = floor->GetSurfaceHeight(x, location.Height, z, true);
+ auto ceilingHeight = floor->GetSurfaceHeight(x, location.Height, z, false);
- location.yNumber = std::clamp(location.yNumber, std::min(ceilingHeight, floorHeight), std::max(ceilingHeight, floorHeight));
+ location.Height = std::clamp(location.Height, std::min(ceilingHeight, floorHeight), std::max(ceilingHeight, floorHeight));
- if (floor->GetInsideBridgeItemNumber(x, location.yNumber, z, location.yNumber == ceilingHeight, location.yNumber == floorHeight) >= 0)
+ if (floor->GetInsideBridgeItemNumber(x, location.Height, z, location.Height == ceilingHeight, location.Height == floorHeight) >= 0)
{
- const auto height = GetBottomHeight(*floor, Vector3i(x, location.yNumber, z), &location.roomNumber, &floor);
+ const auto height = GetBottomHeight(*floor, Vector3i(x, location.Height, z), &location.RoomNumber, &floor);
if (!height)
return std::nullopt;
- location.yNumber = *height;
+ location.Height = *height;
}
- floorHeight = floor->GetSurfaceHeight(x, location.yNumber, z, true);
- ceilingHeight = floor->GetSurfaceHeight(x, location.yNumber, z, false);
+ floorHeight = floor->GetSurfaceHeight(x, location.Height, z, true);
+ ceilingHeight = floor->GetSurfaceHeight(x, location.Height, z, false);
- if (y < ceilingHeight && floor->GetRoomNumberAbove(x, location.yNumber, z))
+ if (y < ceilingHeight && floor->GetRoomNumberAbove(x, location.Height, z))
return std::nullopt;
if (y <= floorHeight)
{
- location.yNumber = std::max(y, ceilingHeight);
+ location.Height = std::max(y, ceilingHeight);
return std::optional{location};
}
- auto roomBelow = floor->GetRoomNumberBelow(x, location.yNumber, z);
+ auto roomBelow = floor->GetRoomNumberBelow(x, location.Height, z);
while (roomBelow)
{
- floor = &GetFloorSide(*roomBelow, x, z, &location.roomNumber);
- location.yNumber = floor->GetSurfaceHeight(x, z, false);
+ floor = &GetFloorSide(*roomBelow, x, z, &location.RoomNumber);
+ location.Height = floor->GetSurfaceHeight(x, z, false);
- floorHeight = floor->GetSurfaceHeight(x, location.yNumber, z, true);
- ceilingHeight = floor->GetSurfaceHeight(x, location.yNumber, z, false);
+ floorHeight = floor->GetSurfaceHeight(x, location.Height, z, true);
+ ceilingHeight = floor->GetSurfaceHeight(x, location.Height, z, false);
- if (y < ceilingHeight && floor->GetRoomNumberAbove(x, location.yNumber, z))
+ if (y < ceilingHeight && floor->GetRoomNumberAbove(x, location.Height, z))
return std::nullopt;
if (y <= floorHeight)
{
- location.yNumber = std::max(y, ceilingHeight);
+ location.Height = std::max(y, ceilingHeight);
return std::optional{location};
}
- roomBelow = floor->GetRoomNumberBelow(x, location.yNumber, z);
+ roomBelow = floor->GetRoomNumberBelow(x, location.Height, z);
}
return std::nullopt;
}
- std::optional GetTopRoom(ROOM_VECTOR location, int x, int y, int z)
+ std::optional GetTopRoom(RoomVector location, int x, int y, int z)
{
- auto floor = &GetFloorSide(location.roomNumber, x, z, &location.roomNumber);
+ auto floor = &GetFloorSide(location.RoomNumber, x, z, &location.RoomNumber);
if (floor->IsWall(x, z))
{
- floor = &GetTopFloor(location.roomNumber, x, z, &location.roomNumber);
+ floor = &GetTopFloor(location.RoomNumber, x, z, &location.RoomNumber);
if (floor->IsWall(x, z))
return std::nullopt;
- location.yNumber = floor->GetSurfaceHeight(x, z, true);
+ location.Height = floor->GetSurfaceHeight(x, z, true);
}
- auto floorHeight = floor->GetSurfaceHeight(x, location.yNumber, z, true);
- auto ceilingHeight = floor->GetSurfaceHeight(x, location.yNumber, z, false);
+ auto floorHeight = floor->GetSurfaceHeight(x, location.Height, z, true);
+ auto ceilingHeight = floor->GetSurfaceHeight(x, location.Height, z, false);
- location.yNumber = std::clamp(location.yNumber, std::min(ceilingHeight, floorHeight), std::max(ceilingHeight, floorHeight));
+ location.Height = std::clamp(location.Height, std::min(ceilingHeight, floorHeight), std::max(ceilingHeight, floorHeight));
- if (floor->GetInsideBridgeItemNumber(x, location.yNumber, z, location.yNumber == ceilingHeight, location.yNumber == floorHeight) >= 0)
+ if (floor->GetInsideBridgeItemNumber(x, location.Height, z, location.Height == ceilingHeight, location.Height == floorHeight) >= 0)
{
- const auto height = GetTopHeight(*floor, Vector3i(x, location.yNumber, z), &location.roomNumber, &floor);
+ const auto height = GetTopHeight(*floor, Vector3i(x, location.Height, z), &location.RoomNumber, &floor);
if (!height)
return std::nullopt;
- location.yNumber = *height;
+ location.Height = *height;
}
- floorHeight = floor->GetSurfaceHeight(x, location.yNumber, z, true);
- ceilingHeight = floor->GetSurfaceHeight(x, location.yNumber, z, false);
+ floorHeight = floor->GetSurfaceHeight(x, location.Height, z, true);
+ ceilingHeight = floor->GetSurfaceHeight(x, location.Height, z, false);
- if (y > floorHeight && floor->GetRoomNumberBelow(x, location.yNumber, z))
+ if (y > floorHeight && floor->GetRoomNumberBelow(x, location.Height, z))
return std::nullopt;
if (y >= ceilingHeight)
{
- location.yNumber = std::min(y, floorHeight);
+ location.Height = std::min(y, floorHeight);
return std::optional{location};
}
- auto roomAbove = floor->GetRoomNumberAbove(x, location.yNumber, z);
+ auto roomAbove = floor->GetRoomNumberAbove(x, location.Height, z);
while (roomAbove)
{
- floor = &GetFloorSide(*roomAbove, x, z, &location.roomNumber);
- location.yNumber = floor->GetSurfaceHeight(x, z, true);
+ floor = &GetFloorSide(*roomAbove, x, z, &location.RoomNumber);
+ location.Height = floor->GetSurfaceHeight(x, z, true);
- floorHeight = floor->GetSurfaceHeight(x, location.yNumber, z, true);
- ceilingHeight = floor->GetSurfaceHeight(x, location.yNumber, z, false);
+ floorHeight = floor->GetSurfaceHeight(x, location.Height, z, true);
+ ceilingHeight = floor->GetSurfaceHeight(x, location.Height, z, false);
- if (y > floorHeight && floor->GetRoomNumberBelow(x, location.yNumber, z))
+ if (y > floorHeight && floor->GetRoomNumberBelow(x, location.Height, z))
return std::nullopt;
if (y >= ceilingHeight)
{
- location.yNumber = std::min(y, floorHeight);
+ location.Height = std::min(y, floorHeight);
return std::optional{location};
}
- roomAbove = floor->GetRoomNumberAbove(x, location.yNumber, z);
+ roomAbove = floor->GetRoomNumberAbove(x, location.Height, z);
}
return std::nullopt;
}
- ROOM_VECTOR GetRoom(ROOM_VECTOR location, int x, int y, int z)
+ RoomVector GetRoom(RoomVector location, int x, int y, int z)
{
const auto locationBelow = GetBottomRoom(location, x, y, z);
if (locationBelow)
diff --git a/TombEngine/Game/collision/floordata.h b/TombEngine/Game/collision/floordata.h
index 90ba4f368..77ee59ebc 100644
--- a/TombEngine/Game/collision/floordata.h
+++ b/TombEngine/Game/collision/floordata.h
@@ -55,6 +55,20 @@ enum class ClimbDirectionFlags
West = (1 << 11)
};
+struct RoomVector
+{
+ int RoomNumber = 0;
+ int Height = 0;
+
+ RoomVector() {};
+
+ RoomVector(int roomNumber, int height)
+ {
+ RoomNumber = roomNumber;
+ Height = height;
+ }
+};
+
struct SurfaceCollisionData
{
private:
@@ -174,12 +188,12 @@ namespace TEN::Collision::Floordata
std::optional GetTopHeight(FloorInfo& startSector, Vector3i pos, int* topRoomNumberPtr = nullptr, FloorInfo** topSectorPtr = nullptr);
std::optional GetBottomHeight(FloorInfo& startSector, Vector3i pos, int* bottomRoomNumberPtr = nullptr, FloorInfo** bottomSectorPtr = nullptr);
- std::optional GetFloorHeight(const ROOM_VECTOR& location, int x, int z);
- std::optional GetCeilingHeight(const ROOM_VECTOR& location, int x, int z);
+ std::optional GetFloorHeight(const RoomVector& location, int x, int z);
+ std::optional GetCeilingHeight(const RoomVector& location, int x, int z);
- std::optional GetBottomRoom(ROOM_VECTOR location, int x, int y, int z);
- std::optional GetTopRoom(ROOM_VECTOR location, int x, int y, int z);
- ROOM_VECTOR GetRoom(ROOM_VECTOR location, int x, int y, int z);
+ std::optional GetBottomRoom(RoomVector location, int x, int y, int z);
+ std::optional GetTopRoom(RoomVector location, int x, int y, int z);
+ RoomVector GetRoom(RoomVector location, int x, int y, int z);
void AddBridge(int itemNumber, int x = 0, int z = 0);
void RemoveBridge(int itemNumber, int x = 0, int z = 0);
diff --git a/TombEngine/Game/effects/bubble.cpp b/TombEngine/Game/effects/bubble.cpp
index a8d78e761..3bf53d479 100644
--- a/TombEngine/Game/effects/bubble.cpp
+++ b/TombEngine/Game/effects/bubble.cpp
@@ -148,8 +148,8 @@ namespace TEN::Effects::Bubble
continue;
// Update room number. TODO: Should use GetCollision(), but calling it for each bubble is very inefficient.
- auto roomVector = ROOM_VECTOR{ bubble.RoomNumber, int(bubble.Position.y - bubble.Gravity) };
- int roomNumber = GetRoom(roomVector, bubble.Position.x, bubble.Position.y - bubble.Gravity, bubble.Position.z).roomNumber;
+ auto roomVector = RoomVector(bubble.RoomNumber, int(bubble.Position.y - bubble.Gravity));
+ int roomNumber = GetRoom(roomVector, bubble.Position.x, bubble.Position.y - bubble.Gravity, bubble.Position.z).RoomNumber;
int prevRoomNumber = bubble.RoomNumber;
bubble.RoomNumber = roomNumber;
diff --git a/TombEngine/Game/items.h b/TombEngine/Game/items.h
index 2ac0bd5d7..a76821d15 100644
--- a/TombEngine/Game/items.h
+++ b/TombEngine/Game/items.h
@@ -125,7 +125,7 @@ struct ItemInfo
Pose StartPose;
Pose Pose;
- ROOM_VECTOR Location;
+ RoomVector Location;
short RoomNumber;
int Floor;
diff --git a/TombEngine/Game/savegame.cpp b/TombEngine/Game/savegame.cpp
index ebfe02372..ec8133a49 100644
--- a/TombEngine/Game/savegame.cpp
+++ b/TombEngine/Game/savegame.cpp
@@ -1555,8 +1555,8 @@ bool SaveGame::Load(int slot)
{
LaraItem->Data = nullptr;
LaraItem = item;
- LaraItem->Location.roomNumber = savedItem->room_number();
- LaraItem->Location.yNumber = item->Pose.Position.y;
+ LaraItem->Location.RoomNumber = savedItem->room_number();
+ LaraItem->Location.Height = item->Pose.Position.y;
LaraItem->Data = &Lara;
}
diff --git a/TombEngine/Renderer/Renderer11DrawMenu.cpp b/TombEngine/Renderer/Renderer11DrawMenu.cpp
index 35f47267e..531c5e116 100644
--- a/TombEngine/Renderer/Renderer11DrawMenu.cpp
+++ b/TombEngine/Renderer/Renderer11DrawMenu.cpp
@@ -1125,7 +1125,7 @@ namespace TEN::Renderer
PrintDebugMessage("Pos: %d %d %d", LaraItem->Pose.Position.x, LaraItem->Pose.Position.y, LaraItem->Pose.Position.z);
PrintDebugMessage("Orient: %d %d %d", LaraItem->Pose.Orientation.x, LaraItem->Pose.Orientation.y, LaraItem->Pose.Orientation.z);
PrintDebugMessage("RoomNumber: %d", LaraItem->RoomNumber);
- PrintDebugMessage("Location: %d %d", LaraItem->Location.roomNumber, LaraItem->Location.yNumber);
+ PrintDebugMessage("Location: %d %d", LaraItem->Location.RoomNumber, LaraItem->Location.Height);
PrintDebugMessage("BoxNumber: %d", LaraItem->BoxNumber);
PrintDebugMessage("WaterSurfaceDist: %d", Lara.Context.WaterSurfaceDist);
PrintDebugMessage("Room: %d %d %d %d", r->x, r->z, r->x + r->xSize * BLOCK(1), r->z + r->zSize * BLOCK(1));
diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp
index 05568ed8e..71a4bf970 100644
--- a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp
@@ -920,7 +920,7 @@ void Moveable::SetRoomNumber(int roomNumber)
// or else camera won't be updated properly.
if (m_item->IsLara())
- m_item->Location.roomNumber = roomNumber;
+ m_item->Location.RoomNumber = roomNumber;
}
}
diff --git a/TombEngine/Specific/newtypes.h b/TombEngine/Specific/newtypes.h
index 6881ae985..46712f3d0 100644
--- a/TombEngine/Specific/newtypes.h
+++ b/TombEngine/Specific/newtypes.h
@@ -2,12 +2,6 @@
#include "framework.h"
#include "Renderer/Renderer11Enums.h"
-struct ROOM_VECTOR
-{
- int roomNumber;
- int yNumber;
-};
-
struct POLYGON
{
int shape;
From 210b24fb6d446c840a965d9a3cc3274ca819996b Mon Sep 17 00:00:00 2001
From: Sezz
Date: Tue, 15 Aug 2023 14:36:03 +1000
Subject: [PATCH 007/410] Remove wrappers; simplify
---
TombEngine/Game/collision/PointCollision.cpp | 29 +++++---------------
1 file changed, 7 insertions(+), 22 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 24709da29..82c379234 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -14,17 +14,6 @@ using namespace TEN::Room;
namespace TEN::Collision
{
- // TEMP: Wrappers to avoid name clashes.
- static std::optional WrapGetFloorHeight(const RoomVector& roomVector, int x, int z)
- {
- return GetFloorHeight(roomVector, x, z);
- }
-
- static std::optional WrapGetCeilingHeight(const RoomVector& roomVector, int x, int z)
- {
- return GetCeilingHeight(roomVector, x, z);
- }
-
PointCollision::PointCollision(const Vector3i& pos, int roomNumber) :
Position(pos),
RoomNumber(roomNumber)
@@ -56,7 +45,7 @@ namespace TEN::Collision
auto roomNumberAbove = topSectorPtr->GetRoomNumberAbove(Position.x, Position.y, Position.z);
auto& room = g_Level.Rooms[roomNumberAbove.value_or(topSectorPtr->Room)];
- topSectorPtr = TEN::Room::GetSector(&room, Position.x - room.x, Position.z - room.z);
+ topSectorPtr = Room::GetSector(&room, Position.x - room.x, Position.z - room.z);
}
TopSectorPtr = topSectorPtr;
@@ -75,7 +64,7 @@ namespace TEN::Collision
auto roomNumberBelow = bottomSectorPtr->GetRoomNumberBelow(Position.x, Position.y, Position.z);
auto& room = g_Level.Rooms[roomNumberBelow.value_or(bottomSectorPtr->Room)];
- bottomSectorPtr = TEN::Room::GetSector(&room, Position.x - room.x, Position.z - room.z);
+ bottomSectorPtr = Room::GetSector(&room, Position.x - room.x, Position.z - room.z);
}
BottomSectorPtr = bottomSectorPtr;
@@ -89,7 +78,7 @@ namespace TEN::Collision
// Set floor height.
auto roomVector = RoomVector(GetSector().Room, Position.y);
- FloorHeight = WrapGetFloorHeight(roomVector, Position.x, Position.z).value_or(NO_HEIGHT);
+ FloorHeight = Floordata::GetFloorHeight(roomVector, Position.x, Position.z).value_or(NO_HEIGHT);
return *FloorHeight;
}
@@ -101,7 +90,7 @@ namespace TEN::Collision
// Set ceiling height.
auto roomVector = RoomVector(GetSector().Room, Position.y);
- CeilingHeight = WrapGetCeilingHeight(roomVector, Position.x, Position.z).value_or(NO_HEIGHT);
+ CeilingHeight = Floordata::GetCeilingHeight(roomVector, Position.x, Position.z).value_or(NO_HEIGHT);
return *CeilingHeight;
}
@@ -120,8 +109,7 @@ namespace TEN::Collision
else
{
auto floorTilt = GetBottomSector().GetSurfaceTilt(Position.x, Position.z, true);
- auto floorNormal = GetSurfaceNormal(floorTilt, true);
- FloorNormal = floorNormal;
+ FloorNormal = GetSurfaceNormal(floorTilt, true);
}
return *FloorNormal;
@@ -140,10 +128,8 @@ namespace TEN::Collision
}
else
{
- // TODO: Check GetTopSector().
auto ceilingTilt = GetTopSector().GetSurfaceTilt(Position.x, Position.z, false);
- auto ceilingNormal = GetSurfaceNormal(ceilingTilt, false);
- CeilingNormal = ceilingNormal;
+ CeilingNormal = GetSurfaceNormal(ceilingTilt, false);
}
return *CeilingNormal;
@@ -156,8 +142,7 @@ namespace TEN::Collision
// Set bridge item number.
int floorHeight = GetFloorHeight();
- int bridgItemNumber = GetBottomSector().GetInsideBridgeItemNumber(Position.x, floorHeight, Position.z, true, false);
- BridgeItemNumber = bridgItemNumber;
+ BridgeItemNumber = GetBottomSector().GetInsideBridgeItemNumber(Position.x, floorHeight, Position.z, true, false);;
return *BridgeItemNumber;
}
From 102d317b08fc8e2a3132148178411109db171d26 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Tue, 15 Aug 2023 14:41:19 +1000
Subject: [PATCH 008/410] Organise
---
TombEngine/Game/collision/PointCollision.cpp | 15 +++++++--------
TombEngine/Game/collision/floordata.cpp | 8 ++++----
2 files changed, 11 insertions(+), 12 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 82c379234..02432df46 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -240,11 +240,10 @@ namespace TEN::Collision
{
short tempRoomNumber = roomNumber;
const auto& sector = *GetFloor(pos.x, pos.y, pos.z, &tempRoomNumber);
-
- auto roomVector = RoomVector(sector.Room, pos.y);
+ auto location = RoomVector(sector.Room, pos.y);
auto probePos = Geometry::TranslatePoint(pos, headingAngle, forward, down, right);
- int adjacentRoomNumber = GetRoom(roomVector, pos.x, probePos.y, pos.z).RoomNumber;
+ int adjacentRoomNumber = GetRoom(location, pos.x, probePos.y, pos.z).RoomNumber;
return PointCollision(probePos, adjacentRoomNumber);
}
@@ -253,9 +252,9 @@ namespace TEN::Collision
return PointCollision(item.Pose.Position, item.RoomNumber);
}
- // TODO: Find cleaner solution. Constructing a room vector (sometimes dubbed "Location")
- // on the spot for the player can result in a stumble when climbing onto thin platforms. -- Sezz 2022.06.14
- static RoomVector GetEntityRoomVector(const ItemInfo& item)
+ // TODO: Find cleaner solution. Constructing a "location" on the spot for the player
+ // can result in a stumble when climbing onto thin platforms. -- Sezz 2022.06.14
+ static RoomVector GetEntityLocation(const ItemInfo& item)
{
if (item.IsLara())
return item.Location;
@@ -268,10 +267,10 @@ namespace TEN::Collision
PointCollision GetPointCollision(const ItemInfo& item, short headingAngle, float forward, float down, float right)
{
- auto roomVector = GetEntityRoomVector(item);
+ auto location = GetEntityLocation(item);
auto probePos = Geometry::TranslatePoint(item.Pose.Position, headingAngle, forward, down, right);
- int adjacentRoomNumber = GetRoom(roomVector, item.Pose.Position.x, probePos.y, item.Pose.Position.z).RoomNumber;
+ int adjacentRoomNumber = GetRoom(location, item.Pose.Position.x, probePos.y, item.Pose.Position.z).RoomNumber;
return PointCollision(probePos, adjacentRoomNumber);
}
}
diff --git a/TombEngine/Game/collision/floordata.cpp b/TombEngine/Game/collision/floordata.cpp
index b03d921d3..f7e25a9f3 100644
--- a/TombEngine/Game/collision/floordata.cpp
+++ b/TombEngine/Game/collision/floordata.cpp
@@ -742,12 +742,12 @@ namespace TEN::Collision::Floordata
RoomVector GetRoom(RoomVector location, int x, int y, int z)
{
- const auto locationBelow = GetBottomRoom(location, x, y, z);
- if (locationBelow)
+ auto locationBelow = GetBottomRoom(location, x, y, z);
+ if (locationBelow.has_value())
return *locationBelow;
- const auto locationAbove = GetTopRoom(location, x, y, z);
- if (locationAbove)
+ auto locationAbove = GetTopRoom(location, x, y, z);
+ if (locationAbove.has_value())
return *locationAbove;
return location;
From d9e8275ca32adbb9a4b23bdc994e6e1d85a2b711 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Tue, 15 Aug 2023 14:48:11 +1000
Subject: [PATCH 009/410] Update namespace
---
TombEngine/Game/collision/PointCollision.cpp | 2 +-
TombEngine/Game/collision/collide_room.cpp | 2 +-
TombEngine/Game/control/box.cpp | 2 +-
TombEngine/Game/control/lot.cpp | 2 +-
TombEngine/Game/items.cpp | 2 +-
TombEngine/Game/room.cpp | 2 +-
TombEngine/Game/room.h | 2 +-
TombEngine/Objects/Generic/Doors/generic_doors.cpp | 2 +-
TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp | 2 +-
TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp | 2 +-
TombEngine/Objects/TR5/Object/tr5_pushableblock.cpp | 2 +-
TombEngine/Objects/TR5/Shatter/tr5_smashobject.cpp | 2 +-
12 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 02432df46..f3cc63462 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -9,8 +9,8 @@
#include "Specific/level.h"
using namespace TEN::Collision::Floordata;
+using namespace TEN::Collision::Room;
using namespace TEN::Math;
-using namespace TEN::Room;
namespace TEN::Collision
{
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index 0b91a8356..0af378f3c 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -15,9 +15,9 @@
using namespace TEN::Collision;
using namespace TEN::Collision::Floordata;
+using namespace TEN::Collision::Room;
using namespace TEN::Math;
using namespace TEN::Renderer;
-using namespace TEN::Room;
void ShiftItem(ItemInfo* item, CollisionInfo* coll)
{
diff --git a/TombEngine/Game/control/box.cpp b/TombEngine/Game/control/box.cpp
index e265e53eb..9969554b5 100644
--- a/TombEngine/Game/control/box.cpp
+++ b/TombEngine/Game/control/box.cpp
@@ -22,8 +22,8 @@
#include "Objects/TR5/Object/tr5_pushableblock.h"
#include "Renderer/Renderer11.h"
+using namespace TEN::Collision::Room;
using namespace TEN::Effects::Smoke;
-using namespace TEN::Room;
constexpr auto ESCAPE_DIST = BLOCK(5);
constexpr auto STALK_DIST = BLOCK(3);
diff --git a/TombEngine/Game/control/lot.cpp b/TombEngine/Game/control/lot.cpp
index 373d70a76..9f125f49d 100644
--- a/TombEngine/Game/control/lot.cpp
+++ b/TombEngine/Game/control/lot.cpp
@@ -10,7 +10,7 @@
#include "Game/Setup.h"
#include "Specific/level.h"
-using namespace TEN::Room;
+using namespace TEN::Collision::Room;
#define DEFAULT_FLY_UPDOWN_SPEED 16
#define DEFAULT_SWIM_UPDOWN_SPEED 32
diff --git a/TombEngine/Game/items.cpp b/TombEngine/Game/items.cpp
index 7bd42c6f7..4b579c43e 100644
--- a/TombEngine/Game/items.cpp
+++ b/TombEngine/Game/items.cpp
@@ -22,11 +22,11 @@
#include "Scripting/Internal/TEN/Objects/ObjectIDs.h"
using namespace TEN::Collision::Floordata;
+using namespace TEN::Collision::Room;
using namespace TEN::Control::Volumes;
using namespace TEN::Effects::Items;
using namespace TEN::Input;
using namespace TEN::Math;
-using namespace TEN::Room;
constexpr int ITEM_DEATH_TIMEOUT = 4 * FPS;
diff --git a/TombEngine/Game/room.cpp b/TombEngine/Game/room.cpp
index aef5da31e..d15a0d242 100644
--- a/TombEngine/Game/room.cpp
+++ b/TombEngine/Game/room.cpp
@@ -159,7 +159,7 @@ int IsRoomOutside(int x, int y, int z)
return NO_ROOM;
}
-namespace TEN::Room
+namespace TEN::Collision::Room
{
FloorInfo* GetSector(ROOM_INFO* room, int x, int z)
{
diff --git a/TombEngine/Game/room.h b/TombEngine/Game/room.h
index 81a0570d0..1e40f19da 100644
--- a/TombEngine/Game/room.h
+++ b/TombEngine/Game/room.h
@@ -156,7 +156,7 @@ void InitializeNeighborRoomList();
GameBoundingBox& GetBoundsAccurate(const MESH_INFO& mesh, bool visibility);
-namespace TEN::Room
+namespace TEN::Collision::Room
{
FloorInfo* GetSector(ROOM_INFO* room, int x, int z);
}
diff --git a/TombEngine/Objects/Generic/Doors/generic_doors.cpp b/TombEngine/Objects/Generic/Doors/generic_doors.cpp
index 94f6f3769..8df4c601d 100644
--- a/TombEngine/Objects/Generic/Doors/generic_doors.cpp
+++ b/TombEngine/Objects/Generic/Doors/generic_doors.cpp
@@ -23,9 +23,9 @@
#include "Game/collision/collide_item.h"
#include "Game/itemdata/itemdata.h"
+using namespace TEN::Collision::Room;
using namespace TEN::Gui;
using namespace TEN::Input;
-using namespace TEN::Room;
namespace TEN::Entities::Doors
{
diff --git a/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp b/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp
index 62efd7a60..ce611c676 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp
@@ -15,8 +15,8 @@
#include "Sound/sound.h"
#include "Specific/level.h"
+using namespace TEN::Collision::Room;
using namespace TEN::Math;
-using namespace TEN::Room;
namespace TEN::Entities::Creatures::TR5
{
diff --git a/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp b/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp
index e94e48405..7c192fdb0 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp
@@ -20,10 +20,10 @@
#include "Sound/sound.h"
#include "Specific/level.h"
+using namespace TEN::Collision::Room;
using namespace TEN::Effects::Electricity;
using namespace TEN::Effects::Spark;
using namespace TEN::Math;
-using namespace TEN::Room;
namespace TEN::Entities::Creatures::TR5
{
diff --git a/TombEngine/Objects/TR5/Object/tr5_pushableblock.cpp b/TombEngine/Objects/TR5/Object/tr5_pushableblock.cpp
index aa629e109..ccc538fa2 100644
--- a/TombEngine/Objects/TR5/Object/tr5_pushableblock.cpp
+++ b/TombEngine/Objects/TR5/Object/tr5_pushableblock.cpp
@@ -16,8 +16,8 @@
#include "Specific/level.h"
using namespace TEN::Collision::Floordata;
+using namespace TEN::Collision::Room;
using namespace TEN::Input;
-using namespace TEN::Room;
namespace TEN::Entities::Generic
{
diff --git a/TombEngine/Objects/TR5/Shatter/tr5_smashobject.cpp b/TombEngine/Objects/TR5/Shatter/tr5_smashobject.cpp
index 4ed96e273..bb75a6201 100644
--- a/TombEngine/Objects/TR5/Shatter/tr5_smashobject.cpp
+++ b/TombEngine/Objects/TR5/Shatter/tr5_smashobject.cpp
@@ -6,7 +6,7 @@
#include "Game/effects/tomb4fx.h"
#include "Game/items.h"
-using namespace TEN::Room;
+using namespace TEN::Collision::Room;
void InitializeSmashObject(short itemNumber)
{
From 433f877d82e97d16f15de951b567830d4c77df37 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Tue, 15 Aug 2023 23:44:22 +1000
Subject: [PATCH 010/410] Fix room number probing; Wrap GetPointCollision()
calls in old GetCollision()
---
TombEngine/Game/camera.cpp | 6 +-
TombEngine/Game/collision/PointCollision.cpp | 68 ++++++++++--
TombEngine/Game/collision/PointCollision.h | 2 +
TombEngine/Game/collision/collide_room.cpp | 103 +++++++++----------
4 files changed, 115 insertions(+), 64 deletions(-)
diff --git a/TombEngine/Game/camera.cpp b/TombEngine/Game/camera.cpp
index db2c95cdb..88951d2a6 100644
--- a/TombEngine/Game/camera.cpp
+++ b/TombEngine/Game/camera.cpp
@@ -3,6 +3,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/los.h"
#include "Game/effects/debris.h"
#include "Game/effects/effects.h"
@@ -21,6 +22,7 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
+using namespace TEN::Collision;
using TEN::Renderer::g_Renderer;
using namespace TEN::Effects::Environment;
@@ -175,8 +177,8 @@ void LookCamera(ItemInfo& item, const CollisionInfo& coll)
auto lookAtPos = Geometry::TranslatePoint(pivotPos, orient, LOOK_AT_DIST);
// Determine best position.
- auto origin = GameVector(pivotPos, GetCollision(&item, item.Pose.Orientation.y, pivotOffset.z, pivotOffset.y).RoomNumber);
- auto target = GameVector(idealPos, GetCollision(origin.ToVector3i(), origin.RoomNumber, orient, idealDist).RoomNumber);
+ auto origin = GameVector(pivotPos, GetPointCollision(item, item.Pose.Orientation.y, pivotOffset.z, pivotOffset.y).RoomNumber);
+ auto target = GameVector(idealPos, GetPointCollision(origin.ToVector3i(), origin.RoomNumber, orient.ToDirection(), idealDist).RoomNumber);
// Handle room and object collisions.
LOSAndReturnTarget(&origin, &target, 0);
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index f3cc63462..221438c18 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -27,8 +27,7 @@ namespace TEN::Collision
// Set current sector pointer.
short probedRoomNumber = RoomNumber;
- auto* sectorPtr = GetFloor(Position.x, Position.y, Position.z, &probedRoomNumber);
- SectorPtr = sectorPtr;
+ SectorPtr = GetFloor(Position.x, Position.y, Position.z, &probedRoomNumber);
return *SectorPtr;
}
@@ -233,18 +232,48 @@ namespace TEN::Collision
PointCollision GetPointCollision(const Vector3i& pos, int roomNumber)
{
- return PointCollision(pos, roomNumber);
+ // HACK: This function takes arguments for a *current* position and room number.
+ // However, since some calls to the previous implementation (GetCollision()) had *projected*
+ // positions passed to it, for now the room number must be corrected to account for such cases.
+ // They are primarily found in camera.cpp.
+ short correctedRoomNumber = roomNumber;
+ GetFloor(pos.x, pos.y, pos.z, &correctedRoomNumber);
+
+ return PointCollision(pos, correctedRoomNumber);
}
- PointCollision GetPointCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down, float right)
+ PointCollision GetPointCollision(const Vector3i& pos, int roomNumber, const Vector3& dir, float dist)
{
+ // Get "location".
short tempRoomNumber = roomNumber;
const auto& sector = *GetFloor(pos.x, pos.y, pos.z, &tempRoomNumber);
auto location = RoomVector(sector.Room, pos.y);
+ // Calculate probe position.
+ auto probePos = Geometry::TranslatePoint(pos, dir, dist);
+
+ // Get probe position's room number.
+ short probeRoomNumber = GetRoom(location, pos.x, probePos.y, pos.z).RoomNumber;
+ GetFloor(probePos.x, probePos.y, probePos.z, &probeRoomNumber);
+
+ return PointCollision(probePos, probeRoomNumber);
+ }
+
+ PointCollision GetPointCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down, float right)
+ {
+ // Get "location".
+ short tempRoomNumber = roomNumber;
+ const auto& sector = *GetFloor(pos.x, pos.y, pos.z, &tempRoomNumber);
+ auto location = RoomVector(sector.Room, pos.y);
+
+ // Calculate probe position.
auto probePos = Geometry::TranslatePoint(pos, headingAngle, forward, down, right);
- int adjacentRoomNumber = GetRoom(location, pos.x, probePos.y, pos.z).RoomNumber;
- return PointCollision(probePos, adjacentRoomNumber);
+
+ // Get probe position's room number.
+ short probeRoomNumber = GetRoom(location, pos.x, probePos.y, pos.z).RoomNumber;
+ GetFloor(probePos.x, probePos.y, probePos.z, &probeRoomNumber);
+
+ return PointCollision(probePos, probeRoomNumber);
}
PointCollision GetPointCollision(const ItemInfo& item)
@@ -265,12 +294,33 @@ namespace TEN::Collision
return RoomVector(sector.Room, item.Pose.Position.y);
}
- PointCollision GetPointCollision(const ItemInfo& item, short headingAngle, float forward, float down, float right)
+ PointCollision GetPointCollision(const ItemInfo& item, const Vector3& dir, float dist)
{
+ // Get "location".
auto location = GetEntityLocation(item);
+ // Calculate probe position.
+ auto probePos = Geometry::TranslatePoint(item.Pose.Position, dir, dist);
+
+ // Get probe position's room number.
+ short probeRoomNumber = GetRoom(location, item.Pose.Position.x, probePos.y, item.Pose.Position.z).RoomNumber;
+ GetFloor(probePos.x, probePos.y, probePos.z, &probeRoomNumber);
+
+ return PointCollision(probePos, probeRoomNumber);
+ }
+
+ PointCollision GetPointCollision(const ItemInfo& item, short headingAngle, float forward, float down, float right)
+ {
+ // Get "location".
+ auto location = GetEntityLocation(item);
+
+ // Calculate probe position.
auto probePos = Geometry::TranslatePoint(item.Pose.Position, headingAngle, forward, down, right);
- int adjacentRoomNumber = GetRoom(location, item.Pose.Position.x, probePos.y, item.Pose.Position.z).RoomNumber;
- return PointCollision(probePos, adjacentRoomNumber);
+
+ // Get probe position's room number.
+ short probeRoomNumber = GetRoom(location, item.Pose.Position.x, probePos.y, item.Pose.Position.z).RoomNumber;
+ GetFloor(probePos.x, probePos.y, probePos.z, &probeRoomNumber);
+
+ return PointCollision(probePos, probeRoomNumber);
}
}
diff --git a/TombEngine/Game/collision/PointCollision.h b/TombEngine/Game/collision/PointCollision.h
index fef3952d8..9b504cd52 100644
--- a/TombEngine/Game/collision/PointCollision.h
+++ b/TombEngine/Game/collision/PointCollision.h
@@ -60,7 +60,9 @@ namespace TEN::Collision
};
PointCollision GetPointCollision(const Vector3i& pos, int roomNumber);
+ PointCollision GetPointCollision(const Vector3i& pos, int roomNumber, const Vector3& dir, float dist);
PointCollision GetPointCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down = 0.0f, float right = 0.0f);
PointCollision GetPointCollision(const ItemInfo& item);
+ PointCollision GetPointCollision(const ItemInfo& item, const Vector3& dir, float dist);
PointCollision GetPointCollision(const ItemInfo& item, short headingAngle, float forward, float down = 0.0f, float right = 0.0f);
}
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index 0af378f3c..e0bb0c125 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -117,47 +117,51 @@ bool TestItemRoomCollisionAABB(ItemInfo* item)
return collided;
}
-// Overload used to quickly get point collision parameters at a given item's position.
+static CollisionResult ConvertPointCollisionToCollisionResult(PointCollision& pointColl)
+{
+ auto collResult = CollisionResult{};
+
+ collResult.Coordinates = pointColl.Position;
+ collResult.RoomNumber = pointColl.RoomNumber;
+ collResult.Block = &pointColl.GetSector();
+ collResult.BottomBlock = &pointColl.GetBottomSector();
+
+ collResult.Position.Floor = pointColl.GetFloorHeight();
+ collResult.Position.Ceiling = pointColl.GetCeilingHeight();
+ collResult.Position.Bridge = pointColl.GetBridgeItemNumber();
+ collResult.Position.SplitAngle = pointColl.GetBottomSector().FloorCollision.SplitAngle;
+ collResult.Position.FloorSlope = pointColl.IsFloorSlope();
+ collResult.Position.CeilingSlope = pointColl.IsCeilingSlope();
+ collResult.Position.DiagonalStep = pointColl.IsDiagonalStep();
+
+ collResult.FloorTilt = collResult.BottomBlock->GetSurfaceTilt(pointColl.Position.x, pointColl.Position.z, true);
+ collResult.CeilingTilt = collResult.BottomBlock->GetSurfaceTilt(pointColl.Position.x, pointColl.Position.z, false);
+
+ return collResult;
+}
+
CollisionResult GetCollision(const ItemInfo& item)
{
- auto newRoomNumber = item.RoomNumber;
- auto floor = GetFloor(item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z, &newRoomNumber);
- auto probe = GetCollision(floor, item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z);
-
- probe.RoomNumber = newRoomNumber;
- return probe;
+ auto pointColl = GetPointCollision(item);
+ return ConvertPointCollisionToCollisionResult(pointColl);
}
-// Deprecated.
CollisionResult GetCollision(ItemInfo* item)
{
- return GetCollision(*item);
+ auto pointColl = GetPointCollision(*item);
+ return ConvertPointCollisionToCollisionResult(pointColl);
}
-// Overload used to probe point collision parameters from a given item's position.
CollisionResult GetCollision(ItemInfo* item, short headingAngle, float forward, float down, float right)
{
- short tempRoomNumber = item->RoomNumber;
-
- // TODO: Find cleaner solution. Constructing a Location for Lara on the spot can result in a stumble when climbing onto thin platforms. -- Sezz 2022.06.14
- auto location = item->IsLara() ?
- item->Location :
- RoomVector(GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &tempRoomNumber)->Room, item->Pose.Position.y);
-
- auto point = Geometry::TranslatePoint(item->Pose.Position, headingAngle, forward, down, right);
- int adjacentRoomNumber = GetRoom(location, item->Pose.Position.x, point.y, item->Pose.Position.z).RoomNumber;
- return GetCollision(point.x, point.y, point.z, adjacentRoomNumber);
+ auto pointColl = GetPointCollision(*item, headingAngle, forward, down, right);
+ return ConvertPointCollisionToCollisionResult(pointColl);
}
-// Overload used to probe point collision parameters from a given position.
CollisionResult GetCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down, float right)
{
- short tempRoomNumber = roomNumber;
- auto location = RoomVector(GetFloor(pos.x, pos.y, pos.z, &tempRoomNumber)->Room, pos.y);
-
- auto point = Geometry::TranslatePoint(pos, headingAngle, forward, down, right);
- int adjacentRoomNumber = GetRoom(location, pos.x, point.y, pos.z).RoomNumber;
- return GetCollision(point.x, point.y, point.z, adjacentRoomNumber);
+ auto pointColl = GetPointCollision(pos, roomNumber, headingAngle, forward, down, right);
+ return ConvertPointCollisionToCollisionResult(pointColl);
}
CollisionResult GetCollision(const Vector3i& pos, int roomNumber, const EulerAngles& orient, float dist)
@@ -165,9 +169,15 @@ CollisionResult GetCollision(const Vector3i& pos, int roomNumber, const EulerAng
auto point = Geometry::TranslatePoint(pos, orient, dist);
short tempRoomNumber = roomNumber;
- auto location = RoomVector{ GetFloor(pos.x, pos.y, pos.z, &tempRoomNumber)->Room, pos.y };
+ auto location = RoomVector(GetFloor(pos.x, pos.y, pos.z, &tempRoomNumber)->Room, pos.y);
int adjacentRoomNumber = GetRoom(location, pos.x, point.y, pos.z).RoomNumber;
- return GetCollision(point.x, point.y, point.z, adjacentRoomNumber);
+
+ // Get probe position's room number.
+ short probeRoomNumber = GetRoom(location, pos.x, point.y, pos.z).RoomNumber;
+ GetFloor(point.x, point.y, point.z, &probeRoomNumber);
+
+ auto pointColl = GetPointCollision(point, roomNumber);
+ return ConvertPointCollisionToCollisionResult(pointColl);
}
// Overload used as universal wrapper across collisional code replacing
@@ -177,39 +187,26 @@ CollisionResult GetCollision(const Vector3i& pos, int roomNumber, const EulerAng
// This way, no external variables are modified as output arguments.
CollisionResult GetCollision(const Vector3i& pos, int roomNumber)
{
- return GetCollision(pos.x, pos.y, pos.z, roomNumber);
+ auto pointColl = GetPointCollision(pos, roomNumber);
+ return ConvertPointCollisionToCollisionResult(pointColl);
}
-// Deprecated.
CollisionResult GetCollision(int x, int y, int z, short roomNumber)
{
+ /*auto room = roomNumber;
+ auto floor = GetFloor(x, y, z, &room);
+ auto result = GetCollision(floor, x, y, z);
+ result.RoomNumber = room;
+ return result;*/
+
auto pointColl = GetPointCollision(Vector3i(x, y, z), roomNumber);
-
- auto result = CollisionResult{};
-
- result.Coordinates = pointColl.Position;
- result.RoomNumber = pointColl.RoomNumber;
- result.Block = &pointColl.GetSector();
- result.BottomBlock = &pointColl.GetBottomSector();
-
- result.Position.Floor = pointColl.GetFloorHeight();
- result.Position.Ceiling = pointColl.GetCeilingHeight();
- result.Position.Bridge = pointColl.GetBridgeItemNumber();
- result.Position.SplitAngle = pointColl.GetBottomSector().FloorCollision.SplitAngle;
- result.Position.FloorSlope = pointColl.IsFloorSlope();
- result.Position.CeilingSlope = pointColl.IsCeilingSlope();
- result.Position.DiagonalStep = pointColl.IsDiagonalStep();
-
- result.FloorTilt = result.BottomBlock->GetSurfaceTilt(x, z, true);
- result.CeilingTilt = result.BottomBlock->GetSurfaceTilt(x, z, false);
-
- return result;
+ return ConvertPointCollisionToCollisionResult(pointColl);
}
-// NOTE: To be used only when absolutely necessary.
CollisionResult GetCollision(const GameVector& pos)
{
- return GetCollision(pos.x, pos.y, pos.z, pos.RoomNumber);
+ auto pointColl = GetPointCollision(pos.ToVector3i(), pos.RoomNumber);
+ return ConvertPointCollisionToCollisionResult(pointColl);
}
// A reworked legacy GetFloorHeight() function which writes data
From bc212b041da3dedacd22ca2755af1a6f7ce8b2a7 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Tue, 15 Aug 2023 23:59:34 +1000
Subject: [PATCH 011/410] Remove deprecated GetCollision() overload
---
TombEngine/Game/collision/PointCollision.cpp | 2 +-
TombEngine/Game/collision/collide_room.cpp | 16 ----------------
TombEngine/Game/collision/collide_room.h | 1 -
3 files changed, 1 insertion(+), 18 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 221438c18..8ac20b67d 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -233,7 +233,7 @@ namespace TEN::Collision
PointCollision GetPointCollision(const Vector3i& pos, int roomNumber)
{
// HACK: This function takes arguments for a *current* position and room number.
- // However, since some calls to the previous implementation (GetCollision()) had *projected*
+ // However, since some calls to the previous implementation (GetCollision()) had *vertically projected*
// positions passed to it, for now the room number must be corrected to account for such cases.
// They are primarily found in camera.cpp.
short correctedRoomNumber = roomNumber;
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index e0bb0c125..321795e46 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -164,22 +164,6 @@ CollisionResult GetCollision(const Vector3i& pos, int roomNumber, short headingA
return ConvertPointCollisionToCollisionResult(pointColl);
}
-CollisionResult GetCollision(const Vector3i& pos, int roomNumber, const EulerAngles& orient, float dist)
-{
- auto point = Geometry::TranslatePoint(pos, orient, dist);
-
- short tempRoomNumber = roomNumber;
- auto location = RoomVector(GetFloor(pos.x, pos.y, pos.z, &tempRoomNumber)->Room, pos.y);
- int adjacentRoomNumber = GetRoom(location, pos.x, point.y, pos.z).RoomNumber;
-
- // Get probe position's room number.
- short probeRoomNumber = GetRoom(location, pos.x, point.y, pos.z).RoomNumber;
- GetFloor(point.x, point.y, point.z, &probeRoomNumber);
-
- auto pointColl = GetPointCollision(point, roomNumber);
- return ConvertPointCollisionToCollisionResult(pointColl);
-}
-
// Overload used as universal wrapper across collisional code replacing
// triads of roomNumber-GetFloor()-GetFloorHeight() calls.
// Advantage is that it does NOT modify incoming roomNumber argument,
diff --git a/TombEngine/Game/collision/collide_room.h b/TombEngine/Game/collision/collide_room.h
index 74cd6fd0e..761b7f16e 100644
--- a/TombEngine/Game/collision/collide_room.h
+++ b/TombEngine/Game/collision/collide_room.h
@@ -134,7 +134,6 @@ CollisionResult GetCollision(const ItemInfo& item);
CollisionResult GetCollision(ItemInfo* item);
CollisionResult GetCollision(ItemInfo* item, short headingAngle, float forward, float down = 0.0f, float right = 0.0f);
CollisionResult GetCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down = 0.0f, float right = 0.0f);
-CollisionResult GetCollision(const Vector3i& pos, int roomNumber, const EulerAngles& orient, float dist);
CollisionResult GetCollision(const Vector3i& pos, int roomNumber);
CollisionResult GetCollision(int x, int y, int z, short roomNumber);
CollisionResult GetCollision(const GameVector& pos);
From 14af4269e1be673278ac90489498ee1ed30515cd Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 16 Aug 2023 00:50:11 +1000
Subject: [PATCH 012/410] Update slope query methods
---
TombEngine/Game/collision/PointCollision.cpp | 12 +++++++-----
TombEngine/Game/collision/PointCollision.h | 5 +++--
TombEngine/Game/collision/collide_room.cpp | 10 ++--------
TombEngine/Game/collision/collide_room.h | 4 ++--
4 files changed, 14 insertions(+), 17 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 8ac20b67d..be2ba8b11 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -184,22 +184,24 @@ namespace TEN::Collision
return ((GetFloorHeight() == NO_HEIGHT) || (GetCeilingHeight() == NO_HEIGHT));
}
- bool PointCollision::IsFloorSlope()
+ bool PointCollision::IsSlipperyFloor(short slopeAngleMin)
{
// Get floor slope angle.
auto floorNormal = GetFloorNormal();
auto slopeAngle = Geometry::GetSurfaceSlopeAngle(floorNormal);
- return ((GetBridgeItemNumber() == NO_ITEM) && (abs(slopeAngle) >= SLIPPERY_FLOOR_SLOPE_ANGLE));
+ // TODO: Slippery bridges.
+ return ((GetBridgeItemNumber() == NO_ITEM) && (abs(slopeAngle) >= slopeAngleMin));
}
- bool PointCollision::IsCeilingSlope()
+ bool PointCollision::IsSlipperyCeiling(short slopeAngleMin)
{
// Get ceiling slope angle.
auto ceilingNormal = GetCeilingNormal();
auto slopeAngle = Geometry::GetSurfaceSlopeAngle(ceilingNormal, -Vector3::UnitY);
-
- return (abs(slopeAngle) >= SLIPPERY_CEILING_SLOPE_ANGLE);
+
+ // TODO: Slippery bridges.
+ return (abs(slopeAngle) >= slopeAngleMin);
}
bool PointCollision::IsDiagonalStep()
diff --git a/TombEngine/Game/collision/PointCollision.h b/TombEngine/Game/collision/PointCollision.h
index 9b504cd52..31ef6df92 100644
--- a/TombEngine/Game/collision/PointCollision.h
+++ b/TombEngine/Game/collision/PointCollision.h
@@ -1,4 +1,5 @@
#pragma once
+#include "Game/collision/collide_room.h"
#include "Math/Math.h"
enum RoomEnvFlags;
@@ -51,8 +52,8 @@ namespace TEN::Collision
// Inquirers
bool IsWall();
- bool IsFloorSlope();
- bool IsCeilingSlope();
+ bool IsSlipperyFloor(short slopeAngleMin = DEFAULT_SLIPPERY_FLOOR_SLOPE_ANGLE);
+ bool IsSlipperyCeiling(short slopeAngleMin = DEFAULT_SLIPPERY_CEILING_SLOPE_ANGLE);
bool IsDiagonalStep();
bool HasDiagonalSplit();
bool HasFlippedDiagonalSplit();
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index 321795e46..58c212e3b 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -130,8 +130,8 @@ static CollisionResult ConvertPointCollisionToCollisionResult(PointCollision& po
collResult.Position.Ceiling = pointColl.GetCeilingHeight();
collResult.Position.Bridge = pointColl.GetBridgeItemNumber();
collResult.Position.SplitAngle = pointColl.GetBottomSector().FloorCollision.SplitAngle;
- collResult.Position.FloorSlope = pointColl.IsFloorSlope();
- collResult.Position.CeilingSlope = pointColl.IsCeilingSlope();
+ collResult.Position.FloorSlope = pointColl.IsSlipperyFloor();
+ collResult.Position.CeilingSlope = pointColl.IsSlipperyCeiling();
collResult.Position.DiagonalStep = pointColl.IsDiagonalStep();
collResult.FloorTilt = collResult.BottomBlock->GetSurfaceTilt(pointColl.Position.x, pointColl.Position.z, true);
@@ -177,12 +177,6 @@ CollisionResult GetCollision(const Vector3i& pos, int roomNumber)
CollisionResult GetCollision(int x, int y, int z, short roomNumber)
{
- /*auto room = roomNumber;
- auto floor = GetFloor(x, y, z, &room);
- auto result = GetCollision(floor, x, y, z);
- result.RoomNumber = room;
- return result;*/
-
auto pointColl = GetPointCollision(Vector3i(x, y, z), roomNumber);
return ConvertPointCollisionToCollisionResult(pointColl);
}
diff --git a/TombEngine/Game/collision/collide_room.h b/TombEngine/Game/collision/collide_room.h
index 761b7f16e..1ac8a1633 100644
--- a/TombEngine/Game/collision/collide_room.h
+++ b/TombEngine/Game/collision/collide_room.h
@@ -13,8 +13,8 @@ constexpr auto NO_LOWER_BOUND = -NO_HEIGHT; // Used by coll->Setup.LowerFloorBou
constexpr auto NO_UPPER_BOUND = NO_HEIGHT; // Used by coll->Setup.UpperFloorBound.
constexpr auto COLLISION_CHECK_DISTANCE = BLOCK(8);
-constexpr auto SLIPPERY_FLOOR_SLOPE_ANGLE = short(ANGLE(45.0f) * 0.75f);
-constexpr auto SLIPPERY_CEILING_SLOPE_ANGLE = ANGLE(45.0f);
+constexpr auto DEFAULT_SLIPPERY_FLOOR_SLOPE_ANGLE = short(ANGLE(45.0f) * 0.75f);
+constexpr auto DEFAULT_SLIPPERY_CEILING_SLOPE_ANGLE = ANGLE(45.0f);
enum CollisionType
{
From 7da15230eebad8ea0894a4e01e23dd6400aae97a Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 16 Aug 2023 01:41:44 +1000
Subject: [PATCH 013/410] Update collide_room.cpp
---
TombEngine/Game/collision/collide_room.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index 58c212e3b..f0a9d1113 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -1125,7 +1125,7 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance)
FloorInfo* GetFloor(int x, int y, int z, short* roomNumber)
{
- const auto location = GetRoom(RoomVector{ *roomNumber, y }, x, y, z);
+ auto location = GetRoom(RoomVector(*roomNumber, y), x, y, z);
*roomNumber = location.RoomNumber;
return &GetFloor(*roomNumber, x, z);
}
From 70ffe72e1fc60e1adf545e4f3dd55f1ab4643552 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 16 Aug 2023 16:58:43 +1000
Subject: [PATCH 014/410] Rename class
---
TombEngine/Game/collision/PointCollision.cpp | 62 ++++++++++----------
TombEngine/Game/collision/PointCollision.h | 16 ++---
TombEngine/Game/collision/collide_room.cpp | 2 +-
3 files changed, 40 insertions(+), 40 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index be2ba8b11..1c84e0918 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -14,13 +14,13 @@ using namespace TEN::Math;
namespace TEN::Collision
{
- PointCollision::PointCollision(const Vector3i& pos, int roomNumber) :
+ PointCollisionData::PointCollisionData(const Vector3i& pos, int roomNumber) :
Position(pos),
RoomNumber(roomNumber)
{
}
- FloorInfo& PointCollision::GetSector()
+ FloorInfo& PointCollisionData::GetSector()
{
if (SectorPtr != nullptr)
return *SectorPtr;
@@ -32,7 +32,7 @@ namespace TEN::Collision
return *SectorPtr;
}
- FloorInfo& PointCollision::GetTopSector()
+ FloorInfo& PointCollisionData::GetTopSector()
{
if (TopSectorPtr != nullptr)
return *TopSectorPtr;
@@ -51,7 +51,7 @@ namespace TEN::Collision
return *TopSectorPtr;
}
- FloorInfo& PointCollision::GetBottomSector()
+ FloorInfo& PointCollisionData::GetBottomSector()
{
if (BottomSectorPtr != nullptr)
return *BottomSectorPtr;
@@ -70,7 +70,7 @@ namespace TEN::Collision
return *BottomSectorPtr;
}
- int PointCollision::GetFloorHeight()
+ int PointCollisionData::GetFloorHeight()
{
if (FloorHeight.has_value())
return *FloorHeight;
@@ -82,7 +82,7 @@ namespace TEN::Collision
return *FloorHeight;
}
- int PointCollision::GetCeilingHeight()
+ int PointCollisionData::GetCeilingHeight()
{
if (CeilingHeight.has_value())
return *CeilingHeight;
@@ -94,7 +94,7 @@ namespace TEN::Collision
return *CeilingHeight;
}
- Vector3 PointCollision::GetFloorNormal()
+ Vector3 PointCollisionData::GetFloorNormal()
{
if (FloorNormal.has_value())
return *FloorNormal;
@@ -114,7 +114,7 @@ namespace TEN::Collision
return *FloorNormal;
}
- Vector3 PointCollision::GetCeilingNormal()
+ Vector3 PointCollisionData::GetCeilingNormal()
{
if (CeilingNormal.has_value())
return *CeilingNormal;
@@ -134,7 +134,7 @@ namespace TEN::Collision
return *CeilingNormal;
}
- int PointCollision::GetBridgeItemNumber()
+ int PointCollisionData::GetBridgeItemNumber()
{
if (BridgeItemNumber.has_value())
return *BridgeItemNumber;
@@ -146,7 +146,7 @@ namespace TEN::Collision
return *BridgeItemNumber;
}
- int PointCollision::GetWaterSurfaceHeight()
+ int PointCollisionData::GetWaterSurfaceHeight()
{
if (WaterSurfaceHeight.has_value())
return *WaterSurfaceHeight;
@@ -157,7 +157,7 @@ namespace TEN::Collision
return *WaterSurfaceHeight;
}
- int PointCollision::GetWaterTopHeight()
+ int PointCollisionData::GetWaterTopHeight()
{
if (WaterTopHeight.has_value())
return *WaterTopHeight;
@@ -168,7 +168,7 @@ namespace TEN::Collision
return *WaterTopHeight;
}
- int PointCollision::GetWaterBottomHeight()
+ int PointCollisionData::GetWaterBottomHeight()
{
if (WaterBottomHeight.has_value())
return *WaterBottomHeight;
@@ -179,12 +179,12 @@ namespace TEN::Collision
return *WaterBottomHeight;
}
- bool PointCollision::IsWall()
+ bool PointCollisionData::IsWall()
{
return ((GetFloorHeight() == NO_HEIGHT) || (GetCeilingHeight() == NO_HEIGHT));
}
- bool PointCollision::IsSlipperyFloor(short slopeAngleMin)
+ bool PointCollisionData::IsSlipperyFloor(short slopeAngleMin)
{
// Get floor slope angle.
auto floorNormal = GetFloorNormal();
@@ -194,7 +194,7 @@ namespace TEN::Collision
return ((GetBridgeItemNumber() == NO_ITEM) && (abs(slopeAngle) >= slopeAngleMin));
}
- bool PointCollision::IsSlipperyCeiling(short slopeAngleMin)
+ bool PointCollisionData::IsSlipperyCeiling(short slopeAngleMin)
{
// Get ceiling slope angle.
auto ceilingNormal = GetCeilingNormal();
@@ -204,12 +204,12 @@ namespace TEN::Collision
return (abs(slopeAngle) >= slopeAngleMin);
}
- bool PointCollision::IsDiagonalStep()
+ bool PointCollisionData::IsDiagonalStep()
{
return GetBottomSector().IsSurfaceDiagonalStep(true);
}
- bool PointCollision::HasDiagonalSplit()
+ bool PointCollisionData::HasDiagonalSplit()
{
constexpr auto DIAGONAL_SPLIT_0 = 45.0f * RADIAN;
constexpr auto DIAGONAL_SPLIT_1 = 135.0f * RADIAN;
@@ -218,7 +218,7 @@ namespace TEN::Collision
return ((splitAngle == DIAGONAL_SPLIT_0) || (splitAngle == DIAGONAL_SPLIT_1));
}
- bool PointCollision::HasFlippedDiagonalSplit()
+ bool PointCollisionData::HasFlippedDiagonalSplit()
{
constexpr auto DIAGONAL_SPLIT_0 = 45.0f * RADIAN;
@@ -226,13 +226,13 @@ namespace TEN::Collision
return (HasDiagonalSplit() && (splitAngle != DIAGONAL_SPLIT_0));
}
- bool PointCollision::HasEnvironmentFlag(RoomEnvFlags envFlag)
+ bool PointCollisionData::HasEnvironmentFlag(RoomEnvFlags envFlag)
{
const auto& room = g_Level.Rooms[RoomNumber];
return ((room.flags & envFlag) == envFlag);
}
- PointCollision GetPointCollision(const Vector3i& pos, int roomNumber)
+ PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber)
{
// HACK: This function takes arguments for a *current* position and room number.
// However, since some calls to the previous implementation (GetCollision()) had *vertically projected*
@@ -241,10 +241,10 @@ namespace TEN::Collision
short correctedRoomNumber = roomNumber;
GetFloor(pos.x, pos.y, pos.z, &correctedRoomNumber);
- return PointCollision(pos, correctedRoomNumber);
+ return PointCollisionData(pos, correctedRoomNumber);
}
- PointCollision GetPointCollision(const Vector3i& pos, int roomNumber, const Vector3& dir, float dist)
+ PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber, const Vector3& dir, float dist)
{
// Get "location".
short tempRoomNumber = roomNumber;
@@ -258,10 +258,10 @@ namespace TEN::Collision
short probeRoomNumber = GetRoom(location, pos.x, probePos.y, pos.z).RoomNumber;
GetFloor(probePos.x, probePos.y, probePos.z, &probeRoomNumber);
- return PointCollision(probePos, probeRoomNumber);
+ return PointCollisionData(probePos, probeRoomNumber);
}
- PointCollision GetPointCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down, float right)
+ PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down, float right)
{
// Get "location".
short tempRoomNumber = roomNumber;
@@ -275,12 +275,12 @@ namespace TEN::Collision
short probeRoomNumber = GetRoom(location, pos.x, probePos.y, pos.z).RoomNumber;
GetFloor(probePos.x, probePos.y, probePos.z, &probeRoomNumber);
- return PointCollision(probePos, probeRoomNumber);
+ return PointCollisionData(probePos, probeRoomNumber);
}
- PointCollision GetPointCollision(const ItemInfo& item)
+ PointCollisionData GetPointCollision(const ItemInfo& item)
{
- return PointCollision(item.Pose.Position, item.RoomNumber);
+ return PointCollisionData(item.Pose.Position, item.RoomNumber);
}
// TODO: Find cleaner solution. Constructing a "location" on the spot for the player
@@ -296,7 +296,7 @@ namespace TEN::Collision
return RoomVector(sector.Room, item.Pose.Position.y);
}
- PointCollision GetPointCollision(const ItemInfo& item, const Vector3& dir, float dist)
+ PointCollisionData GetPointCollision(const ItemInfo& item, const Vector3& dir, float dist)
{
// Get "location".
auto location = GetEntityLocation(item);
@@ -308,10 +308,10 @@ namespace TEN::Collision
short probeRoomNumber = GetRoom(location, item.Pose.Position.x, probePos.y, item.Pose.Position.z).RoomNumber;
GetFloor(probePos.x, probePos.y, probePos.z, &probeRoomNumber);
- return PointCollision(probePos, probeRoomNumber);
+ return PointCollisionData(probePos, probeRoomNumber);
}
- PointCollision GetPointCollision(const ItemInfo& item, short headingAngle, float forward, float down, float right)
+ PointCollisionData GetPointCollision(const ItemInfo& item, short headingAngle, float forward, float down, float right)
{
// Get "location".
auto location = GetEntityLocation(item);
@@ -323,6 +323,6 @@ namespace TEN::Collision
short probeRoomNumber = GetRoom(location, item.Pose.Position.x, probePos.y, item.Pose.Position.z).RoomNumber;
GetFloor(probePos.x, probePos.y, probePos.z, &probeRoomNumber);
- return PointCollision(probePos, probeRoomNumber);
+ return PointCollisionData(probePos, probeRoomNumber);
}
}
diff --git a/TombEngine/Game/collision/PointCollision.h b/TombEngine/Game/collision/PointCollision.h
index 31ef6df92..d69dcc831 100644
--- a/TombEngine/Game/collision/PointCollision.h
+++ b/TombEngine/Game/collision/PointCollision.h
@@ -9,7 +9,7 @@ using namespace TEN::Math;
namespace TEN::Collision
{
- class PointCollision
+ class PointCollisionData
{
public:
// Members
@@ -33,7 +33,7 @@ namespace TEN::Collision
public:
// Constructors
- PointCollision(const Vector3i& pos, int roomNumber);
+ PointCollisionData(const Vector3i& pos, int roomNumber);
// Getters
FloorInfo& GetSector();
@@ -60,10 +60,10 @@ namespace TEN::Collision
bool HasEnvironmentFlag(RoomEnvFlags envFlag);
};
- PointCollision GetPointCollision(const Vector3i& pos, int roomNumber);
- PointCollision GetPointCollision(const Vector3i& pos, int roomNumber, const Vector3& dir, float dist);
- PointCollision GetPointCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down = 0.0f, float right = 0.0f);
- PointCollision GetPointCollision(const ItemInfo& item);
- PointCollision GetPointCollision(const ItemInfo& item, const Vector3& dir, float dist);
- PointCollision GetPointCollision(const ItemInfo& item, short headingAngle, float forward, float down = 0.0f, float right = 0.0f);
+ PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber);
+ PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber, const Vector3& dir, float dist);
+ PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down = 0.0f, float right = 0.0f);
+ PointCollisionData GetPointCollision(const ItemInfo& item);
+ PointCollisionData GetPointCollision(const ItemInfo& item, const Vector3& dir, float dist);
+ PointCollisionData GetPointCollision(const ItemInfo& item, short headingAngle, float forward, float down = 0.0f, float right = 0.0f);
}
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index f0a9d1113..8c4bfa446 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -117,7 +117,7 @@ bool TestItemRoomCollisionAABB(ItemInfo* item)
return collided;
}
-static CollisionResult ConvertPointCollisionToCollisionResult(PointCollision& pointColl)
+static CollisionResult ConvertPointCollisionToCollisionResult(PointCollisionData& pointColl)
{
auto collResult = CollisionResult{};
From b2da3a9d03929a438cda3355c523466246e8fa72 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 16 Aug 2023 20:23:28 +1000
Subject: [PATCH 015/410] Optimise
---
TombEngine/Game/collision/PointCollision.cpp | 26 +++++++++++---------
1 file changed, 14 insertions(+), 12 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 1c84e0918..f2745450f 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -26,8 +26,8 @@ namespace TEN::Collision
return *SectorPtr;
// Set current sector pointer.
- short probedRoomNumber = RoomNumber;
- SectorPtr = GetFloor(Position.x, Position.y, Position.z, &probedRoomNumber);
+ short probeRoomNumber = RoomNumber;
+ SectorPtr = GetFloor(Position.x, Position.y, Position.z, &probeRoomNumber);
return *SectorPtr;
}
@@ -39,12 +39,13 @@ namespace TEN::Collision
// Set top sector pointer.
auto* topSectorPtr = &GetSector();
- while (topSectorPtr->GetRoomNumberAbove(Position.x, Position.y, Position.z).has_value())
+ auto roomNumberAbove = topSectorPtr->GetRoomNumberAbove(Position.x, Position.y, Position.z);
+ while (roomNumberAbove.has_value())
{
- auto roomNumberAbove = topSectorPtr->GetRoomNumberAbove(Position.x, Position.y, Position.z);
auto& room = g_Level.Rooms[roomNumberAbove.value_or(topSectorPtr->Room)];
-
topSectorPtr = Room::GetSector(&room, Position.x - room.x, Position.z - room.z);
+
+ roomNumberAbove = topSectorPtr->GetRoomNumberAbove(Position.x, Position.y, Position.z);
}
TopSectorPtr = topSectorPtr;
@@ -58,12 +59,13 @@ namespace TEN::Collision
// Set bottom sector pointer.
auto* bottomSectorPtr = &GetSector();
- while (bottomSectorPtr->GetRoomNumberBelow(Position.x, Position.y, Position.z).has_value())
+ auto roomNumberBelow = bottomSectorPtr->GetRoomNumberBelow(Position.x, Position.y, Position.z);
+ while (roomNumberBelow.has_value())
{
- auto roomNumberBelow = bottomSectorPtr->GetRoomNumberBelow(Position.x, Position.y, Position.z);
auto& room = g_Level.Rooms[roomNumberBelow.value_or(bottomSectorPtr->Room)];
-
bottomSectorPtr = Room::GetSector(&room, Position.x - room.x, Position.z - room.z);
+
+ roomNumberBelow = bottomSectorPtr->GetRoomNumberBelow(Position.x, Position.y, Position.z);
}
BottomSectorPtr = bottomSectorPtr;
@@ -181,7 +183,7 @@ namespace TEN::Collision
bool PointCollisionData::IsWall()
{
- return ((GetFloorHeight() == NO_HEIGHT) || (GetCeilingHeight() == NO_HEIGHT));
+ return (GetFloorHeight() == NO_HEIGHT || GetCeilingHeight() == NO_HEIGHT);
}
bool PointCollisionData::IsSlipperyFloor(short slopeAngleMin)
@@ -191,7 +193,7 @@ namespace TEN::Collision
auto slopeAngle = Geometry::GetSurfaceSlopeAngle(floorNormal);
// TODO: Slippery bridges.
- return ((GetBridgeItemNumber() == NO_ITEM) && (abs(slopeAngle) >= slopeAngleMin));
+ return (GetBridgeItemNumber() == NO_ITEM && abs(slopeAngle) >= slopeAngleMin);
}
bool PointCollisionData::IsSlipperyCeiling(short slopeAngleMin)
@@ -215,7 +217,7 @@ namespace TEN::Collision
constexpr auto DIAGONAL_SPLIT_1 = 135.0f * RADIAN;
float splitAngle = GetBottomSector().FloorCollision.SplitAngle;
- return ((splitAngle == DIAGONAL_SPLIT_0) || (splitAngle == DIAGONAL_SPLIT_1));
+ return (splitAngle == DIAGONAL_SPLIT_0 || splitAngle == DIAGONAL_SPLIT_1);
}
bool PointCollisionData::HasFlippedDiagonalSplit()
@@ -223,7 +225,7 @@ namespace TEN::Collision
constexpr auto DIAGONAL_SPLIT_0 = 45.0f * RADIAN;
float splitAngle = GetBottomSector().FloorCollision.SplitAngle;
- return (HasDiagonalSplit() && (splitAngle != DIAGONAL_SPLIT_0));
+ return (HasDiagonalSplit() && splitAngle != DIAGONAL_SPLIT_0);
}
bool PointCollisionData::HasEnvironmentFlag(RoomEnvFlags envFlag)
From 23efb49677338f5fcd8d24c496dcae0ae4033607 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 16 Aug 2023 21:46:16 +1000
Subject: [PATCH 016/410] Add GetCeilingBridgeItemID(); consider bridges above
when checking for slippery ceiling
---
TombEngine/Game/Lara/lara.cpp | 8 ++++-
TombEngine/Game/collision/PointCollision.cpp | 32 ++++++++++++++------
TombEngine/Game/collision/PointCollision.h | 14 +++++----
TombEngine/Game/collision/collide_room.cpp | 6 ++--
4 files changed, 40 insertions(+), 20 deletions(-)
diff --git a/TombEngine/Game/Lara/lara.cpp b/TombEngine/Game/Lara/lara.cpp
index 9608309f1..eac7789bd 100644
--- a/TombEngine/Game/Lara/lara.cpp
+++ b/TombEngine/Game/Lara/lara.cpp
@@ -25,6 +25,7 @@
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/floordata.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/flipeffect.h"
#include "Game/control/volume.h"
#include "Game/effects/Hair.h"
@@ -40,10 +41,11 @@
#include "Sound/sound.h"
#include "Specific/winmain.h"
+using namespace TEN::Collision;
+using namespace TEN::Collision::Floordata;
using namespace TEN::Control::Volumes;
using namespace TEN::Effects::Hair;
using namespace TEN::Effects::Items;
-using namespace TEN::Collision::Floordata;
using namespace TEN::Input;
using namespace TEN::Math;
@@ -445,6 +447,10 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
+ auto pointColl = GetPointCollision(*item);
+ g_Renderer.PrintDebugMessage("Floor bridge: %d", pointColl.GetFloorBridgeItemID());
+ g_Renderer.PrintDebugMessage("Ceiling bridge: %d", pointColl.GetCeilingBridgeItemID());
+
if (lara->Control.Weapon.HasFired)
{
AlertNearbyGuards(item);
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index f2745450f..9f739501f 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -102,7 +102,7 @@ namespace TEN::Collision
return *FloorNormal;
// Set floor normal.
- if (GetBridgeItemNumber() != NO_ITEM)
+ if (GetFloorBridgeItemID() != NO_ITEM)
{
// TODO: Get bridge normal.
FloorNormal = -Vector3::UnitY;
@@ -122,7 +122,7 @@ namespace TEN::Collision
return *CeilingNormal;
// Set ceiling normal.
- if (GetBridgeItemNumber() != NO_ITEM)
+ if (GetCeilingBridgeItemID() != NO_ITEM)
{
// TODO: Get bridge normal.
CeilingNormal = Vector3::UnitY;
@@ -136,16 +136,28 @@ namespace TEN::Collision
return *CeilingNormal;
}
- int PointCollisionData::GetBridgeItemNumber()
+ int PointCollisionData::GetFloorBridgeItemID()
{
- if (BridgeItemNumber.has_value())
- return *BridgeItemNumber;
+ if (FloorBridgeItemID.has_value())
+ return *FloorBridgeItemID;
- // Set bridge item number.
+ // Set floor bridge item ID.
int floorHeight = GetFloorHeight();
- BridgeItemNumber = GetBottomSector().GetInsideBridgeItemNumber(Position.x, floorHeight, Position.z, true, false);;
+ FloorBridgeItemID = GetBottomSector().GetInsideBridgeItemNumber(Position.x, floorHeight, Position.z, true, false);;
- return *BridgeItemNumber;
+ return *FloorBridgeItemID;
+ }
+
+ int PointCollisionData::GetCeilingBridgeItemID()
+ {
+ if (CeilingBridgeItemID.has_value())
+ return *CeilingBridgeItemID;
+
+ // Set ceiling bridge item ID.
+ int ceilingHeight = GetCeilingHeight();
+ CeilingBridgeItemID = GetTopSector().GetInsideBridgeItemNumber(Position.x, ceilingHeight, Position.z, false, true);;
+
+ return *CeilingBridgeItemID;
}
int PointCollisionData::GetWaterSurfaceHeight()
@@ -193,7 +205,7 @@ namespace TEN::Collision
auto slopeAngle = Geometry::GetSurfaceSlopeAngle(floorNormal);
// TODO: Slippery bridges.
- return (GetBridgeItemNumber() == NO_ITEM && abs(slopeAngle) >= slopeAngleMin);
+ return (GetFloorBridgeItemID() == NO_ITEM && abs(slopeAngle) >= slopeAngleMin);
}
bool PointCollisionData::IsSlipperyCeiling(short slopeAngleMin)
@@ -203,7 +215,7 @@ namespace TEN::Collision
auto slopeAngle = Geometry::GetSurfaceSlopeAngle(ceilingNormal, -Vector3::UnitY);
// TODO: Slippery bridges.
- return (abs(slopeAngle) >= slopeAngleMin);
+ return (GetCeilingBridgeItemID() == NO_ITEM && abs(slopeAngle) >= slopeAngleMin);
}
bool PointCollisionData::IsDiagonalStep()
diff --git a/TombEngine/Game/collision/PointCollision.h b/TombEngine/Game/collision/PointCollision.h
index d69dcc831..ea0893dbe 100644
--- a/TombEngine/Game/collision/PointCollision.h
+++ b/TombEngine/Game/collision/PointCollision.h
@@ -21,11 +21,12 @@ namespace TEN::Collision
FloorInfo* TopSectorPtr = nullptr;
FloorInfo* BottomSectorPtr = nullptr;
- std::optional FloorHeight = std::nullopt;
- std::optional CeilingHeight = std::nullopt;
- std::optional FloorNormal = std::nullopt;
- std::optional CeilingNormal = std::nullopt;
- std::optional BridgeItemNumber = std::nullopt;
+ std::optional FloorHeight = std::nullopt;
+ std::optional CeilingHeight = std::nullopt;
+ std::optional FloorNormal = std::nullopt;
+ std::optional CeilingNormal = std::nullopt;
+ std::optional FloorBridgeItemID = std::nullopt;
+ std::optional CeilingBridgeItemID = std::nullopt;
std::optional WaterSurfaceHeight = std::nullopt;
std::optional WaterTopHeight = std::nullopt;
@@ -44,7 +45,8 @@ namespace TEN::Collision
int GetCeilingHeight();
Vector3 GetFloorNormal();
Vector3 GetCeilingNormal();
- int GetBridgeItemNumber();
+ int GetFloorBridgeItemID();
+ int GetCeilingBridgeItemID();
int GetWaterSurfaceHeight();
int GetWaterTopHeight();
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index 8c4bfa446..33c9294cb 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -128,14 +128,14 @@ static CollisionResult ConvertPointCollisionToCollisionResult(PointCollisionData
collResult.Position.Floor = pointColl.GetFloorHeight();
collResult.Position.Ceiling = pointColl.GetCeilingHeight();
- collResult.Position.Bridge = pointColl.GetBridgeItemNumber();
+ collResult.Position.Bridge = pointColl.GetFloorBridgeItemID();
collResult.Position.SplitAngle = pointColl.GetBottomSector().FloorCollision.SplitAngle;
collResult.Position.FloorSlope = pointColl.IsSlipperyFloor();
collResult.Position.CeilingSlope = pointColl.IsSlipperyCeiling();
collResult.Position.DiagonalStep = pointColl.IsDiagonalStep();
- collResult.FloorTilt = collResult.BottomBlock->GetSurfaceTilt(pointColl.Position.x, pointColl.Position.z, true);
- collResult.CeilingTilt = collResult.BottomBlock->GetSurfaceTilt(pointColl.Position.x, pointColl.Position.z, false);
+ collResult.FloorTilt = pointColl.GetBottomSector().GetSurfaceTilt(pointColl.Position.x, pointColl.Position.z, true);
+ collResult.CeilingTilt = pointColl.GetTopSector().GetSurfaceTilt(pointColl.Position.x, pointColl.Position.z, false);
return collResult;
}
From 426b99d75dc590fc4b861e42fd022a8a8119b58a Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 16 Aug 2023 22:27:23 +1000
Subject: [PATCH 017/410] Update methods
---
TombEngine/Game/Lara/lara.cpp | 4 +--
TombEngine/Game/collision/PointCollision.cpp | 28 ++++++++++----------
TombEngine/Game/collision/PointCollision.h | 16 +++++------
TombEngine/Game/collision/collide_room.cpp | 2 +-
4 files changed, 25 insertions(+), 25 deletions(-)
diff --git a/TombEngine/Game/Lara/lara.cpp b/TombEngine/Game/Lara/lara.cpp
index eac7789bd..2c4f3198d 100644
--- a/TombEngine/Game/Lara/lara.cpp
+++ b/TombEngine/Game/Lara/lara.cpp
@@ -448,8 +448,8 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
auto* lara = GetLaraInfo(item);
auto pointColl = GetPointCollision(*item);
- g_Renderer.PrintDebugMessage("Floor bridge: %d", pointColl.GetFloorBridgeItemID());
- g_Renderer.PrintDebugMessage("Ceiling bridge: %d", pointColl.GetCeilingBridgeItemID());
+ g_Renderer.PrintDebugMessage("Floor bridge: %d", pointColl.GetFloorBridgeEntityID());
+ g_Renderer.PrintDebugMessage("Ceiling bridge: %d", pointColl.GetCeilingBridgeEntityID());
if (lara->Control.Weapon.HasFired)
{
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 9f739501f..45e513ea3 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -102,7 +102,7 @@ namespace TEN::Collision
return *FloorNormal;
// Set floor normal.
- if (GetFloorBridgeItemID() != NO_ITEM)
+ if (GetFloorBridgeEntityID() != NO_ITEM)
{
// TODO: Get bridge normal.
FloorNormal = -Vector3::UnitY;
@@ -122,7 +122,7 @@ namespace TEN::Collision
return *CeilingNormal;
// Set ceiling normal.
- if (GetCeilingBridgeItemID() != NO_ITEM)
+ if (GetCeilingBridgeEntityID() != NO_ITEM)
{
// TODO: Get bridge normal.
CeilingNormal = Vector3::UnitY;
@@ -136,28 +136,28 @@ namespace TEN::Collision
return *CeilingNormal;
}
- int PointCollisionData::GetFloorBridgeItemID()
+ int PointCollisionData::GetFloorBridgeEntityID()
{
- if (FloorBridgeItemID.has_value())
- return *FloorBridgeItemID;
+ if (FloorBridgeEntityID.has_value())
+ return *FloorBridgeEntityID;
// Set floor bridge item ID.
int floorHeight = GetFloorHeight();
- FloorBridgeItemID = GetBottomSector().GetInsideBridgeItemNumber(Position.x, floorHeight, Position.z, true, false);;
+ FloorBridgeEntityID = GetBottomSector().GetInsideBridgeItemNumber(Position.x, floorHeight, Position.z, true, false);;
- return *FloorBridgeItemID;
+ return *FloorBridgeEntityID;
}
- int PointCollisionData::GetCeilingBridgeItemID()
+ int PointCollisionData::GetCeilingBridgeEntityID()
{
- if (CeilingBridgeItemID.has_value())
- return *CeilingBridgeItemID;
+ if (CeilingBridgeEntityID.has_value())
+ return *CeilingBridgeEntityID;
// Set ceiling bridge item ID.
int ceilingHeight = GetCeilingHeight();
- CeilingBridgeItemID = GetTopSector().GetInsideBridgeItemNumber(Position.x, ceilingHeight, Position.z, false, true);;
+ CeilingBridgeEntityID = GetTopSector().GetInsideBridgeItemNumber(Position.x, ceilingHeight, Position.z, false, true);;
- return *CeilingBridgeItemID;
+ return *CeilingBridgeEntityID;
}
int PointCollisionData::GetWaterSurfaceHeight()
@@ -205,7 +205,7 @@ namespace TEN::Collision
auto slopeAngle = Geometry::GetSurfaceSlopeAngle(floorNormal);
// TODO: Slippery bridges.
- return (GetFloorBridgeItemID() == NO_ITEM && abs(slopeAngle) >= slopeAngleMin);
+ return (GetFloorBridgeEntityID() == NO_ITEM && abs(slopeAngle) >= slopeAngleMin);
}
bool PointCollisionData::IsSlipperyCeiling(short slopeAngleMin)
@@ -215,7 +215,7 @@ namespace TEN::Collision
auto slopeAngle = Geometry::GetSurfaceSlopeAngle(ceilingNormal, -Vector3::UnitY);
// TODO: Slippery bridges.
- return (GetCeilingBridgeItemID() == NO_ITEM && abs(slopeAngle) >= slopeAngleMin);
+ return (GetCeilingBridgeEntityID() == NO_ITEM && abs(slopeAngle) >= slopeAngleMin);
}
bool PointCollisionData::IsDiagonalStep()
diff --git a/TombEngine/Game/collision/PointCollision.h b/TombEngine/Game/collision/PointCollision.h
index ea0893dbe..2b05afb97 100644
--- a/TombEngine/Game/collision/PointCollision.h
+++ b/TombEngine/Game/collision/PointCollision.h
@@ -21,12 +21,12 @@ namespace TEN::Collision
FloorInfo* TopSectorPtr = nullptr;
FloorInfo* BottomSectorPtr = nullptr;
- std::optional FloorHeight = std::nullopt;
- std::optional CeilingHeight = std::nullopt;
- std::optional FloorNormal = std::nullopt;
- std::optional CeilingNormal = std::nullopt;
- std::optional FloorBridgeItemID = std::nullopt;
- std::optional CeilingBridgeItemID = std::nullopt;
+ std::optional FloorHeight = std::nullopt;
+ std::optional CeilingHeight = std::nullopt;
+ std::optional FloorNormal = std::nullopt;
+ std::optional CeilingNormal = std::nullopt;
+ std::optional FloorBridgeEntityID = std::nullopt;
+ std::optional CeilingBridgeEntityID = std::nullopt;
std::optional WaterSurfaceHeight = std::nullopt;
std::optional WaterTopHeight = std::nullopt;
@@ -45,8 +45,8 @@ namespace TEN::Collision
int GetCeilingHeight();
Vector3 GetFloorNormal();
Vector3 GetCeilingNormal();
- int GetFloorBridgeItemID();
- int GetCeilingBridgeItemID();
+ int GetFloorBridgeEntityID();
+ int GetCeilingBridgeEntityID();
int GetWaterSurfaceHeight();
int GetWaterTopHeight();
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index 33c9294cb..f3bb4f838 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -128,7 +128,7 @@ static CollisionResult ConvertPointCollisionToCollisionResult(PointCollisionData
collResult.Position.Floor = pointColl.GetFloorHeight();
collResult.Position.Ceiling = pointColl.GetCeilingHeight();
- collResult.Position.Bridge = pointColl.GetFloorBridgeItemID();
+ collResult.Position.Bridge = pointColl.GetFloorBridgeEntityID();
collResult.Position.SplitAngle = pointColl.GetBottomSector().FloorCollision.SplitAngle;
collResult.Position.FloorSlope = pointColl.IsSlipperyFloor();
collResult.Position.CeilingSlope = pointColl.IsSlipperyCeiling();
From 8c47b067211061f91f36dceab9656d8fee8cc56d Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 16 Aug 2023 23:01:23 +1000
Subject: [PATCH 018/410] Update comments
---
TombEngine/Game/collision/PointCollision.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 45e513ea3..f43e69c9b 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -141,7 +141,7 @@ namespace TEN::Collision
if (FloorBridgeEntityID.has_value())
return *FloorBridgeEntityID;
- // Set floor bridge item ID.
+ // Set floor bridge entity ID.
int floorHeight = GetFloorHeight();
FloorBridgeEntityID = GetBottomSector().GetInsideBridgeItemNumber(Position.x, floorHeight, Position.z, true, false);;
@@ -153,7 +153,7 @@ namespace TEN::Collision
if (CeilingBridgeEntityID.has_value())
return *CeilingBridgeEntityID;
- // Set ceiling bridge item ID.
+ // Set ceiling bridge entity ID.
int ceilingHeight = GetCeilingHeight();
CeilingBridgeEntityID = GetTopSector().GetInsideBridgeItemNumber(Position.x, ceilingHeight, Position.z, false, true);;
From a97f5954ce5b520e52bd45b51c866891c2462a29 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Thu, 17 Aug 2023 20:05:24 +1000
Subject: [PATCH 019/410] Update comment
---
TombEngine/Game/collision/PointCollision.cpp | 4 ++--
TombEngine/Game/collision/PointCollision.h | 1 +
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index f43e69c9b..5a0858936 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -249,8 +249,8 @@ namespace TEN::Collision
PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber)
{
// HACK: This function takes arguments for a *current* position and room number.
- // However, since some calls to the previous implementation (GetCollision()) had *vertically projected*
- // positions passed to it, for now the room number must be corrected to account for such cases.
+ // However, since some calls to the previous implementation (GetCollision()) had *projected*
+ // positions passed to it, the room number must be corrected to account for such cases for now.
// They are primarily found in camera.cpp.
short correctedRoomNumber = roomNumber;
GetFloor(pos.x, pos.y, pos.z, &correctedRoomNumber);
diff --git a/TombEngine/Game/collision/PointCollision.h b/TombEngine/Game/collision/PointCollision.h
index 2b05afb97..0b604f3fe 100644
--- a/TombEngine/Game/collision/PointCollision.h
+++ b/TombEngine/Game/collision/PointCollision.h
@@ -65,6 +65,7 @@ namespace TEN::Collision
PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber);
PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber, const Vector3& dir, float dist);
PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down = 0.0f, float right = 0.0f);
+
PointCollisionData GetPointCollision(const ItemInfo& item);
PointCollisionData GetPointCollision(const ItemInfo& item, const Vector3& dir, float dist);
PointCollisionData GetPointCollision(const ItemInfo& item, short headingAngle, float forward, float down = 0.0f, float right = 0.0f);
From be03784ddac75c16e189ab706713c901c0d9c394 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sun, 20 Aug 2023 17:52:08 +1000
Subject: [PATCH 020/410] Add helper functions to simplify
---
TombEngine/Game/collision/PointCollision.cpp | 84 ++++++++++----------
TombEngine/Game/collision/PointCollision.h | 18 +++--
TombEngine/Game/collision/collide_room.cpp | 2 +-
3 files changed, 54 insertions(+), 50 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 5a0858936..03ab3f7a0 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -102,7 +102,7 @@ namespace TEN::Collision
return *FloorNormal;
// Set floor normal.
- if (GetFloorBridgeEntityID() != NO_ITEM)
+ if (GetFloorBridgeItemNumber() != NO_ITEM)
{
// TODO: Get bridge normal.
FloorNormal = -Vector3::UnitY;
@@ -122,7 +122,7 @@ namespace TEN::Collision
return *CeilingNormal;
// Set ceiling normal.
- if (GetCeilingBridgeEntityID() != NO_ITEM)
+ if (GetCeilingBridgeItemNumber() != NO_ITEM)
{
// TODO: Get bridge normal.
CeilingNormal = Vector3::UnitY;
@@ -136,28 +136,28 @@ namespace TEN::Collision
return *CeilingNormal;
}
- int PointCollisionData::GetFloorBridgeEntityID()
+ int PointCollisionData::GetFloorBridgeItemNumber()
{
- if (FloorBridgeEntityID.has_value())
- return *FloorBridgeEntityID;
+ if (FloorBridgeItemNumber.has_value())
+ return *FloorBridgeItemNumber;
- // Set floor bridge entity ID.
+ // Set floor bridge item number.
int floorHeight = GetFloorHeight();
- FloorBridgeEntityID = GetBottomSector().GetInsideBridgeItemNumber(Position.x, floorHeight, Position.z, true, false);;
+ FloorBridgeItemNumber = GetBottomSector().GetInsideBridgeItemNumber(Position.x, floorHeight, Position.z, true, false);;
- return *FloorBridgeEntityID;
+ return *FloorBridgeItemNumber;
}
- int PointCollisionData::GetCeilingBridgeEntityID()
+ int PointCollisionData::GetCeilingBridgeItemNumber()
{
- if (CeilingBridgeEntityID.has_value())
- return *CeilingBridgeEntityID;
+ if (CeilingBridgeItemNumber.has_value())
+ return *CeilingBridgeItemNumber;
- // Set ceiling bridge entity ID.
+ // Set ceiling bridge item number.
int ceilingHeight = GetCeilingHeight();
- CeilingBridgeEntityID = GetTopSector().GetInsideBridgeItemNumber(Position.x, ceilingHeight, Position.z, false, true);;
+ CeilingBridgeItemNumber = GetTopSector().GetInsideBridgeItemNumber(Position.x, ceilingHeight, Position.z, false, true);;
- return *CeilingBridgeEntityID;
+ return *CeilingBridgeItemNumber;
}
int PointCollisionData::GetWaterSurfaceHeight()
@@ -205,7 +205,7 @@ namespace TEN::Collision
auto slopeAngle = Geometry::GetSurfaceSlopeAngle(floorNormal);
// TODO: Slippery bridges.
- return (GetFloorBridgeEntityID() == NO_ITEM && abs(slopeAngle) >= slopeAngleMin);
+ return (GetFloorBridgeItemNumber() == NO_ITEM && abs(slopeAngle) >= slopeAngleMin);
}
bool PointCollisionData::IsSlipperyCeiling(short slopeAngleMin)
@@ -215,7 +215,7 @@ namespace TEN::Collision
auto slopeAngle = Geometry::GetSurfaceSlopeAngle(ceilingNormal, -Vector3::UnitY);
// TODO: Slippery bridges.
- return (GetCeilingBridgeEntityID() == NO_ITEM && abs(slopeAngle) >= slopeAngleMin);
+ return (GetCeilingBridgeItemNumber() == NO_ITEM && abs(slopeAngle) >= slopeAngleMin);
}
bool PointCollisionData::IsDiagonalStep()
@@ -250,7 +250,7 @@ namespace TEN::Collision
{
// HACK: This function takes arguments for a *current* position and room number.
// However, since some calls to the previous implementation (GetCollision()) had *projected*
- // positions passed to it, the room number must be corrected to account for such cases for now.
+ // positions passed to it, the room number must be corrected to account for such cases.
// They are primarily found in camera.cpp.
short correctedRoomNumber = roomNumber;
GetFloor(pos.x, pos.y, pos.z, &correctedRoomNumber);
@@ -258,19 +258,31 @@ namespace TEN::Collision
return PointCollisionData(pos, correctedRoomNumber);
}
+ static int GetProbeRoomNumber(const Vector3i& pos, const RoomVector& location, const Vector3i& probePos)
+ {
+ // Conduct L-shaped room traversal.
+ short probeRoomNumber = GetRoom(location, pos.x, probePos.y, pos.z).RoomNumber;
+ GetFloor(probePos.x, probePos.y, probePos.z, &probeRoomNumber);
+
+ return probeRoomNumber;
+ }
+
+ static RoomVector GetPositionLocation(const Vector3i& pos, int roomNumber)
+ {
+ short tempRoomNumber = roomNumber;
+ const auto& sector = *GetFloor(pos.x, pos.y, pos.z, &tempRoomNumber);
+
+ return RoomVector(sector.Room, pos.y);
+ }
+
PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber, const Vector3& dir, float dist)
{
// Get "location".
- short tempRoomNumber = roomNumber;
- const auto& sector = *GetFloor(pos.x, pos.y, pos.z, &tempRoomNumber);
- auto location = RoomVector(sector.Room, pos.y);
+ auto location = GetPositionLocation(pos, roomNumber);
// Calculate probe position.
auto probePos = Geometry::TranslatePoint(pos, dir, dist);
-
- // Get probe position's room number.
- short probeRoomNumber = GetRoom(location, pos.x, probePos.y, pos.z).RoomNumber;
- GetFloor(probePos.x, probePos.y, probePos.z, &probeRoomNumber);
+ short probeRoomNumber = GetProbeRoomNumber(pos, location, probePos);
return PointCollisionData(probePos, probeRoomNumber);
}
@@ -278,16 +290,11 @@ namespace TEN::Collision
PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down, float right)
{
// Get "location".
- short tempRoomNumber = roomNumber;
- const auto& sector = *GetFloor(pos.x, pos.y, pos.z, &tempRoomNumber);
- auto location = RoomVector(sector.Room, pos.y);
+ auto location = GetPositionLocation(pos, roomNumber);
// Calculate probe position.
auto probePos = Geometry::TranslatePoint(pos, headingAngle, forward, down, right);
-
- // Get probe position's room number.
- short probeRoomNumber = GetRoom(location, pos.x, probePos.y, pos.z).RoomNumber;
- GetFloor(probePos.x, probePos.y, probePos.z, &probeRoomNumber);
+ short probeRoomNumber = GetProbeRoomNumber(pos, location, probePos);
return PointCollisionData(probePos, probeRoomNumber);
}
@@ -297,10 +304,11 @@ namespace TEN::Collision
return PointCollisionData(item.Pose.Position, item.RoomNumber);
}
- // TODO: Find cleaner solution. Constructing a "location" on the spot for the player
- // can result in a stumble when climbing onto thin platforms. -- Sezz 2022.06.14
static RoomVector GetEntityLocation(const ItemInfo& item)
{
+ // TODO: Find cleaner solution. Constructing a "location" for the player on the spot
+ // can result in stumbles when climbing onto thin platforms.
+ // May have to do with player's room number being updated at half-height? -- Sezz 2022.06.14
if (item.IsLara())
return item.Location;
@@ -317,10 +325,7 @@ namespace TEN::Collision
// Calculate probe position.
auto probePos = Geometry::TranslatePoint(item.Pose.Position, dir, dist);
-
- // Get probe position's room number.
- short probeRoomNumber = GetRoom(location, item.Pose.Position.x, probePos.y, item.Pose.Position.z).RoomNumber;
- GetFloor(probePos.x, probePos.y, probePos.z, &probeRoomNumber);
+ short probeRoomNumber = GetProbeRoomNumber(item.Pose.Position, location, probePos);
return PointCollisionData(probePos, probeRoomNumber);
}
@@ -332,10 +337,7 @@ namespace TEN::Collision
// Calculate probe position.
auto probePos = Geometry::TranslatePoint(item.Pose.Position, headingAngle, forward, down, right);
-
- // Get probe position's room number.
- short probeRoomNumber = GetRoom(location, item.Pose.Position.x, probePos.y, item.Pose.Position.z).RoomNumber;
- GetFloor(probePos.x, probePos.y, probePos.z, &probeRoomNumber);
+ short probeRoomNumber = GetProbeRoomNumber(item.Pose.Position, location, probePos);
return PointCollisionData(probePos, probeRoomNumber);
}
diff --git a/TombEngine/Game/collision/PointCollision.h b/TombEngine/Game/collision/PointCollision.h
index 0b604f3fe..7869e690f 100644
--- a/TombEngine/Game/collision/PointCollision.h
+++ b/TombEngine/Game/collision/PointCollision.h
@@ -4,6 +4,8 @@
enum RoomEnvFlags;
class FloorInfo;
+struct ItemInfo;
+struct RoomVector;
using namespace TEN::Math;
@@ -21,12 +23,12 @@ namespace TEN::Collision
FloorInfo* TopSectorPtr = nullptr;
FloorInfo* BottomSectorPtr = nullptr;
- std::optional FloorHeight = std::nullopt;
- std::optional CeilingHeight = std::nullopt;
- std::optional FloorNormal = std::nullopt;
- std::optional CeilingNormal = std::nullopt;
- std::optional FloorBridgeEntityID = std::nullopt;
- std::optional CeilingBridgeEntityID = std::nullopt;
+ std::optional FloorHeight = std::nullopt;
+ std::optional CeilingHeight = std::nullopt;
+ std::optional FloorNormal = std::nullopt;
+ std::optional CeilingNormal = std::nullopt;
+ std::optional FloorBridgeItemNumber = std::nullopt;
+ std::optional CeilingBridgeItemNumber = std::nullopt;
std::optional WaterSurfaceHeight = std::nullopt;
std::optional WaterTopHeight = std::nullopt;
@@ -45,8 +47,8 @@ namespace TEN::Collision
int GetCeilingHeight();
Vector3 GetFloorNormal();
Vector3 GetCeilingNormal();
- int GetFloorBridgeEntityID();
- int GetCeilingBridgeEntityID();
+ int GetFloorBridgeItemNumber();
+ int GetCeilingBridgeItemNumber();
int GetWaterSurfaceHeight();
int GetWaterTopHeight();
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index f3bb4f838..d62d17f5d 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -128,7 +128,7 @@ static CollisionResult ConvertPointCollisionToCollisionResult(PointCollisionData
collResult.Position.Floor = pointColl.GetFloorHeight();
collResult.Position.Ceiling = pointColl.GetCeilingHeight();
- collResult.Position.Bridge = pointColl.GetFloorBridgeEntityID();
+ collResult.Position.Bridge = pointColl.GetFloorBridgeItemNumber();
collResult.Position.SplitAngle = pointColl.GetBottomSector().FloorCollision.SplitAngle;
collResult.Position.FloorSlope = pointColl.IsSlipperyFloor();
collResult.Position.CeilingSlope = pointColl.IsSlipperyCeiling();
From bacb5c99ce2f05fe75227b40a28e71004b58e706 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sun, 20 Aug 2023 17:56:53 +1000
Subject: [PATCH 021/410] Get location
---
TombEngine/Game/collision/PointCollision.cpp | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 03ab3f7a0..3ac69ddf0 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -267,7 +267,7 @@ namespace TEN::Collision
return probeRoomNumber;
}
- static RoomVector GetPositionLocation(const Vector3i& pos, int roomNumber)
+ static RoomVector GetLocation(const Vector3i& pos, int roomNumber)
{
short tempRoomNumber = roomNumber;
const auto& sector = *GetFloor(pos.x, pos.y, pos.z, &tempRoomNumber);
@@ -278,7 +278,7 @@ namespace TEN::Collision
PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber, const Vector3& dir, float dist)
{
// Get "location".
- auto location = GetPositionLocation(pos, roomNumber);
+ auto location = GetLocation(pos, roomNumber);
// Calculate probe position.
auto probePos = Geometry::TranslatePoint(pos, dir, dist);
@@ -290,7 +290,7 @@ namespace TEN::Collision
PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down, float right)
{
// Get "location".
- auto location = GetPositionLocation(pos, roomNumber);
+ auto location = GetLocation(pos, roomNumber);
// Calculate probe position.
auto probePos = Geometry::TranslatePoint(pos, headingAngle, forward, down, right);
@@ -304,7 +304,7 @@ namespace TEN::Collision
return PointCollisionData(item.Pose.Position, item.RoomNumber);
}
- static RoomVector GetEntityLocation(const ItemInfo& item)
+ static RoomVector GetLocation(const ItemInfo& item)
{
// TODO: Find cleaner solution. Constructing a "location" for the player on the spot
// can result in stumbles when climbing onto thin platforms.
@@ -321,7 +321,7 @@ namespace TEN::Collision
PointCollisionData GetPointCollision(const ItemInfo& item, const Vector3& dir, float dist)
{
// Get "location".
- auto location = GetEntityLocation(item);
+ auto location = GetLocation(item);
// Calculate probe position.
auto probePos = Geometry::TranslatePoint(item.Pose.Position, dir, dist);
@@ -333,7 +333,7 @@ namespace TEN::Collision
PointCollisionData GetPointCollision(const ItemInfo& item, short headingAngle, float forward, float down, float right)
{
// Get "location".
- auto location = GetEntityLocation(item);
+ auto location = GetLocation(item);
// Calculate probe position.
auto probePos = Geometry::TranslatePoint(item.Pose.Position, headingAngle, forward, down, right);
From 104066b91519f6d2efc9b8449f987e5c37185f81 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sun, 20 Aug 2023 23:43:55 +1000
Subject: [PATCH 022/410] Get bridge surface normals
---
TombEngine/Game/Lara/lara.cpp | 9 +-
TombEngine/Game/collision/PointCollision.cpp | 96 +++++++++++++-------
TombEngine/Game/collision/PointCollision.h | 4 +
TombEngine/Game/collision/collide_room.cpp | 15 +--
4 files changed, 78 insertions(+), 46 deletions(-)
diff --git a/TombEngine/Game/Lara/lara.cpp b/TombEngine/Game/Lara/lara.cpp
index 2c4f3198d..2ecc32754 100644
--- a/TombEngine/Game/Lara/lara.cpp
+++ b/TombEngine/Game/Lara/lara.cpp
@@ -448,8 +448,13 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
auto* lara = GetLaraInfo(item);
auto pointColl = GetPointCollision(*item);
- g_Renderer.PrintDebugMessage("Floor bridge: %d", pointColl.GetFloorBridgeEntityID());
- g_Renderer.PrintDebugMessage("Ceiling bridge: %d", pointColl.GetCeilingBridgeEntityID());
+
+ auto origin = item->Pose.Position + Vector3i(0, -BLOCK(1), 0);
+ g_Renderer.AddLine3D(origin.ToVector3(), Geometry::TranslatePoint(origin, pointColl.GetFloorNormal(), BLOCK(0.5f)).ToVector3(), Vector4(0, 1, 0, 1));
+ g_Renderer.AddLine3D(origin.ToVector3(), Geometry::TranslatePoint(origin, pointColl.GetCeilingNormal(), BLOCK(0.5f)).ToVector3(), Vector4(1, 0, 0, 1));
+
+ g_Renderer.PrintDebugMessage("Floor bridge: %d", pointColl.GetFloorBridgeItemNumber());
+ g_Renderer.PrintDebugMessage("Ceiling bridge: %d", pointColl.GetCeilingBridgeItemNumber());
if (lara->Control.Weapon.HasFired)
{
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 3ac69ddf0..79cdc780a 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -5,7 +5,9 @@
#include "Game/collision/floordata.h"
#include "Game/items.h"
#include "Game/room.h"
+#include "Game/Setup.h"
#include "Math/Math.h"
+#include "Objects/game_object_ids.h"
#include "Specific/level.h"
using namespace TEN::Collision::Floordata;
@@ -104,8 +106,7 @@ namespace TEN::Collision
// Set floor normal.
if (GetFloorBridgeItemNumber() != NO_ITEM)
{
- // TODO: Get bridge normal.
- FloorNormal = -Vector3::UnitY;
+ FloorNormal = GetBridgeNormal(true);
}
else
{
@@ -124,8 +125,7 @@ namespace TEN::Collision
// Set ceiling normal.
if (GetCeilingBridgeItemNumber() != NO_ITEM)
{
- // TODO: Get bridge normal.
- CeilingNormal = Vector3::UnitY;
+ CeilingNormal = GetBridgeNormal(false);
}
else
{
@@ -195,7 +195,8 @@ namespace TEN::Collision
bool PointCollisionData::IsWall()
{
- return (GetFloorHeight() == NO_HEIGHT || GetCeilingHeight() == NO_HEIGHT);
+ return (GetFloorHeight() == NO_HEIGHT || GetCeilingHeight() == NO_HEIGHT ||
+ GetFloorHeight() < GetCeilingHeight());
}
bool PointCollisionData::IsSlipperyFloor(short slopeAngleMin)
@@ -204,8 +205,7 @@ namespace TEN::Collision
auto floorNormal = GetFloorNormal();
auto slopeAngle = Geometry::GetSurfaceSlopeAngle(floorNormal);
- // TODO: Slippery bridges.
- return (GetFloorBridgeItemNumber() == NO_ITEM && abs(slopeAngle) >= slopeAngleMin);
+ return (abs(slopeAngle) >= slopeAngleMin);
}
bool PointCollisionData::IsSlipperyCeiling(short slopeAngleMin)
@@ -214,8 +214,7 @@ namespace TEN::Collision
auto ceilingNormal = GetCeilingNormal();
auto slopeAngle = Geometry::GetSurfaceSlopeAngle(ceilingNormal, -Vector3::UnitY);
- // TODO: Slippery bridges.
- return (GetCeilingBridgeItemNumber() == NO_ITEM && abs(slopeAngle) >= slopeAngleMin);
+ return (abs(slopeAngle) >= slopeAngleMin);
}
bool PointCollisionData::IsDiagonalStep()
@@ -246,16 +245,39 @@ namespace TEN::Collision
return ((room.flags & envFlag) == envFlag);
}
- PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber)
+ // HACK.
+ Vector3 PointCollisionData::GetBridgeNormal(bool isFloor)
{
- // HACK: This function takes arguments for a *current* position and room number.
- // However, since some calls to the previous implementation (GetCollision()) had *projected*
- // positions passed to it, the room number must be corrected to account for such cases.
- // They are primarily found in camera.cpp.
- short correctedRoomNumber = roomNumber;
- GetFloor(pos.x, pos.y, pos.z, &correctedRoomNumber);
+ constexpr auto ANGLE_STEP = ANGLE(11.25f);
- return PointCollisionData(pos, correctedRoomNumber);
+ int itemNumber = isFloor ? GetFloorBridgeItemNumber() : GetCeilingBridgeItemNumber();
+ const auto& item = g_Level.Items[itemNumber];
+
+ auto orient = item.Pose.Orientation;
+ switch (item.ObjectNumber)
+ {
+ default:
+ case ID_BRIDGE_FLAT:
+ break;
+
+ case ID_BRIDGE_TILT1:
+ orient.z -= ANGLE_STEP;
+ break;
+
+ case ID_BRIDGE_TILT2:
+ orient.z -= ANGLE_STEP * 2;
+ break;
+
+ case ID_BRIDGE_TILT3:
+ orient.z -= ANGLE_STEP * 3;
+ break;
+
+ case ID_BRIDGE_TILT4:
+ orient.z -= ANGLE_STEP * 4;
+ break;
+ }
+
+ return Vector3::Transform(isFloor ? -Vector3::UnitY : Vector3::UnitY, orient.ToRotationMatrix());
}
static int GetProbeRoomNumber(const Vector3i& pos, const RoomVector& location, const Vector3i& probePos)
@@ -275,6 +297,32 @@ namespace TEN::Collision
return RoomVector(sector.Room, pos.y);
}
+ static RoomVector GetLocation(const ItemInfo& item)
+ {
+ // TODO: Find cleaner solution. Constructing a "location" for the player on the spot
+ // can result in stumbles when climbing onto thin platforms.
+ // May have to do with player's room number being updated at half-height? -- Sezz 2022.06.14
+ if (item.IsLara())
+ return item.Location;
+
+ short tempRoomNumber = item.RoomNumber;
+ const auto& sector = *GetFloor(item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z, &tempRoomNumber);
+
+ return RoomVector(sector.Room, item.Pose.Position.y);
+ }
+
+ PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber)
+ {
+ // HACK: This function takes arguments for a *current* position and room number.
+ // However, since some calls to the previous implementation (GetCollision()) had *projected*
+ // positions passed to it, the room number must be corrected to account for such cases.
+ // They are primarily found in camera.cpp.
+ short correctedRoomNumber = roomNumber;
+ GetFloor(pos.x, pos.y, pos.z, &correctedRoomNumber);
+
+ return PointCollisionData(pos, correctedRoomNumber);
+ }
+
PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber, const Vector3& dir, float dist)
{
// Get "location".
@@ -304,20 +352,6 @@ namespace TEN::Collision
return PointCollisionData(item.Pose.Position, item.RoomNumber);
}
- static RoomVector GetLocation(const ItemInfo& item)
- {
- // TODO: Find cleaner solution. Constructing a "location" for the player on the spot
- // can result in stumbles when climbing onto thin platforms.
- // May have to do with player's room number being updated at half-height? -- Sezz 2022.06.14
- if (item.IsLara())
- return item.Location;
-
- short tempRoomNumber = item.RoomNumber;
- const auto& sector = *GetFloor(item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z, &tempRoomNumber);
-
- return RoomVector(sector.Room, item.Pose.Position.y);
- }
-
PointCollisionData GetPointCollision(const ItemInfo& item, const Vector3& dir, float dist)
{
// Get "location".
diff --git a/TombEngine/Game/collision/PointCollision.h b/TombEngine/Game/collision/PointCollision.h
index 7869e690f..a61e78656 100644
--- a/TombEngine/Game/collision/PointCollision.h
+++ b/TombEngine/Game/collision/PointCollision.h
@@ -62,6 +62,10 @@ namespace TEN::Collision
bool HasDiagonalSplit();
bool HasFlippedDiagonalSplit();
bool HasEnvironmentFlag(RoomEnvFlags envFlag);
+
+ private:
+ // Helpers
+ Vector3 GetBridgeNormal(bool isFloor);
};
PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber);
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index d62d17f5d..535262702 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -187,32 +187,21 @@ CollisionResult GetCollision(const GameVector& pos)
return ConvertPointCollisionToCollisionResult(pointColl);
}
-// A reworked legacy GetFloorHeight() function which writes data
-// into a special CollisionResult struct instead of global variables.
-// It writes for both floor and ceiling heights at the same coordinates, meaning it should be used
-// in place of successive GetFloorHeight() and GetCeilingHeight() calls to increase readability.
+// Deprecated.
CollisionResult GetCollision(FloorInfo* floor, int x, int y, int z)
{
auto result = CollisionResult{};
- // Record coordinates.
result.Coordinates = Vector3i(x, y, z);
-
- // Return provided collision block into result as itself.
- result.Block = floor;
-
- // Floor and ceiling heights are borrowed directly from floordata.
result.Position.Floor = GetFloorHeight(RoomVector(floor->Room, y), x, z).value_or(NO_HEIGHT);
result.Position.Ceiling = GetCeilingHeight(RoomVector(floor->Room, y), x, z).value_or(NO_HEIGHT);
- // Probe bottom collision block through portals.
+ result.Block = floor;
while (floor->GetRoomNumberBelow(x, y, z).value_or(NO_ROOM) != NO_ROOM)
{
auto* room = &g_Level.Rooms[floor->GetRoomNumberBelow(x, y, z).value_or(floor->Room)];
floor = GetSector(room, x - room->x, z - room->z);
}
-
- // Return probed bottom collision block into result.
result.BottomBlock = floor;
// Get tilts.
From 7acff7d9125d50dcbf157a56d7289e5c77deed51 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Tue, 22 Aug 2023 16:45:43 +1000
Subject: [PATCH 023/410] Update constant
---
TombEngine/Game/collision/PointCollision.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 79cdc780a..7f05df2e1 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -248,7 +248,7 @@ namespace TEN::Collision
// HACK.
Vector3 PointCollisionData::GetBridgeNormal(bool isFloor)
{
- constexpr auto ANGLE_STEP = ANGLE(11.25f);
+ constexpr auto ANGLE_STEP = short(ANGLE(45.0f) / 4);
int itemNumber = isFloor ? GetFloorBridgeItemNumber() : GetCeilingBridgeItemNumber();
const auto& item = g_Level.Items[itemNumber];
From 666fe3e60500cf45d8c5295de3dbff7b78faba06 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sun, 27 Aug 2023 17:41:37 +1000
Subject: [PATCH 024/410] Simplify
---
TombEngine/Game/collision/PointCollision.cpp | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 7f05df2e1..34c27c0a1 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -80,8 +80,8 @@ namespace TEN::Collision
return *FloorHeight;
// Set floor height.
- auto roomVector = RoomVector(GetSector().Room, Position.y);
- FloorHeight = Floordata::GetFloorHeight(roomVector, Position.x, Position.z).value_or(NO_HEIGHT);
+ auto location = RoomVector(GetSector().Room, Position.y);
+ FloorHeight = Floordata::GetFloorHeight(location, Position.x, Position.z).value_or(NO_HEIGHT);
return *FloorHeight;
}
@@ -92,8 +92,8 @@ namespace TEN::Collision
return *CeilingHeight;
// Set ceiling height.
- auto roomVector = RoomVector(GetSector().Room, Position.y);
- CeilingHeight = Floordata::GetCeilingHeight(roomVector, Position.x, Position.z).value_or(NO_HEIGHT);
+ auto location = RoomVector(GetSector().Room, Position.y);
+ CeilingHeight = Floordata::GetCeilingHeight(location, Position.x, Position.z).value_or(NO_HEIGHT);
return *CeilingHeight;
}
@@ -277,7 +277,8 @@ namespace TEN::Collision
break;
}
- return Vector3::Transform(isFloor ? -Vector3::UnitY : Vector3::UnitY, orient.ToRotationMatrix());
+ int sign = isFloor ? -1 : 1;
+ return Vector3::Transform(Vector3::UnitY * sign, orient.ToRotationMatrix());
}
static int GetProbeRoomNumber(const Vector3i& pos, const RoomVector& location, const Vector3i& probePos)
From a8b1f6575ac25a92523dd9f7e2c72c5f3248eb87 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sun, 27 Aug 2023 18:45:44 +1000
Subject: [PATCH 025/410] Update comments; make parameters const
---
TombEngine/Game/collision/collide_room.cpp | 23 +++++++++++++---------
TombEngine/Game/collision/collide_room.h | 6 +++---
2 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index 535262702..bdfa12a09 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -140,54 +140,56 @@ static CollisionResult ConvertPointCollisionToCollisionResult(PointCollisionData
return collResult;
}
+// NOTE: Deprecated. Use GetPointCollision().
CollisionResult GetCollision(const ItemInfo& item)
{
auto pointColl = GetPointCollision(item);
return ConvertPointCollisionToCollisionResult(pointColl);
}
-CollisionResult GetCollision(ItemInfo* item)
+// NOTE: Deprecated. Use GetPointCollision().
+CollisionResult GetCollision(const ItemInfo* item)
{
auto pointColl = GetPointCollision(*item);
return ConvertPointCollisionToCollisionResult(pointColl);
}
-CollisionResult GetCollision(ItemInfo* item, short headingAngle, float forward, float down, float right)
+// NOTE: Deprecated. Use GetPointCollision().
+CollisionResult GetCollision(const ItemInfo* item, short headingAngle, float forward, float down, float right)
{
auto pointColl = GetPointCollision(*item, headingAngle, forward, down, right);
return ConvertPointCollisionToCollisionResult(pointColl);
}
+// NOTE: Deprecated. Use GetPointCollision().
CollisionResult GetCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down, float right)
{
auto pointColl = GetPointCollision(pos, roomNumber, headingAngle, forward, down, right);
return ConvertPointCollisionToCollisionResult(pointColl);
}
-// Overload used as universal wrapper across collisional code replacing
-// triads of roomNumber-GetFloor()-GetFloorHeight() calls.
-// Advantage is that it does NOT modify incoming roomNumber argument,
-// instead storing one modified by GetFloor() within a returned CollisionResult struct.
-// This way, no external variables are modified as output arguments.
+// NOTE: Deprecated. Use GetPointCollision().
CollisionResult GetCollision(const Vector3i& pos, int roomNumber)
{
auto pointColl = GetPointCollision(pos, roomNumber);
return ConvertPointCollisionToCollisionResult(pointColl);
}
+// NOTE: Deprecated. Use GetPointCollision().
CollisionResult GetCollision(int x, int y, int z, short roomNumber)
{
auto pointColl = GetPointCollision(Vector3i(x, y, z), roomNumber);
return ConvertPointCollisionToCollisionResult(pointColl);
}
+// NOTE: Deprecated. Use GetPointCollision().
CollisionResult GetCollision(const GameVector& pos)
{
auto pointColl = GetPointCollision(pos.ToVector3i(), pos.RoomNumber);
return ConvertPointCollisionToCollisionResult(pointColl);
}
-// Deprecated.
+// NOTE: Deprecated. Use GetPointCollision().
CollisionResult GetCollision(FloorInfo* floor, int x, int y, int z)
{
auto result = CollisionResult{};
@@ -213,7 +215,10 @@ CollisionResult GetCollision(FloorInfo* floor, int x, int y, int z)
result.Position.SplitAngle = floor->FloorCollision.SplitAngle;
result.Position.Bridge = result.BottomBlock->GetInsideBridgeItemNumber(x, result.Position.Floor, z, true, false);
result.Position.FloorSlope = result.Position.Bridge < 0 && (abs(result.FloorTilt.x) >= 3 || (abs(result.FloorTilt.y) >= 3));
- result.Position.CeilingSlope = abs(result.CeilingTilt.x) >= 4 || abs(result.CeilingTilt.y) >= 4; // TODO: Fix on bridges placed beneath ceiling slopes. @Sezz 2022.01.29
+
+ // TODO: Fix on bridges placed beneath ceiling slopes. @Sezz 2022.01.29
+ // NOTE: Already fixed if using GetPointCollision().
+ result.Position.CeilingSlope = abs(result.CeilingTilt.x) >= 4 || abs(result.CeilingTilt.y) >= 4;
return result;
}
diff --git a/TombEngine/Game/collision/collide_room.h b/TombEngine/Game/collision/collide_room.h
index 1ac8a1633..09558c0d7 100644
--- a/TombEngine/Game/collision/collide_room.h
+++ b/TombEngine/Game/collision/collide_room.h
@@ -129,10 +129,10 @@ struct CollisionInfo
[[nodiscard]] bool TestItemRoomCollisionAABB(ItemInfo* item);
-// All deprecated. Use GetPointCollision() instead.
+// NOTE: All overloads deprecated. Use GetPointCollision().
CollisionResult GetCollision(const ItemInfo& item);
-CollisionResult GetCollision(ItemInfo* item);
-CollisionResult GetCollision(ItemInfo* item, short headingAngle, float forward, float down = 0.0f, float right = 0.0f);
+CollisionResult GetCollision(const ItemInfo* item);
+CollisionResult GetCollision(const ItemInfo* item, short headingAngle, float forward, float down = 0.0f, float right = 0.0f);
CollisionResult GetCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down = 0.0f, float right = 0.0f);
CollisionResult GetCollision(const Vector3i& pos, int roomNumber);
CollisionResult GetCollision(int x, int y, int z, short roomNumber);
From a286dbdd0309cccd32100a4d6bb19ccb72006b8f Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sun, 27 Aug 2023 18:51:30 +1000
Subject: [PATCH 026/410] Update collide_room.cpp
---
TombEngine/Game/collision/collide_room.cpp | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index bdfa12a09..646f9120e 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -117,7 +117,7 @@ bool TestItemRoomCollisionAABB(ItemInfo* item)
return collided;
}
-static CollisionResult ConvertPointCollisionToCollisionResult(PointCollisionData& pointColl)
+static CollisionResult ConvertPointCollDataToCollResult(PointCollisionData& pointColl)
{
auto collResult = CollisionResult{};
@@ -144,49 +144,49 @@ static CollisionResult ConvertPointCollisionToCollisionResult(PointCollisionData
CollisionResult GetCollision(const ItemInfo& item)
{
auto pointColl = GetPointCollision(item);
- return ConvertPointCollisionToCollisionResult(pointColl);
+ return ConvertPointCollDataToCollResult(pointColl);
}
// NOTE: Deprecated. Use GetPointCollision().
CollisionResult GetCollision(const ItemInfo* item)
{
auto pointColl = GetPointCollision(*item);
- return ConvertPointCollisionToCollisionResult(pointColl);
+ return ConvertPointCollDataToCollResult(pointColl);
}
// NOTE: Deprecated. Use GetPointCollision().
CollisionResult GetCollision(const ItemInfo* item, short headingAngle, float forward, float down, float right)
{
auto pointColl = GetPointCollision(*item, headingAngle, forward, down, right);
- return ConvertPointCollisionToCollisionResult(pointColl);
+ return ConvertPointCollDataToCollResult(pointColl);
}
// NOTE: Deprecated. Use GetPointCollision().
CollisionResult GetCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down, float right)
{
auto pointColl = GetPointCollision(pos, roomNumber, headingAngle, forward, down, right);
- return ConvertPointCollisionToCollisionResult(pointColl);
+ return ConvertPointCollDataToCollResult(pointColl);
}
// NOTE: Deprecated. Use GetPointCollision().
CollisionResult GetCollision(const Vector3i& pos, int roomNumber)
{
auto pointColl = GetPointCollision(pos, roomNumber);
- return ConvertPointCollisionToCollisionResult(pointColl);
+ return ConvertPointCollDataToCollResult(pointColl);
}
// NOTE: Deprecated. Use GetPointCollision().
CollisionResult GetCollision(int x, int y, int z, short roomNumber)
{
auto pointColl = GetPointCollision(Vector3i(x, y, z), roomNumber);
- return ConvertPointCollisionToCollisionResult(pointColl);
+ return ConvertPointCollDataToCollResult(pointColl);
}
// NOTE: Deprecated. Use GetPointCollision().
CollisionResult GetCollision(const GameVector& pos)
{
auto pointColl = GetPointCollision(pos.ToVector3i(), pos.RoomNumber);
- return ConvertPointCollisionToCollisionResult(pointColl);
+ return ConvertPointCollDataToCollResult(pointColl);
}
// NOTE: Deprecated. Use GetPointCollision().
From fde6c2827be22e5012e500465272997e112bd905 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sun, 27 Aug 2023 18:58:34 +1000
Subject: [PATCH 027/410] Add comment
---
TombEngine/Game/collision/collide_room.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/TombEngine/Game/collision/collide_room.h b/TombEngine/Game/collision/collide_room.h
index 09558c0d7..33365e2f7 100644
--- a/TombEngine/Game/collision/collide_room.h
+++ b/TombEngine/Game/collision/collide_room.h
@@ -55,6 +55,7 @@ struct CollisionPosition
bool HasFlippedDiagonalSplit() { return (HasDiagonalSplit() && (SplitAngle != (45.0f * RADIAN))); }
};
+// Deprecated. Use PointCollisionData.
struct CollisionResult
{
Vector3i Coordinates;
From 0d2d22fa8db7e0cfb97aedbb2270abaa81d067d4 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Tue, 29 Aug 2023 19:57:32 +1000
Subject: [PATCH 028/410] Add comment
---
TombEngine/Game/collision/collide_room.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index 646f9120e..4675bfc51 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -134,6 +134,7 @@ static CollisionResult ConvertPointCollDataToCollResult(PointCollisionData& poin
collResult.Position.CeilingSlope = pointColl.IsSlipperyCeiling();
collResult.Position.DiagonalStep = pointColl.IsDiagonalStep();
+ // NOTE: Bridge tilts ignored by old method.
collResult.FloorTilt = pointColl.GetBottomSector().GetSurfaceTilt(pointColl.Position.x, pointColl.Position.z, true);
collResult.CeilingTilt = pointColl.GetTopSector().GetSurfaceTilt(pointColl.Position.x, pointColl.Position.z, false);
From 2833c35ac9561e91a046f4c345204418d2222832 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Tue, 29 Aug 2023 23:41:07 +1000
Subject: [PATCH 029/410] Add stub function for object intersections
---
TombEngine/Game/collision/PointCollision.cpp | 11 +++++++++++
TombEngine/Game/collision/PointCollision.h | 5 +++++
2 files changed, 16 insertions(+)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 34c27c0a1..6715dd38b 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -193,6 +193,17 @@ namespace TEN::Collision
return *WaterBottomHeight;
}
+ Vector3 PointCollisionData::GetObjectIntersectPoint()
+ {
+ if (ObjectIntersectPoint.has_value())
+ return *ObjectIntersectPoint;
+
+ // Set object intersect point.
+ ObjectIntersectPoint = Vector3::Zero;
+
+ return *ObjectIntersectPoint;
+ }
+
bool PointCollisionData::IsWall()
{
return (GetFloorHeight() == NO_HEIGHT || GetCeilingHeight() == NO_HEIGHT ||
diff --git a/TombEngine/Game/collision/PointCollision.h b/TombEngine/Game/collision/PointCollision.h
index a61e78656..d9f8f1f7f 100644
--- a/TombEngine/Game/collision/PointCollision.h
+++ b/TombEngine/Game/collision/PointCollision.h
@@ -34,6 +34,8 @@ namespace TEN::Collision
std::optional WaterTopHeight = std::nullopt;
std::optional WaterBottomHeight = std::nullopt;
+ std::optional ObjectIntersectPoint = std::nullopt;
+
public:
// Constructors
PointCollisionData(const Vector3i& pos, int roomNumber);
@@ -54,6 +56,9 @@ namespace TEN::Collision
int GetWaterTopHeight();
int GetWaterBottomHeight();
+ // TODO: Above and below. Also return reference to object itself? May need std::variant.
+ Vector3 GetObjectIntersectPoint();
+
// Inquirers
bool IsWall();
bool IsSlipperyFloor(short slopeAngleMin = DEFAULT_SLIPPERY_FLOOR_SLOPE_ANGLE);
From 0d62bbb823d15c8d0806d0eb015b089ff140aaa8 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sun, 3 Sep 2023 21:59:19 +1000
Subject: [PATCH 030/410] Remove dummy method to keep it simple for now
---
TombEngine/Game/collision/PointCollision.cpp | 11 -----------
TombEngine/Game/collision/PointCollision.h | 3 ---
2 files changed, 14 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 6715dd38b..34c27c0a1 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -193,17 +193,6 @@ namespace TEN::Collision
return *WaterBottomHeight;
}
- Vector3 PointCollisionData::GetObjectIntersectPoint()
- {
- if (ObjectIntersectPoint.has_value())
- return *ObjectIntersectPoint;
-
- // Set object intersect point.
- ObjectIntersectPoint = Vector3::Zero;
-
- return *ObjectIntersectPoint;
- }
-
bool PointCollisionData::IsWall()
{
return (GetFloorHeight() == NO_HEIGHT || GetCeilingHeight() == NO_HEIGHT ||
diff --git a/TombEngine/Game/collision/PointCollision.h b/TombEngine/Game/collision/PointCollision.h
index d9f8f1f7f..3686fe7af 100644
--- a/TombEngine/Game/collision/PointCollision.h
+++ b/TombEngine/Game/collision/PointCollision.h
@@ -56,9 +56,6 @@ namespace TEN::Collision
int GetWaterTopHeight();
int GetWaterBottomHeight();
- // TODO: Above and below. Also return reference to object itself? May need std::variant.
- Vector3 GetObjectIntersectPoint();
-
// Inquirers
bool IsWall();
bool IsSlipperyFloor(short slopeAngleMin = DEFAULT_SLIPPERY_FLOOR_SLOPE_ANGLE);
From 53ad627f7243642882053afffdb3a76714ecc2fb Mon Sep 17 00:00:00 2001
From: Sezz
Date: Thu, 7 Sep 2023 23:04:33 +1000
Subject: [PATCH 031/410] Update PointCollision.cpp
---
TombEngine/Game/collision/PointCollision.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 34c27c0a1..3c932488f 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -143,7 +143,7 @@ namespace TEN::Collision
// Set floor bridge item number.
int floorHeight = GetFloorHeight();
- FloorBridgeItemNumber = GetBottomSector().GetInsideBridgeItemNumber(Position.x, floorHeight, Position.z, true, false);;
+ FloorBridgeItemNumber = GetBottomSector().GetInsideBridgeItemNumber(Position.x, floorHeight, Position.z, true, false);
return *FloorBridgeItemNumber;
}
@@ -155,7 +155,7 @@ namespace TEN::Collision
// Set ceiling bridge item number.
int ceilingHeight = GetCeilingHeight();
- CeilingBridgeItemNumber = GetTopSector().GetInsideBridgeItemNumber(Position.x, ceilingHeight, Position.z, false, true);;
+ CeilingBridgeItemNumber = GetTopSector().GetInsideBridgeItemNumber(Position.x, ceilingHeight, Position.z, false, true);
return *CeilingBridgeItemNumber;
}
@@ -196,7 +196,7 @@ namespace TEN::Collision
bool PointCollisionData::IsWall()
{
return (GetFloorHeight() == NO_HEIGHT || GetCeilingHeight() == NO_HEIGHT ||
- GetFloorHeight() < GetCeilingHeight());
+ GetFloorHeight() <= GetCeilingHeight());
}
bool PointCollisionData::IsSlipperyFloor(short slopeAngleMin)
From 2a19651480a7b12c8cbd804661220cb03a3c9ae0 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Thu, 7 Sep 2023 23:47:31 +1000
Subject: [PATCH 032/410] Update PointCollision.h
---
TombEngine/Game/collision/PointCollision.h | 2 --
1 file changed, 2 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.h b/TombEngine/Game/collision/PointCollision.h
index 3686fe7af..a61e78656 100644
--- a/TombEngine/Game/collision/PointCollision.h
+++ b/TombEngine/Game/collision/PointCollision.h
@@ -34,8 +34,6 @@ namespace TEN::Collision
std::optional WaterTopHeight = std::nullopt;
std::optional WaterBottomHeight = std::nullopt;
- std::optional ObjectIntersectPoint = std::nullopt;
-
public:
// Constructors
PointCollisionData(const Vector3i& pos, int roomNumber);
From a0eea51fbfae943253860db074b865f2e7fbdbee Mon Sep 17 00:00:00 2001
From: Sezz
Date: Fri, 8 Sep 2023 00:23:52 +1000
Subject: [PATCH 033/410] Move hack to deprecated functions.
---
TombEngine/Game/collision/PointCollision.cpp | 9 +--------
TombEngine/Game/collision/collide_room.cpp | 21 +++++++++++++++++---
2 files changed, 19 insertions(+), 11 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 3c932488f..0b42afb25 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -314,14 +314,7 @@ namespace TEN::Collision
PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber)
{
- // HACK: This function takes arguments for a *current* position and room number.
- // However, since some calls to the previous implementation (GetCollision()) had *projected*
- // positions passed to it, the room number must be corrected to account for such cases.
- // They are primarily found in camera.cpp.
- short correctedRoomNumber = roomNumber;
- GetFloor(pos.x, pos.y, pos.z, &correctedRoomNumber);
-
- return PointCollisionData(pos, correctedRoomNumber);
+ return PointCollisionData(pos, roomNumber);
}
PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber, const Vector3& dir, float dist)
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index 4675bfc51..ac5bbffe4 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -172,21 +172,36 @@ CollisionResult GetCollision(const Vector3i& pos, int roomNumber, short headingA
// NOTE: Deprecated. Use GetPointCollision().
CollisionResult GetCollision(const Vector3i& pos, int roomNumber)
{
- auto pointColl = GetPointCollision(pos, roomNumber);
+ // HACK: GetPointCollision() takes arguments for a *current* position and room number.
+ // However, since some calls to this deprecated function had *projected*
+ // positions passed to it, the room number must be corrected to account for such cases.
+ // They are primarily found in camera.cpp.
+ short correctedRoomNumber = roomNumber;
+ GetFloor(pos.x, pos.y, pos.z, &correctedRoomNumber);
+
+ auto pointColl = GetPointCollision(pos, correctedRoomNumber);
return ConvertPointCollDataToCollResult(pointColl);
}
// NOTE: Deprecated. Use GetPointCollision().
CollisionResult GetCollision(int x, int y, int z, short roomNumber)
{
- auto pointColl = GetPointCollision(Vector3i(x, y, z), roomNumber);
+ // HACK: Explained above.
+ short correctedRoomNumber = roomNumber;
+ GetFloor(x, y, z, &correctedRoomNumber);
+
+ auto pointColl = GetPointCollision(Vector3i(x, y, z), correctedRoomNumber);
return ConvertPointCollDataToCollResult(pointColl);
}
// NOTE: Deprecated. Use GetPointCollision().
CollisionResult GetCollision(const GameVector& pos)
{
- auto pointColl = GetPointCollision(pos.ToVector3i(), pos.RoomNumber);
+ // HACK: Explained above.
+ short correctedRoomNumber = pos.RoomNumber;
+ GetFloor(pos.x, pos.y, pos.z, &correctedRoomNumber);
+
+ auto pointColl = GetPointCollision(pos.ToVector3i(), correctedRoomNumber);
return ConvertPointCollDataToCollResult(pointColl);
}
From cb78e08d89c32adef9cd276102e3f92698dd8c2d Mon Sep 17 00:00:00 2001
From: Sezz
Date: Fri, 8 Sep 2023 00:29:41 +1000
Subject: [PATCH 034/410] Fix compile error
---
TombEngine/Game/Lara/lara_overhang.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/TombEngine/Game/Lara/lara_overhang.cpp b/TombEngine/Game/Lara/lara_overhang.cpp
index 5a47625bf..b10fde0ee 100644
--- a/TombEngine/Game/Lara/lara_overhang.cpp
+++ b/TombEngine/Game/Lara/lara_overhang.cpp
@@ -960,7 +960,7 @@ void SlopeClimbExtra(ItemInfo* item, CollisionInfo* coll)
// Extends LS_LADDER_IDLE (56)
bool LadderMonkeyExtra(ItemInfo* item, CollisionInfo* coll)
{
- auto probe = GetCollision(item);
+ auto probe = GetCollision(*item);
if (probe.Position.CeilingSlope)
return false;
From ba3bd0b1d33afdea081eeba8494234401349d1db Mon Sep 17 00:00:00 2001
From: Sezz
Date: Fri, 13 Oct 2023 12:41:36 +1100
Subject: [PATCH 035/410] Include files
---
TombEngine/TombEngine.vcxproj | 2 ++
1 file changed, 2 insertions(+)
diff --git a/TombEngine/TombEngine.vcxproj b/TombEngine/TombEngine.vcxproj
index eb5f54535..75c2f5f68 100644
--- a/TombEngine/TombEngine.vcxproj
+++ b/TombEngine/TombEngine.vcxproj
@@ -323,6 +323,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
+
@@ -794,6 +795,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
+
From b38d9754d741fe47f55ab5151aada30073f7f8f9 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Mon, 16 Oct 2023 16:20:52 +1100
Subject: [PATCH 036/410] Add error handling; don't duplicate constants
---
TombEngine/Game/collision/PointCollision.cpp | 25 ++++++++------------
1 file changed, 10 insertions(+), 15 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 0b42afb25..64290a100 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -201,19 +201,13 @@ namespace TEN::Collision
bool PointCollisionData::IsSlipperyFloor(short slopeAngleMin)
{
- // Get floor slope angle.
- auto floorNormal = GetFloorNormal();
- auto slopeAngle = Geometry::GetSurfaceSlopeAngle(floorNormal);
-
+ auto slopeAngle = Geometry::GetSurfaceSlopeAngle(GetFloorNormal());
return (abs(slopeAngle) >= slopeAngleMin);
}
bool PointCollisionData::IsSlipperyCeiling(short slopeAngleMin)
{
- // Get ceiling slope angle.
- auto ceilingNormal = GetCeilingNormal();
- auto slopeAngle = Geometry::GetSurfaceSlopeAngle(ceilingNormal, -Vector3::UnitY);
-
+ auto slopeAngle = Geometry::GetSurfaceSlopeAngle(GetCeilingNormal(), -Vector3::UnitY);
return (abs(slopeAngle) >= slopeAngleMin);
}
@@ -224,19 +218,14 @@ namespace TEN::Collision
bool PointCollisionData::HasDiagonalSplit()
{
- constexpr auto DIAGONAL_SPLIT_0 = 45.0f * RADIAN;
- constexpr auto DIAGONAL_SPLIT_1 = 135.0f * RADIAN;
-
float splitAngle = GetBottomSector().FloorCollision.SplitAngle;
- return (splitAngle == DIAGONAL_SPLIT_0 || splitAngle == DIAGONAL_SPLIT_1);
+ return (splitAngle == SurfaceCollisionData::SPLIT_ANGLE_0 || splitAngle == SurfaceCollisionData::SPLIT_ANGLE_1);
}
bool PointCollisionData::HasFlippedDiagonalSplit()
{
- constexpr auto DIAGONAL_SPLIT_0 = 45.0f * RADIAN;
-
float splitAngle = GetBottomSector().FloorCollision.SplitAngle;
- return (HasDiagonalSplit() && splitAngle != DIAGONAL_SPLIT_0);
+ return (HasDiagonalSplit() && splitAngle == SurfaceCollisionData::SPLIT_ANGLE_1);
}
bool PointCollisionData::HasEnvironmentFlag(RoomEnvFlags envFlag)
@@ -251,6 +240,12 @@ namespace TEN::Collision
constexpr auto ANGLE_STEP = short(ANGLE(45.0f) / 4);
int itemNumber = isFloor ? GetFloorBridgeItemNumber() : GetCeilingBridgeItemNumber();
+ if (itemNumber == NO_ITEM)
+ {
+ TENLog("PointCollisionData error: invalid bridge item number in GetBridgeNormal().", LogLevel::Warning);
+ return -Vector3::UnitY;
+ }
+
const auto& item = g_Level.Items[itemNumber];
auto orient = item.Pose.Orientation;
From b35367339ea7e1867d5d280ee5aec544f2343ecf Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sat, 28 Oct 2023 16:49:02 +1100
Subject: [PATCH 037/410] Formatting
---
TombEngine/Game/collision/PointCollision.cpp | 146 +++++++++----------
TombEngine/Game/collision/PointCollision.h | 28 ++--
2 files changed, 87 insertions(+), 87 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 64290a100..32a912b0d 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -24,40 +24,20 @@ namespace TEN::Collision
FloorInfo& PointCollisionData::GetSector()
{
- if (SectorPtr != nullptr)
- return *SectorPtr;
+ if (_sectorPtr != nullptr)
+ return *_sectorPtr;
// Set current sector pointer.
short probeRoomNumber = RoomNumber;
- SectorPtr = GetFloor(Position.x, Position.y, Position.z, &probeRoomNumber);
+ _sectorPtr = GetFloor(Position.x, Position.y, Position.z, &probeRoomNumber);
- return *SectorPtr;
- }
-
- FloorInfo& PointCollisionData::GetTopSector()
- {
- if (TopSectorPtr != nullptr)
- return *TopSectorPtr;
-
- // Set top sector pointer.
- auto* topSectorPtr = &GetSector();
- auto roomNumberAbove = topSectorPtr->GetRoomNumberAbove(Position.x, Position.y, Position.z);
- while (roomNumberAbove.has_value())
- {
- auto& room = g_Level.Rooms[roomNumberAbove.value_or(topSectorPtr->Room)];
- topSectorPtr = Room::GetSector(&room, Position.x - room.x, Position.z - room.z);
-
- roomNumberAbove = topSectorPtr->GetRoomNumberAbove(Position.x, Position.y, Position.z);
- }
- TopSectorPtr = topSectorPtr;
-
- return *TopSectorPtr;
+ return *_sectorPtr;
}
FloorInfo& PointCollisionData::GetBottomSector()
{
- if (BottomSectorPtr != nullptr)
- return *BottomSectorPtr;
+ if (_bottomSectorPtr != nullptr)
+ return *_bottomSectorPtr;
// Set bottom sector pointer.
auto* bottomSectorPtr = &GetSector();
@@ -69,128 +49,148 @@ namespace TEN::Collision
roomNumberBelow = bottomSectorPtr->GetRoomNumberBelow(Position.x, Position.y, Position.z);
}
- BottomSectorPtr = bottomSectorPtr;
+ _bottomSectorPtr = bottomSectorPtr;
- return *BottomSectorPtr;
+ return *_bottomSectorPtr;
+ }
+
+ FloorInfo& PointCollisionData::GetTopSector()
+ {
+ if (_topSectorPtr != nullptr)
+ return *_topSectorPtr;
+
+ // Set top sector pointer.
+ auto* topSectorPtr = &GetSector();
+ auto roomNumberAbove = topSectorPtr->GetRoomNumberAbove(Position.x, Position.y, Position.z);
+ while (roomNumberAbove.has_value())
+ {
+ auto& room = g_Level.Rooms[roomNumberAbove.value_or(topSectorPtr->Room)];
+ topSectorPtr = Room::GetSector(&room, Position.x - room.x, Position.z - room.z);
+
+ roomNumberAbove = topSectorPtr->GetRoomNumberAbove(Position.x, Position.y, Position.z);
+ }
+ _topSectorPtr = topSectorPtr;
+
+ return *_topSectorPtr;
}
int PointCollisionData::GetFloorHeight()
{
- if (FloorHeight.has_value())
- return *FloorHeight;
+ if (_floorHeight.has_value())
+ return *_floorHeight;
// Set floor height.
auto location = RoomVector(GetSector().Room, Position.y);
- FloorHeight = Floordata::GetFloorHeight(location, Position.x, Position.z).value_or(NO_HEIGHT);
+ _floorHeight = Floordata::GetFloorHeight(location, Position.x, Position.z).value_or(NO_HEIGHT);
- return *FloorHeight;
+ return *_floorHeight;
}
int PointCollisionData::GetCeilingHeight()
{
- if (CeilingHeight.has_value())
- return *CeilingHeight;
+ if (_ceilingHeight.has_value())
+ return *_ceilingHeight;
// Set ceiling height.
auto location = RoomVector(GetSector().Room, Position.y);
- CeilingHeight = Floordata::GetCeilingHeight(location, Position.x, Position.z).value_or(NO_HEIGHT);
+ _ceilingHeight = Floordata::GetCeilingHeight(location, Position.x, Position.z).value_or(NO_HEIGHT);
- return *CeilingHeight;
+ return *_ceilingHeight;
}
Vector3 PointCollisionData::GetFloorNormal()
{
- if (FloorNormal.has_value())
- return *FloorNormal;
+ if (_floorNormal.has_value())
+ return *_floorNormal;
// Set floor normal.
if (GetFloorBridgeItemNumber() != NO_ITEM)
{
- FloorNormal = GetBridgeNormal(true);
+ _floorNormal = GetBridgeNormal(true);
}
else
{
auto floorTilt = GetBottomSector().GetSurfaceTilt(Position.x, Position.z, true);
- FloorNormal = GetSurfaceNormal(floorTilt, true);
+ _floorNormal = GetSurfaceNormal(floorTilt, true);
}
- return *FloorNormal;
+ return *_floorNormal;
}
Vector3 PointCollisionData::GetCeilingNormal()
{
- if (CeilingNormal.has_value())
- return *CeilingNormal;
+ if (_ceilingNormal.has_value())
+ return *_ceilingNormal;
// Set ceiling normal.
if (GetCeilingBridgeItemNumber() != NO_ITEM)
{
- CeilingNormal = GetBridgeNormal(false);
+ _ceilingNormal = GetBridgeNormal(false);
}
else
{
auto ceilingTilt = GetTopSector().GetSurfaceTilt(Position.x, Position.z, false);
- CeilingNormal = GetSurfaceNormal(ceilingTilt, false);
+ _ceilingNormal = GetSurfaceNormal(ceilingTilt, false);
}
- return *CeilingNormal;
+ return *_ceilingNormal;
}
int PointCollisionData::GetFloorBridgeItemNumber()
{
- if (FloorBridgeItemNumber.has_value())
- return *FloorBridgeItemNumber;
+ if (_floorBridgeItemNumber.has_value())
+ return *_floorBridgeItemNumber;
// Set floor bridge item number.
int floorHeight = GetFloorHeight();
- FloorBridgeItemNumber = GetBottomSector().GetInsideBridgeItemNumber(Position.x, floorHeight, Position.z, true, false);
+ _floorBridgeItemNumber = GetBottomSector().GetInsideBridgeItemNumber(Position.x, floorHeight, Position.z, true, false);
- return *FloorBridgeItemNumber;
+ return *_floorBridgeItemNumber;
}
int PointCollisionData::GetCeilingBridgeItemNumber()
{
- if (CeilingBridgeItemNumber.has_value())
- return *CeilingBridgeItemNumber;
+ if (_ceilingBridgeItemNumber.has_value())
+ return *_ceilingBridgeItemNumber;
// Set ceiling bridge item number.
int ceilingHeight = GetCeilingHeight();
- CeilingBridgeItemNumber = GetTopSector().GetInsideBridgeItemNumber(Position.x, ceilingHeight, Position.z, false, true);
+ _ceilingBridgeItemNumber = GetTopSector().GetInsideBridgeItemNumber(Position.x, ceilingHeight, Position.z, false, true);
- return *CeilingBridgeItemNumber;
+ return *_ceilingBridgeItemNumber;
}
int PointCollisionData::GetWaterSurfaceHeight()
{
- if (WaterSurfaceHeight.has_value())
- return *WaterSurfaceHeight;
+ if (_waterSurfaceHeight.has_value())
+ return *_waterSurfaceHeight;
// Set water surface height.
- WaterSurfaceHeight = GetWaterSurface(Position.x, Position.y, Position.z, RoomNumber);
+ _waterSurfaceHeight = GetWaterSurface(Position.x, Position.y, Position.z, RoomNumber);
- return *WaterSurfaceHeight;
- }
-
- int PointCollisionData::GetWaterTopHeight()
- {
- if (WaterTopHeight.has_value())
- return *WaterTopHeight;
-
- // Set water top height.
- WaterTopHeight = GetWaterHeight(Position.x, Position.y, Position.z, RoomNumber);
-
- return *WaterTopHeight;
+ return *_waterSurfaceHeight;
}
int PointCollisionData::GetWaterBottomHeight()
{
- if (WaterBottomHeight.has_value())
- return *WaterBottomHeight;
+ if (_waterBottomHeight.has_value())
+ return *_waterBottomHeight;
// Set water bottom height.
- WaterBottomHeight = GetWaterDepth(Position.x, Position.y, Position.z, RoomNumber);
+ _waterBottomHeight = GetWaterDepth(Position.x, Position.y, Position.z, RoomNumber);
- return *WaterBottomHeight;
+ return *_waterBottomHeight;
+ }
+
+ int PointCollisionData::GetWaterTopHeight()
+ {
+ if (_waterTopHeight.has_value())
+ return *_waterTopHeight;
+
+ // Set water top height.
+ _waterTopHeight = GetWaterHeight(Position.x, Position.y, Position.z, RoomNumber);
+
+ return *_waterTopHeight;
}
bool PointCollisionData::IsWall()
diff --git a/TombEngine/Game/collision/PointCollision.h b/TombEngine/Game/collision/PointCollision.h
index a61e78656..d8271d0d5 100644
--- a/TombEngine/Game/collision/PointCollision.h
+++ b/TombEngine/Game/collision/PointCollision.h
@@ -19,20 +19,20 @@ namespace TEN::Collision
const int RoomNumber = 0;
private:
- FloorInfo* SectorPtr = nullptr;
- FloorInfo* TopSectorPtr = nullptr;
- FloorInfo* BottomSectorPtr = nullptr;
+ FloorInfo* _sectorPtr = nullptr;
+ FloorInfo* _bottomSectorPtr = nullptr;
+ FloorInfo* _topSectorPtr = nullptr;
- std::optional FloorHeight = std::nullopt;
- std::optional CeilingHeight = std::nullopt;
- std::optional FloorNormal = std::nullopt;
- std::optional CeilingNormal = std::nullopt;
- std::optional FloorBridgeItemNumber = std::nullopt;
- std::optional CeilingBridgeItemNumber = std::nullopt;
+ std::optional _floorHeight = std::nullopt;
+ std::optional _ceilingHeight = std::nullopt;
+ std::optional _floorNormal = std::nullopt;
+ std::optional _ceilingNormal = std::nullopt;
+ std::optional _floorBridgeItemNumber = std::nullopt;
+ std::optional _ceilingBridgeItemNumber = std::nullopt;
- std::optional WaterSurfaceHeight = std::nullopt;
- std::optional WaterTopHeight = std::nullopt;
- std::optional WaterBottomHeight = std::nullopt;
+ std::optional _waterSurfaceHeight = std::nullopt;
+ std::optional _waterBottomHeight = std::nullopt;
+ std::optional _waterTopHeight = std::nullopt;
public:
// Constructors
@@ -40,8 +40,8 @@ namespace TEN::Collision
// Getters
FloorInfo& GetSector();
- FloorInfo& GetTopSector();
FloorInfo& GetBottomSector();
+ FloorInfo& GetTopSector();
int GetFloorHeight();
int GetCeilingHeight();
@@ -51,8 +51,8 @@ namespace TEN::Collision
int GetCeilingBridgeItemNumber();
int GetWaterSurfaceHeight();
- int GetWaterTopHeight();
int GetWaterBottomHeight();
+ int GetWaterTopHeight();
// Inquirers
bool IsWall();
From 7aa1a8338b88c1a7779d2c06d626f839f5e85e55 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sat, 28 Oct 2023 16:50:41 +1100
Subject: [PATCH 038/410] Update PointCollision.cpp
---
TombEngine/Game/collision/PointCollision.cpp | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 32a912b0d..11a9c4138 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -237,19 +237,19 @@ namespace TEN::Collision
// HACK.
Vector3 PointCollisionData::GetBridgeNormal(bool isFloor)
{
- constexpr auto ANGLE_STEP = short(ANGLE(45.0f) / 4);
+ constexpr auto ANGLE_STEP = ANGLE(45.0f / 4);
- int itemNumber = isFloor ? GetFloorBridgeItemNumber() : GetCeilingBridgeItemNumber();
- if (itemNumber == NO_ITEM)
+ int bridgeItemNumber = isFloor ? GetFloorBridgeItemNumber() : GetCeilingBridgeItemNumber();
+ if (bridgeItemNumber == NO_ITEM)
{
TENLog("PointCollisionData error: invalid bridge item number in GetBridgeNormal().", LogLevel::Warning);
return -Vector3::UnitY;
}
- const auto& item = g_Level.Items[itemNumber];
+ const auto& bridgeItem = g_Level.Items[bridgeItemNumber];
- auto orient = item.Pose.Orientation;
- switch (item.ObjectNumber)
+ auto orient = bridgeItem.Pose.Orientation;
+ switch (bridgeItem.ObjectNumber)
{
default:
case ID_BRIDGE_FLAT:
From fb20bf535509f1a7ac42837abd1d03c92e56e9af Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sat, 4 Nov 2023 23:08:32 +1100
Subject: [PATCH 039/410] Complete method set
---
TombEngine/Game/collision/PointCollision.cpp | 35 +++++++++++++++-----
TombEngine/Game/collision/PointCollision.h | 16 +++++----
TombEngine/Game/collision/collide_room.cpp | 6 ++--
TombEngine/Game/collision/collide_room.h | 4 +--
4 files changed, 41 insertions(+), 20 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 11a9c4138..166d07657 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -199,36 +199,53 @@ namespace TEN::Collision
GetFloorHeight() <= GetCeilingHeight());
}
- bool PointCollisionData::IsSlipperyFloor(short slopeAngleMin)
+ bool PointCollisionData::IsIllegalFloor(short slopeAngleMin)
{
auto slopeAngle = Geometry::GetSurfaceSlopeAngle(GetFloorNormal());
return (abs(slopeAngle) >= slopeAngleMin);
}
- bool PointCollisionData::IsSlipperyCeiling(short slopeAngleMin)
+ bool PointCollisionData::IsIllegalCeiling(short slopeAngleMin)
{
auto slopeAngle = Geometry::GetSurfaceSlopeAngle(GetCeilingNormal(), -Vector3::UnitY);
return (abs(slopeAngle) >= slopeAngleMin);
}
- bool PointCollisionData::IsDiagonalStep()
+ bool PointCollisionData::IsDiagonalFloorStep()
{
return GetBottomSector().IsSurfaceDiagonalStep(true);
}
+
+ bool PointCollisionData::IsDiagonalCeilingStep()
+ {
+ return GetTopSector().IsSurfaceDiagonalStep(false);
+ }
- bool PointCollisionData::HasDiagonalSplit()
+ bool PointCollisionData::IsFloorDiagonalSplit()
{
float splitAngle = GetBottomSector().FloorCollision.SplitAngle;
return (splitAngle == SurfaceCollisionData::SPLIT_ANGLE_0 || splitAngle == SurfaceCollisionData::SPLIT_ANGLE_1);
}
-
- bool PointCollisionData::HasFlippedDiagonalSplit()
+
+ bool PointCollisionData::IsCeilingDiagonalSplit()
{
- float splitAngle = GetBottomSector().FloorCollision.SplitAngle;
- return (HasDiagonalSplit() && splitAngle == SurfaceCollisionData::SPLIT_ANGLE_1);
+ float splitAngle = GetTopSector().CeilingCollision.SplitAngle;
+ return (splitAngle == SurfaceCollisionData::SPLIT_ANGLE_0 || splitAngle == SurfaceCollisionData::SPLIT_ANGLE_1);
}
- bool PointCollisionData::HasEnvironmentFlag(RoomEnvFlags envFlag)
+ bool PointCollisionData::IsFloorFlippedDiagonalSplit()
+ {
+ float splitAngle = GetBottomSector().FloorCollision.SplitAngle;
+ return (IsDiagonalFloorStep() && splitAngle == SurfaceCollisionData::SPLIT_ANGLE_1);
+ }
+
+ bool PointCollisionData::IsCeilingFlippedDiagonalSplit()
+ {
+ float splitAngle = GetTopSector().CeilingCollision.SplitAngle;
+ return (IsDiagonalCeilingStep() && splitAngle == SurfaceCollisionData::SPLIT_ANGLE_1);
+ }
+
+ bool PointCollisionData::TestEnvironmentFlag(RoomEnvFlags envFlag)
{
const auto& room = g_Level.Rooms[RoomNumber];
return ((room.flags & envFlag) == envFlag);
diff --git a/TombEngine/Game/collision/PointCollision.h b/TombEngine/Game/collision/PointCollision.h
index d8271d0d5..92b56723a 100644
--- a/TombEngine/Game/collision/PointCollision.h
+++ b/TombEngine/Game/collision/PointCollision.h
@@ -56,12 +56,16 @@ namespace TEN::Collision
// Inquirers
bool IsWall();
- bool IsSlipperyFloor(short slopeAngleMin = DEFAULT_SLIPPERY_FLOOR_SLOPE_ANGLE);
- bool IsSlipperyCeiling(short slopeAngleMin = DEFAULT_SLIPPERY_CEILING_SLOPE_ANGLE);
- bool IsDiagonalStep();
- bool HasDiagonalSplit();
- bool HasFlippedDiagonalSplit();
- bool HasEnvironmentFlag(RoomEnvFlags envFlag);
+ bool IsIllegalFloor(short slopeAngleMin = DEFAULT_ILLEGAL_FLOOR_SLOPE_ANGLE);
+ bool IsIllegalCeiling(short slopeAngleMin = DEFAULT_ILLEGAL_CEILING_SLOPE_ANGLE);
+ bool IsDiagonalFloorStep();
+ bool IsDiagonalCeilingStep();
+ bool IsFloorDiagonalSplit();
+ bool IsCeilingDiagonalSplit();
+ bool IsFloorFlippedDiagonalSplit();
+ bool IsCeilingFlippedDiagonalSplit();
+
+ bool TestEnvironmentFlag(RoomEnvFlags envFlag);
private:
// Helpers
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index ac5bbffe4..2187f30ea 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -130,9 +130,9 @@ static CollisionResult ConvertPointCollDataToCollResult(PointCollisionData& poin
collResult.Position.Ceiling = pointColl.GetCeilingHeight();
collResult.Position.Bridge = pointColl.GetFloorBridgeItemNumber();
collResult.Position.SplitAngle = pointColl.GetBottomSector().FloorCollision.SplitAngle;
- collResult.Position.FloorSlope = pointColl.IsSlipperyFloor();
- collResult.Position.CeilingSlope = pointColl.IsSlipperyCeiling();
- collResult.Position.DiagonalStep = pointColl.IsDiagonalStep();
+ collResult.Position.FloorSlope = pointColl.IsIllegalFloor();
+ collResult.Position.CeilingSlope = pointColl.IsIllegalCeiling();
+ collResult.Position.DiagonalStep = pointColl.IsDiagonalFloorStep();
// NOTE: Bridge tilts ignored by old method.
collResult.FloorTilt = pointColl.GetBottomSector().GetSurfaceTilt(pointColl.Position.x, pointColl.Position.z, true);
diff --git a/TombEngine/Game/collision/collide_room.h b/TombEngine/Game/collision/collide_room.h
index 33365e2f7..2ef86555a 100644
--- a/TombEngine/Game/collision/collide_room.h
+++ b/TombEngine/Game/collision/collide_room.h
@@ -13,8 +13,8 @@ constexpr auto NO_LOWER_BOUND = -NO_HEIGHT; // Used by coll->Setup.LowerFloorBou
constexpr auto NO_UPPER_BOUND = NO_HEIGHT; // Used by coll->Setup.UpperFloorBound.
constexpr auto COLLISION_CHECK_DISTANCE = BLOCK(8);
-constexpr auto DEFAULT_SLIPPERY_FLOOR_SLOPE_ANGLE = short(ANGLE(45.0f) * 0.75f);
-constexpr auto DEFAULT_SLIPPERY_CEILING_SLOPE_ANGLE = ANGLE(45.0f);
+constexpr auto DEFAULT_ILLEGAL_FLOOR_SLOPE_ANGLE = ANGLE(45.0f * 0.75f);
+constexpr auto DEFAULT_ILLEGAL_CEILING_SLOPE_ANGLE = ANGLE(45.0f);
enum CollisionType
{
From bb21ea285ef32fdeb71b6d70f948b28f076f15d7 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sat, 25 Nov 2023 20:03:02 +1100
Subject: [PATCH 040/410] Update collide_room.cpp
---
TombEngine/Game/collision/collide_room.cpp | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index 44a8af74e..5f07dafbf 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -134,13 +134,13 @@ static CollisionResult ConvertPointCollDataToCollResult(PointCollisionData& poin
collResult.Position.Ceiling = pointColl.GetCeilingHeight();
collResult.Position.Bridge = pointColl.GetFloorBridgeItemNumber();
collResult.Position.SplitAngle = pointColl.GetBottomSector().FloorSurface.SplitAngle;
- collResult.Position.FloorSlope = pointColl.IsIllegalFloor();
+ collResult.Position.FloorSlope = collResult.Position.Bridge == NO_ITEM && pointColl.IsIllegalFloor();
collResult.Position.CeilingSlope = pointColl.IsIllegalCeiling();
collResult.Position.DiagonalStep = pointColl.IsDiagonalFloorStep();
// NOTE: Bridge tilts ignored by old method.
- collResult.FloorTilt = GetSurfaceTilt(pointColl.GetBottomSector().GetSurfaceNormal(pointColl.Position.x, pointColl.Position.z, true), true).ToVector2();
- collResult.CeilingTilt = GetSurfaceTilt(pointColl.GetTopSector().GetSurfaceNormal(pointColl.Position.x, pointColl.Position.z, false), false).ToVector2();
+ collResult.FloorTilt = GetSurfaceTilt(pointColl.GetFloorNormal(), true).ToVector2();
+ collResult.CeilingTilt = GetSurfaceTilt(pointColl.GetCeilingNormal(), false).ToVector2();
return collResult;
}
@@ -219,12 +219,15 @@ CollisionResult GetCollision(const GameVector& pos)
// NOTE: Deprecated. Use GetPointCollision().
CollisionResult GetCollision(FloorInfo* floor, int x, int y, int z)
{
+ auto pointColl = GetPointCollision(Vector3i(x, y, z), floor->RoomNumber);
+ return ConvertPointCollDataToCollResult(pointColl);
+
auto result = CollisionResult{};
result.Coordinates = Vector3i(x, y, z);
result.Position.Floor = GetFloorHeight(RoomVector(floor->RoomNumber, y), x, z).value_or(NO_HEIGHT);
result.Position.Ceiling = GetCeilingHeight(RoomVector(floor->RoomNumber, y), x, z).value_or(NO_HEIGHT);
-
+
result.Block = floor;
while (floor->GetRoomNumberBelow(Vector3i(x, y, z)).value_or(NO_ROOM) != NO_ROOM)
{
From 26a54e211c5bd9ada40dcfd309f557075949549c Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sat, 25 Nov 2023 20:10:04 +1100
Subject: [PATCH 041/410] Fix slopes
---
TombEngine/Game/collision/PointCollision.cpp | 8 ++++----
TombEngine/Game/collision/collide_room.cpp | 6 ++++--
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index f417d0951..0bf6ece89 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -199,14 +199,14 @@ namespace TEN::Collision
bool PointCollisionData::IsIllegalFloor(short slopeAngleMin)
{
- auto slopeAngle = Geometry::GetSurfaceSlopeAngle(GetFloorNormal());
- return (abs(slopeAngle) >= FROM_RAD(GetBottomSector().GetSurfaceIllegalSlopeAngle(Position.x, Position.z, true)));
+ short slopeAngle = Geometry::GetSurfaceSlopeAngle(GetFloorNormal());
+ return (abs(slopeAngle) >= GetBottomSector().GetSurfaceIllegalSlopeAngle(Position.x, Position.z, true));
}
bool PointCollisionData::IsIllegalCeiling(short slopeAngleMin)
{
- auto slopeAngle = Geometry::GetSurfaceSlopeAngle(GetCeilingNormal(), -Vector3::UnitY);
- return (abs(slopeAngle) >= FROM_RAD(GetTopSector().GetSurfaceIllegalSlopeAngle(Position.x, Position.z, false)));
+ short slopeAngle = Geometry::GetSurfaceSlopeAngle(GetCeilingNormal(), -Vector3::UnitY);
+ return (abs(slopeAngle) >= GetTopSector().GetSurfaceIllegalSlopeAngle(Position.x, Position.z, false));
}
bool PointCollisionData::IsDiagonalFloorStep()
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index 5f07dafbf..a4263d6cc 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -137,10 +137,12 @@ static CollisionResult ConvertPointCollDataToCollResult(PointCollisionData& poin
collResult.Position.FloorSlope = collResult.Position.Bridge == NO_ITEM && pointColl.IsIllegalFloor();
collResult.Position.CeilingSlope = pointColl.IsIllegalCeiling();
collResult.Position.DiagonalStep = pointColl.IsDiagonalFloorStep();
+ collResult.FloorNormal = pointColl.GetFloorNormal();
+ collResult.CeilingNormal = pointColl.GetCeilingNormal();
// NOTE: Bridge tilts ignored by old method.
- collResult.FloorTilt = GetSurfaceTilt(pointColl.GetFloorNormal(), true).ToVector2();
- collResult.CeilingTilt = GetSurfaceTilt(pointColl.GetCeilingNormal(), false).ToVector2();
+ collResult.FloorTilt = GetSurfaceTilt(collResult.FloorNormal, true).ToVector2();
+ collResult.CeilingTilt = GetSurfaceTilt(collResult.CeilingNormal, false).ToVector2();
return collResult;
}
From 3533d49d9df03edf7ae98a3d6ad80686453c5199 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sat, 25 Nov 2023 20:19:27 +1100
Subject: [PATCH 042/410] Fix monkey swing bridges below illegal ceilings
---
TombEngine/Game/collision/PointCollision.cpp | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 0bf6ece89..04317e0ea 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -199,14 +199,22 @@ namespace TEN::Collision
bool PointCollisionData::IsIllegalFloor(short slopeAngleMin)
{
+ if (GetFloorBridgeItemNumber() != NO_ITEM)
+ return false;
+
short slopeAngle = Geometry::GetSurfaceSlopeAngle(GetFloorNormal());
- return (abs(slopeAngle) >= GetBottomSector().GetSurfaceIllegalSlopeAngle(Position.x, Position.z, true));
+ short illegalSlopeAngle = GetBottomSector().GetSurfaceIllegalSlopeAngle(Position.x, Position.z, true);
+ return (abs(slopeAngle) >= illegalSlopeAngle);
}
bool PointCollisionData::IsIllegalCeiling(short slopeAngleMin)
{
+ if (GetCeilingBridgeItemNumber() != NO_ITEM)
+ return false;
+
short slopeAngle = Geometry::GetSurfaceSlopeAngle(GetCeilingNormal(), -Vector3::UnitY);
- return (abs(slopeAngle) >= GetTopSector().GetSurfaceIllegalSlopeAngle(Position.x, Position.z, false));
+ short illegalSlopeAngle = GetTopSector().GetSurfaceIllegalSlopeAngle(Position.x, Position.z, false);
+ return (abs(slopeAngle) >= illegalSlopeAngle);
}
bool PointCollisionData::IsDiagonalFloorStep()
From d5ac711da4f6dded97249a82d4ee7b208e094a80 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sun, 21 Jan 2024 23:40:06 +1100
Subject: [PATCH 043/410] Extend GetPointCollision(); fix merge errors
---
TombEngine/Game/collision/PointCollision.cpp | 21 ++++++++++----------
TombEngine/Game/collision/PointCollision.h | 6 ++++--
2 files changed, 15 insertions(+), 12 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 04317e0ea..c019096c9 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -81,7 +81,7 @@ namespace TEN::Collision
// Set floor height.
auto location = RoomVector(GetSector().RoomNumber, Position.y);
- _floorHeight = Floordata::GetFloorHeight(location, Position.x, Position.z).value_or(NO_HEIGHT);
+ _floorHeight = Floordata::GetSurfaceHeight(location, Position.x, Position.z, true).value_or(NO_HEIGHT);
return *_floorHeight;
}
@@ -93,7 +93,7 @@ namespace TEN::Collision
// Set ceiling height.
auto location = RoomVector(GetSector().RoomNumber, Position.y);
- _ceilingHeight = Floordata::GetCeilingHeight(location, Position.x, Position.z).value_or(NO_HEIGHT);
+ _ceilingHeight = Floordata::GetSurfaceHeight(location, Position.x, Position.z, false).value_or(NO_HEIGHT);
return *_ceilingHeight;
}
@@ -141,7 +141,8 @@ namespace TEN::Collision
// Set floor bridge item number.
int floorHeight = GetFloorHeight();
- _floorBridgeItemNumber = GetBottomSector().GetInsideBridgeItemNumber(Vector3i(Position.x, floorHeight, Position.z), true, false);
+ auto pos = Vector3i(Position.x, floorHeight, Position.z);
+ _floorBridgeItemNumber = GetBottomSector().GetInsideBridgeItemNumber(pos, true, false);
return *_floorBridgeItemNumber;
}
@@ -153,7 +154,8 @@ namespace TEN::Collision
// Set ceiling bridge item number.
int ceilingHeight = GetCeilingHeight();
- _ceilingBridgeItemNumber = GetTopSector().GetInsideBridgeItemNumber(Vector3i(Position.x, ceilingHeight, Position.z), false, true);
+ auto pos = Vector3i(Position.x, ceilingHeight, Position.z);
+ _ceilingBridgeItemNumber = GetTopSector().GetInsideBridgeItemNumber(pos, false, true);
return *_ceilingBridgeItemNumber;
}
@@ -312,8 +314,7 @@ namespace TEN::Collision
static RoomVector GetLocation(const ItemInfo& item)
{
- // TODO: Find cleaner solution. Constructing a "location" for the player on the spot
- // can result in stumbles when climbing onto thin platforms.
+ // TODO: Find cleaner solution. Manually constructing a player "location" can result in stumbles when climbing onto thin platforms.
// May have to do with player's room number being updated at half-height? -- Sezz 2022.06.14
if (item.IsLara())
return item.Location;
@@ -341,13 +342,13 @@ namespace TEN::Collision
return PointCollisionData(probePos, probeRoomNumber);
}
- PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down, float right)
+ PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down, float right, const Vector3& axis)
{
// Get "location".
auto location = GetLocation(pos, roomNumber);
// Calculate probe position.
- auto probePos = Geometry::TranslatePoint(pos, headingAngle, forward, down, right);
+ auto probePos = Geometry::TranslatePoint(pos, headingAngle, forward, down, right, axis);
short probeRoomNumber = GetProbeRoomNumber(pos, location, probePos);
return PointCollisionData(probePos, probeRoomNumber);
@@ -370,13 +371,13 @@ namespace TEN::Collision
return PointCollisionData(probePos, probeRoomNumber);
}
- PointCollisionData GetPointCollision(const ItemInfo& item, short headingAngle, float forward, float down, float right)
+ PointCollisionData GetPointCollision(const ItemInfo& item, short headingAngle, float forward, float down, float right, const Vector3& axis)
{
// Get "location".
auto location = GetLocation(item);
// Calculate probe position.
- auto probePos = Geometry::TranslatePoint(item.Pose.Position, headingAngle, forward, down, right);
+ auto probePos = Geometry::TranslatePoint(item.Pose.Position, headingAngle, forward, down, right, axis);
short probeRoomNumber = GetProbeRoomNumber(item.Pose.Position, location, probePos);
return PointCollisionData(probePos, probeRoomNumber);
diff --git a/TombEngine/Game/collision/PointCollision.h b/TombEngine/Game/collision/PointCollision.h
index 447e75f50..be315cb6f 100644
--- a/TombEngine/Game/collision/PointCollision.h
+++ b/TombEngine/Game/collision/PointCollision.h
@@ -73,9 +73,11 @@ namespace TEN::Collision
PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber);
PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber, const Vector3& dir, float dist);
- PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down = 0.0f, float right = 0.0f);
+ PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down = 0.0f, float right = 0.0f,
+ const Vector3& axis = Vector3::UnitY);
PointCollisionData GetPointCollision(const ItemInfo& item);
PointCollisionData GetPointCollision(const ItemInfo& item, const Vector3& dir, float dist);
- PointCollisionData GetPointCollision(const ItemInfo& item, short headingAngle, float forward, float down = 0.0f, float right = 0.0f);
+ PointCollisionData GetPointCollision(const ItemInfo& item, short headingAngle, float forward, float down = 0.0f, float right = 0.0f,
+ const Vector3& axis = Vector3::UnitY);
}
From 7c21558f18805b518938789c883f1e58dcb2bae4 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 31 Jan 2024 18:19:59 +1100
Subject: [PATCH 044/410] Implement missing method
---
TombEngine/Game/collision/PointCollision.cpp | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index c019096c9..65ae7628d 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -235,6 +235,12 @@ namespace TEN::Collision
return (splitAngle == SectorSurfaceData::SPLIT_ANGLE_0 || splitAngle == SectorSurfaceData::SPLIT_ANGLE_1);
}
+ bool PointCollisionData::IsCeilingDiagonalSplit()
+ {
+ float splitAngle = GetTopSector().CeilingSurface.SplitAngle;
+ return (splitAngle == SectorSurfaceData::SPLIT_ANGLE_0 || splitAngle == SectorSurfaceData::SPLIT_ANGLE_1);
+ }
+
bool PointCollisionData::IsFloorFlippedDiagonalSplit()
{
float splitAngle = GetBottomSector().FloorSurface.SplitAngle;
From 85c35e4eb3d9b48eb64bc808b92901c0bcb04eac Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 31 Jan 2024 18:35:45 +1100
Subject: [PATCH 045/410] Remove warning
---
TombEngine/Game/collision/PointCollision.cpp | 6 ------
1 file changed, 6 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 65ae7628d..dcfdb7277 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -265,12 +265,6 @@ namespace TEN::Collision
constexpr auto ANGLE_STEP = ANGLE(45.0f / 4);
int bridgeItemNumber = isFloor ? GetFloorBridgeItemNumber() : GetCeilingBridgeItemNumber();
- if (bridgeItemNumber == NO_ITEM)
- {
- TENLog("PointCollisionData error: invalid bridge item number in GetBridgeNormal().", LogLevel::Warning);
- return -Vector3::UnitY;
- }
-
const auto& bridgeItem = g_Level.Items[bridgeItemNumber];
auto orient = bridgeItem.Pose.Orientation;
From bedc4ee37ad44876e00701795ed68b706a5f700a Mon Sep 17 00:00:00 2001
From: Sezz
Date: Thu, 1 Feb 2024 16:45:26 +1100
Subject: [PATCH 046/410] Update bridge parenting; let bridge orientation
influence collision
---
TombEngine/Game/Lara/lara.cpp | 60 ++++++++++++++++++++
TombEngine/Game/collision/PointCollision.cpp | 16 +++---
TombEngine/Game/collision/collide_item.cpp | 33 +++++------
TombEngine/Game/collision/collide_item.h | 2 +-
TombEngine/Game/collision/collide_room.cpp | 36 +-----------
TombEngine/Game/collision/floordata.cpp | 2 +-
6 files changed, 88 insertions(+), 61 deletions(-)
diff --git a/TombEngine/Game/Lara/lara.cpp b/TombEngine/Game/Lara/lara.cpp
index 45d1ce32c..02f5b9cd1 100644
--- a/TombEngine/Game/Lara/lara.cpp
+++ b/TombEngine/Game/Lara/lara.cpp
@@ -63,10 +63,68 @@ LaraInfo Lara = {};
ItemInfo* LaraItem;
CollisionInfo LaraCollision = {};
+//---------debug
+#include
+#include "Specific/Input/Input.h"
+//----------
+
void LaraControl(ItemInfo* item, CollisionInfo* coll)
{
auto& player = GetLaraInfo(*item);
+ //---------debug
+
+ static int bridgeItemNumber = NO_ITEM;
+ if (coll->LastBridgeItemNumber != NO_ITEM)
+ bridgeItemNumber = coll->LastBridgeItemNumber;
+
+ if (bridgeItemNumber != NO_ITEM)
+ {
+ constexpr auto TRANSLATE_STEP = BLOCK(0.1f);
+
+ auto& bridgeItem = g_Level.Items[bridgeItemNumber];
+
+ // Move bridge.
+ if (KeyMap[OIS::KeyCode::KC_K])
+ {
+ auto rotMatrix = EulerAngles(0, Camera.actualAngle, 0).ToRotationMatrix();
+ auto offset = Vector3(AxisMap[(int)InputAxis::Mouse].x, 0.0f, -AxisMap[(int)InputAxis::Mouse].y) * 1000;
+ bridgeItem.Pose.Position += Vector3::Transform(offset, rotMatrix);
+
+ UpdateItemRoom(bridgeItem.Index);
+ UpdateBridgeItem(bridgeItem);
+ }
+ else if (KeyMap[OIS::KeyCode::KC_L])
+ {
+ auto offset = Vector3(0.0f, AxisMap[(int)InputAxis::Mouse].y, 0.0f) * 1000;
+ bridgeItem.Pose.Position += offset;
+
+ UpdateItemRoom(bridgeItem.Index);
+ UpdateBridgeItem(bridgeItem);
+ }
+ // Rotate bridge.
+ else if (KeyMap[OIS::KeyCode::KC_H])
+ {
+ auto rotMatrix = EulerAngles(0, Camera.actualAngle, 0).ToRotationMatrix();
+ auto offset = Vector3(AxisMap[(int)InputAxis::Mouse].x, 0.0f, -AxisMap[(int)InputAxis::Mouse].y) * 10000;
+ offset = Vector3::Transform(offset, rotMatrix);
+
+ auto rot = EulerAngles(-AxisMap[(int)InputAxis::Mouse].x * 10000, 0.0f, -AxisMap[(int)InputAxis::Mouse].y * 10000);
+ bridgeItem.Pose.Orientation += rot;
+
+ UpdateItemRoom(bridgeItem.Index);
+ UpdateBridgeItem(bridgeItem);
+ }
+ else if (KeyMap[OIS::KeyCode::KC_J])
+ {
+ auto rot = EulerAngles(0.0f, AxisMap[(int)InputAxis::Mouse].y * 10000, 0.0f);
+ bridgeItem.Pose.Orientation += rot;
+
+ UpdateItemRoom(bridgeItem.Index);
+ UpdateBridgeItem(bridgeItem);
+ }
+ }
+
auto pointColl = GetPointCollision(*item);
auto origin = item->Pose.Position + Vector3i(0, -BLOCK(1), 0);
@@ -76,6 +134,8 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
g_Renderer.PrintDebugMessage("Floor bridge: %d", pointColl.GetFloorBridgeItemNumber());
g_Renderer.PrintDebugMessage("Ceiling bridge: %d", pointColl.GetCeilingBridgeItemNumber());
+ //----------
+
// Alert nearby creatures.
if (player.Control.Weapon.HasFired)
{
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index dcfdb7277..918f6ad06 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -201,21 +201,21 @@ namespace TEN::Collision
bool PointCollisionData::IsIllegalFloor(short slopeAngleMin)
{
- if (GetFloorBridgeItemNumber() != NO_ITEM)
- return false;
-
short slopeAngle = Geometry::GetSurfaceSlopeAngle(GetFloorNormal());
- short illegalSlopeAngle = GetBottomSector().GetSurfaceIllegalSlopeAngle(Position.x, Position.z, true);
+ short illegalSlopeAngle = (GetFloorBridgeItemNumber() != NO_ITEM) ?
+ DEFAULT_ILLEGAL_FLOOR_SLOPE_ANGLE :
+ GetBottomSector().GetSurfaceIllegalSlopeAngle(Position.x, Position.z, true);
+
return (abs(slopeAngle) >= illegalSlopeAngle);
}
bool PointCollisionData::IsIllegalCeiling(short slopeAngleMin)
{
- if (GetCeilingBridgeItemNumber() != NO_ITEM)
- return false;
-
short slopeAngle = Geometry::GetSurfaceSlopeAngle(GetCeilingNormal(), -Vector3::UnitY);
- short illegalSlopeAngle = GetTopSector().GetSurfaceIllegalSlopeAngle(Position.x, Position.z, false);
+ short illegalSlopeAngle = (GetCeilingBridgeItemNumber() != NO_ITEM) ?
+ DEFAULT_ILLEGAL_CEILING_SLOPE_ANGLE :
+ GetTopSector().GetSurfaceIllegalSlopeAngle(Position.x, Position.z, false);
+
return (abs(slopeAngle) >= illegalSlopeAngle);
}
diff --git a/TombEngine/Game/collision/collide_item.cpp b/TombEngine/Game/collision/collide_item.cpp
index 534194a3d..d6ac72700 100644
--- a/TombEngine/Game/collision/collide_item.cpp
+++ b/TombEngine/Game/collision/collide_item.cpp
@@ -898,22 +898,20 @@ void ItemPushBridge(ItemInfo& item, CollisionInfo& coll)
ShiftItem(&item, &coll);
}
-void CollideBridgeItems(ItemInfo& item, CollisionInfo& coll, const CollisionResult& collResult)
+void CollideBridgeItems(ItemInfo& item, CollisionInfo& coll, const CollisionResult& pointColl)
{
- // Store an offset for a bridge item into shifts, if exists.
- if (coll.LastBridgeItemNumber == collResult.Position.Bridge && coll.LastBridgeItemNumber != NO_ITEM)
+ // Store offset for bridge item into shifts if it exists.
+ if (coll.LastBridgeItemNumber == pointColl.Position.Bridge &&
+ coll.LastBridgeItemNumber != NO_ITEM)
{
- auto& bridgeItem = g_Level.Items[collResult.Position.Bridge];
+ auto& bridgeItem = g_Level.Items[pointColl.Position.Bridge];
auto deltaPos = bridgeItem.Pose.Position - coll.LastBridgeItemPose.Position;
auto deltaOrient = bridgeItem.Pose.Orientation - coll.LastBridgeItemPose.Orientation;
auto deltaPose = Pose(deltaPos, deltaOrient);
- int absDeltaHeight = item.Pose.Position.y - collResult.Position.Floor;
- int relDeltaHeight = absDeltaHeight + GameBoundingBox(&item).Y2;
-
- if (deltaPose != Pose::Zero &&
- (abs(absDeltaHeight) <= CLICK(1 / 8.0f) || abs(relDeltaHeight) <= CLICK(1 / 8.0f)))
+ // Item is grounded and bridge position changed; set shift.
+ if (deltaPose != Pose::Zero && !item.Animation.IsAirborne)
{
const auto& bridgePos = bridgeItem.Pose.Position;
@@ -923,15 +921,18 @@ void CollideBridgeItems(ItemInfo& item, CollisionInfo& coll, const CollisionResu
auto offset = bridgePos.ToVector3() + Vector3::Transform(relOffset, rotMatrix);
deltaPose.Position -= item.Pose.Position - Vector3i(offset);
-
- // Don't update shifts if difference is too big (possibly bridge was teleported or just entered bridge).
- if (deltaPose.Position.ToVector3().Length() <= coll.Setup.Radius * 2)
+
+ // Don't update shifts if difference is too big (bridge was possibly teleported or just entered).
+ if (Vector2(deltaPose.Position.x, deltaPose.Position.z).Length() <= (coll.Setup.Radius * 2))
+ {
+ deltaPose.Orientation = EulerAngles(0, deltaPose.Orientation.y, 0);
coll.Shift = deltaPose;
+ }
}
- else if (deltaPos.ToVector3().Length() <= coll.Setup.Radius && relDeltaHeight > 0 &&
- (deltaPos != Vector3i::Zero || deltaOrient != EulerAngles::Identity))
+ // Push item.
+ else if (Vector2(deltaPose.Position.x, deltaPose.Position.z).Length() <= coll.Setup.Radius &&
+ (deltaPos != Vector3i::Zero || deltaOrient != EulerAngles::Identity))
{
- // Push item away if not directly above bridge, and bridge position was changed.
ItemPushItem(&bridgeItem, &item);
}
@@ -943,7 +944,7 @@ void CollideBridgeItems(ItemInfo& item, CollisionInfo& coll, const CollisionResu
coll.LastBridgeItemNumber = NO_ITEM;
}
- coll.LastBridgeItemNumber = collResult.Position.Bridge;
+ coll.LastBridgeItemNumber = pointColl.Position.Bridge;
}
void CollideSolidStatics(ItemInfo* item, CollisionInfo* coll)
diff --git a/TombEngine/Game/collision/collide_item.h b/TombEngine/Game/collision/collide_item.h
index 68f02bbe2..31a275928 100644
--- a/TombEngine/Game/collision/collide_item.h
+++ b/TombEngine/Game/collision/collide_item.h
@@ -45,7 +45,7 @@ void ItemPushBridge(ItemInfo& item, CollisionInfo& coll);
bool CollideSolidBounds(ItemInfo* item, const GameBoundingBox& box, const Pose& pose, CollisionInfo* coll);
void CollideSolidStatics(ItemInfo* item, CollisionInfo* coll);
-void CollideBridgeItems(ItemInfo& item, CollisionInfo& coll, const CollisionResult& collResult);
+void CollideBridgeItems(ItemInfo& item, CollisionInfo& coll, const CollisionResult& pointColl);
void AIPickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll);
void ObjectCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll);
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index ab1f055a0..61d0a3286 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -143,7 +143,7 @@ static CollisionResult ConvertPointCollDataToCollResult(PointCollisionData& poin
// NOTE: Bridge tilts ignored by old method.
collResult.FloorTilt = GetSurfaceTilt(collResult.FloorNormal, true).ToVector2();
collResult.CeilingTilt = GetSurfaceTilt(collResult.CeilingNormal, false).ToVector2();
-
+
return collResult;
}
@@ -223,40 +223,6 @@ CollisionResult GetCollision(FloorInfo* floor, int x, int y, int z)
{
auto pointColl = GetPointCollision(Vector3i(x, y, z), floor->RoomNumber);
return ConvertPointCollDataToCollResult(pointColl);
-
- auto result = CollisionResult{};
-
- result.Coordinates = Vector3i(x, y, z);
- result.Position.Floor = GetFloorHeight(RoomVector(floor->RoomNumber, y), x, z).value_or(NO_HEIGHT);
- result.Position.Ceiling = GetCeilingHeight(RoomVector(floor->RoomNumber, y), x, z).value_or(NO_HEIGHT);
-
- result.Block = floor;
- while (floor->GetRoomNumberBelow(Vector3i(x, y, z)).value_or(NO_ROOM) != NO_ROOM)
- {
- auto* room = &g_Level.Rooms[floor->GetRoomNumberBelow(Vector3i(x, y, z)).value_or(floor->RoomNumber)];
- floor = Room::GetSector(room, x - room->x, z - room->z);
- }
- result.BottomBlock = floor;
-
- // Get surface noramls.
- result.FloorNormal = floor->GetSurfaceNormal(x, z, true);
- result.CeilingNormal = floor->GetSurfaceNormal(x, z, false);
-
- // Backport surface normals to tilts.
- result.FloorTilt = GetSurfaceTilt(result.FloorNormal, true).ToVector2();
- result.CeilingTilt = GetSurfaceTilt(result.CeilingNormal, false).ToVector2();
-
- // Split, bridge and slope data.
- result.Position.DiagonalStep = floor->IsSurfaceDiagonalStep(true);
- result.Position.SplitAngle = TO_RAD(floor->FloorSurface.SplitAngle);
- result.Position.Bridge = result.BottomBlock->GetInsideBridgeItemNumber(Vector3i(x, result.Position.Floor, z), true, false);
- result.Position.FloorSlope = result.Position.Bridge < 0 && (abs(result.FloorTilt.x) >= 3 || (abs(result.FloorTilt.y) >= 3));
-
- // TODO: Fix on bridges placed beneath ceiling slopes. @Sezz 2022.01.29
- // NOTE: Already fixed if using GetPointCollision().
- result.Position.CeilingSlope = abs(result.CeilingTilt.x) >= 4 || abs(result.CeilingTilt.y) >= 4;
-
- return result;
}
void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, bool resetRoom)
diff --git a/TombEngine/Game/collision/floordata.cpp b/TombEngine/Game/collision/floordata.cpp
index be7a49f2a..01e386268 100644
--- a/TombEngine/Game/collision/floordata.cpp
+++ b/TombEngine/Game/collision/floordata.cpp
@@ -925,7 +925,7 @@ namespace TEN::Collision::Floordata
// Ray intersects box; return bridge box height.
float dist = 0.0f;
if (box.Intersects(origin, dir, dist))
- return (item.Pose.Position.y + (useBottomHeight ? bounds.Y2 : bounds.Y1));
+ return Geometry::TranslatePoint(origin, dir, dist).y;
return std::nullopt;
}
From 68899231f49e593b404dafcf7eba5105982c2324 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Thu, 1 Feb 2024 17:23:36 +1100
Subject: [PATCH 047/410] Update PointCollisionData class; adopt
PointCollisionData in camera.cpp
---
TombEngine/Game/camera.cpp | 278 +++++++++----------
TombEngine/Game/collision/PointCollision.cpp | 70 +++--
TombEngine/Game/collision/PointCollision.h | 12 +-
TombEngine/Game/collision/collide_room.cpp | 25 +-
4 files changed, 195 insertions(+), 190 deletions(-)
diff --git a/TombEngine/Game/camera.cpp b/TombEngine/Game/camera.cpp
index 4c74ce093..c07b395b9 100644
--- a/TombEngine/Game/camera.cpp
+++ b/TombEngine/Game/camera.cpp
@@ -134,8 +134,8 @@ static int GetLookCameraVerticalOffset(const ItemInfo& item, const CollisionInfo
}
// Get floor-to-ceiling height.
- auto pointColl = GetCollision(item);
- int floorToCeilHeight = abs(pointColl.Position.Ceiling - pointColl.Position.Floor);
+ auto pointColl = GetPointCollision(item);
+ int floorToCeilHeight = abs(pointColl.GetCeilingHeight() - pointColl.GetFloorHeight());
// Return appropriate vertical offset.
return -((verticalOffset < floorToCeilHeight) ? verticalOffset : floorToCeilHeight);
@@ -175,8 +175,8 @@ void LookCamera(ItemInfo& item, const CollisionInfo& coll)
auto lookAtPos = Geometry::TranslatePoint(pivotPos, orient, LOOK_AT_DIST);
// Determine best position.
- auto origin = GameVector(pivotPos, GetPointCollision(item, item.Pose.Orientation.y, pivotOffset.z, pivotOffset.y).RoomNumber);
- auto target = GameVector(idealPos, GetPointCollision(origin.ToVector3i(), origin.RoomNumber, orient.ToDirection(), idealDist).RoomNumber);
+ auto origin = GameVector(pivotPos, GetPointCollision(item, item.Pose.Orientation.y, pivotOffset.z, pivotOffset.y).GetRoomNumber());
+ auto target = GameVector(idealPos, GetPointCollision(origin.ToVector3i(), origin.RoomNumber, orient.ToDirection(), idealDist).GetRoomNumber());
// Handle room and object collisions.
LOSAndReturnTarget(&origin, &target, 0);
@@ -345,9 +345,9 @@ void MoveCamera(GameVector* ideal, int speed)
if (TestEnvironment(ENV_FLAG_SWAMP, Camera.pos.RoomNumber))
y = g_Level.Rooms[Camera.pos.RoomNumber].y - CLICK(1);
- auto probe = GetCollision(Camera.pos.x, y, Camera.pos.z, Camera.pos.RoomNumber);
- if (y < probe.Position.Ceiling ||
- y > probe.Position.Floor)
+ auto pointColl = GetPointCollision(Vector3i(Camera.pos.x, y, Camera.pos.z), Camera.pos.RoomNumber);
+ if (y < pointColl.GetCeilingHeight() ||
+ y > pointColl.GetFloorHeight())
{
LOSAndReturnTarget(&Camera.target, &Camera.pos, 0);
@@ -366,41 +366,41 @@ void MoveCamera(GameVector* ideal, int speed)
}
}
- probe = GetCollision(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.pos.RoomNumber);
+ pointColl = GetPointCollision(Camera.pos.ToVector3i(), Camera.pos.RoomNumber);
int buffer = CLICK(1) - 1;
- if ((Camera.pos.y - buffer) < probe.Position.Ceiling &&
- (Camera.pos.y + buffer) > probe.Position.Floor &&
- probe.Position.Ceiling < probe.Position.Floor &&
- probe.Position.Ceiling != NO_HEIGHT &&
- probe.Position.Floor != NO_HEIGHT)
+ if ((Camera.pos.y - buffer) < pointColl.GetCeilingHeight() &&
+ (Camera.pos.y + buffer) > pointColl.GetFloorHeight() &&
+ pointColl.GetCeilingHeight() < pointColl.GetFloorHeight() &&
+ pointColl.GetCeilingHeight() != NO_HEIGHT &&
+ pointColl.GetFloorHeight() != NO_HEIGHT)
{
- Camera.pos.y = (probe.Position.Floor + probe.Position.Ceiling) / 2;
+ Camera.pos.y = (pointColl.GetFloorHeight() + pointColl.GetCeilingHeight()) / 2;
}
- else if ((Camera.pos.y + buffer) > probe.Position.Floor &&
- probe.Position.Ceiling < probe.Position.Floor &&
- probe.Position.Ceiling != NO_HEIGHT &&
- probe.Position.Floor != NO_HEIGHT)
+ else if ((Camera.pos.y + buffer) > pointColl.GetFloorHeight() &&
+ pointColl.GetCeilingHeight() < pointColl.GetFloorHeight() &&
+ pointColl.GetCeilingHeight() != NO_HEIGHT &&
+ pointColl.GetFloorHeight() != NO_HEIGHT)
{
- Camera.pos.y = probe.Position.Floor - buffer;
+ Camera.pos.y = pointColl.GetFloorHeight() - buffer;
}
- else if ((Camera.pos.y - buffer) < probe.Position.Ceiling &&
- probe.Position.Ceiling < probe.Position.Floor &&
- probe.Position.Ceiling != NO_HEIGHT &&
- probe.Position.Floor != NO_HEIGHT)
+ else if ((Camera.pos.y - buffer) < pointColl.GetCeilingHeight() &&
+ pointColl.GetCeilingHeight() < pointColl.GetFloorHeight() &&
+ pointColl.GetCeilingHeight() != NO_HEIGHT &&
+ pointColl.GetFloorHeight() != NO_HEIGHT)
{
- Camera.pos.y = probe.Position.Ceiling + buffer;
+ Camera.pos.y = pointColl.GetCeilingHeight() + buffer;
}
- else if (probe.Position.Ceiling >= probe.Position.Floor ||
- probe.Position.Floor == NO_HEIGHT ||
- probe.Position.Ceiling == NO_HEIGHT)
+ else if (pointColl.GetCeilingHeight() >= pointColl.GetFloorHeight() ||
+ pointColl.GetFloorHeight() == NO_HEIGHT ||
+ pointColl.GetCeilingHeight() == NO_HEIGHT)
{
Camera.pos = *ideal;
}
ItemsCollideCamera();
- Camera.pos.RoomNumber = GetCollision(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.pos.RoomNumber).RoomNumber;
+ Camera.pos.RoomNumber = GetPointCollision(Camera.pos.ToVector3i(), Camera.pos.RoomNumber).GetRoomNumber();
LookAt(&Camera, 0);
UpdateMikePos(*LaraItem);
Camera.oldType = Camera.type;
@@ -467,7 +467,7 @@ void MoveObjCamera(GameVector* ideal, ItemInfo* camSlotId, int camMeshId, ItemIn
}
Camera.pos += (ideal->ToVector3i() - Camera.pos.ToVector3i()) / speed;
- Camera.pos.RoomNumber = GetCollision(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.pos.RoomNumber).RoomNumber;
+ Camera.pos.RoomNumber = GetPointCollision(Camera.pos.ToVector3i(), Camera.pos.RoomNumber).GetRoomNumber();
LookAt(&Camera, 0);
auto angle = Camera.target.ToVector3i() - Camera.pos.ToVector3i();
@@ -531,21 +531,23 @@ void ChaseCamera(ItemInfo* item)
int distance = Camera.targetDistance * phd_cos(Camera.actualElevation);
- auto probe = GetCollision(Camera.target.x, Camera.target.y + CLICK(1), Camera.target.z, Camera.target.RoomNumber);
+ auto pointColl = GetPointCollision(Vector3i(Camera.target.x, Camera.target.y + CLICK(1), Camera.target.z), Camera.target.RoomNumber);
- if (TestEnvironment(ENV_FLAG_SWAMP, probe.RoomNumber))
- Camera.target.y = g_Level.Rooms[probe.RoomNumber].maxceiling - CLICK(1);
+ if (TestEnvironment(ENV_FLAG_SWAMP, pointColl.GetRoomNumber()))
+ Camera.target.y = g_Level.Rooms[pointColl.GetRoomNumber()].maxceiling - CLICK(1);
int y = Camera.target.y;
- probe = GetCollision(Camera.target.x, y, Camera.target.z, Camera.target.RoomNumber);
- if (((y < probe.Position.Ceiling || probe.Position.Floor < y) || probe.Position.Floor <= probe.Position.Ceiling) ||
- (probe.Position.Floor == NO_HEIGHT || probe.Position.Ceiling == NO_HEIGHT))
+ pointColl = GetPointCollision(Vector3i(Camera.target.x, y, Camera.target.z), Camera.target.RoomNumber);
+ if (((y < pointColl.GetCeilingHeight() || pointColl.GetFloorHeight() < y) || pointColl.GetFloorHeight() <= pointColl.GetCeilingHeight()) ||
+ (pointColl.GetFloorHeight() == NO_HEIGHT || pointColl.GetCeilingHeight() == NO_HEIGHT))
{
TargetSnaps++;
Camera.target = LastTarget;
}
else
+ {
TargetSnaps = 0;
+ }
for (int i = 0; i < maxSwivelSteps; i++)
Ideals[i].y = Camera.target.y + (Camera.targetDistance * phd_sin(Camera.actualElevation));
@@ -648,43 +650,43 @@ void CombatCamera(ItemInfo* item)
Camera.targetElevation = player.ExtraHeadRot.x + player.ExtraTorsoRot.x + item->Pose.Orientation.x - ANGLE(15.0f);
}
- auto probe = GetCollision(Camera.target.x, Camera.target.y + CLICK(1), Camera.target.z, Camera.target.RoomNumber);
- if (TestEnvironment(ENV_FLAG_SWAMP, probe.RoomNumber))
- Camera.target.y = g_Level.Rooms[probe.RoomNumber].y - CLICK(1);
+ auto pointColl = GetPointCollision(Vector3i(Camera.target.x, Camera.target.y + CLICK(1), Camera.target.z), Camera.target.RoomNumber);
+ if (TestEnvironment(ENV_FLAG_SWAMP, pointColl.GetRoomNumber()))
+ Camera.target.y = g_Level.Rooms[pointColl.GetRoomNumber()].y - CLICK(1);
- probe = GetCollision(Camera.target.x, Camera.target.y, Camera.target.z, Camera.target.RoomNumber);
- Camera.target.RoomNumber = probe.RoomNumber;
+ pointColl = GetPointCollision(Camera.target.ToVector3i(), Camera.target.RoomNumber);
+ Camera.target.RoomNumber = pointColl.GetRoomNumber();
int buffer = CLICK(0.25f);
- if ((probe.Position.Ceiling + buffer) > (probe.Position.Floor - buffer) &&
- probe.Position.Floor != NO_HEIGHT &&
- probe.Position.Ceiling != NO_HEIGHT)
+ if ((pointColl.GetCeilingHeight() + buffer) > (pointColl.GetFloorHeight() - buffer) &&
+ pointColl.GetFloorHeight() != NO_HEIGHT &&
+ pointColl.GetCeilingHeight() != NO_HEIGHT)
{
- Camera.target.y = (probe.Position.Ceiling + probe.Position.Floor) / 2;
+ Camera.target.y = (pointColl.GetCeilingHeight() + pointColl.GetFloorHeight()) / 2;
Camera.targetElevation = 0;
}
- else if (Camera.target.y > (probe.Position.Floor - buffer) &&
- probe.Position.Floor != NO_HEIGHT)
+ else if (Camera.target.y > (pointColl.GetFloorHeight() - buffer) &&
+ pointColl.GetFloorHeight() != NO_HEIGHT)
{
- Camera.target.y = probe.Position.Floor - buffer;
+ Camera.target.y = pointColl.GetFloorHeight() - buffer;
Camera.targetElevation = 0;
}
- else if (Camera.target.y < (probe.Position.Ceiling + buffer) &&
- probe.Position.Ceiling != NO_HEIGHT)
+ else if (Camera.target.y < (pointColl.GetCeilingHeight() + buffer) &&
+ pointColl.GetCeilingHeight() != NO_HEIGHT)
{
- Camera.target.y = probe.Position.Ceiling + buffer;
+ Camera.target.y = pointColl.GetCeilingHeight() + buffer;
Camera.targetElevation = 0;
}
int y = Camera.target.y;
- probe = GetCollision(Camera.target.x, y, Camera.target.z, Camera.target.RoomNumber);
- Camera.target.RoomNumber = probe.RoomNumber;
+ pointColl = GetPointCollision(Vector3i(Camera.target.x, y, Camera.target.z), Camera.target.RoomNumber);
+ Camera.target.RoomNumber = pointColl.GetRoomNumber();
- if (y < probe.Position.Ceiling ||
- y > probe.Position.Floor ||
- probe.Position.Ceiling >= probe.Position.Floor ||
- probe.Position.Floor == NO_HEIGHT ||
- probe.Position.Ceiling == NO_HEIGHT)
+ if (y < pointColl.GetCeilingHeight() ||
+ y > pointColl.GetFloorHeight() ||
+ pointColl.GetCeilingHeight() >= pointColl.GetFloorHeight() ||
+ pointColl.GetFloorHeight() == NO_HEIGHT ||
+ pointColl.GetCeilingHeight() == NO_HEIGHT)
{
TargetSnaps++;
Camera.target = LastTarget;
@@ -770,116 +772,114 @@ bool CameraCollisionBounds(GameVector* ideal, int push, bool yFirst)
int y = ideal->y;
int z = ideal->z;
- CollisionResult probe = {};
+ auto pointColl = GetPointCollision(Vector3i(x, y, z), ideal->RoomNumber);
if (yFirst)
{
- probe = GetCollision(x, y, z, ideal->RoomNumber);
-
int buffer = CLICK(1) - 1;
- if ((y - buffer) < probe.Position.Ceiling &&
- (y + buffer) > probe.Position.Floor &&
- probe.Position.Ceiling < probe.Position.Floor &&
- probe.Position.Ceiling != NO_HEIGHT &&
- probe.Position.Floor != NO_HEIGHT)
+ if ((y - buffer) < pointColl.GetCeilingHeight() &&
+ (y + buffer) > pointColl.GetFloorHeight() &&
+ pointColl.GetCeilingHeight() < pointColl.GetFloorHeight() &&
+ pointColl.GetCeilingHeight() != NO_HEIGHT &&
+ pointColl.GetFloorHeight() != NO_HEIGHT)
{
- y = (probe.Position.Floor + probe.Position.Ceiling) / 2;
+ y = (pointColl.GetFloorHeight() + pointColl.GetCeilingHeight()) / 2;
}
- else if ((y + buffer) > probe.Position.Floor &&
- probe.Position.Ceiling < probe.Position.Floor &&
- probe.Position.Ceiling != NO_HEIGHT &&
- probe.Position.Floor != NO_HEIGHT)
+ else if ((y + buffer) > pointColl.GetFloorHeight() &&
+ pointColl.GetCeilingHeight() < pointColl.GetFloorHeight() &&
+ pointColl.GetCeilingHeight() != NO_HEIGHT &&
+ pointColl.GetFloorHeight() != NO_HEIGHT)
{
- y = probe.Position.Floor - buffer;
+ y = pointColl.GetFloorHeight() - buffer;
}
- else if ((y - buffer) < probe.Position.Ceiling &&
- probe.Position.Ceiling < probe.Position.Floor &&
- probe.Position.Ceiling != NO_HEIGHT &&
- probe.Position.Floor != NO_HEIGHT)
+ else if ((y - buffer) < pointColl.GetCeilingHeight() &&
+ pointColl.GetCeilingHeight() < pointColl.GetFloorHeight() &&
+ pointColl.GetCeilingHeight() != NO_HEIGHT &&
+ pointColl.GetFloorHeight() != NO_HEIGHT)
{
- y = probe.Position.Ceiling + buffer;
+ y = pointColl.GetCeilingHeight() + buffer;
}
}
- probe = GetCollision(x - push, y, z, ideal->RoomNumber);
- if (y > probe.Position.Floor ||
- probe.Position.Floor == NO_HEIGHT ||
- probe.Position.Ceiling == NO_HEIGHT ||
- probe.Position.Ceiling >= probe.Position.Floor ||
- y < probe.Position.Ceiling)
+ pointColl = GetPointCollision(Vector3i(x - push, y, z), ideal->RoomNumber);
+ if (y > pointColl.GetFloorHeight() ||
+ pointColl.GetFloorHeight() == NO_HEIGHT ||
+ pointColl.GetCeilingHeight() == NO_HEIGHT ||
+ pointColl.GetCeilingHeight() >= pointColl.GetFloorHeight() ||
+ y < pointColl.GetCeilingHeight())
{
x = (x & (~1023)) + push;
}
- probe = GetCollision(x, y, z - push, ideal->RoomNumber);
- if (y > probe.Position.Floor ||
- probe.Position.Floor == NO_HEIGHT ||
- probe.Position.Ceiling == NO_HEIGHT ||
- probe.Position.Ceiling >= probe.Position.Floor ||
- y < probe.Position.Ceiling)
+ pointColl = GetPointCollision(Vector3i(x, y, z - push), ideal->RoomNumber);
+ if (y > pointColl.GetFloorHeight() ||
+ pointColl.GetFloorHeight() == NO_HEIGHT ||
+ pointColl.GetCeilingHeight() == NO_HEIGHT ||
+ pointColl.GetCeilingHeight() >= pointColl.GetFloorHeight() ||
+ y < pointColl.GetCeilingHeight())
{
z = (z & (~1023)) + push;
}
- probe = GetCollision(x + push, y, z, ideal->RoomNumber);
- if (y > probe.Position.Floor ||
- probe.Position.Floor == NO_HEIGHT ||
- probe.Position.Ceiling == NO_HEIGHT ||
- probe.Position.Ceiling >= probe.Position.Floor ||
- y < probe.Position.Ceiling)
+ pointColl = GetPointCollision(Vector3i(x + push, y, z), ideal->RoomNumber);
+ if (y > pointColl.GetFloorHeight() ||
+ pointColl.GetFloorHeight() == NO_HEIGHT ||
+ pointColl.GetCeilingHeight() == NO_HEIGHT ||
+ pointColl.GetCeilingHeight() >= pointColl.GetFloorHeight() ||
+ y < pointColl.GetCeilingHeight())
{
x = (x | 1023) - push;
}
- probe = GetCollision(x, y, z + push, ideal->RoomNumber);
- if (y > probe.Position.Floor ||
- probe.Position.Floor == NO_HEIGHT ||
- probe.Position.Ceiling == NO_HEIGHT ||
- probe.Position.Ceiling >= probe.Position.Floor ||
- y < probe.Position.Ceiling)
+ pointColl = GetPointCollision(Vector3i(x, y, z + push), ideal->RoomNumber);
+ if (y > pointColl.GetFloorHeight() ||
+ pointColl.GetFloorHeight() == NO_HEIGHT ||
+ pointColl.GetCeilingHeight() == NO_HEIGHT ||
+ pointColl.GetCeilingHeight() >= pointColl.GetFloorHeight() ||
+ y < pointColl.GetCeilingHeight())
{
z = (z | 1023) - push;
}
if (!yFirst)
{
- probe = GetCollision(x, y, z, ideal->RoomNumber);
+ pointColl = GetPointCollision(Vector3i(x, y, z), ideal->RoomNumber);
int buffer = CLICK(1) - 1;
- if ((y - buffer) < probe.Position.Ceiling &&
- (y + buffer) > probe.Position.Floor &&
- probe.Position.Ceiling < probe.Position.Floor &&
- probe.Position.Ceiling != NO_HEIGHT &&
- probe.Position.Floor != NO_HEIGHT)
+ if ((y - buffer) < pointColl.GetCeilingHeight() &&
+ (y + buffer) > pointColl.GetFloorHeight() &&
+ pointColl.GetCeilingHeight() < pointColl.GetFloorHeight() &&
+ pointColl.GetCeilingHeight() != NO_HEIGHT &&
+ pointColl.GetFloorHeight() != NO_HEIGHT)
{
- y = (probe.Position.Floor + probe.Position.Ceiling) / 2;
+ y = (pointColl.GetFloorHeight() + pointColl.GetCeilingHeight()) / 2;
}
- else if ((y + buffer) > probe.Position.Floor &&
- probe.Position.Ceiling < probe.Position.Floor &&
- probe.Position.Ceiling != NO_HEIGHT &&
- probe.Position.Floor != NO_HEIGHT)
+ else if ((y + buffer) > pointColl.GetFloorHeight() &&
+ pointColl.GetCeilingHeight() < pointColl.GetFloorHeight() &&
+ pointColl.GetCeilingHeight() != NO_HEIGHT &&
+ pointColl.GetFloorHeight() != NO_HEIGHT)
{
- y = probe.Position.Floor - buffer;
+ y = pointColl.GetFloorHeight() - buffer;
}
- else if ((y - buffer) < probe.Position.Ceiling &&
- probe.Position.Ceiling < probe.Position.Floor &&
- probe.Position.Ceiling != NO_HEIGHT &&
- probe.Position.Floor != NO_HEIGHT)
+ else if ((y - buffer) < pointColl.GetCeilingHeight() &&
+ pointColl.GetCeilingHeight() < pointColl.GetFloorHeight() &&
+ pointColl.GetCeilingHeight() != NO_HEIGHT &&
+ pointColl.GetFloorHeight() != NO_HEIGHT)
{
- y = probe.Position.Ceiling + buffer;
+ y = pointColl.GetCeilingHeight() + buffer;
}
}
- probe = GetCollision(x, y, z, ideal->RoomNumber);
- if (y > probe.Position.Floor ||
- y < probe.Position.Ceiling ||
- probe.Position.Floor == NO_HEIGHT ||
- probe.Position.Ceiling == NO_HEIGHT ||
- probe.Position.Ceiling >= probe.Position.Floor)
+ pointColl = GetPointCollision(Vector3i(x, y, z), ideal->RoomNumber);
+ if (y > pointColl.GetFloorHeight() ||
+ y < pointColl.GetCeilingHeight() ||
+ pointColl.GetFloorHeight() == NO_HEIGHT ||
+ pointColl.GetCeilingHeight() == NO_HEIGHT ||
+ pointColl.GetCeilingHeight() >= pointColl.GetFloorHeight())
{
return true;
}
- ideal->RoomNumber = probe.RoomNumber;
+ ideal->RoomNumber = pointColl.GetRoomNumber();
ideal->x = x;
ideal->y = y;
ideal->z = z;
@@ -963,20 +963,20 @@ void BinocularCamera(ItemInfo* item)
int y = item->Pose.Position.y - CLICK(2);
int z = item->Pose.Position.z;
- auto probe = GetCollision(x, y, z, item->RoomNumber);
- if (probe.Position.Ceiling <= (y - CLICK(1)))
+ auto pointColl = GetPointCollision(Vector3i(x, y, z), item->RoomNumber);
+ if (pointColl.GetCeilingHeight() <= (y - CLICK(1)))
{
y -= CLICK(1);
}
else
{
- y = probe.Position.Ceiling + CLICK(0.25f);
+ y = pointColl.GetCeilingHeight() + CLICK(0.25f);
}
Camera.pos.x = x;
Camera.pos.y = y;
Camera.pos.z = z;
- Camera.pos.RoomNumber = probe.RoomNumber;
+ Camera.pos.RoomNumber = pointColl.GetRoomNumber();
float l = BLOCK(20.25f) * phd_cos(player.Control.Look.Orientation.x);
float tx = x + l * phd_sin(item->Pose.Orientation.y + player.Control.Look.Orientation.y);
@@ -1016,7 +1016,7 @@ void BinocularCamera(ItemInfo* item)
}
}
- Camera.target.RoomNumber = GetCollision(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.target.RoomNumber).RoomNumber;
+ Camera.target.RoomNumber = GetPointCollision(Camera.pos.ToVector3i(), Camera.target.RoomNumber).GetRoomNumber();
LookAt(&Camera, 0);
UpdateMikePos(*item);
Camera.oldType = Camera.type;
@@ -1052,12 +1052,12 @@ void ConfirmCameraTargetPos()
}
int y = Camera.target.y;
- auto probe = GetCollision(Camera.target.x, y, Camera.target.z, Camera.target.RoomNumber);
- if (y < probe.Position.Ceiling ||
- probe.Position.Floor < y ||
- probe.Position.Floor <= probe.Position.Ceiling ||
- probe.Position.Floor == NO_HEIGHT ||
- probe.Position.Ceiling == NO_HEIGHT)
+ auto pointColl = GetPointCollision(Vector3i(Camera.target.x, y, Camera.target.z), Camera.target.RoomNumber);
+ if (y < pointColl.GetCeilingHeight() ||
+ pointColl.GetFloorHeight() < y ||
+ pointColl.GetFloorHeight() <= pointColl.GetCeilingHeight() ||
+ pointColl.GetFloorHeight() == NO_HEIGHT ||
+ pointColl.GetCeilingHeight() == NO_HEIGHT)
{
Camera.target.x = pos.x;
Camera.target.y = pos.y;
@@ -1268,7 +1268,7 @@ void CalculateCamera(const CollisionInfo& coll)
Camera.speed = 1;
}
- Camera.target.RoomNumber = GetCollision(x, y, z, Camera.target.RoomNumber).RoomNumber;
+ Camera.target.RoomNumber = GetPointCollision(Vector3i(x, y, z), Camera.target.RoomNumber).GetRoomNumber();
if (abs(LastTarget.x - Camera.target.x) < 4 &&
abs(LastTarget.y - Camera.target.y) < 4 &&
@@ -1361,9 +1361,9 @@ void ItemPushCamera(GameBoundingBox* bounds, Pose* pos, short radius)
Camera.pos.x = pos->Position.x + ((x * cosY) + (z * sinY));
Camera.pos.z = pos->Position.z + ((z * cosY) - (x * sinY));
- auto pointColl = GetCollision(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.pos.RoomNumber);
- if (pointColl.Position.Floor == NO_HEIGHT || Camera.pos.y > pointColl.Position.Floor || Camera.pos.y < pointColl.Position.Ceiling)
- Camera.pos = GameVector(CamOldPos, pointColl.RoomNumber);
+ auto pointColl = GetPointCollision(Camera.pos.ToVector3i(), Camera.pos.RoomNumber);
+ if (pointColl.GetFloorHeight() == NO_HEIGHT || Camera.pos.y > pointColl.GetFloorHeight() || Camera.pos.y < pointColl.GetCeilingHeight())
+ Camera.pos = GameVector(CamOldPos, pointColl.GetRoomNumber());
}
bool CheckItemCollideCamera(ItemInfo* item)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 918f6ad06..6765df0c6 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -16,10 +16,20 @@ using namespace TEN::Math;
namespace TEN::Collision
{
- PointCollisionData::PointCollisionData(const Vector3i& pos, int roomNumber) :
- Position(pos),
- RoomNumber(roomNumber)
+ PointCollisionData::PointCollisionData(const Vector3i& pos, int roomNumber)
{
+ _position = pos;
+ _roomNumber = roomNumber;
+ }
+
+ Vector3i PointCollisionData::GetPosition() const
+ {
+ return _position;
+ }
+
+ int PointCollisionData::GetRoomNumber() const
+ {
+ return _roomNumber;
}
FloorInfo& PointCollisionData::GetSector()
@@ -28,8 +38,8 @@ namespace TEN::Collision
return *_sectorPtr;
// Set current sector pointer.
- short probeRoomNumber = RoomNumber;
- _sectorPtr = GetFloor(Position.x, Position.y, Position.z, &probeRoomNumber);
+ short probeRoomNumber = _roomNumber;
+ _sectorPtr = GetFloor(_position.x, _position.y, _position.z, &probeRoomNumber);
return *_sectorPtr;
}
@@ -41,13 +51,13 @@ namespace TEN::Collision
// Set bottom sector pointer.
auto* bottomSectorPtr = &GetSector();
- auto roomNumberBelow = bottomSectorPtr->GetRoomNumberBelow(Position);
+ auto roomNumberBelow = bottomSectorPtr->GetRoomNumberBelow(_position);
while (roomNumberBelow.has_value())
{
auto& room = g_Level.Rooms[roomNumberBelow.value_or(bottomSectorPtr->RoomNumber)];
- bottomSectorPtr = Room::GetSector(&room, Position.x - room.x, Position.z - room.z);
+ bottomSectorPtr = Room::GetSector(&room, _position.x - room.x, _position.z - room.z);
- roomNumberBelow = bottomSectorPtr->GetRoomNumberBelow(Position);
+ roomNumberBelow = bottomSectorPtr->GetRoomNumberBelow(_position);
}
_bottomSectorPtr = bottomSectorPtr;
@@ -61,13 +71,13 @@ namespace TEN::Collision
// Set top sector pointer.
auto* topSectorPtr = &GetSector();
- auto roomNumberAbove = topSectorPtr->GetRoomNumberAbove(Position);
+ auto roomNumberAbove = topSectorPtr->GetRoomNumberAbove(_position);
while (roomNumberAbove.has_value())
{
auto& room = g_Level.Rooms[roomNumberAbove.value_or(topSectorPtr->RoomNumber)];
- topSectorPtr = Room::GetSector(&room, Position.x - room.x, Position.z - room.z);
+ topSectorPtr = Room::GetSector(&room, _position.x - room.x, _position.z - room.z);
- roomNumberAbove = topSectorPtr->GetRoomNumberAbove(Position);
+ roomNumberAbove = topSectorPtr->GetRoomNumberAbove(_position);
}
_topSectorPtr = topSectorPtr;
@@ -80,8 +90,8 @@ namespace TEN::Collision
return *_floorHeight;
// Set floor height.
- auto location = RoomVector(GetSector().RoomNumber, Position.y);
- _floorHeight = Floordata::GetSurfaceHeight(location, Position.x, Position.z, true).value_or(NO_HEIGHT);
+ auto location = RoomVector(GetSector().RoomNumber, _position.y);
+ _floorHeight = Floordata::GetSurfaceHeight(location, _position.x, _position.z, true).value_or(NO_HEIGHT);
return *_floorHeight;
}
@@ -92,8 +102,8 @@ namespace TEN::Collision
return *_ceilingHeight;
// Set ceiling height.
- auto location = RoomVector(GetSector().RoomNumber, Position.y);
- _ceilingHeight = Floordata::GetSurfaceHeight(location, Position.x, Position.z, false).value_or(NO_HEIGHT);
+ auto location = RoomVector(GetSector().RoomNumber, _position.y);
+ _ceilingHeight = Floordata::GetSurfaceHeight(location, _position.x, _position.z, false).value_or(NO_HEIGHT);
return *_ceilingHeight;
}
@@ -110,7 +120,7 @@ namespace TEN::Collision
}
else
{
- _floorNormal = GetBottomSector().GetSurfaceNormal(Position.x, Position.z, true);
+ _floorNormal = GetBottomSector().GetSurfaceNormal(_position.x, _position.z, true);
}
return *_floorNormal;
@@ -128,7 +138,7 @@ namespace TEN::Collision
}
else
{
- _ceilingNormal = GetTopSector().GetSurfaceNormal(Position.x, Position.z, false);
+ _ceilingNormal = GetTopSector().GetSurfaceNormal(_position.x, _position.z, false);
}
return *_ceilingNormal;
@@ -141,7 +151,7 @@ namespace TEN::Collision
// Set floor bridge item number.
int floorHeight = GetFloorHeight();
- auto pos = Vector3i(Position.x, floorHeight, Position.z);
+ auto pos = Vector3i(_position.x, floorHeight, _position.z);
_floorBridgeItemNumber = GetBottomSector().GetInsideBridgeItemNumber(pos, true, false);
return *_floorBridgeItemNumber;
@@ -154,7 +164,7 @@ namespace TEN::Collision
// Set ceiling bridge item number.
int ceilingHeight = GetCeilingHeight();
- auto pos = Vector3i(Position.x, ceilingHeight, Position.z);
+ auto pos = Vector3i(_position.x, ceilingHeight, _position.z);
_ceilingBridgeItemNumber = GetTopSector().GetInsideBridgeItemNumber(pos, false, true);
return *_ceilingBridgeItemNumber;
@@ -166,7 +176,7 @@ namespace TEN::Collision
return *_waterSurfaceHeight;
// Set water surface height.
- _waterSurfaceHeight = GetWaterSurface(Position.x, Position.y, Position.z, RoomNumber);
+ _waterSurfaceHeight = GetWaterSurface(_position.x, _position.y, _position.z, _roomNumber);
return *_waterSurfaceHeight;
}
@@ -177,7 +187,7 @@ namespace TEN::Collision
return *_waterBottomHeight;
// Set water bottom height.
- _waterBottomHeight = GetWaterDepth(Position.x, Position.y, Position.z, RoomNumber);
+ _waterBottomHeight = GetWaterDepth(_position.x, _position.y, _position.z, _roomNumber);
return *_waterBottomHeight;
}
@@ -188,7 +198,7 @@ namespace TEN::Collision
return *_waterTopHeight;
// Set water top height.
- _waterTopHeight = GetWaterHeight(Position.x, Position.y, Position.z, RoomNumber);
+ _waterTopHeight = GetWaterHeight(_position.x, _position.y, _position.z, _roomNumber);
return *_waterTopHeight;
}
@@ -204,7 +214,7 @@ namespace TEN::Collision
short slopeAngle = Geometry::GetSurfaceSlopeAngle(GetFloorNormal());
short illegalSlopeAngle = (GetFloorBridgeItemNumber() != NO_ITEM) ?
DEFAULT_ILLEGAL_FLOOR_SLOPE_ANGLE :
- GetBottomSector().GetSurfaceIllegalSlopeAngle(Position.x, Position.z, true);
+ GetBottomSector().GetSurfaceIllegalSlopeAngle(_position.x, _position.z, true);
return (abs(slopeAngle) >= illegalSlopeAngle);
}
@@ -214,7 +224,7 @@ namespace TEN::Collision
short slopeAngle = Geometry::GetSurfaceSlopeAngle(GetCeilingNormal(), -Vector3::UnitY);
short illegalSlopeAngle = (GetCeilingBridgeItemNumber() != NO_ITEM) ?
DEFAULT_ILLEGAL_CEILING_SLOPE_ANGLE :
- GetTopSector().GetSurfaceIllegalSlopeAngle(Position.x, Position.z, false);
+ GetTopSector().GetSurfaceIllegalSlopeAngle(_position.x, _position.z, false);
return (abs(slopeAngle) >= illegalSlopeAngle);
}
@@ -255,7 +265,7 @@ namespace TEN::Collision
bool PointCollisionData::TestEnvironmentFlag(RoomEnvFlags envFlag)
{
- const auto& room = g_Level.Rooms[RoomNumber];
+ const auto& room = g_Level.Rooms[_roomNumber];
return ((room.flags & envFlag) == envFlag);
}
@@ -327,7 +337,15 @@ namespace TEN::Collision
PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber)
{
- return PointCollisionData(pos, roomNumber);
+ // TEMP HACK
+ // GetPointCollision() takes arguments for a *current* position and room number.
+ // However, since some calls to the equivalent deprecated function had *projected*
+ // positions passed to it, the room number had be corrected to account for such cases.
+ // These are primarily found in camera.cpp.
+ short correctedRoomNumber = roomNumber;
+ GetFloor(pos.x, pos.y, pos.z, &correctedRoomNumber);
+
+ return PointCollisionData(pos, correctedRoomNumber);
}
PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber, const Vector3& dir, float dist)
diff --git a/TombEngine/Game/collision/PointCollision.h b/TombEngine/Game/collision/PointCollision.h
index be315cb6f..b6ec8da81 100644
--- a/TombEngine/Game/collision/PointCollision.h
+++ b/TombEngine/Game/collision/PointCollision.h
@@ -12,12 +12,11 @@ namespace TEN::Collision
{
class PointCollisionData
{
- public:
- // Members
- const Vector3i Position = Vector3i::Zero;
- const int RoomNumber = 0;
-
private:
+ // Members
+ Vector3i _position = Vector3i::Zero;
+ int _roomNumber = 0;
+
FloorInfo* _sectorPtr = nullptr;
FloorInfo* _bottomSectorPtr = nullptr;
FloorInfo* _topSectorPtr = nullptr;
@@ -38,6 +37,9 @@ namespace TEN::Collision
PointCollisionData(const Vector3i& pos, int roomNumber);
// Getters
+ Vector3i GetPosition() const;
+ int GetRoomNumber() const;
+
FloorInfo& GetSector();
FloorInfo& GetBottomSector();
FloorInfo& GetTopSector();
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index 61d0a3286..d10facb25 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -125,8 +125,8 @@ static CollisionResult ConvertPointCollDataToCollResult(PointCollisionData& poin
{
auto collResult = CollisionResult{};
- collResult.Coordinates = pointColl.Position;
- collResult.RoomNumber = pointColl.RoomNumber;
+ collResult.Coordinates = pointColl.GetPosition();
+ collResult.RoomNumber = pointColl.GetRoomNumber();
collResult.Block = &pointColl.GetSector();
collResult.BottomBlock = &pointColl.GetBottomSector();
@@ -185,36 +185,21 @@ CollisionResult GetCollision(const Vector3i& pos, int roomNumber, const Vector3&
// NOTE: Deprecated. Use GetPointCollision().
CollisionResult GetCollision(const Vector3i& pos, int roomNumber)
{
- // HACK: GetPointCollision() takes arguments for a *current* position and room number.
- // However, since some calls to this deprecated function had *projected*
- // positions passed to it, the room number must be corrected to account for such cases.
- // They are primarily found in camera.cpp.
- short correctedRoomNumber = roomNumber;
- GetFloor(pos.x, pos.y, pos.z, &correctedRoomNumber);
-
- auto pointColl = GetPointCollision(pos, correctedRoomNumber);
+ auto pointColl = GetPointCollision(pos, roomNumber);
return ConvertPointCollDataToCollResult(pointColl);
}
// NOTE: Deprecated. Use GetPointCollision().
CollisionResult GetCollision(int x, int y, int z, short roomNumber)
{
- // HACK: Explained above.
- short correctedRoomNumber = roomNumber;
- GetFloor(x, y, z, &correctedRoomNumber);
-
- auto pointColl = GetPointCollision(Vector3i(x, y, z), correctedRoomNumber);
+ auto pointColl = GetPointCollision(Vector3i(x, y, z), roomNumber);
return ConvertPointCollDataToCollResult(pointColl);
}
// NOTE: Deprecated. Use GetPointCollision().
CollisionResult GetCollision(const GameVector& pos)
{
- // HACK: Explained above.
- short correctedRoomNumber = pos.RoomNumber;
- GetFloor(pos.x, pos.y, pos.z, &correctedRoomNumber);
-
- auto pointColl = GetPointCollision(pos.ToVector3i(), correctedRoomNumber);
+ auto pointColl = GetPointCollision(pos.ToVector3i(), pos.RoomNumber);
return ConvertPointCollDataToCollResult(pointColl);
}
From e9012c619e0eaa35cceb05c99048665ef5b53908 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Thu, 1 Feb 2024 17:30:31 +1100
Subject: [PATCH 048/410] Remove parameters
---
TombEngine/Game/collision/PointCollision.cpp | 4 ++--
TombEngine/Game/collision/PointCollision.h | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 6765df0c6..6abc6d33d 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -209,7 +209,7 @@ namespace TEN::Collision
GetFloorHeight() <= GetCeilingHeight());
}
- bool PointCollisionData::IsIllegalFloor(short slopeAngleMin)
+ bool PointCollisionData::IsIllegalFloor()
{
short slopeAngle = Geometry::GetSurfaceSlopeAngle(GetFloorNormal());
short illegalSlopeAngle = (GetFloorBridgeItemNumber() != NO_ITEM) ?
@@ -219,7 +219,7 @@ namespace TEN::Collision
return (abs(slopeAngle) >= illegalSlopeAngle);
}
- bool PointCollisionData::IsIllegalCeiling(short slopeAngleMin)
+ bool PointCollisionData::IsIllegalCeiling()
{
short slopeAngle = Geometry::GetSurfaceSlopeAngle(GetCeilingNormal(), -Vector3::UnitY);
short illegalSlopeAngle = (GetCeilingBridgeItemNumber() != NO_ITEM) ?
diff --git a/TombEngine/Game/collision/PointCollision.h b/TombEngine/Game/collision/PointCollision.h
index b6ec8da81..71b90e2d3 100644
--- a/TombEngine/Game/collision/PointCollision.h
+++ b/TombEngine/Game/collision/PointCollision.h
@@ -57,8 +57,8 @@ namespace TEN::Collision
// Inquirers
bool IsWall();
- bool IsIllegalFloor(short slopeAngleMin = DEFAULT_ILLEGAL_FLOOR_SLOPE_ANGLE);
- bool IsIllegalCeiling(short slopeAngleMin = DEFAULT_ILLEGAL_CEILING_SLOPE_ANGLE);
+ bool IsIllegalFloor();
+ bool IsIllegalCeiling();
bool IsDiagonalFloorStep();
bool IsDiagonalCeilingStep();
bool IsFloorDiagonalSplit();
From 923790041df614ace139d65c4e70da80c917de1b Mon Sep 17 00:00:00 2001
From: Sezz
Date: Thu, 1 Feb 2024 23:43:41 +1100
Subject: [PATCH 049/410] Process tilts correctly for bridges rotated on X and
Z axes
---
.../Objects/Generic/Object/generic_bridge.cpp | 37 +++++++++----------
.../Objects/Generic/Object/generic_bridge.h | 1 -
2 files changed, 18 insertions(+), 20 deletions(-)
diff --git a/TombEngine/Objects/Generic/Object/generic_bridge.cpp b/TombEngine/Objects/Generic/Object/generic_bridge.cpp
index 05826f823..c5fdcedb4 100644
--- a/TombEngine/Objects/Generic/Object/generic_bridge.cpp
+++ b/TombEngine/Objects/Generic/Object/generic_bridge.cpp
@@ -10,15 +10,28 @@ using namespace TEN::Collision::Floordata;
namespace TEN::Entities::Generic
{
+ static int GetTiltOffset(const ItemInfo& item, const Vector3i& pos, int tiltGrade, bool isFloor)
+ {
+ // Calculate delta position.
+ auto deltaPos = (item.Pose.Position - pos).ToVector3();
+
+ // Calculate tilt normal.
+ int sign = isFloor ? -1 : 1;
+ auto rotMatrix = EulerAngles(0, item.Pose.Orientation.y, 0).ToRotationMatrix();
+ auto normal = Vector3::Transform(Vector3(-tiltGrade, 1.0f, 0.0f) * sign, rotMatrix);
+ normal.Normalize();
+
+ // Calculate and return tilt offset.
+ float relPlaneHeight = -((normal.x * deltaPos.x) + (normal.z * deltaPos.z)) / normal.y;
+ return ((relPlaneHeight / 4) + CLICK(tiltGrade * 0.5f)); // TODO: Wrong when walking near some bridge edges?
+ }
+
template
static std::optional GetBridgeFloorHeight(const ItemInfo& item, const Vector3i& pos)
{
auto boxHeight = GetBridgeItemIntersect(item, pos, false);
if (boxHeight.has_value() && tiltGrade != 0)
- {
- int height = item.Pose.Position.y + (tiltGrade * ((GetOffset(item.Pose.Orientation.y, pos.x, pos.z) / 4) + (BLOCK(1 / 8.0f))));
- return height;
- }
+ return (*boxHeight + GetTiltOffset(item, pos, tiltGrade, true));
return boxHeight;
}
@@ -28,10 +41,7 @@ namespace TEN::Entities::Generic
{
auto boxHeight = GetBridgeItemIntersect(item, pos, true);
if (boxHeight.has_value() && tiltGrade != 0)
- {
- int height = item.Pose.Position.y + (tiltGrade * ((GetOffset(item.Pose.Orientation.y, pos.x, pos.z) / 4) + (BLOCK(1 / 8.0f))));
- return (height + CLICK(1));
- }
+ return ((item.Pose.Position.y + GetTiltOffset(item, pos, tiltGrade, false)) + CLICK(1));
return boxHeight;
}
@@ -96,15 +106,4 @@ namespace TEN::Entities::Generic
UpdateBridgeItem(bridgeItem);
}
-
- int GetOffset(short angle, int x, int z)
- {
- // Get rotated sector point.
- auto sectorPoint = GetSectorPoint(x, z).ToVector2();
- auto rotMatrix = Matrix::CreateRotationZ(TO_RAD(angle));
- Vector2::Transform(sectorPoint, rotMatrix, sectorPoint);
-
- // Return offset.
- return -sectorPoint.x;
- }
}
diff --git a/TombEngine/Objects/Generic/Object/generic_bridge.h b/TombEngine/Objects/Generic/Object/generic_bridge.h
index 3830ecd23..12dfee101 100644
--- a/TombEngine/Objects/Generic/Object/generic_bridge.h
+++ b/TombEngine/Objects/Generic/Object/generic_bridge.h
@@ -3,5 +3,4 @@
namespace TEN::Entities::Generic
{
void InitializeBridge(short itemNumber);
- int GetOffset(short angle, int x, int z);
}
From 4d6f22a948f9fa81b87700807d009278ad1b576b Mon Sep 17 00:00:00 2001
From: Sezz
Date: Thu, 1 Feb 2024 23:44:09 +1100
Subject: [PATCH 050/410] Remove comment
---
TombEngine/Objects/Generic/Object/generic_bridge.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/TombEngine/Objects/Generic/Object/generic_bridge.cpp b/TombEngine/Objects/Generic/Object/generic_bridge.cpp
index c5fdcedb4..81abfa392 100644
--- a/TombEngine/Objects/Generic/Object/generic_bridge.cpp
+++ b/TombEngine/Objects/Generic/Object/generic_bridge.cpp
@@ -23,7 +23,7 @@ namespace TEN::Entities::Generic
// Calculate and return tilt offset.
float relPlaneHeight = -((normal.x * deltaPos.x) + (normal.z * deltaPos.z)) / normal.y;
- return ((relPlaneHeight / 4) + CLICK(tiltGrade * 0.5f)); // TODO: Wrong when walking near some bridge edges?
+ return ((relPlaneHeight / 4) + CLICK(tiltGrade * 0.5f));
}
template
From 75c8ff2601c955dc9fc0152eb8b32c150e82983e Mon Sep 17 00:00:00 2001
From: Sezz
Date: Fri, 2 Feb 2024 00:07:05 +1100
Subject: [PATCH 051/410] Simplify
---
TombEngine/Game/collision/floordata.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/TombEngine/Game/collision/floordata.cpp b/TombEngine/Game/collision/floordata.cpp
index 01e386268..8a24dbba4 100644
--- a/TombEngine/Game/collision/floordata.cpp
+++ b/TombEngine/Game/collision/floordata.cpp
@@ -916,8 +916,7 @@ namespace TEN::Collision::Floordata
{
constexpr auto VERTICAL_MARGIN = 4;
- auto bounds = GameBoundingBox(&item);
- auto box = bounds.ToBoundingOrientedBox(item.Pose);
+ auto box = GameBoundingBox(&item).ToBoundingOrientedBox(item.Pose);
auto origin = Vector3(pos.x, pos.y + (useBottomHeight ? VERTICAL_MARGIN : -VERTICAL_MARGIN), pos.z);
auto dir = useBottomHeight ? -Vector3::UnitY : Vector3::UnitY;
From 253aa3816d4e6d062d90bc60015a4b560e1e7bc7 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Fri, 2 Feb 2024 00:44:52 +1100
Subject: [PATCH 052/410] Remove 3 GetCollision() overloads
---
TombEngine/Game/Lara/lara.cpp | 2 +-
TombEngine/Game/Lara/lara_helpers.cpp | 6 ++-
TombEngine/Game/Lara/lara_overhang.cpp | 10 +++--
TombEngine/Game/camera.cpp | 4 +-
TombEngine/Game/collision/PointCollision.cpp | 2 +-
TombEngine/Game/collision/PointCollision.h | 2 +-
TombEngine/Game/collision/collide_room.cpp | 23 +---------
TombEngine/Game/collision/collide_room.h | 3 --
TombEngine/Game/collision/floordata.cpp | 25 ++++++-----
TombEngine/Game/missile.cpp | 14 +++---
.../Object/Pushable/PushableCollision.cpp | 14 +++---
.../Generic/Object/Pushable/PushableSound.cpp | 7 ++-
.../Generic/Traps/crumblingPlatform.cpp | 14 +++---
TombEngine/Objects/TR1/Entity/tr1_bear.cpp | 6 ++-
.../Objects/TR3/Trap/ElectricCleaner.cpp | 45 +++++++++++--------
TombEngine/Objects/TR5/Entity/tr5_guard.cpp | 4 +-
16 files changed, 92 insertions(+), 89 deletions(-)
diff --git a/TombEngine/Game/Lara/lara.cpp b/TombEngine/Game/Lara/lara.cpp
index 02f5b9cd1..7eec415d2 100644
--- a/TombEngine/Game/Lara/lara.cpp
+++ b/TombEngine/Game/Lara/lara.cpp
@@ -47,8 +47,8 @@
#include "Specific/Input/Input.h"
#include "Specific/winmain.h"
-using namespace TEN::Collision;
using namespace TEN::Collision::Floordata;
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Control::Volumes;
using namespace TEN::Effects::Hair;
using namespace TEN::Effects::Items;
diff --git a/TombEngine/Game/Lara/lara_helpers.cpp b/TombEngine/Game/Lara/lara_helpers.cpp
index 584391b80..d6bb58a65 100644
--- a/TombEngine/Game/Lara/lara_helpers.cpp
+++ b/TombEngine/Game/Lara/lara_helpers.cpp
@@ -7,6 +7,7 @@
#include "Game/camera.h"
#include "Game/collision/collide_room.h"
#include "Game/collision/floordata.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/control.h"
#include "Game/control/volume.h"
#include "Game/items.h"
@@ -37,6 +38,7 @@
#include "Objects/TR4/Vehicles/motorbike.h"
using namespace TEN::Collision::Floordata;
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Control::Volumes;
using namespace TEN::Effects::Bubble;
using namespace TEN::Effects::Drip;
@@ -1257,8 +1259,8 @@ PlayerWaterData GetPlayerWaterData(ItemInfo& item)
int waterDepth = GetWaterDepth(&item);
int waterHeight = GetWaterHeight(&item);
- auto pointColl = GetCollision(item);
- int heightFromWater = (waterHeight == NO_HEIGHT) ? NO_HEIGHT : (std::min(item.Pose.Position.y, pointColl.Position.Floor) - waterHeight);
+ auto pointColl = GetPointCollision(item);
+ int heightFromWater = (waterHeight == NO_HEIGHT) ? NO_HEIGHT : (std::min(item.Pose.Position.y, pointColl.GetFloorHeight()) - waterHeight);
return PlayerWaterData
{
diff --git a/TombEngine/Game/Lara/lara_overhang.cpp b/TombEngine/Game/Lara/lara_overhang.cpp
index b398a0fb1..72e93f579 100644
--- a/TombEngine/Game/Lara/lara_overhang.cpp
+++ b/TombEngine/Game/Lara/lara_overhang.cpp
@@ -2,8 +2,9 @@
#include "Game/Lara/lara_overhang.h"
#include "Game/camera.h"
-#include "Game/collision/floordata.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/floordata.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/control.h"
#include "Game/Lara/lara.h"
#include "Game/Lara/lara_climb.h"
@@ -16,6 +17,7 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Entities::Generic;
using namespace TEN::Input;
@@ -967,12 +969,12 @@ void SlopeClimbExtra(ItemInfo* item, CollisionInfo* coll)
// Extends LS_LADDER_IDLE (56)
bool LadderMonkeyExtra(ItemInfo* item, CollisionInfo* coll)
{
- auto probe = GetCollision(*item);
+ auto probe = GetPointCollision(*item);
- if (probe.Position.CeilingSlope)
+ if (probe.IsIllegalCeiling())
return false;
- if (probe.BottomBlock->Flags.Monkeyswing && (item->Pose.Position.y - coll->Setup.Height - CLICK(0.5f) <= probe.Position.Ceiling))
+ if (probe.GetBottomSector().Flags.Monkeyswing && (item->Pose.Position.y - coll->Setup.Height - CLICK(0.5f) <= probe.GetCeilingHeight()))
{
item->Animation.TargetState = LS_MONKEY_IDLE;
return true;
diff --git a/TombEngine/Game/camera.cpp b/TombEngine/Game/camera.cpp
index c07b395b9..9e13f0bd7 100644
--- a/TombEngine/Game/camera.cpp
+++ b/TombEngine/Game/camera.cpp
@@ -22,13 +22,13 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
-using namespace TEN::Collision;
-using TEN::Renderer::g_Renderer;
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Effects::Environment;
using namespace TEN::Entities::Generic;
using namespace TEN::Input;
using namespace TEN::Math;
+using TEN::Renderer::g_Renderer;
constexpr auto PARTICLE_FADE_THRESHOLD = BLOCK(14);
constexpr auto COLL_CHECK_THRESHOLD = BLOCK(4);
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 6abc6d33d..652a47af5 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -14,7 +14,7 @@ using namespace TEN::Collision::Floordata;
using namespace TEN::Collision::Room;
using namespace TEN::Math;
-namespace TEN::Collision
+namespace TEN::Collision::PointCollision
{
PointCollisionData::PointCollisionData(const Vector3i& pos, int roomNumber)
{
diff --git a/TombEngine/Game/collision/PointCollision.h b/TombEngine/Game/collision/PointCollision.h
index 71b90e2d3..cc031d4ab 100644
--- a/TombEngine/Game/collision/PointCollision.h
+++ b/TombEngine/Game/collision/PointCollision.h
@@ -8,7 +8,7 @@ struct ItemInfo;
using namespace TEN::Math;
-namespace TEN::Collision
+namespace TEN::Collision::PointCollision
{
class PointCollisionData
{
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index d10facb25..4ecd49296 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -13,8 +13,8 @@
#include "Sound/sound.h"
#include "Renderer/Renderer.h"
-using namespace TEN::Collision;
using namespace TEN::Collision::Floordata;
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Collision::Room;
using namespace TEN::Math;
using namespace TEN::Renderer;
@@ -147,13 +147,6 @@ static CollisionResult ConvertPointCollDataToCollResult(PointCollisionData& poin
return collResult;
}
-// NOTE: Deprecated. Use GetPointCollision().
-CollisionResult GetCollision(const ItemInfo& item)
-{
- auto pointColl = GetPointCollision(item);
- return ConvertPointCollDataToCollResult(pointColl);
-}
-
// NOTE: Deprecated. Use GetPointCollision().
CollisionResult GetCollision(const ItemInfo* item)
{
@@ -168,20 +161,6 @@ CollisionResult GetCollision(const ItemInfo* item, short headingAngle, float for
return ConvertPointCollDataToCollResult(pointColl);
}
-// NOTE: Deprecated. Use GetPointCollision().
-CollisionResult GetCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down, float right)
-{
- auto pointColl = GetPointCollision(pos, roomNumber, headingAngle, forward, down, right);
- return ConvertPointCollDataToCollResult(pointColl);
-}
-
-// NOTE: Deprecated. Use GetPointCollision().
-CollisionResult GetCollision(const Vector3i& pos, int roomNumber, const Vector3& dir, float dist)
-{
- auto pointColl = GetPointCollision(pos, roomNumber, dir, dist);
- return ConvertPointCollDataToCollResult(pointColl);
-}
-
// NOTE: Deprecated. Use GetPointCollision().
CollisionResult GetCollision(const Vector3i& pos, int roomNumber)
{
diff --git a/TombEngine/Game/collision/collide_room.h b/TombEngine/Game/collision/collide_room.h
index 755a2eb85..99a94bd35 100644
--- a/TombEngine/Game/collision/collide_room.h
+++ b/TombEngine/Game/collision/collide_room.h
@@ -136,11 +136,8 @@ struct CollisionInfo
[[nodiscard]] bool TestItemRoomCollisionAABB(ItemInfo* item);
// NOTE: All overloads deprecated. Use GetPointCollision().
-CollisionResult GetCollision(const ItemInfo& item);
CollisionResult GetCollision(const ItemInfo* item);
CollisionResult GetCollision(const ItemInfo* item, short headingAngle, float forward, float down = 0.0f, float right = 0.0f);
-CollisionResult GetCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down = 0.0f, float right = 0.0f);
-CollisionResult GetCollision(const Vector3i& pos, int roomNumber, const Vector3& dir, float dist);
CollisionResult GetCollision(const Vector3i& pos, int roomNumber);
CollisionResult GetCollision(int x, int y, int z, short roomNumber);
CollisionResult GetCollision(const GameVector& pos);
diff --git a/TombEngine/Game/collision/floordata.cpp b/TombEngine/Game/collision/floordata.cpp
index 8a24dbba4..0303e233c 100644
--- a/TombEngine/Game/collision/floordata.cpp
+++ b/TombEngine/Game/collision/floordata.cpp
@@ -1,6 +1,8 @@
#include "framework.h"
#include "Game/collision/floordata.h"
+
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/items.h"
#include "Game/room.h"
#include "Game/Setup.h"
@@ -11,6 +13,7 @@
#include "Specific/trutils.h"
using namespace TEN::Collision::Floordata;
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Entities::Generic;
using namespace TEN::Math;
using namespace TEN::Utils;
@@ -1036,7 +1039,7 @@ namespace TEN::Collision::Floordata
constexpr auto MINECART_STOP_COLOR = Vector4(0.4f, 1.0f, 1.0f, 1.0f);
// Get point collision.
- auto pointColl = GetCollision(item);
+ auto pointColl = GetPointCollision(item);
auto pos = item.Pose.Position.ToVector3();
// Run through neighboring rooms.
@@ -1052,50 +1055,50 @@ namespace TEN::Collision::Floordata
pos.x = BLOCK(roomGridCoord.x) + neighborRoom.x;
pos.z = BLOCK(roomGridCoord.y) + neighborRoom.z;
- pointColl = GetCollision(pos, neighborRoomNumber);
- pos.y = pointColl.Position.Floor;
+ pointColl = GetPointCollision(pos, neighborRoomNumber);
+ pos.y = pointColl.GetFloorHeight();
float verticalOffset = STRING_SPACING;
// Stopper
- if (pointColl.Block->Stopper)
+ if (pointColl.GetSector().Stopper)
{
DrawSectorFlagLabel(pos, "Stopper", STOPPER_COLOR, verticalOffset);
verticalOffset += STRING_SPACING;
}
// Death
- if (pointColl.Block->Flags.Death)
+ if (pointColl.GetSector().Flags.Death)
{
DrawSectorFlagLabel(pos, "Death", DEATH_COLOR, verticalOffset);
verticalOffset += STRING_SPACING;
}
// Monkey Swing
- if (pointColl.Block->Flags.Monkeyswing)
+ if (pointColl.GetSector().Flags.Monkeyswing)
{
DrawSectorFlagLabel(pos, "Monkey Swing", MONKEY_SWING_COLOR, verticalOffset);
verticalOffset += STRING_SPACING;
}
// Beetle / Minecart Right
- if (pointColl.Block->Flags.MarkBeetle)
+ if (pointColl.GetSector().Flags.MarkBeetle)
{
- auto labelString = std::string("Beetle") + (!pointColl.Block->Flags.MinecartStop() ? " / Minecart Right" : "");
+ auto labelString = std::string("Beetle") + (!pointColl.GetSector().Flags.MinecartStop() ? " / Minecart Right" : "");
DrawSectorFlagLabel(pos, labelString, BEETLE_MINECART_RIGHT_COLOR, verticalOffset);
verticalOffset += STRING_SPACING;
}
// Activator / Minecart Left
- if (pointColl.Block->Flags.MarkTriggerer)
+ if (pointColl.GetSector().Flags.MarkTriggerer)
{
- auto labelString = std::string("Activator") + (!pointColl.Block->Flags.MinecartStop() ? " / Minecart Left" : "");
+ auto labelString = std::string("Activator") + (!pointColl.GetSector().Flags.MinecartStop() ? " / Minecart Left" : "");
DrawSectorFlagLabel(pos, labelString, ACTIVATOR_MINECART_LEFT_COLOR, verticalOffset);
verticalOffset += STRING_SPACING;
}
// Minecart Stop
- if (pointColl.Block->Flags.MinecartStop())
+ if (pointColl.GetSector().Flags.MinecartStop())
{
DrawSectorFlagLabel(pos, "Minecart Stop", MINECART_STOP_COLOR, verticalOffset);
verticalOffset += STRING_SPACING;
diff --git a/TombEngine/Game/missile.cpp b/TombEngine/Game/missile.cpp
index e0655c903..b1449629b 100644
--- a/TombEngine/Game/missile.cpp
+++ b/TombEngine/Game/missile.cpp
@@ -4,6 +4,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/effects/tomb4fx.h"
#include "Game/effects/effects.h"
#include "Game/effects/explosion.h"
@@ -15,6 +16,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;;
using namespace TEN::Effects::Bubble;
using namespace TEN::Effects::Explosion;
using namespace TEN::Math;
@@ -142,23 +144,23 @@ void ControlNatlaGun(short fxNumber)
// If first frame, start another explosion at next position.
if (fx.frameNumber == -1)
{
- auto pointColl = GetCollision(fx.pos.Position, fx.roomNumber, fx.pos.Orientation.y, fx.speed);
+ auto pointColl = GetPointCollision(fx.pos.Position, fx.roomNumber, fx.pos.Orientation.y, fx.speed);
// Don't create one if hit a wall.
- if (pointColl.Coordinates.y >= pointColl.Position.Floor ||
- pointColl.Coordinates.y <= pointColl.Position.Ceiling)
+ if (pointColl.GetPosition().y >= pointColl.GetFloorHeight() ||
+ pointColl.GetPosition().y <= pointColl.GetCeilingHeight())
{
return;
}
- fxNumber = CreateNewEffect(pointColl.RoomNumber);
+ fxNumber = CreateNewEffect(pointColl.GetRoomNumber());
if (fxNumber != NO_ITEM)
{
auto& fxNew = EffectList[fxNumber];
- fxNew.pos.Position = pointColl.Coordinates;
+ fxNew.pos.Position = pointColl.GetPosition();
fxNew.pos.Orientation.y = fx.pos.Orientation.y;
- fxNew.roomNumber = pointColl.RoomNumber;
+ fxNew.roomNumber = pointColl.GetRoomNumber();
fxNew.speed = fx.speed;
fxNew.frameNumber = 0;
fxNew.objectNumber = ID_PROJ_BOMB;
diff --git a/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp b/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
index 5a96b5ce2..4e9634660 100644
--- a/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
+++ b/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
@@ -3,6 +3,7 @@
#include "Game/collision/collide_item.h"
#include "Game/collision/floordata.h"
+#include "Game/collision/PointCollision.h"
#include "Game/Lara/lara.h"
#include "Game/Setup.h"
#include "Objects/Generic/Object/BridgeObject.h"
@@ -12,6 +13,7 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Collision::Floordata;
using namespace TEN::Entities::Generic;
using namespace TEN::Input;
@@ -309,14 +311,14 @@ namespace TEN::Entities::Generic
{
auto& pushable = GetPushableInfo(item);
- auto pointColl = CollisionResult{};
+ auto pointColl = GetPointCollision(item);
int waterHeight = NO_HEIGHT;
if (pushable.UseBridgeCollision)
{
RemovePushableBridge(item);
- pointColl = GetCollision(item);
+ pointColl = GetPointCollision(item);
waterHeight = GetWaterSurface(item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z, item.RoomNumber);
if (waterHeight == NO_HEIGHT && TestEnvironment(ENV_FLAG_SWAMP, item.RoomNumber))
@@ -326,7 +328,7 @@ namespace TEN::Entities::Generic
}
else
{
- pointColl = GetCollision(item);
+ pointColl = GetPointCollision(item);
waterHeight = GetWaterSurface(item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z, item.RoomNumber);
if (waterHeight == NO_HEIGHT && TestEnvironment(ENV_FLAG_SWAMP, item.RoomNumber))
@@ -334,8 +336,8 @@ namespace TEN::Entities::Generic
}
auto pushableColl = PushableCollisionData{};
- pushableColl.FloorHeight = pointColl.Position.Floor;
- pushableColl.CeilingHeight = pointColl.Position.Ceiling;
+ pushableColl.FloorHeight = pointColl.GetFloorHeight();
+ pushableColl.CeilingHeight = pointColl.GetCeilingHeight();
// Above water.
if (TestEnvironment(ENV_FLAG_WATER, item.RoomNumber) ||
@@ -367,7 +369,7 @@ namespace TEN::Entities::Generic
// Grounded.
else
{
- auto floorSlopeAngle = Geometry::GetSurfaceSlopeAngle(pointColl.FloorNormal);
+ auto floorSlopeAngle = Geometry::GetSurfaceSlopeAngle(pointColl.GetFloorNormal());
if (floorSlopeAngle == 0)
{
diff --git a/TombEngine/Objects/Generic/Object/Pushable/PushableSound.cpp b/TombEngine/Objects/Generic/Object/Pushable/PushableSound.cpp
index 4509c346f..b28869af2 100644
--- a/TombEngine/Objects/Generic/Object/Pushable/PushableSound.cpp
+++ b/TombEngine/Objects/Generic/Object/Pushable/PushableSound.cpp
@@ -1,10 +1,13 @@
#include "framework.h"
#include "Objects/Generic/Object/Pushable/PushableSound.h"
+#include "Game/collision/PointCollision.h"
#include "Objects/Generic/Object/Pushable/PushableObject.h"
#include "Sound/sound.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
+
namespace TEN::Entities::Generic
{
enum PushableSoundType
@@ -64,8 +67,8 @@ namespace TEN::Entities::Generic
static std::optional GetPushableSoundID(const ItemInfo& pushableItem, PushableSoundType soundType)
{
// Get floor material.
- auto pointColl = GetCollision(pushableItem);
- auto material = pointColl.BottomBlock->GetSurfaceMaterial(pointColl.Coordinates.x, pointColl.Coordinates.z, true);
+ auto pointColl = GetPointCollision(pushableItem);
+ auto material = pointColl.GetBottomSector().GetSurfaceMaterial(pointColl.GetPosition().x, pointColl.GetPosition().z, true);
switch (soundType)
{
diff --git a/TombEngine/Objects/Generic/Traps/crumblingPlatform.cpp b/TombEngine/Objects/Generic/Traps/crumblingPlatform.cpp
index 4af04c235..406262f9f 100644
--- a/TombEngine/Objects/Generic/Traps/crumblingPlatform.cpp
+++ b/TombEngine/Objects/Generic/Traps/crumblingPlatform.cpp
@@ -3,6 +3,7 @@
#include "Game/collision/collide_item.h"
#include "Game/collision/floordata.h"
+#include "Game/collision/PointCollision.h"
#include "Game/Lara/lara.h"
#include "Game/Lara/lara_helpers.h"
#include "Game/setup.h"
@@ -11,6 +12,7 @@
#include "Specific/level.h"
using namespace TEN::Collision::Floordata;
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Entities::Generic;
// NOTES:
@@ -139,8 +141,8 @@ namespace TEN::Entities::Traps
item.Animation.TargetState = CRUMBLING_PLATFORM_STATE_FALL;
item.ItemFlags[1] = CRUMBLING_PLATFORM_VELOCITY_MIN;
- auto pointColl = GetCollision(item);
- pointColl.Block->RemoveBridge(itemNumber);
+ auto pointColl = GetPointCollision(item);
+ pointColl.GetSector().RemoveBridge(itemNumber);
}
}
@@ -152,8 +154,8 @@ namespace TEN::Entities::Traps
// Get point collision.
auto box = GameBoundingBox(&item);
- auto pointColl = GetCollision(item);
- int relFloorHeight = (item.Pose.Position.y - pointColl.Position.Floor) - box.Y1 ;
+ auto pointColl = GetPointCollision(item);
+ int relFloorHeight = (item.Pose.Position.y - pointColl.GetFloorHeight()) - box.Y1 ;
// Airborne.
if (relFloorHeight <= fallVel)
@@ -168,11 +170,11 @@ namespace TEN::Entities::Traps
else
{
item.Animation.TargetState = CRUMBLING_PLATFORM_STATE_LAND;
- item.Pose.Position.y = pointColl.Position.Floor;
+ item.Pose.Position.y = pointColl.GetFloorHeight();
}
// Update room number.
- int probedRoomNumber = pointColl.RoomNumber;
+ int probedRoomNumber = pointColl.GetRoomNumber();
if (item.RoomNumber != probedRoomNumber)
ItemNewRoom(itemNumber, probedRoomNumber);
}
diff --git a/TombEngine/Objects/TR1/Entity/tr1_bear.cpp b/TombEngine/Objects/TR1/Entity/tr1_bear.cpp
index 01b67ec76..fce60b3eb 100644
--- a/TombEngine/Objects/TR1/Entity/tr1_bear.cpp
+++ b/TombEngine/Objects/TR1/Entity/tr1_bear.cpp
@@ -2,6 +2,7 @@
#include "Objects/TR1/Entity/tr1_bear.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/box.h"
#include "Game/control/control.h"
#include "Game/effects/effects.h"
@@ -13,6 +14,7 @@
#include "Math/Math.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Math;
namespace TEN::Entities::Creatures::TR1
@@ -146,8 +148,8 @@ namespace TEN::Entities::Creatures::TR1
bool isPlayerDead = LaraItem->HitPoints <= 0;
- auto pointColl = GetCollision(item);
- int floorToCeilHeight = abs(pointColl.Position.Ceiling - pointColl.Position.Floor);
+ auto pointColl = GetPointCollision(item);
+ int floorToCeilHeight = abs(pointColl.GetCeilingHeight() - pointColl.GetFloorHeight());
switch (item.Animation.ActiveState)
{
diff --git a/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp b/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp
index f99da99eb..3f88cdc9d 100644
--- a/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp
+++ b/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp
@@ -2,6 +2,8 @@
#include "Objects/TR3/Trap/ElectricCleaner.h"
#include "Game/collision/collide_item.h"
+#include "Game/collision/floordata.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/box.h"
#include "Game/effects/item_fx.h"
#include "Game/effects/spark.h"
@@ -9,6 +11,8 @@
#include "Game/Lara/lara_helpers.h"
#include "Game/Setup.h"
+using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Floordata;
using namespace TEN::Effects::Items;
using namespace TEN::Effects::Spark;
@@ -72,21 +76,24 @@ namespace TEN::Entities::Traps
static bool IsNextSectorValid(const ItemInfo& item, const Vector3& dir)
{
auto projectedPos = Geometry::TranslatePoint(item.Pose.Position, dir, BLOCK(1));
- auto pointColl = GetCollision(item.Pose.Position, item.RoomNumber, dir, BLOCK(1));
+ auto pointColl = GetPointCollision(item.Pose.Position, item.RoomNumber, dir, BLOCK(1));
+
+ // TODO: Use floor normal directly.
+ auto floorTilt = GetSurfaceTilt(pointColl.GetFloorNormal(), true);
// Test for wall.
- if (pointColl.Block->IsWall(projectedPos.x, projectedPos.z))
+ if (pointColl.GetSector().IsWall(projectedPos.x, projectedPos.z))
return false;
// Test for slippery slope.
- if (pointColl.Position.FloorSlope)
+ if (pointColl.IsIllegalFloor())
return false;
// Flat floor.
- if (abs(pointColl.FloorTilt.x) == 0 && abs(pointColl.FloorTilt.y) == 0)
+ if (abs(floorTilt.x) == 0 && abs(floorTilt.y) == 0)
{
// Test for step.
- int relFloorHeight = abs(pointColl.Position.Floor - item.Pose.Position.y);
+ int relFloorHeight = abs(pointColl.GetFloorHeight() - item.Pose.Position.y);
if (relFloorHeight >= CLICK(1))
return false;
}
@@ -94,25 +101,25 @@ namespace TEN::Entities::Traps
else
{
// Half block.
- int relFloorHeight = abs(pointColl.Position.Floor - item.Pose.Position.y);
+ int relFloorHeight = abs(pointColl.GetFloorHeight() - item.Pose.Position.y);
if (relFloorHeight > CLICK(2))
return false;
short slopeAngle = ANGLE(0.0f);
- if (pointColl.FloorTilt.x > 0)
+ if (floorTilt.x > 0)
{
slopeAngle = ANGLE(-90.0f);
}
- else if (pointColl.FloorTilt.x < 0)
+ else if (floorTilt.x < 0)
{
slopeAngle = ANGLE(90.0f);
}
- if (pointColl.FloorTilt.y > 0 && pointColl.FloorTilt.y > abs(pointColl.FloorTilt.x))
+ if (floorTilt.y > 0 && floorTilt.y > abs(floorTilt.x))
{
slopeAngle = ANGLE(180.0f);
}
- else if (pointColl.FloorTilt.y < 0 && -pointColl.FloorTilt.y > abs(pointColl.FloorTilt.x))
+ else if (floorTilt.y < 0 && -floorTilt.y > abs(floorTilt.x))
{
slopeAngle = ANGLE(0.0f);
}
@@ -126,28 +133,28 @@ namespace TEN::Entities::Traps
}
// Check for diagonal split.
- if (pointColl.Position.DiagonalStep)
+ if (pointColl.IsDiagonalFloorStep())
return false;
// Test ceiling height.
- int relCeilHeight = abs(pointColl.Position.Ceiling - pointColl.Position.Floor);
+ int relCeilHeight = abs(pointColl.GetCeilingHeight() - pointColl.GetFloorHeight());
int cleanerHeight = BLOCK(1);
if (relCeilHeight < cleanerHeight)
return false;
// Check for inaccessible sector.
- if (pointColl.Block->Box == NO_BOX)
+ if (pointColl.GetSector().Box == NO_BOX)
return false;
// Check for blocked grey box.
- if (g_Level.Boxes[pointColl.Block->Box].flags & BLOCKABLE)
+ if (g_Level.Boxes[pointColl.GetSector().Box].flags & BLOCKABLE)
{
- if (g_Level.Boxes[pointColl.Block->Box].flags& BLOCKED)
+ if (g_Level.Boxes[pointColl.GetSector().Box].flags& BLOCKED)
return false;
}
// Check for stopper flag.
- if (pointColl.Block->Stopper)
+ if (pointColl.GetSector().Stopper)
return false;
return true;
@@ -309,8 +316,8 @@ namespace TEN::Entities::Traps
case ElectricCleanerState::MOVE:
{
- auto pointColl = GetCollision(item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z, item.RoomNumber);
- item.Pose.Position.y = pointColl.Position.Floor;
+ auto pointColl = GetPointCollision(item);
+ item.Pose.Position.y = pointColl.GetFloorHeight();
auto forwardDir = EulerAngles(0, item.Pose.Orientation.y, 0).ToDirection();
@@ -321,7 +328,7 @@ namespace TEN::Entities::Traps
(item.Pose.Position.z & WALL_MASK) == BLOCK(0.5f))
{
// Only turn on flat floor.
- if (abs(pointColl.FloorTilt.x) == 0 && abs(pointColl.FloorTilt.y) == 0)
+ if (pointColl.GetFloorNormal() == -Vector3::UnitY)
activeState = ElectricCleanerState::CHOOSE_PATH;
}
}
diff --git a/TombEngine/Objects/TR5/Entity/tr5_guard.cpp b/TombEngine/Objects/TR5/Entity/tr5_guard.cpp
index f00c6eacb..e02a89ca0 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_guard.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_guard.cpp
@@ -3,6 +3,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/box.h"
#include "Game/control/los.h"
#include "Game/effects/effects.h"
@@ -17,6 +18,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Math;
namespace TEN::Entities::Creatures::TR5
@@ -262,7 +264,7 @@ namespace TEN::Entities::Creatures::TR5
case GuardOcb::RopeDownFast:
SetAnimation(item, GUARD_ANIM_ROPE_DOWN_FAST);
- item->Pose.Position.y = GetCollision(*item).Position.Ceiling - BLOCK(2);
+ item->Pose.Position.y = GetPointCollision(*item).GetCeilingHeight() - BLOCK(2);
break;
case GuardOcb::WaitOnWall:
From b72766b46041c60842cb34767434989362b52136 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Fri, 2 Feb 2024 00:58:59 +1100
Subject: [PATCH 053/410] Remove 2 GetCollision() overloads
---
TombEngine/Game/Lara/lara.cpp | 2 +-
TombEngine/Game/collision/PointCollision.cpp | 2 +-
TombEngine/Game/collision/collide_room.cpp | 14 --------
TombEngine/Game/collision/collide_room.h | 2 --
.../Object/Pushable/PushableCollision.cpp | 36 +++++++++----------
.../Object/Pushable/PushableObject.cpp | 6 ++--
6 files changed, 24 insertions(+), 38 deletions(-)
diff --git a/TombEngine/Game/Lara/lara.cpp b/TombEngine/Game/Lara/lara.cpp
index 7eec415d2..1c256a84a 100644
--- a/TombEngine/Game/Lara/lara.cpp
+++ b/TombEngine/Game/Lara/lara.cpp
@@ -125,7 +125,7 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
}
}
- auto pointColl = GetPointCollision(*item);
+ auto pointColl = GetPointCollision(*item, -Vector3::UnitY, coll->Setup.Height / 2);
auto origin = item->Pose.Position + Vector3i(0, -BLOCK(1), 0);
g_Renderer.AddDebugLine(origin.ToVector3(), Geometry::TranslatePoint(origin, pointColl.GetFloorNormal(), BLOCK(0.5f)).ToVector3(), Vector4(0, 1, 0, 1));
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 652a47af5..22869a549 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -339,7 +339,7 @@ namespace TEN::Collision::PointCollision
{
// TEMP HACK
// GetPointCollision() takes arguments for a *current* position and room number.
- // However, since some calls to the equivalent deprecated function had *projected*
+ // However, since some calls to the old GetCollision() function had *projected*
// positions passed to it, the room number had be corrected to account for such cases.
// These are primarily found in camera.cpp.
short correctedRoomNumber = roomNumber;
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index 4ecd49296..0ca7e52bc 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -161,13 +161,6 @@ CollisionResult GetCollision(const ItemInfo* item, short headingAngle, float for
return ConvertPointCollDataToCollResult(pointColl);
}
-// NOTE: Deprecated. Use GetPointCollision().
-CollisionResult GetCollision(const Vector3i& pos, int roomNumber)
-{
- auto pointColl = GetPointCollision(pos, roomNumber);
- return ConvertPointCollDataToCollResult(pointColl);
-}
-
// NOTE: Deprecated. Use GetPointCollision().
CollisionResult GetCollision(int x, int y, int z, short roomNumber)
{
@@ -175,13 +168,6 @@ CollisionResult GetCollision(int x, int y, int z, short roomNumber)
return ConvertPointCollDataToCollResult(pointColl);
}
-// NOTE: Deprecated. Use GetPointCollision().
-CollisionResult GetCollision(const GameVector& pos)
-{
- auto pointColl = GetPointCollision(pos.ToVector3i(), pos.RoomNumber);
- return ConvertPointCollDataToCollResult(pointColl);
-}
-
// NOTE: Deprecated. Use GetPointCollision().
CollisionResult GetCollision(FloorInfo* floor, int x, int y, int z)
{
diff --git a/TombEngine/Game/collision/collide_room.h b/TombEngine/Game/collision/collide_room.h
index 99a94bd35..b597a119a 100644
--- a/TombEngine/Game/collision/collide_room.h
+++ b/TombEngine/Game/collision/collide_room.h
@@ -138,9 +138,7 @@ struct CollisionInfo
// NOTE: All overloads deprecated. Use GetPointCollision().
CollisionResult GetCollision(const ItemInfo* item);
CollisionResult GetCollision(const ItemInfo* item, short headingAngle, float forward, float down = 0.0f, float right = 0.0f);
-CollisionResult GetCollision(const Vector3i& pos, int roomNumber);
CollisionResult GetCollision(int x, int y, int z, short roomNumber);
-CollisionResult GetCollision(const GameVector& pos);
CollisionResult GetCollision(FloorInfo* floor, int x, int y, int z);
void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offset, bool resetRoom = false);
diff --git a/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp b/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
index 4e9634660..d2eac7afb 100644
--- a/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
+++ b/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
@@ -30,24 +30,24 @@ namespace TEN::Entities::Generic
if (pushableItem.Status == ITEM_INVISIBLE || pushableItem.TriggerFlags < 0)
return false;
- auto pointColl = CollisionResult{};
+ auto pointColl = GetPointCollision(pushableItem);
if (pushable.UseRoomCollision)
{
RemovePushableBridge(pushableItem);
- pointColl = GetCollision(&pushableItem);
+ pointColl = GetPointCollision(pushableItem);
AddPushableBridge(pushableItem);
}
else
{
- pointColl = GetCollision(&pushableItem);
+ pointColl = GetPointCollision(pushableItem);
}
// 1) Check for wall.
- if (pointColl.Block->IsWall(pushableItem.Pose.Position.x, pushableItem.Pose.Position.z))
+ if (pointColl.GetSector().IsWall(pushableItem.Pose.Position.x, pushableItem.Pose.Position.z))
return false;
// 2) Test height from floor.
- int heightFromFloor = abs(pointColl.Position.Floor - pushableItem.Pose.Position.y);
+ int heightFromFloor = abs(pointColl.GetFloorHeight() - pushableItem.Pose.Position.y);
if (heightFromFloor >= PUSHABLE_FLOOR_HEIGHT_TOLERANCE)
return false;
@@ -65,18 +65,18 @@ namespace TEN::Entities::Generic
pushable.IsOnEdge = false;
- auto pointColl = GetCollision(targetPos, targetRoomNumber);
+ auto pointColl = GetPointCollision(targetPos, targetRoomNumber);
// 1) Check for wall.
- if (pointColl.Block->IsWall(targetPos.x, targetPos.z))
+ if (pointColl.GetSector().IsWall(targetPos.x, targetPos.z))
return false;
// 2) Check for gaps or steps.
- int heightFromFloor = abs(pointColl.Position.Floor - pushableItem.Pose.Position.y);
+ int heightFromFloor = abs(pointColl.GetFloorHeight() - pushableItem.Pose.Position.y);
if (heightFromFloor >= PUSHABLE_FLOOR_HEIGHT_TOLERANCE)
{
// Step.
- if (pointColl.Position.Floor < pushableItem.Pose.Position.y)
+ if (pointColl.GetFloorHeight() < pushableItem.Pose.Position.y)
{
return false;
}
@@ -90,15 +90,15 @@ namespace TEN::Entities::Generic
}
// 3) Check for slippery floor slope.
- if (pointColl.Position.FloorSlope)
+ if (pointColl.IsIllegalFloor())
return false;
// 4) Check for diagonal floor step.
- if (pointColl.Position.DiagonalStep)
+ if (pointColl.IsDiagonalFloorStep())
return false;
// 5) Test floor slope. TODO: Check slope angles of normals directly.
- if ((pointColl.Block->GetSurfaceNormal(0, true) != -Vector3::UnitY) || (pointColl.Block->GetSurfaceNormal(1, true) != -Vector3::UnitY))
+ if ((pointColl.GetSector().GetSurfaceNormal(0, true) != -Vector3::UnitY) || (pointColl.GetSector().GetSurfaceNormal(1, true) != -Vector3::UnitY))
return false;
// Check for stopper flag.
@@ -109,7 +109,7 @@ namespace TEN::Entities::Generic
}*/
// Is ceiling (square or diagonal) high enough?
- int distFromCeil = abs(pointColl.Position.Ceiling - pointColl.Position.Floor);
+ int distFromCeil = abs(pointColl.GetCeilingHeight() - pointColl.GetFloorHeight());
int blockHeight = GetStackHeight(pushableItem.Index) - PUSHABLE_FLOOR_HEIGHT_TOLERANCE;
if (distFromCeil < blockHeight)
return false;
@@ -174,25 +174,25 @@ namespace TEN::Entities::Generic
}
// This collisionResult is the point where Lara would be at the end of the pushable pull.
- auto pointColl = GetCollision(LaraItem->Pose.Position + playerOffset, LaraItem->RoomNumber);
+ auto pointColl = GetPointCollision(LaraItem->Pose.Position + playerOffset, LaraItem->RoomNumber);
// Test for wall.
- if (pointColl.Block->IsWall(pointColl.Coordinates.x, pointColl.Coordinates.z))
+ if (pointColl.GetSector().IsWall(pointColl.GetPosition().x, pointColl.GetPosition().z))
return false;
// Test for flat floor.
- int floorHeightDelta = abs(pointColl.Position.Floor - LaraItem->Pose.Position.y);
+ int floorHeightDelta = abs(pointColl.GetFloorHeight() - LaraItem->Pose.Position.y);
if (floorHeightDelta >= PUSHABLE_FLOOR_HEIGHT_TOLERANCE)
return false;
// Test floor-to-ceiling height.
- int floorToCeilHeight = abs(pointColl.Position.Ceiling - pointColl.Position.Floor);
+ int floorToCeilHeight = abs(pointColl.GetCeilingHeight() - pointColl.GetFloorHeight());
if (floorToCeilHeight < LARA_HEIGHT)
return false;
// Collide with objects.
auto prevPos = LaraItem->Pose.Position;
- LaraItem->Pose.Position = pointColl.Coordinates;
+ LaraItem->Pose.Position = pointColl.GetPosition();
GetCollidedObjects(LaraItem, LARA_RADIUS, true, &CollidedItems[0], &CollidedMeshes[0], true);
LaraItem->Pose.Position = prevPos;
diff --git a/TombEngine/Objects/Generic/Object/Pushable/PushableObject.cpp b/TombEngine/Objects/Generic/Object/Pushable/PushableObject.cpp
index 530c29c6b..e96226e1b 100644
--- a/TombEngine/Objects/Generic/Object/Pushable/PushableObject.cpp
+++ b/TombEngine/Objects/Generic/Object/Pushable/PushableObject.cpp
@@ -4,6 +4,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/collision/floordata.h"
#include "Game/control/box.h"
#include "Game/control/flipeffect.h"
@@ -22,6 +23,7 @@
#include "Specific/level.h"
using namespace TEN::Collision::Floordata;
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Input;
namespace TEN::Entities::Generic
@@ -224,8 +226,8 @@ namespace TEN::Entities::Generic
void SetPushableStopperFlag(bool isStopper, const Vector3i& pos, int roomNumber)
{
- auto pointColl = GetCollision(pos, roomNumber);
- pointColl.Block->Stopper = isStopper;
+ auto pointColl = GetPointCollision(pos, roomNumber);
+ pointColl.GetSector().Stopper = isStopper;
// TODO: There is a problem, it also has to set/reset the flag in the flipped room.
// Because when flipmaps happens, it forgets about the old flag.
From 0fdf829b3b0ee2c0602f6b957c6ef122d8623537 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Fri, 2 Feb 2024 01:22:28 +1100
Subject: [PATCH 054/410] Remove 1 GetCollision() overload
---
TombEngine/Game/Lara/lara.cpp | 2 +-
TombEngine/Game/Lara/lara_overhang.cpp | 32 +++++++++++-----------
TombEngine/Game/collision/collide_room.cpp | 13 ++-------
TombEngine/Game/collision/collide_room.h | 1 -
TombEngine/Game/control/box.cpp | 6 ++--
TombEngine/Game/control/trigger.cpp | 4 ++-
6 files changed, 27 insertions(+), 31 deletions(-)
diff --git a/TombEngine/Game/Lara/lara.cpp b/TombEngine/Game/Lara/lara.cpp
index 1c256a84a..7df426cc5 100644
--- a/TombEngine/Game/Lara/lara.cpp
+++ b/TombEngine/Game/Lara/lara.cpp
@@ -278,7 +278,7 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
// pre-TR5 bug where player would keep submerged until root mesh was above water level.
isWaterOnHeadspace = TestEnvironment(
ENV_FLAG_WATER, item->Pose.Position.x, item->Pose.Position.y - CLICK(1), item->Pose.Position.z,
- GetCollision(item->Pose.Position.x, item->Pose.Position.y - CLICK(1), item->Pose.Position.z, item->RoomNumber).RoomNumber);
+ GetPointCollision(*item, 0, 0, -CLICK(1)).GetRoomNumber());
if (water.WaterDepth == NO_HEIGHT || abs(water.HeightFromWater) >= CLICK(1) || isWaterOnHeadspace ||
item->Animation.AnimNumber == LA_UNDERWATER_RESURFACE || item->Animation.AnimNumber == LA_ONWATER_DIVE)
diff --git a/TombEngine/Game/Lara/lara_overhang.cpp b/TombEngine/Game/Lara/lara_overhang.cpp
index 72e93f579..d1245b90d 100644
--- a/TombEngine/Game/Lara/lara_overhang.cpp
+++ b/TombEngine/Game/Lara/lara_overhang.cpp
@@ -370,11 +370,11 @@ void lara_col_slopeclimb(ItemInfo* item, CollisionInfo* coll)
if (GetClimbFlags(probeUp.BottomBlock) & slopeData.ClimbOrient &&
InStrip(item->Pose.Position.x, item->Pose.Position.z, item->Pose.Orientation.y, CLICK(3), CLICK(4)))
{
- if (GetCollision(probeUp.Block, up.x, up.y, up.z).Position.Ceiling - item->Pose.Position.y <= (BLOCK(1.5f) - 80)) // Check if a wall is actually there.
- {
- AlignToEdge(item, FORWARD_ALIGNMENT);
- SetAnimation(item, LA_OVERHANG_SLOPE_LADDER_CONVEX_START);
- }
+ //if (GetCollision(probeUp.Block, up.x, up.y, up.z).Position.Ceiling - item->Pose.Position.y <= (BLOCK(1.5f) - 80)) // Check if a wall is actually there.
+ //{
+ // AlignToEdge(item, FORWARD_ALIGNMENT);
+ // SetAnimation(item, LA_OVERHANG_SLOPE_LADDER_CONVEX_START);
+ //}
}
// Test for monkey at next position.
@@ -415,13 +415,13 @@ void lara_col_slopeclimb(ItemInfo* item, CollisionInfo* coll)
}
else if (IsHeld(In::Back))
{
- if ((GetClimbFlags(GetCollision(probeNow.Block, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z).BottomBlock) & slopeData.ClimbOrient) &&
- InStrip(item->Pose.Position.x, item->Pose.Position.z, item->Pose.Orientation.y, 0, CLICK(1)))
- {
- AlignToEdge(item, BACKWARD_ALIGNMENT);
- SetAnimation(item, LA_OVERHANG_SLOPE_LADDER_CONCAVE); // Slope to underlying ladder transition (concave).
- return;
- }
+ //if ((GetClimbFlags(GetCollision(probeNow.Block, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z).BottomBlock) & slopeData.ClimbOrient) &&
+ // InStrip(item->Pose.Position.x, item->Pose.Position.z, item->Pose.Orientation.y, 0, CLICK(1)))
+ //{
+ // AlignToEdge(item, BACKWARD_ALIGNMENT);
+ // SetAnimation(item, LA_OVERHANG_SLOPE_LADDER_CONCAVE); // Slope to underlying ladder transition (concave).
+ // return;
+ //}
if (probeDown.BottomBlock->Flags.Monkeyswing)
{
@@ -1075,8 +1075,8 @@ void SlopeMonkeyExtra(ItemInfo* item, CollisionInfo* coll)
{
lara->Context.NextCornerPos.Orientation.z = AlignToGrab(item);
- int ceiling = GetCollision(probeNow.Block, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z).Position.Ceiling;
- item->Pose.Position.y = ceiling + HEIGHT_ADJUST;
+ /*int ceiling = GetCollision(probeNow.Block, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z).Position.Ceiling;
+ item->Pose.Position.y = ceiling + HEIGHT_ADJUST;*/
SetAnimation(item, LA_OVERHANG_HANG_SWING);
}
@@ -1091,7 +1091,7 @@ void SlopeMonkeyExtra(ItemInfo* item, CollisionInfo* coll)
if (abs(OrientDelta(slopeData.GoalOrient, item->Pose.Orientation.y)) <= ANGLE(30.0f) &&
InStrip(item->Pose.Position.x, item->Pose.Position.z, item->Pose.Orientation.y, 0, CLICK(0.5f)))
{
- if (probeDown.BottomBlock->Flags.Monkeyswing)
+ /*if (probeDown.BottomBlock->Flags.Monkeyswing)
{
int ceiling = GetCollision(probeDown.Block, down.x, now.y, down.z).Position.Ceiling;
int yDiff = ceiling - probeNow.Position.Ceiling;
@@ -1115,7 +1115,7 @@ void SlopeMonkeyExtra(ItemInfo* item, CollisionInfo* coll)
return;
//item->Pose.Position.y = ceiling + 914;
}
- }
+ }*/
}
}
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index 0ca7e52bc..221e358aa 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -168,13 +168,6 @@ CollisionResult GetCollision(int x, int y, int z, short roomNumber)
return ConvertPointCollDataToCollResult(pointColl);
}
-// NOTE: Deprecated. Use GetPointCollision().
-CollisionResult GetCollision(FloorInfo* floor, int x, int y, int z)
-{
- auto pointColl = GetPointCollision(Vector3i(x, y, z), floor->RoomNumber);
- return ConvertPointCollDataToCollResult(pointColl);
-}
-
void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, bool resetRoom)
{
GetCollisionInfo(coll, item, Vector3i::Zero, resetRoom);
@@ -1225,7 +1218,7 @@ int GetWaterDepth(int x, int y, int z, short roomNumber)
!TestEnvironment(ENV_FLAG_SWAMP, roomPtr))
{
int waterHeight = sectorPtr->GetSurfaceHeight(x, z, false);
- int floorHeight = GetCollision(sectorPtr, x, y, z).BottomBlock->GetSurfaceHeight(x, z, true);
+ int floorHeight = GetPointCollision(Vector3i(x, y, z), sectorPtr->RoomNumber).GetBottomSector().GetSurfaceHeight(x, z, true);
return (floorHeight - waterHeight);
}
@@ -1334,7 +1327,7 @@ int GetWaterHeight(int x, int y, int z, short roomNumber)
sectorPtr = GetSector(room, x - room->x, z - room->z);
}
- return GetCollision(sectorPtr, x, y, z).Block->GetSurfaceHeight(Vector3i(x, y, z), false);
+ return GetPointCollision(Vector3i(x, y, z), sectorPtr->RoomNumber).GetSector().GetSurfaceHeight(Vector3i(x, y, z), false);
}
else if (sectorPtr->GetRoomNumberBelow(Vector3i(x, y, z)).value_or(NO_ROOM) != NO_ROOM)
{
@@ -1351,7 +1344,7 @@ int GetWaterHeight(int x, int y, int z, short roomNumber)
sectorPtr = GetSector(roomPtr2, x - roomPtr2->x, z - roomPtr2->z);
}
- return GetCollision(sectorPtr, x, y, z).Block->GetSurfaceHeight(Vector3i(x, y, z), true);
+ return GetPointCollision(Vector3i(x, y, z), sectorPtr->RoomNumber).GetSector().GetSurfaceHeight(Vector3i(x, y, z), true);
}
return NO_HEIGHT;
diff --git a/TombEngine/Game/collision/collide_room.h b/TombEngine/Game/collision/collide_room.h
index b597a119a..58936b2d8 100644
--- a/TombEngine/Game/collision/collide_room.h
+++ b/TombEngine/Game/collision/collide_room.h
@@ -139,7 +139,6 @@ struct CollisionInfo
CollisionResult GetCollision(const ItemInfo* item);
CollisionResult GetCollision(const ItemInfo* item, short headingAngle, float forward, float down = 0.0f, float right = 0.0f);
CollisionResult GetCollision(int x, int y, int z, short roomNumber);
-CollisionResult GetCollision(FloorInfo* floor, int x, int y, int z);
void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offset, bool resetRoom = false);
void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, bool resetRoom = false);
diff --git a/TombEngine/Game/control/box.cpp b/TombEngine/Game/control/box.cpp
index 85555a94f..3bdc5fb3d 100644
--- a/TombEngine/Game/control/box.cpp
+++ b/TombEngine/Game/control/box.cpp
@@ -5,6 +5,7 @@
#include "Game/camera.h"
#include "Game/collision/sphere.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/control.h"
#include "Game/control/lot.h"
#include "Game/effects/smoke.h"
@@ -22,6 +23,7 @@
#include "Objects/Generic/Object/Pushable/PushableObject.h"
#include "Renderer/Renderer.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Collision::Room;
using namespace TEN::Effects::Smoke;
@@ -1508,9 +1510,9 @@ int TargetReachable(ItemInfo* item, ItemInfo* enemy)
}
else
{
- auto pointColl = GetCollision(floor, enemy->Pose.Position.x, enemy->Pose.Position.y, enemy->Pose.Position.z);
+ auto pointColl = GetPointCollision(enemy->Pose.Position, floor->RoomNumber);
auto bounds = GameBoundingBox(item);
- isReachable = abs(enemy->Pose.Position.y - pointColl.Position.Floor) < bounds.GetHeight();
+ isReachable = abs(enemy->Pose.Position.y - pointColl.GetFloorHeight()) < bounds.GetHeight();
}
return (isReachable ? floor->Box : NO_BOX);
diff --git a/TombEngine/Game/control/trigger.cpp b/TombEngine/Game/control/trigger.cpp
index 6f4f4f3aa..7a9443d12 100644
--- a/TombEngine/Game/control/trigger.cpp
+++ b/TombEngine/Game/control/trigger.cpp
@@ -3,6 +3,7 @@
#include "Game/camera.h"
#include "Game/collision/floordata.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/flipeffect.h"
#include "Game/control/box.h"
#include "Game/control/lot.h"
@@ -24,6 +25,7 @@
#include "Sound/sound.h"
#include "Specific/clock.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Effects::Items;
using namespace TEN::Entities::Switches;
@@ -516,7 +518,7 @@ void TestTriggers(int x, int y, int z, FloorInfo* floor, Activator activator, bo
case TRIGGER_TYPES::PAD:
case TRIGGER_TYPES::ANTIPAD:
- if (GetCollision(floor, x, y, z).Position.Floor == y)
+ if (GetPointCollision(Vector3i(x, y, z), floor->RoomNumber).GetFloorHeight() == y)
break;
return;
From dbeccb885e89db1bd5b96fda762c608b1477c9cb Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sun, 4 Feb 2024 01:05:43 +1100
Subject: [PATCH 055/410] WIP Floordata 1
---
TombEngine/Game/collision/floordata.cpp | 270 +++++++++---------------
TombEngine/Game/collision/floordata.h | 10 +-
2 files changed, 95 insertions(+), 185 deletions(-)
diff --git a/TombEngine/Game/collision/floordata.cpp b/TombEngine/Game/collision/floordata.cpp
index 0303e233c..307148850 100644
--- a/TombEngine/Game/collision/floordata.cpp
+++ b/TombEngine/Game/collision/floordata.cpp
@@ -461,6 +461,7 @@ namespace TEN::Collision::Floordata
return sectorPtrs;
}
+ // GetSector
FloorInfo& GetFloor(int roomNumber, const Vector2i& roomGridCoord)
{
auto& room = g_Level.Rooms[roomNumber];
@@ -469,13 +470,14 @@ namespace TEN::Collision::Floordata
return room.floor[sectorID];
}
+ // GetSector
FloorInfo& GetFloor(int roomNumber, int x, int z)
{
auto roomGridCoord = GetRoomGridCoord(roomNumber, x, z);
return GetFloor(roomNumber, roomGridCoord);
}
- FloorInfo& GetFloorSide(int roomNumber, int x, int z, int* sideRoomNumberPtr)
+ static FloorInfo& GetSideSector(int roomNumber, int x, int z, int* sideRoomNumberPtr = nullptr)
{
auto* sectorPtr = &GetFloor(roomNumber, x, z);
@@ -494,126 +496,74 @@ namespace TEN::Collision::Floordata
return *sectorPtr;
}
- FloorInfo& GetBottomFloor(int roomNumber, int x, int z, int* bottomRoomNumberPtr)
+ static FloorInfo& GetFarthestSector(int roomNumber, int x, int z, bool isBottom, int* farthestRoomNumberPtr = nullptr)
{
- auto* sectorPtr = &GetFloorSide(roomNumber, x, z, bottomRoomNumberPtr);
+ auto* sectorPtr = &GetSideSector(roomNumber, x, z, farthestRoomNumberPtr);
- // Find bottom sector.
+ // Find bottom or top sector.
bool isWall = sectorPtr->IsWall(x, z);
while (isWall)
{
- auto roomNumberBelow = sectorPtr->GetRoomNumberBelow(x, z);
- if (!roomNumberBelow.has_value())
+ auto nextRoomNumber = isBottom ? sectorPtr->GetRoomNumberBelow(x, z) : sectorPtr->GetRoomNumberAbove(x, z);
+ if (!nextRoomNumber.has_value())
break;
// TODO: Check.
- sectorPtr = &GetFloorSide(*roomNumberBelow, x, z, bottomRoomNumberPtr);
+ sectorPtr = &GetSideSector(*nextRoomNumber, x, z, farthestRoomNumberPtr);
isWall = sectorPtr->IsWall(x, z);
}
return *sectorPtr;
}
- FloorInfo& GetTopFloor(int roomNumber, int x, int z, int* topRoomNumberPtr)
+ static std::optional GetFarthestHeight(FloorInfo& startSector, Vector3i pos, bool isBottom,
+ int* farthestRoomNumberPtr = nullptr, FloorInfo** farthestSectorPtr = nullptr)
{
- auto* sectorPtr = &GetFloorSide(roomNumber, x, z, topRoomNumberPtr);
-
- // Find top sector.
- bool isWall = sectorPtr->IsWall(x, z);
- while (isWall)
- {
- auto roomNumberAbove = sectorPtr->GetRoomNumberAbove(x, z);
- if (!roomNumberAbove)
- break;
+ int roomNumber = (farthestRoomNumberPtr != nullptr) ? *farthestRoomNumberPtr : 0;
- // TODO: Check.
- sectorPtr = &GetFloorSide(*roomNumberAbove, x, z, topRoomNumberPtr);
- isWall = sectorPtr->IsWall(x, z);
- }
-
- return *sectorPtr;
- }
-
- std::optional GetBottomHeight(FloorInfo& startSector, Vector3i pos, int* bottomRoomNumberPtr, FloorInfo** bottomSectorPtr)
- {
- int roomNumber = (bottomRoomNumberPtr != nullptr) ? *bottomRoomNumberPtr : 0;
-
- // Find bottom height.
+ // Find bottom or top height.
auto* sectorPtr = &startSector;
do
{
- // Set vertical position to lowest bridge ceiling height.
- pos.y = sectorPtr->GetBridgeSurfaceHeight(pos, false);
+ // Set vertical position to lowest bridge ceiling height or highest bridge floor height.
+ pos.y = sectorPtr->GetBridgeSurfaceHeight(pos, !isBottom);
- // Find sector at lowest bridge floor height.
- while (pos.y >= sectorPtr->GetSurfaceHeight(pos.x, pos.z, true))
+ // Find sector at lowest bridge floor height or highest bridge ceiling height.
+ while (isBottom ?
+ (pos.y >= sectorPtr->GetSurfaceHeight(pos.x, pos.z, true)) :
+ (pos.y <= sectorPtr->GetSurfaceHeight(pos.x, pos.z, false)))
{
- auto roomNumberBelow = sectorPtr->GetRoomNumberBelow(pos.x, pos.z);
- if (!roomNumberBelow.has_value())
+ auto nextRoomNumber = isBottom ? sectorPtr->GetRoomNumberBelow(pos.x, pos.z) : sectorPtr->GetRoomNumberAbove(pos.x, pos.z);;
+ if (!nextRoomNumber.has_value())
return std::nullopt;
- sectorPtr = &GetFloorSide(*roomNumberBelow, pos.x, pos.z, &roomNumber);
+ sectorPtr = &GetSideSector(*nextRoomNumber, pos.x, pos.z, &roomNumber);
}
}
// Continue running while bridge exists(?).
- while (sectorPtr->GetInsideBridgeItemNumber(pos, true, false) != NO_ITEM);
+ while (sectorPtr->GetInsideBridgeItemNumber(pos, isBottom, !isBottom) != NO_ITEM);
- // Set output bottom room number.
- if (bottomRoomNumberPtr != nullptr)
- *bottomRoomNumberPtr = roomNumber;
+ // Set output bottom or top room number.
+ if (farthestRoomNumberPtr != nullptr)
+ *farthestRoomNumberPtr = roomNumber;
- // Set output bottom sector pointer.
- if (bottomSectorPtr != nullptr)
- *bottomSectorPtr = sectorPtr;
-
- return pos.y;
- }
-
- std::optional GetTopHeight(FloorInfo& startSector, Vector3i pos, int* topRoomNumberPtr, FloorInfo** topSectorPtr)
- {
- int roomNumber = (topRoomNumberPtr != nullptr) ? *topRoomNumberPtr : 0;
-
- // Find top height.
- auto* sectorPtr = &startSector;
- do
- {
- // Set vertical position to highest bridge floor height.
- pos.y = sectorPtr->GetBridgeSurfaceHeight(pos, true);
-
- // Find sector at highest bridge ceiling height.
- while (pos.y <= sectorPtr->GetSurfaceHeight(pos.x, pos.z, false))
- {
- auto roomNumberAbove = sectorPtr->GetRoomNumberAbove(pos.x, pos.z);
- if (!roomNumberAbove.has_value())
- return std::nullopt;
-
- sectorPtr = &GetFloorSide(*roomNumberAbove, pos.x, pos.z, &roomNumber);
- }
- }
- // Continue running while bridge exists(?).
- while (sectorPtr->GetInsideBridgeItemNumber(pos, false, true) >= 0);
-
- // Set output top room number.
- if (topRoomNumberPtr != nullptr)
- *topRoomNumberPtr = roomNumber;
-
- // Set output top sector pointer.
- if (topSectorPtr != nullptr)
- *topSectorPtr = sectorPtr;
+ // Set output bottom or top sector pointer.
+ if (farthestSectorPtr != nullptr)
+ *farthestSectorPtr = sectorPtr;
return pos.y;
}
std::optional GetSurfaceHeight(const RoomVector& location, int x, int z, bool isFloor)
{
- auto* sectorPtr = &GetFloorSide(location.RoomNumber, x, z);
+ auto* sectorPtr = &GetSideSector(location.RoomNumber, x, z);
auto pos = Vector3i(x, location.Height, z);
int polarity = 0;
if (sectorPtr->IsWall(x, z))
{
- sectorPtr = isFloor ? &GetTopFloor(location.RoomNumber, x, z) : &GetBottomFloor(location.RoomNumber, x, z);
+ sectorPtr = &GetFarthestSector(location.RoomNumber, x, z, isFloor);
if (!sectorPtr->IsWall(x, z))
{
@@ -622,7 +572,7 @@ namespace TEN::Collision::Floordata
}
else
{
- sectorPtr = isFloor ? &GetBottomFloor(location.RoomNumber, x, z) : &GetTopFloor(location.RoomNumber, x, z);
+ sectorPtr = &GetFarthestSector(location.RoomNumber, x, z, isFloor);
if (!sectorPtr->IsWall(x, z))
{
@@ -647,19 +597,16 @@ namespace TEN::Collision::Floordata
if (insideBridgeItemNumber != NO_ITEM)
{
- if (isFloor ? (polarity <= 0) : (polarity >= 0))
+ if (isFloor ? (polarity <= 0) : (polarity >= 0))
{
- auto heightBound = isFloor ? GetTopHeight(*sectorPtr, pos) : GetBottomHeight(*sectorPtr, pos);
+ auto heightBound = GetFarthestHeight(*sectorPtr, pos, !isFloor);
if (heightBound.has_value())
return heightBound;
}
if (isFloor ? (polarity >= 0) : (polarity <= 0))
{
- auto heightBound = isFloor ?
- GetBottomHeight(*sectorPtr, pos, nullptr, §orPtr) :
- GetTopHeight(*sectorPtr, pos, nullptr, §orPtr);
-
+ auto heightBound = GetFarthestHeight(*sectorPtr, pos, isFloor, nullptr, §orPtr);
if (!heightBound.has_value())
return std::nullopt;
@@ -672,7 +619,7 @@ namespace TEN::Collision::Floordata
auto nextRoomNumber = isFloor ? sectorPtr->GetRoomNumberBelow(pos) : sectorPtr->GetRoomNumberAbove(pos);
while (nextRoomNumber.has_value())
{
- sectorPtr = &GetFloorSide(*nextRoomNumber, x, z);
+ sectorPtr = &GetSideSector(*nextRoomNumber, x, z);
nextRoomNumber = isFloor ? sectorPtr->GetRoomNumberBelow(pos) : sectorPtr->GetRoomNumberAbove(pos);
}
}
@@ -680,18 +627,17 @@ namespace TEN::Collision::Floordata
return sectorPtr->GetSurfaceHeight(pos, isFloor);
}
- std::optional GetBottomRoom(RoomVector location, const Vector3i& pos)
+ static std::optional GetFarthestRoom(RoomVector location, const Vector3i& pos, bool isBottom)
{
- auto* sectorPtr = &GetFloorSide(location.RoomNumber, pos.x, pos.z, &location.RoomNumber);
+ auto* sectorPtr = &GetSideSector(location.RoomNumber, pos.x, pos.z, &location.RoomNumber);
if (sectorPtr->IsWall(pos.x, pos.z))
{
- sectorPtr = &GetBottomFloor(location.RoomNumber, pos.x, pos.z, &location.RoomNumber);
-
+ sectorPtr = &GetFarthestSector(location.RoomNumber, pos.x, pos.z, isBottom, &location.RoomNumber);
if (sectorPtr->IsWall(pos.x, pos.z))
return std::nullopt;
- location.Height = sectorPtr->GetSurfaceHeight(pos.x, pos.z, false);
+ location.Height = sectorPtr->GetSurfaceHeight(pos.x, pos.z, !isBottom);
}
int floorHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), true);
@@ -705,30 +651,15 @@ namespace TEN::Collision::Floordata
if (insideBridgeItemNumber != NO_ITEM)
{
- auto bottomHeight = GetBottomHeight(*sectorPtr, Vector3i(pos.x, location.Height, pos.z), &location.RoomNumber, §orPtr);
- if (!bottomHeight.has_value())
+ auto farthestHeight = GetFarthestHeight(*sectorPtr, Vector3i(pos.x, location.Height, pos.z), isBottom, &location.RoomNumber, §orPtr);
+ if (!farthestHeight.has_value())
return std::nullopt;
- location.Height = *bottomHeight;
+ location.Height = *farthestHeight;
}
- ceilingHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), false);
- if (pos.y < ceilingHeight && sectorPtr->GetRoomNumberAbove(Vector3i(pos.x, location.Height, pos.z)))
- return std::nullopt;
-
- floorHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), true);
- if (pos.y <= floorHeight)
+ if (isBottom)
{
- location.Height = std::max(pos.y, ceilingHeight);
- return location;
- }
-
- auto roomNumberBelow = sectorPtr->GetRoomNumberBelow(Vector3i(pos.x, location.Height, pos.z));
- while (roomNumberBelow.has_value())
- {
- sectorPtr = &GetFloorSide(*roomNumberBelow, pos.x, pos.z, &location.RoomNumber);
- location.Height = sectorPtr->GetSurfaceHeight(pos.x, pos.z, false);
-
ceilingHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), false);
if (pos.y < ceilingHeight && sectorPtr->GetRoomNumberAbove(Vector3i(pos.x, location.Height, pos.z)))
return std::nullopt;
@@ -739,62 +670,9 @@ namespace TEN::Collision::Floordata
location.Height = std::max(pos.y, ceilingHeight);
return location;
}
-
- roomNumberBelow = sectorPtr->GetRoomNumberBelow(Vector3i(pos.x, location.Height, pos.z));
}
-
- return std::nullopt;
- }
-
- std::optional GetTopRoom(RoomVector location, const Vector3i& pos)
- {
- auto* sectorPtr = &GetFloorSide(location.RoomNumber, pos.x, pos.z, &location.RoomNumber);
-
- if (sectorPtr->IsWall(pos.x, pos.z))
+ else
{
- sectorPtr = &GetTopFloor(location.RoomNumber, pos.x, pos.z, &location.RoomNumber);
-
- if (sectorPtr->IsWall(pos.x, pos.z))
- return std::nullopt;
-
- location.Height = sectorPtr->GetSurfaceHeight(pos.x, pos.z, true);
- }
-
- int floorHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), true);
- int ceilingHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), false);
-
- location.Height = std::clamp(location.Height, std::min(ceilingHeight, floorHeight), std::max(ceilingHeight, floorHeight));
-
- bool testFloorBorder = (location.Height == ceilingHeight);
- bool testCeilBorder = (location.Height == floorHeight);
- int insideBridgeItemNumber = sectorPtr->GetInsideBridgeItemNumber(Vector3i(pos.x, location.Height, pos.z), testFloorBorder, testCeilBorder);
-
- if (insideBridgeItemNumber != NO_ITEM)
- {
- auto topHeight = GetTopHeight(*sectorPtr, Vector3i(pos.x, location.Height, pos.z), &location.RoomNumber, §orPtr);
- if (!topHeight.has_value())
- return std::nullopt;
-
- location.Height = *topHeight;
- }
-
- floorHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), true);
- if (pos.y > floorHeight && sectorPtr->GetRoomNumberBelow(Vector3i(pos.x, location.Height, pos.z)))
- return std::nullopt;
-
- ceilingHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), false);
- if (pos.y >= ceilingHeight)
- {
- location.Height = std::min(pos.y, floorHeight);
- return location;
- }
-
- auto roomNumberAbove = sectorPtr->GetRoomNumberAbove(Vector3i(pos.x, location.Height, pos.z));
- while (roomNumberAbove.has_value())
- {
- sectorPtr = &GetFloorSide(*roomNumberAbove, pos.x, pos.z, &location.RoomNumber);
- location.Height = sectorPtr->GetSurfaceHeight(pos.x, pos.z, true);
-
floorHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), true);
if (pos.y > floorHeight && sectorPtr->GetRoomNumberBelow(Vector3i(pos.x, location.Height, pos.z)))
return std::nullopt;
@@ -805,20 +683,60 @@ namespace TEN::Collision::Floordata
location.Height = std::min(pos.y, floorHeight);
return location;
}
+ }
- roomNumberAbove = sectorPtr->GetRoomNumberAbove(Vector3i(pos.x, location.Height, pos.z));
+ auto nextRoomNumber = isBottom ?
+ sectorPtr->GetRoomNumberBelow(Vector3i(pos.x, location.Height, pos.z)) :
+ sectorPtr->GetRoomNumberAbove(Vector3i(pos.x, location.Height, pos.z));
+
+ while (nextRoomNumber.has_value())
+ {
+ sectorPtr = &GetSideSector(*nextRoomNumber, pos.x, pos.z, &location.RoomNumber);
+ location.Height = sectorPtr->GetSurfaceHeight(pos.x, pos.z, !isBottom);
+
+ if (isBottom)
+ {
+ ceilingHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), false);
+ if (pos.y < ceilingHeight && sectorPtr->GetRoomNumberAbove(Vector3i(pos.x, location.Height, pos.z)))
+ return std::nullopt;
+
+ floorHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), true);
+ if (pos.y <= floorHeight)
+ {
+ location.Height = std::max(pos.y, ceilingHeight);
+ return location;
+ }
+ }
+ else
+ {
+ floorHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), true);
+ if (pos.y > floorHeight && sectorPtr->GetRoomNumberBelow(Vector3i(pos.x, location.Height, pos.z)))
+ return std::nullopt;
+
+ ceilingHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), false);
+ if (pos.y >= ceilingHeight)
+ {
+ location.Height = std::min(pos.y, floorHeight);
+ return location;
+ }
+ }
+
+ nextRoomNumber = isBottom ?
+ sectorPtr->GetRoomNumberBelow(Vector3i(pos.x, location.Height, pos.z)) :
+ sectorPtr->GetRoomNumberAbove(Vector3i(pos.x, location.Height, pos.z));
}
return std::nullopt;
}
+ // GetRoomVector
RoomVector GetRoom(RoomVector location, const Vector3i& pos)
{
- auto locationBelow = GetBottomRoom(location, pos);
+ auto locationBelow = GetFarthestRoom(location, pos, true);
if (locationBelow.has_value())
return *locationBelow;
- auto locationAbove = GetTopRoom(location, pos);
+ auto locationAbove = GetFarthestRoom(location, pos, false);
if (locationAbove.has_value())
return *locationAbove;
@@ -836,7 +754,7 @@ namespace TEN::Collision::Floordata
x += bridgeItem.Pose.Position.x;
z += bridgeItem.Pose.Position.z;
- auto* sectorPtr = &GetFloorSide(bridgeItem.RoomNumber, x, z);
+ auto* sectorPtr = &GetSideSector(bridgeItem.RoomNumber, x, z);
sectorPtr->AddBridge(itemNumber);
if (bridge.GetFloorBorder != nullptr)
@@ -848,7 +766,7 @@ namespace TEN::Collision::Floordata
if (!roomNumberAbove.has_value())
break;
- sectorPtr = &GetFloorSide(*roomNumberAbove, x, z);
+ sectorPtr = &GetSideSector(*roomNumberAbove, x, z);
sectorPtr->AddBridge(itemNumber);
}
}
@@ -862,7 +780,7 @@ namespace TEN::Collision::Floordata
if (!roomNumberBelow.has_value())
break;
- sectorPtr = &GetFloorSide(*roomNumberBelow, x, z);
+ sectorPtr = &GetSideSector(*roomNumberBelow, x, z);
sectorPtr->AddBridge(itemNumber);
}
}
@@ -879,7 +797,7 @@ namespace TEN::Collision::Floordata
x += bridgeItem.Pose.Position.x;
z += bridgeItem.Pose.Position.z;
- auto* sectorPtr = &GetFloorSide(bridgeItem.RoomNumber, x, z);
+ auto* sectorPtr = &GetSideSector(bridgeItem.RoomNumber, x, z);
sectorPtr->RemoveBridge(itemNumber);
if (bridge.GetFloorBorder != nullptr)
@@ -891,7 +809,7 @@ namespace TEN::Collision::Floordata
if (!roomNumberAbove.has_value())
break;
- sectorPtr = &GetFloorSide(*roomNumberAbove, x, z);
+ sectorPtr = &GetSideSector(*roomNumberAbove, x, z);
sectorPtr->RemoveBridge(itemNumber);
}
}
@@ -905,7 +823,7 @@ namespace TEN::Collision::Floordata
if (!roomNumberBelow.has_value())
break;
- sectorPtr = &GetFloorSide(*roomNumberBelow, x, z);
+ sectorPtr = &GetSideSector(*roomNumberBelow, x, z);
sectorPtr->RemoveBridge(itemNumber);
}
}
diff --git a/TombEngine/Game/collision/floordata.h b/TombEngine/Game/collision/floordata.h
index 68730cedd..33de6fd54 100644
--- a/TombEngine/Game/collision/floordata.h
+++ b/TombEngine/Game/collision/floordata.h
@@ -194,17 +194,9 @@ namespace TEN::Collision::Floordata
FloorInfo& GetFloor(int roomNumber, const Vector2i& roomGridCoord);
FloorInfo& GetFloor(int roomNumber, int x, int z);
- FloorInfo& GetFloorSide(int roomNumber, int x, int z, int* sideRoomNumber = nullptr);
- FloorInfo& GetBottomFloor(int roomNumber, int x, int z, int* bottomRoomNumber = nullptr);
- FloorInfo& GetTopFloor(int roomNumber, int x, int z, int* topRoomNumber = nullptr);
- std::optional GetBottomHeight(FloorInfo& startSector, Vector3i pos, int* bottomRoomNumberPtr = nullptr, FloorInfo** bottomSectorPtr = nullptr);
- std::optional GetTopHeight(FloorInfo& startSector, Vector3i pos, int* topRoomNumberPtr = nullptr, FloorInfo** topSectorPtr = nullptr);
std::optional GetSurfaceHeight(const RoomVector& location, int x, int z, bool isFloor);
-
- std::optional GetBottomRoom(RoomVector location, const Vector3i& pos);
- std::optional GetTopRoom(RoomVector location, const Vector3i& pos);
- RoomVector GetRoom(RoomVector location, const Vector3i& pos);
+ RoomVector GetRoom(RoomVector location, const Vector3i& pos);
void AddBridge(int itemNumber, int x = 0, int z = 0);
void RemoveBridge(int itemNumber, int x = 0, int z = 0);
From 41508a221770bfdc95250dc53255c3443c97a146 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sun, 4 Feb 2024 01:06:48 +1100
Subject: [PATCH 056/410] Revert "WIP Floordata 1"
This reverts commit dbeccb885e89db1bd5b96fda762c608b1477c9cb.
---
TombEngine/Game/collision/floordata.cpp | 270 +++++++++++++++---------
TombEngine/Game/collision/floordata.h | 10 +-
2 files changed, 185 insertions(+), 95 deletions(-)
diff --git a/TombEngine/Game/collision/floordata.cpp b/TombEngine/Game/collision/floordata.cpp
index 307148850..0303e233c 100644
--- a/TombEngine/Game/collision/floordata.cpp
+++ b/TombEngine/Game/collision/floordata.cpp
@@ -461,7 +461,6 @@ namespace TEN::Collision::Floordata
return sectorPtrs;
}
- // GetSector
FloorInfo& GetFloor(int roomNumber, const Vector2i& roomGridCoord)
{
auto& room = g_Level.Rooms[roomNumber];
@@ -470,14 +469,13 @@ namespace TEN::Collision::Floordata
return room.floor[sectorID];
}
- // GetSector
FloorInfo& GetFloor(int roomNumber, int x, int z)
{
auto roomGridCoord = GetRoomGridCoord(roomNumber, x, z);
return GetFloor(roomNumber, roomGridCoord);
}
- static FloorInfo& GetSideSector(int roomNumber, int x, int z, int* sideRoomNumberPtr = nullptr)
+ FloorInfo& GetFloorSide(int roomNumber, int x, int z, int* sideRoomNumberPtr)
{
auto* sectorPtr = &GetFloor(roomNumber, x, z);
@@ -496,74 +494,126 @@ namespace TEN::Collision::Floordata
return *sectorPtr;
}
- static FloorInfo& GetFarthestSector(int roomNumber, int x, int z, bool isBottom, int* farthestRoomNumberPtr = nullptr)
+ FloorInfo& GetBottomFloor(int roomNumber, int x, int z, int* bottomRoomNumberPtr)
{
- auto* sectorPtr = &GetSideSector(roomNumber, x, z, farthestRoomNumberPtr);
+ auto* sectorPtr = &GetFloorSide(roomNumber, x, z, bottomRoomNumberPtr);
- // Find bottom or top sector.
+ // Find bottom sector.
bool isWall = sectorPtr->IsWall(x, z);
while (isWall)
{
- auto nextRoomNumber = isBottom ? sectorPtr->GetRoomNumberBelow(x, z) : sectorPtr->GetRoomNumberAbove(x, z);
- if (!nextRoomNumber.has_value())
+ auto roomNumberBelow = sectorPtr->GetRoomNumberBelow(x, z);
+ if (!roomNumberBelow.has_value())
break;
// TODO: Check.
- sectorPtr = &GetSideSector(*nextRoomNumber, x, z, farthestRoomNumberPtr);
+ sectorPtr = &GetFloorSide(*roomNumberBelow, x, z, bottomRoomNumberPtr);
isWall = sectorPtr->IsWall(x, z);
}
return *sectorPtr;
}
- static std::optional GetFarthestHeight(FloorInfo& startSector, Vector3i pos, bool isBottom,
- int* farthestRoomNumberPtr = nullptr, FloorInfo** farthestSectorPtr = nullptr)
+ FloorInfo& GetTopFloor(int roomNumber, int x, int z, int* topRoomNumberPtr)
{
- int roomNumber = (farthestRoomNumberPtr != nullptr) ? *farthestRoomNumberPtr : 0;
+ auto* sectorPtr = &GetFloorSide(roomNumber, x, z, topRoomNumberPtr);
+
+ // Find top sector.
+ bool isWall = sectorPtr->IsWall(x, z);
+ while (isWall)
+ {
+ auto roomNumberAbove = sectorPtr->GetRoomNumberAbove(x, z);
+ if (!roomNumberAbove)
+ break;
- // Find bottom or top height.
+ // TODO: Check.
+ sectorPtr = &GetFloorSide(*roomNumberAbove, x, z, topRoomNumberPtr);
+ isWall = sectorPtr->IsWall(x, z);
+ }
+
+ return *sectorPtr;
+ }
+
+ std::optional GetBottomHeight(FloorInfo& startSector, Vector3i pos, int* bottomRoomNumberPtr, FloorInfo** bottomSectorPtr)
+ {
+ int roomNumber = (bottomRoomNumberPtr != nullptr) ? *bottomRoomNumberPtr : 0;
+
+ // Find bottom height.
auto* sectorPtr = &startSector;
do
{
- // Set vertical position to lowest bridge ceiling height or highest bridge floor height.
- pos.y = sectorPtr->GetBridgeSurfaceHeight(pos, !isBottom);
+ // Set vertical position to lowest bridge ceiling height.
+ pos.y = sectorPtr->GetBridgeSurfaceHeight(pos, false);
- // Find sector at lowest bridge floor height or highest bridge ceiling height.
- while (isBottom ?
- (pos.y >= sectorPtr->GetSurfaceHeight(pos.x, pos.z, true)) :
- (pos.y <= sectorPtr->GetSurfaceHeight(pos.x, pos.z, false)))
+ // Find sector at lowest bridge floor height.
+ while (pos.y >= sectorPtr->GetSurfaceHeight(pos.x, pos.z, true))
{
- auto nextRoomNumber = isBottom ? sectorPtr->GetRoomNumberBelow(pos.x, pos.z) : sectorPtr->GetRoomNumberAbove(pos.x, pos.z);;
- if (!nextRoomNumber.has_value())
+ auto roomNumberBelow = sectorPtr->GetRoomNumberBelow(pos.x, pos.z);
+ if (!roomNumberBelow.has_value())
return std::nullopt;
- sectorPtr = &GetSideSector(*nextRoomNumber, pos.x, pos.z, &roomNumber);
+ sectorPtr = &GetFloorSide(*roomNumberBelow, pos.x, pos.z, &roomNumber);
}
}
// Continue running while bridge exists(?).
- while (sectorPtr->GetInsideBridgeItemNumber(pos, isBottom, !isBottom) != NO_ITEM);
+ while (sectorPtr->GetInsideBridgeItemNumber(pos, true, false) != NO_ITEM);
- // Set output bottom or top room number.
- if (farthestRoomNumberPtr != nullptr)
- *farthestRoomNumberPtr = roomNumber;
+ // Set output bottom room number.
+ if (bottomRoomNumberPtr != nullptr)
+ *bottomRoomNumberPtr = roomNumber;
- // Set output bottom or top sector pointer.
- if (farthestSectorPtr != nullptr)
- *farthestSectorPtr = sectorPtr;
+ // Set output bottom sector pointer.
+ if (bottomSectorPtr != nullptr)
+ *bottomSectorPtr = sectorPtr;
+
+ return pos.y;
+ }
+
+ std::optional GetTopHeight(FloorInfo& startSector, Vector3i pos, int* topRoomNumberPtr, FloorInfo** topSectorPtr)
+ {
+ int roomNumber = (topRoomNumberPtr != nullptr) ? *topRoomNumberPtr : 0;
+
+ // Find top height.
+ auto* sectorPtr = &startSector;
+ do
+ {
+ // Set vertical position to highest bridge floor height.
+ pos.y = sectorPtr->GetBridgeSurfaceHeight(pos, true);
+
+ // Find sector at highest bridge ceiling height.
+ while (pos.y <= sectorPtr->GetSurfaceHeight(pos.x, pos.z, false))
+ {
+ auto roomNumberAbove = sectorPtr->GetRoomNumberAbove(pos.x, pos.z);
+ if (!roomNumberAbove.has_value())
+ return std::nullopt;
+
+ sectorPtr = &GetFloorSide(*roomNumberAbove, pos.x, pos.z, &roomNumber);
+ }
+ }
+ // Continue running while bridge exists(?).
+ while (sectorPtr->GetInsideBridgeItemNumber(pos, false, true) >= 0);
+
+ // Set output top room number.
+ if (topRoomNumberPtr != nullptr)
+ *topRoomNumberPtr = roomNumber;
+
+ // Set output top sector pointer.
+ if (topSectorPtr != nullptr)
+ *topSectorPtr = sectorPtr;
return pos.y;
}
std::optional GetSurfaceHeight(const RoomVector& location, int x, int z, bool isFloor)
{
- auto* sectorPtr = &GetSideSector(location.RoomNumber, x, z);
+ auto* sectorPtr = &GetFloorSide(location.RoomNumber, x, z);
auto pos = Vector3i(x, location.Height, z);
int polarity = 0;
if (sectorPtr->IsWall(x, z))
{
- sectorPtr = &GetFarthestSector(location.RoomNumber, x, z, isFloor);
+ sectorPtr = isFloor ? &GetTopFloor(location.RoomNumber, x, z) : &GetBottomFloor(location.RoomNumber, x, z);
if (!sectorPtr->IsWall(x, z))
{
@@ -572,7 +622,7 @@ namespace TEN::Collision::Floordata
}
else
{
- sectorPtr = &GetFarthestSector(location.RoomNumber, x, z, isFloor);
+ sectorPtr = isFloor ? &GetBottomFloor(location.RoomNumber, x, z) : &GetTopFloor(location.RoomNumber, x, z);
if (!sectorPtr->IsWall(x, z))
{
@@ -597,16 +647,19 @@ namespace TEN::Collision::Floordata
if (insideBridgeItemNumber != NO_ITEM)
{
- if (isFloor ? (polarity <= 0) : (polarity >= 0))
+ if (isFloor ? (polarity <= 0) : (polarity >= 0))
{
- auto heightBound = GetFarthestHeight(*sectorPtr, pos, !isFloor);
+ auto heightBound = isFloor ? GetTopHeight(*sectorPtr, pos) : GetBottomHeight(*sectorPtr, pos);
if (heightBound.has_value())
return heightBound;
}
if (isFloor ? (polarity >= 0) : (polarity <= 0))
{
- auto heightBound = GetFarthestHeight(*sectorPtr, pos, isFloor, nullptr, §orPtr);
+ auto heightBound = isFloor ?
+ GetBottomHeight(*sectorPtr, pos, nullptr, §orPtr) :
+ GetTopHeight(*sectorPtr, pos, nullptr, §orPtr);
+
if (!heightBound.has_value())
return std::nullopt;
@@ -619,7 +672,7 @@ namespace TEN::Collision::Floordata
auto nextRoomNumber = isFloor ? sectorPtr->GetRoomNumberBelow(pos) : sectorPtr->GetRoomNumberAbove(pos);
while (nextRoomNumber.has_value())
{
- sectorPtr = &GetSideSector(*nextRoomNumber, x, z);
+ sectorPtr = &GetFloorSide(*nextRoomNumber, x, z);
nextRoomNumber = isFloor ? sectorPtr->GetRoomNumberBelow(pos) : sectorPtr->GetRoomNumberAbove(pos);
}
}
@@ -627,17 +680,18 @@ namespace TEN::Collision::Floordata
return sectorPtr->GetSurfaceHeight(pos, isFloor);
}
- static std::optional GetFarthestRoom(RoomVector location, const Vector3i& pos, bool isBottom)
+ std::optional GetBottomRoom(RoomVector location, const Vector3i& pos)
{
- auto* sectorPtr = &GetSideSector(location.RoomNumber, pos.x, pos.z, &location.RoomNumber);
+ auto* sectorPtr = &GetFloorSide(location.RoomNumber, pos.x, pos.z, &location.RoomNumber);
if (sectorPtr->IsWall(pos.x, pos.z))
{
- sectorPtr = &GetFarthestSector(location.RoomNumber, pos.x, pos.z, isBottom, &location.RoomNumber);
+ sectorPtr = &GetBottomFloor(location.RoomNumber, pos.x, pos.z, &location.RoomNumber);
+
if (sectorPtr->IsWall(pos.x, pos.z))
return std::nullopt;
- location.Height = sectorPtr->GetSurfaceHeight(pos.x, pos.z, !isBottom);
+ location.Height = sectorPtr->GetSurfaceHeight(pos.x, pos.z, false);
}
int floorHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), true);
@@ -651,15 +705,30 @@ namespace TEN::Collision::Floordata
if (insideBridgeItemNumber != NO_ITEM)
{
- auto farthestHeight = GetFarthestHeight(*sectorPtr, Vector3i(pos.x, location.Height, pos.z), isBottom, &location.RoomNumber, §orPtr);
- if (!farthestHeight.has_value())
+ auto bottomHeight = GetBottomHeight(*sectorPtr, Vector3i(pos.x, location.Height, pos.z), &location.RoomNumber, §orPtr);
+ if (!bottomHeight.has_value())
return std::nullopt;
- location.Height = *farthestHeight;
+ location.Height = *bottomHeight;
}
- if (isBottom)
+ ceilingHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), false);
+ if (pos.y < ceilingHeight && sectorPtr->GetRoomNumberAbove(Vector3i(pos.x, location.Height, pos.z)))
+ return std::nullopt;
+
+ floorHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), true);
+ if (pos.y <= floorHeight)
{
+ location.Height = std::max(pos.y, ceilingHeight);
+ return location;
+ }
+
+ auto roomNumberBelow = sectorPtr->GetRoomNumberBelow(Vector3i(pos.x, location.Height, pos.z));
+ while (roomNumberBelow.has_value())
+ {
+ sectorPtr = &GetFloorSide(*roomNumberBelow, pos.x, pos.z, &location.RoomNumber);
+ location.Height = sectorPtr->GetSurfaceHeight(pos.x, pos.z, false);
+
ceilingHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), false);
if (pos.y < ceilingHeight && sectorPtr->GetRoomNumberAbove(Vector3i(pos.x, location.Height, pos.z)))
return std::nullopt;
@@ -670,9 +739,62 @@ namespace TEN::Collision::Floordata
location.Height = std::max(pos.y, ceilingHeight);
return location;
}
+
+ roomNumberBelow = sectorPtr->GetRoomNumberBelow(Vector3i(pos.x, location.Height, pos.z));
}
- else
+
+ return std::nullopt;
+ }
+
+ std::optional GetTopRoom(RoomVector location, const Vector3i& pos)
+ {
+ auto* sectorPtr = &GetFloorSide(location.RoomNumber, pos.x, pos.z, &location.RoomNumber);
+
+ if (sectorPtr->IsWall(pos.x, pos.z))
{
+ sectorPtr = &GetTopFloor(location.RoomNumber, pos.x, pos.z, &location.RoomNumber);
+
+ if (sectorPtr->IsWall(pos.x, pos.z))
+ return std::nullopt;
+
+ location.Height = sectorPtr->GetSurfaceHeight(pos.x, pos.z, true);
+ }
+
+ int floorHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), true);
+ int ceilingHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), false);
+
+ location.Height = std::clamp(location.Height, std::min(ceilingHeight, floorHeight), std::max(ceilingHeight, floorHeight));
+
+ bool testFloorBorder = (location.Height == ceilingHeight);
+ bool testCeilBorder = (location.Height == floorHeight);
+ int insideBridgeItemNumber = sectorPtr->GetInsideBridgeItemNumber(Vector3i(pos.x, location.Height, pos.z), testFloorBorder, testCeilBorder);
+
+ if (insideBridgeItemNumber != NO_ITEM)
+ {
+ auto topHeight = GetTopHeight(*sectorPtr, Vector3i(pos.x, location.Height, pos.z), &location.RoomNumber, §orPtr);
+ if (!topHeight.has_value())
+ return std::nullopt;
+
+ location.Height = *topHeight;
+ }
+
+ floorHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), true);
+ if (pos.y > floorHeight && sectorPtr->GetRoomNumberBelow(Vector3i(pos.x, location.Height, pos.z)))
+ return std::nullopt;
+
+ ceilingHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), false);
+ if (pos.y >= ceilingHeight)
+ {
+ location.Height = std::min(pos.y, floorHeight);
+ return location;
+ }
+
+ auto roomNumberAbove = sectorPtr->GetRoomNumberAbove(Vector3i(pos.x, location.Height, pos.z));
+ while (roomNumberAbove.has_value())
+ {
+ sectorPtr = &GetFloorSide(*roomNumberAbove, pos.x, pos.z, &location.RoomNumber);
+ location.Height = sectorPtr->GetSurfaceHeight(pos.x, pos.z, true);
+
floorHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), true);
if (pos.y > floorHeight && sectorPtr->GetRoomNumberBelow(Vector3i(pos.x, location.Height, pos.z)))
return std::nullopt;
@@ -683,60 +805,20 @@ namespace TEN::Collision::Floordata
location.Height = std::min(pos.y, floorHeight);
return location;
}
- }
- auto nextRoomNumber = isBottom ?
- sectorPtr->GetRoomNumberBelow(Vector3i(pos.x, location.Height, pos.z)) :
- sectorPtr->GetRoomNumberAbove(Vector3i(pos.x, location.Height, pos.z));
-
- while (nextRoomNumber.has_value())
- {
- sectorPtr = &GetSideSector(*nextRoomNumber, pos.x, pos.z, &location.RoomNumber);
- location.Height = sectorPtr->GetSurfaceHeight(pos.x, pos.z, !isBottom);
-
- if (isBottom)
- {
- ceilingHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), false);
- if (pos.y < ceilingHeight && sectorPtr->GetRoomNumberAbove(Vector3i(pos.x, location.Height, pos.z)))
- return std::nullopt;
-
- floorHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), true);
- if (pos.y <= floorHeight)
- {
- location.Height = std::max(pos.y, ceilingHeight);
- return location;
- }
- }
- else
- {
- floorHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), true);
- if (pos.y > floorHeight && sectorPtr->GetRoomNumberBelow(Vector3i(pos.x, location.Height, pos.z)))
- return std::nullopt;
-
- ceilingHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), false);
- if (pos.y >= ceilingHeight)
- {
- location.Height = std::min(pos.y, floorHeight);
- return location;
- }
- }
-
- nextRoomNumber = isBottom ?
- sectorPtr->GetRoomNumberBelow(Vector3i(pos.x, location.Height, pos.z)) :
- sectorPtr->GetRoomNumberAbove(Vector3i(pos.x, location.Height, pos.z));
+ roomNumberAbove = sectorPtr->GetRoomNumberAbove(Vector3i(pos.x, location.Height, pos.z));
}
return std::nullopt;
}
- // GetRoomVector
RoomVector GetRoom(RoomVector location, const Vector3i& pos)
{
- auto locationBelow = GetFarthestRoom(location, pos, true);
+ auto locationBelow = GetBottomRoom(location, pos);
if (locationBelow.has_value())
return *locationBelow;
- auto locationAbove = GetFarthestRoom(location, pos, false);
+ auto locationAbove = GetTopRoom(location, pos);
if (locationAbove.has_value())
return *locationAbove;
@@ -754,7 +836,7 @@ namespace TEN::Collision::Floordata
x += bridgeItem.Pose.Position.x;
z += bridgeItem.Pose.Position.z;
- auto* sectorPtr = &GetSideSector(bridgeItem.RoomNumber, x, z);
+ auto* sectorPtr = &GetFloorSide(bridgeItem.RoomNumber, x, z);
sectorPtr->AddBridge(itemNumber);
if (bridge.GetFloorBorder != nullptr)
@@ -766,7 +848,7 @@ namespace TEN::Collision::Floordata
if (!roomNumberAbove.has_value())
break;
- sectorPtr = &GetSideSector(*roomNumberAbove, x, z);
+ sectorPtr = &GetFloorSide(*roomNumberAbove, x, z);
sectorPtr->AddBridge(itemNumber);
}
}
@@ -780,7 +862,7 @@ namespace TEN::Collision::Floordata
if (!roomNumberBelow.has_value())
break;
- sectorPtr = &GetSideSector(*roomNumberBelow, x, z);
+ sectorPtr = &GetFloorSide(*roomNumberBelow, x, z);
sectorPtr->AddBridge(itemNumber);
}
}
@@ -797,7 +879,7 @@ namespace TEN::Collision::Floordata
x += bridgeItem.Pose.Position.x;
z += bridgeItem.Pose.Position.z;
- auto* sectorPtr = &GetSideSector(bridgeItem.RoomNumber, x, z);
+ auto* sectorPtr = &GetFloorSide(bridgeItem.RoomNumber, x, z);
sectorPtr->RemoveBridge(itemNumber);
if (bridge.GetFloorBorder != nullptr)
@@ -809,7 +891,7 @@ namespace TEN::Collision::Floordata
if (!roomNumberAbove.has_value())
break;
- sectorPtr = &GetSideSector(*roomNumberAbove, x, z);
+ sectorPtr = &GetFloorSide(*roomNumberAbove, x, z);
sectorPtr->RemoveBridge(itemNumber);
}
}
@@ -823,7 +905,7 @@ namespace TEN::Collision::Floordata
if (!roomNumberBelow.has_value())
break;
- sectorPtr = &GetSideSector(*roomNumberBelow, x, z);
+ sectorPtr = &GetFloorSide(*roomNumberBelow, x, z);
sectorPtr->RemoveBridge(itemNumber);
}
}
diff --git a/TombEngine/Game/collision/floordata.h b/TombEngine/Game/collision/floordata.h
index 33de6fd54..68730cedd 100644
--- a/TombEngine/Game/collision/floordata.h
+++ b/TombEngine/Game/collision/floordata.h
@@ -194,9 +194,17 @@ namespace TEN::Collision::Floordata
FloorInfo& GetFloor(int roomNumber, const Vector2i& roomGridCoord);
FloorInfo& GetFloor(int roomNumber, int x, int z);
+ FloorInfo& GetFloorSide(int roomNumber, int x, int z, int* sideRoomNumber = nullptr);
+ FloorInfo& GetBottomFloor(int roomNumber, int x, int z, int* bottomRoomNumber = nullptr);
+ FloorInfo& GetTopFloor(int roomNumber, int x, int z, int* topRoomNumber = nullptr);
+ std::optional GetBottomHeight(FloorInfo& startSector, Vector3i pos, int* bottomRoomNumberPtr = nullptr, FloorInfo** bottomSectorPtr = nullptr);
+ std::optional GetTopHeight(FloorInfo& startSector, Vector3i pos, int* topRoomNumberPtr = nullptr, FloorInfo** topSectorPtr = nullptr);
std::optional GetSurfaceHeight(const RoomVector& location, int x, int z, bool isFloor);
- RoomVector GetRoom(RoomVector location, const Vector3i& pos);
+
+ std::optional GetBottomRoom(RoomVector location, const Vector3i& pos);
+ std::optional GetTopRoom(RoomVector location, const Vector3i& pos);
+ RoomVector GetRoom(RoomVector location, const Vector3i& pos);
void AddBridge(int itemNumber, int x = 0, int z = 0);
void RemoveBridge(int itemNumber, int x = 0, int z = 0);
From 5a1b1c89bd0bad43ff23c246adbd7bad15969927 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Fri, 23 Feb 2024 18:12:27 +1100
Subject: [PATCH 057/410] Remove GetCollision() overload
---
TombEngine/Game/Lara/lara_climb.cpp | 50 ++---
TombEngine/Game/Lara/lara_flare.cpp | 4 +-
TombEngine/Game/Lara/lara_one_gun.cpp | 10 +-
TombEngine/Game/Lara/lara_overhang.cpp | 155 ++++++++-------
TombEngine/Game/Lara/lara_tests.cpp | 16 +-
TombEngine/Game/collision/PointCollision.cpp | 10 +-
TombEngine/Game/collision/collide_item.cpp | 97 ++++-----
TombEngine/Game/collision/collide_item.h | 5 +-
TombEngine/Game/collision/collide_room.cpp | 188 +++++++++---------
TombEngine/Game/collision/collide_room.h | 20 +-
TombEngine/Game/control/box.cpp | 2 +-
TombEngine/Game/control/trigger.cpp | 6 +-
TombEngine/Game/effects/drip.cpp | 18 +-
TombEngine/Game/effects/effects.cpp | 8 +-
TombEngine/Game/effects/footprint.cpp | 30 +--
TombEngine/Game/effects/hair.cpp | 8 +-
TombEngine/Game/effects/item_fx.cpp | 4 +-
TombEngine/Game/effects/weather.cpp | 24 ++-
TombEngine/Game/items.cpp | 9 +-
TombEngine/Game/missile.cpp | 10 +-
TombEngine/Game/pickup/pickup.cpp | 24 ++-
TombEngine/Game/room.cpp | 10 +-
TombEngine/Objects/Effects/enemy_missile.cpp | 10 +-
.../Objects/Effects/tr5_electricity.cpp | 7 +-
.../Objects/TR1/Entity/tr1_doppelganger.cpp | 5 +-
TombEngine/Objects/TR2/Entity/Dragon.cpp | 8 +-
.../Objects/TR2/Trap/tr2_spinningblade.cpp | 5 +-
TombEngine/Objects/TR2/Vehicles/skidoo.cpp | 10 +-
TombEngine/Objects/TR2/Vehicles/speedboat.cpp | 66 +++---
TombEngine/Objects/TR3/Entity/Shiva.cpp | 4 +-
TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp | 4 +-
TombEngine/Objects/TR3/Entity/tr3_tony.cpp | 20 +-
TombEngine/Objects/TR3/Trap/train.cpp | 14 +-
TombEngine/Objects/TR3/Vehicles/big_gun.cpp | 8 +-
TombEngine/Objects/TR3/Vehicles/kayak.cpp | 12 +-
TombEngine/Objects/TR3/Vehicles/quad_bike.cpp | 25 +--
.../Objects/TR3/Vehicles/rubber_boat.cpp | 46 +++--
TombEngine/Objects/TR3/Vehicles/upv.cpp | 34 ++--
TombEngine/Objects/TR4/Entity/tr4_baboon.cpp | 8 +-
TombEngine/Objects/TR4/Entity/tr4_baddy.cpp | 32 +--
.../Objects/TR4/Entity/tr4_enemy_jeep.cpp | 20 +-
.../Objects/TR4/Entity/tr4_horseman.cpp | 8 +-
TombEngine/Objects/TR4/Entity/tr4_sas.cpp | 4 +-
TombEngine/Objects/TR4/Entity/tr4_setha.cpp | 12 +-
.../Objects/TR4/Entity/tr4_skeleton.cpp | 32 +--
TombEngine/Objects/TR4/Entity/tr4_sphinx.cpp | 13 +-
.../Objects/TR4/Entity/tr4_von_croy.cpp | 28 ++-
TombEngine/Objects/TR4/Object/tr4_senet.cpp | 6 +-
TombEngine/Objects/TR4/Vehicles/jeep.cpp | 12 +-
TombEngine/Objects/TR4/Vehicles/motorbike.cpp | 6 +-
TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp | 50 ++---
TombEngine/Objects/TR5/Entity/tr5_guard.cpp | 6 +-
.../Objects/TR5/Object/tr5_bodypart.cpp | 23 ++-
TombEngine/Objects/TR5/Object/tr5_missile.cpp | 10 +-
.../Objects/TR5/Object/tr5_rollingball.cpp | 65 +++---
TombEngine/Objects/Utils/VehicleHelpers.cpp | 18 +-
56 files changed, 732 insertions(+), 607 deletions(-)
diff --git a/TombEngine/Game/Lara/lara_climb.cpp b/TombEngine/Game/Lara/lara_climb.cpp
index 483ab6b69..f944dde5c 100644
--- a/TombEngine/Game/Lara/lara_climb.cpp
+++ b/TombEngine/Game/Lara/lara_climb.cpp
@@ -3,6 +3,7 @@
#include "Game/animation.h"
#include "Game/camera.h"
+#include "Game/collision/PointCollision.h"
#include "Game/collision/sphere.h"
#include "Game/control/control.h"
#include "Game/items.h"
@@ -14,6 +15,7 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Input;
constexpr auto LADDER_TEST_MARGIN = 8;
@@ -327,8 +329,8 @@ void lara_col_climb_idle(ItemInfo* item, CollisionInfo* coll)
// HACK: Prevent climbing inside sloped ceilings. Breaks overhang even more, but that shouldn't matter since we'll be doing it over. -- Sezz 2022.05.13
int y = item->Pose.Position.y - (coll->Setup.Height + CLICK(0.5f));
- auto probe = GetCollision(item, 0, 0, -(coll->Setup.Height + CLICK(0.5f)));
- if ((probe.Position.Ceiling - y) < 0)
+ auto probe = GetPointCollision(*item, 0, 0, -(coll->Setup.Height + CLICK(0.5f)));
+ if ((probe.GetCeilingHeight() - y) < 0)
{
item->Animation.TargetState = LS_LADDER_UP;
item->Pose.Position.y += yShift;
@@ -416,7 +418,7 @@ void lara_as_climb_stepoff_right(ItemInfo* item, CollisionInfo* coll)
short GetClimbFlags(int x, int y, int z, short roomNumber)
{
- return GetClimbFlags(GetCollision(x, y, z, roomNumber).BottomBlock);
+ return GetClimbFlags(&GetPointCollision(Vector3i(x, y, z), roomNumber).GetBottomSector());
}
short GetClimbFlags(FloorInfo* floor)
@@ -787,13 +789,13 @@ int LaraTestClimb(ItemInfo* item, int xOffset, int yOffset, int zOffset, int xFr
int y = item->Pose.Position.y + yOffset;
int z = item->Pose.Position.z + zOffset;
- auto probeUp = GetCollision(x, y - CLICK(0.5f), z, item->RoomNumber);
- auto probeDown = GetCollision(x, y, z, item->RoomNumber);
+ auto probeUp = GetPointCollision(Vector3i(x, y - CLICK(0.5f), z), item->RoomNumber);
+ auto probeDown = GetPointCollision(Vector3i(x, y, z), item->RoomNumber);
- if (!lara->Control.CanClimbLadder && !TestLaraNearClimbableWall(item, probeDown.BottomBlock))
+ if (!lara->Control.CanClimbLadder && !TestLaraNearClimbableWall(item, &probeDown.GetBottomSector()))
return 0;
- int height = probeUp.Position.Floor;
+ int height = probeUp.GetFloorHeight();
if (height == NO_HEIGHT)
return 0;
@@ -805,7 +807,7 @@ int LaraTestClimb(ItemInfo* item, int xOffset, int yOffset, int zOffset, int xFr
if (height < 0)
*shift = height;
- int ceiling = probeDown.Position.Ceiling - y;
+ int ceiling = probeDown.GetCeilingHeight() - y;
if (ceiling > LADDER_CLIMB_SHIFT)
return 0;
@@ -822,8 +824,8 @@ int LaraTestClimb(ItemInfo* item, int xOffset, int yOffset, int zOffset, int xFr
int dz = zFront + z;
int dx = xFront + x;
- auto probeFront = GetCollision(dx, y, dz, item->RoomNumber);
- height = probeFront.Position.Floor;
+ auto probeFront = GetPointCollision(Vector3i(dx, y, dz), item->RoomNumber);
+ height = probeFront.GetFloorHeight();
if (height != NO_HEIGHT)
height -= y;
@@ -839,9 +841,9 @@ int LaraTestClimb(ItemInfo* item, int xOffset, int yOffset, int zOffset, int xFr
*shift = height;
}
- auto probeTop = GetCollision(x, y + itemHeight, z, item->RoomNumber);
- auto probeTopFront = GetCollision(dx, y + itemHeight, dz, probeTop.RoomNumber);
- ceiling = probeTopFront.Position.Ceiling;
+ auto probeTop = GetPointCollision(Vector3i(x, y + itemHeight, z), item->RoomNumber);
+ auto probeTopFront = GetPointCollision(Vector3i(dx, y + itemHeight, dz), probeTop.GetRoomNumber());
+ ceiling = probeTopFront.GetCeilingHeight();
if (ceiling == NO_HEIGHT)
return 1;
@@ -862,7 +864,7 @@ int LaraTestClimb(ItemInfo* item, int xOffset, int yOffset, int zOffset, int xFr
return 1;
}
- ceiling = probeFront.Position.Ceiling - y;
+ ceiling = probeFront.GetCeilingHeight() - y;
if (ceiling >= CLICK(2))
return 1;
@@ -895,16 +897,16 @@ int LaraTestClimbUpPos(ItemInfo* item, int front, int right, int* shift, int* le
*shift = 0;
// Test center.
- auto pointColl = GetCollision(item);
+ auto pointColl = GetPointCollision(*item);
int vPos = item->Pose.Position.y - CLICK(4);
- if ((pointColl.Position.Ceiling - vPos) > LADDER_CLIMB_SHIFT)
+ if ((pointColl.GetCeilingHeight() - vPos) > LADDER_CLIMB_SHIFT)
return 0;
- pointColl = GetCollision(probePos.x, probePos.y, probePos.z, item->RoomNumber);
- int ceiling = (CLICK(1) - probePos.y) + pointColl.Position.Ceiling;
+ pointColl = GetPointCollision(probePos, item->RoomNumber);
+ int ceiling = (CLICK(1) - probePos.y) + pointColl.GetCeilingHeight();
- pointColl = GetCollision(probePos.x + probeOffset.x, probePos.y, probePos.z + probeOffset.z, pointColl.RoomNumber);
- int height = pointColl.Position.Floor;
+ pointColl = GetPointCollision(Vector3i(probePos.x + probeOffset.x, probePos.y, probePos.z + probeOffset.z), pointColl.GetRoomNumber());
+ int height = pointColl.GetFloorHeight();
if (height == NO_HEIGHT)
{
@@ -933,10 +935,10 @@ int LaraTestClimbUpPos(ItemInfo* item, int front, int right, int* shift, int* le
if (height > 0 && height > *shift)
*shift = height;
- pointColl = GetCollision(probePos.x, probePos.y + CLICK(2), probePos.z, item->RoomNumber);
- pointColl = GetCollision(probePos.x + probeOffset.x, probePos.y + CLICK(2), probePos.z + probeOffset.z, pointColl.RoomNumber);
+ pointColl = GetPointCollision(Vector3i(probePos.x, probePos.y + CLICK(2), probePos.z), item->RoomNumber);
+ pointColl = GetPointCollision(Vector3i(probePos.x + probeOffset.x, probePos.y + CLICK(2), probePos.z + probeOffset.z), pointColl.GetRoomNumber());
- ceiling = pointColl.Position.Ceiling - probePos.y;
+ ceiling = pointColl.GetCeilingHeight() - probePos.y;
if (ceiling <= height)
return 1;
@@ -947,7 +949,7 @@ int LaraTestClimbUpPos(ItemInfo* item, int front, int right, int* shift, int* le
}
else
{
- ceiling = GetCollision(probePos.x + probeOffset.x, probePos.y, probePos.z + probeOffset.z, pointColl.RoomNumber).Position.Ceiling - probePos.y;
+ ceiling = GetPointCollision(Vector3i(probePos.x + probeOffset.x, probePos.y, probePos.z + probeOffset.z), pointColl.GetRoomNumber()).GetCeilingHeight() - probePos.y;
if (ceiling < CLICK(2))
{
if ((height - ceiling) <= LARA_HEIGHT)
diff --git a/TombEngine/Game/Lara/lara_flare.cpp b/TombEngine/Game/Lara/lara_flare.cpp
index eff32b3da..3e8402ec2 100644
--- a/TombEngine/Game/Lara/lara_flare.cpp
+++ b/TombEngine/Game/Lara/lara_flare.cpp
@@ -4,6 +4,7 @@
#include "Game/animation.h"
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/control.h"
#include "Game/effects/effects.h"
#include "Game/effects/chaffFX.h"
@@ -18,6 +19,7 @@
#include "Specific/clock.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Math;
constexpr auto FLARE_LIFE_MAX = 60.0f * FPS;
@@ -323,7 +325,7 @@ void CreateFlare(ItemInfo& laraItem, GAME_OBJECT_ID objectID, bool isThrown)
flareItem.Pose.Position = pos;
- int floorHeight = GetCollision(pos.x, pos.y, pos.z, laraItem.RoomNumber).Position.Floor;
+ int floorHeight = GetPointCollision(pos, laraItem.RoomNumber).GetFloorHeight();
auto hasCollided = GetCollidedObjects(&flareItem, 0, true, CollidedItems, CollidedMeshes, true);
bool hasLanded = false;
diff --git a/TombEngine/Game/Lara/lara_one_gun.cpp b/TombEngine/Game/Lara/lara_one_gun.cpp
index cfea58fe5..b9917a70f 100644
--- a/TombEngine/Game/Lara/lara_one_gun.cpp
+++ b/TombEngine/Game/Lara/lara_one_gun.cpp
@@ -4,6 +4,7 @@
#include "Game/animation.h"
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/box.h"
#include "Game/control/control.h"
#include "Game/control/los.h"
@@ -31,6 +32,7 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Effects::Bubble;
using namespace TEN::Effects::Drip;
using namespace TEN::Effects::Environment;
@@ -600,7 +602,7 @@ bool FireHarpoon(ItemInfo& laraItem, const std::optional& pose)
auto jointPos = GetJointPosition(&laraItem, LM_RHAND, Vector3i(-2, 373, 77));
harpoonItem.RoomNumber = laraItem.RoomNumber;
- int floorHeight = GetCollision(jointPos.x, jointPos.y, jointPos.z, harpoonItem.RoomNumber).Position.Floor;
+ int floorHeight = GetPointCollision(jointPos, harpoonItem.RoomNumber).GetFloorHeight();
if (floorHeight >= jointPos.y)
{
harpoonItem.Pose.Position = jointPos;
@@ -693,7 +695,7 @@ void FireGrenade(ItemInfo& laraItem)
grenadeItem.Pose.Position = jointPos;
auto smokePos = jointPos;
- int floorHeight = GetCollision(jointPos.x, jointPos.y, jointPos.z, grenadeItem.RoomNumber).Position.Floor;
+ int floorHeight = GetPointCollision(jointPos, grenadeItem.RoomNumber).GetFloorHeight();
if (floorHeight < jointPos.y)
{
grenadeItem.Pose.Position.x = laraItem.Pose.Position.x;
@@ -1027,9 +1029,11 @@ void FireCrossbow(ItemInfo& laraItem, const std::optional& pose)
boltItem.RoomNumber = laraItem.RoomNumber;
- int floorHeight = GetCollision(jointPos.x, jointPos.y, jointPos.z, boltItem.RoomNumber).Position.Floor;
+ int floorHeight = GetPointCollision(jointPos, boltItem.RoomNumber).GetFloorHeight();
if (floorHeight >= jointPos.y)
+ {
boltItem.Pose.Position = jointPos;
+ }
else
{
boltItem.Pose.Position = Vector3i(laraItem.Pose.Position.x, jointPos.y, laraItem.Pose.Position.z);
diff --git a/TombEngine/Game/Lara/lara_overhang.cpp b/TombEngine/Game/Lara/lara_overhang.cpp
index 6129d45c1..a558b4035 100644
--- a/TombEngine/Game/Lara/lara_overhang.cpp
+++ b/TombEngine/Game/Lara/lara_overhang.cpp
@@ -17,6 +17,7 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
+using namespace TEN::Collision::Floordata;
using namespace TEN::Collision::PointCollision;
using namespace TEN::Entities::Generic;
using namespace TEN::Input;
@@ -326,14 +327,14 @@ void lara_col_slopeclimb(ItemInfo* item, CollisionInfo* coll)
auto up = Vector3i(item->Pose.Position.x - slopeData.Offset.x, item->Pose.Position.y - CLICK(1), item->Pose.Position.z - slopeData.Offset.z);
auto down = Vector3i(item->Pose.Position.x + slopeData.Offset.x, item->Pose.Position.y + CLICK(1), item->Pose.Position.z + slopeData.Offset.z);
- auto probeNow = GetCollision(now.x, now.y, now.z, item->RoomNumber);
- auto probeUp = GetCollision(up.x, up.y, up.z, item->RoomNumber);
- auto probeDown = GetCollision(down.x, down.y, down.z, item->RoomNumber);
+ auto probeNow = GetPointCollision(now, item->RoomNumber);
+ auto probeUp = GetPointCollision(up, item->RoomNumber);
+ auto probeDown = GetPointCollision(down, item->RoomNumber);
if (item->Animation.AnimNumber == LA_OVERHANG_LADDER_SLOPE_CONCAVE)
return;
- item->Pose.Position.y = probeNow.Position.Ceiling + HEIGHT_ADJUST;
+ item->Pose.Position.y = probeNow.GetCeilingHeight() + HEIGHT_ADJUST;
// Drop down if action not pressed.
if (!IsHeld(In::Action))
@@ -353,13 +354,13 @@ void lara_col_slopeclimb(ItemInfo* item, CollisionInfo* coll)
if (IsHeld(In::Forward))
{
// Test for ledge over slope.
- short tempRoom = probeUp.Block->GetNextRoomNumber(up.x, up.z, false).value_or(NO_ROOM);
+ short tempRoom = probeUp.GetSector().GetNextRoomNumber(up.x, up.z, false).value_or(NO_ROOM);
if (tempRoom != NO_ROOM)
{
- auto probeLedge = GetCollision(now.x, now.y - CLICK(3), now.z, tempRoom);
+ auto probeLedge = GetPointCollision(Vector3i(now.x, now.y - CLICK(3), now.z), tempRoom);
- if ((probeLedge.Position.Floor - probeLedge.Position.Ceiling) >= CLICK(3) &&
- abs((item->Pose.Position.y - (CLICK(2.5f) + 48)) - probeLedge.Position.Floor) < 64)
+ if ((probeLedge.GetFloorHeight() - probeLedge.GetCeilingHeight()) >= CLICK(3) &&
+ abs((item->Pose.Position.y - (CLICK(2.5f) + 48)) - probeLedge.GetFloorHeight()) < 64)
{
AlignToEdge(item, FORWARD_ALIGNMENT);
SetAnimation(item, LA_OVERHANG_LEDGE_VAULT_START); // Ledge climb-up from slope.
@@ -367,10 +368,10 @@ void lara_col_slopeclimb(ItemInfo* item, CollisionInfo* coll)
}
// Test for slope to overhead ladder transition (convex).
- if (GetClimbFlags(probeUp.BottomBlock) & slopeData.ClimbOrient &&
+ if (GetClimbFlags(&probeUp.GetBottomSector()) & slopeData.ClimbOrient &&
InStrip(item->Pose.Position.x, item->Pose.Position.z, item->Pose.Orientation.y, CLICK(3), CLICK(4)))
{
- //if (GetCollision(probeUp.Block, up.x, up.y, up.z).Position.Ceiling - item->Pose.Position.y <= (BLOCK(1.5f) - 80)) // Check if a wall is actually there.
+ //if (GetCollision(probeUp.Block, up.x, up.y, up.z).GetCeilingHeight() - item->Pose.Position.y <= (BLOCK(1.5f) - 80)) // Check if a wall is actually there.
//{
// AlignToEdge(item, FORWARD_ALIGNMENT);
// SetAnimation(item, LA_OVERHANG_SLOPE_LADDER_CONVEX_START);
@@ -378,21 +379,21 @@ void lara_col_slopeclimb(ItemInfo* item, CollisionInfo* coll)
}
// Test for monkey at next position.
- if (probeUp.BottomBlock->Flags.Monkeyswing)
+ if (probeUp.GetBottomSector().Flags.Monkeyswing)
{
- int yDelta = probeUp.Position.Ceiling - probeNow.Position.Ceiling;
+ int yDelta = probeUp.GetCeilingHeight() - probeNow.GetCeilingHeight();
int height; // Height variable for bridge ceiling functions.
// Test for upwards slope to climb.
short bridge = FindBridge(4, item->Pose.Orientation.y, up, &height, -CLICK(2.5f), -CLICK(1.5f));
- if (yDelta >= -CLICK(1.25f) && yDelta <= -CLICK(0.75f) && (SlopeCheck(probeUp.CeilingTilt, slopeData.Goal) || bridge >= 0))
+ if (yDelta >= -CLICK(1.25f) && yDelta <= -CLICK(0.75f) && (SlopeCheck(GetSurfaceTilt(probeUp.GetCeilingNormal(), false).ToVector2(), slopeData.Goal) || bridge >= 0))
{
// Do one more check for wall/ceiling step 2 * offX / Z further to avoid lara sinking her head in wall/step.
- auto probeWall = GetCollision((up.x - slopeData.Offset.x), (up.y - CLICK(1)), (up.z - slopeData.Offset.z), item->RoomNumber);
+ auto probeWall = GetPointCollision(Vector3i((up.x - slopeData.Offset.x), (up.y - CLICK(1)), (up.z - slopeData.Offset.z)), item->RoomNumber);
- if (!probeWall.Block->IsWall((up.x - slopeData.Offset.x), (up.z - slopeData.Offset.z)) &&
- (probeNow.Position.Ceiling - probeWall.Position.Ceiling) > CLICK(0.5f)) // No wall or downward ceiling step.
+ if (!probeWall.GetSector().IsWall((up.x - slopeData.Offset.x), (up.z - slopeData.Offset.z)) &&
+ (probeNow.GetCeilingHeight() - probeWall.GetCeilingHeight()) > CLICK(0.5f)) // No wall or downward ceiling step.
{
TranslateItem(item, 0, -CLICK(1), -CLICK(1));
SetAnimation(item, item->Animation.AnimNumber == LA_OVERHANG_IDLE_LEFT ? LA_OVERHANG_CLIMB_UP_LEFT : LA_OVERHANG_CLIMB_UP_RIGHT);
@@ -407,7 +408,7 @@ void lara_col_slopeclimb(ItemInfo* item, CollisionInfo* coll)
// HACK: because of the different calculations of bridge height in TR4 and TEN, we need to lower yDiff tolerance to 0.9f.
if (yDelta > -CLICK(0.9f) && yDelta <= -CLICK(0.5f) &&
- ((abs(probeUp.CeilingTilt.x) <= 2 && abs(probeUp.CeilingTilt.y) <= 2) || bridge >= 0))
+ ((abs(GetSurfaceTilt(probeUp.GetCeilingNormal(), false).ToVector2().x) <= 2 && abs(GetSurfaceTilt(probeUp.GetCeilingNormal(), false).ToVector2().y) <= 2) || bridge >= 0))
{
SetAnimation(item, LA_OVERHANG_SLOPE_MONKEY_CONCAVE); // Slope to overhead monkey transition (concave).
}
@@ -423,22 +424,22 @@ void lara_col_slopeclimb(ItemInfo* item, CollisionInfo* coll)
// return;
//}
- if (probeDown.BottomBlock->Flags.Monkeyswing)
+ if (probeDown.GetBottomSector().Flags.Monkeyswing)
{
int height;
- int yDiff = probeDown.Position.Ceiling - probeNow.Position.Ceiling;
+ int yDiff = probeDown.GetCeilingHeight() - probeNow.GetCeilingHeight();
// Test for flat monkey (abs(slope) < 2).
short bridge = FindBridge(0, slopeData.GoalOrient, down, &height, -CLICK(3), -CLICK(2));
if (bridge < 0)
bridge = FindBridge(1, slopeData.GoalOrient, down, &height, -CLICK(3), -CLICK(2));
- if ((abs(yDiff) < CLICK(1) && abs(probeDown.CeilingTilt.x) <= 2 && abs(probeDown.CeilingTilt.y) <= 2) || bridge >= 0)
+ if ((abs(yDiff) < CLICK(1) && abs(GetSurfaceTilt(probeDown.GetCeilingNormal(), false).ToVector2().x) <= 2 && abs(GetSurfaceTilt(probeDown.GetCeilingNormal(), false).ToVector2().y) <= 2) || bridge >= 0)
SetAnimation(item, LA_OVERHANG_SLOPE_MONKEY_CONVEX); // Force slope to underlying monkey transition (convex)
// Test for downward slope to climb.
bridge = FindBridge(4, slopeData.GoalOrient, down, &height, -CLICK(2.5f), -CLICK(1.5f));
- if (yDiff >= CLICK(0.75f) && yDiff <= CLICK(1.25f) && (SlopeCheck(probeDown.CeilingTilt, slopeData.Goal) || bridge >= 0))
+ if (yDiff >= CLICK(0.75f) && yDiff <= CLICK(1.25f) && (SlopeCheck(GetSurfaceTilt(probeDown.GetCeilingNormal(), false).ToVector2(), slopeData.Goal) || bridge >= 0))
{
SetAnimation(item, item->Animation.AnimNumber == LA_OVERHANG_IDLE_LEFT ? LA_OVERHANG_CLIMB_DOWN_LEFT : LA_OVERHANG_CLIMB_DOWN_RIGHT);
return;
@@ -493,9 +494,9 @@ void lara_col_slopehang(ItemInfo* item, CollisionInfo* coll)
auto now = item->Pose.Position;
- auto probeNow = GetCollision(now.x, now.y, now.z, item->RoomNumber);
+ auto probeNow = GetPointCollision(now, item->RoomNumber);
- item->Pose.Position.y = probeNow.Position.Ceiling + HEIGHT_ADJUST;
+ item->Pose.Position.y = probeNow.GetCeilingHeight() + HEIGHT_ADJUST;
// Drop down if action not pressed.
if (!IsHeld(In::Action))
@@ -530,16 +531,16 @@ void lara_col_slopehang(ItemInfo* item, CollisionInfo* coll)
direction = ANGLE(90.0f);
}
- auto probeShimmy = GetCollision(shimmy.x, shimmy.y, shimmy.z, item->RoomNumber);
+ auto probeShimmy = GetPointCollision(shimmy, item->RoomNumber);
- if (probeShimmy.BottomBlock->Flags.Monkeyswing)
+ if (probeShimmy.GetBottomSector().Flags.Monkeyswing)
{
- int yDiff = probeShimmy.Position.Ceiling - probeNow.Position.Ceiling;
+ int yDiff = probeShimmy.GetCeilingHeight() - probeNow.GetCeilingHeight();
int height;
short bridge = FindBridge(4, slopeData.GoalOrient, shimmy, &height, -CLICK(2.5f), -CLICK(1.5f));
- if ((SlopeCheck(probeShimmy.CeilingTilt, slopeData.Goal) && abs(yDiff) < 64) || bridge >= 0)
+ if ((SlopeCheck(GetSurfaceTilt(probeShimmy.GetCeilingNormal(), false).ToVector2(), slopeData.Goal) && abs(yDiff) < 64) || bridge >= 0)
SetAnimation(item, direction < 0 ? LA_OVERHANG_SHIMMY_LEFT : LA_OVERHANG_SHIMMY_RIGHT);
}
}
@@ -569,9 +570,9 @@ void lara_col_slopeshimmy(ItemInfo* item, CollisionInfo* coll)
auto now = item->Pose.Position;
- auto probeNow = GetCollision(now.x, now.y, now.z, item->RoomNumber);
+ auto probeNow = GetPointCollision(now, item->RoomNumber);
- item->Pose.Position.y = probeNow.Position.Ceiling + HEIGHT_ADJUST;
+ item->Pose.Position.y = probeNow.GetCeilingHeight() + HEIGHT_ADJUST;
auto shimmy = item->Pose.Position;
if (item->Animation.AnimNumber == LA_OVERHANG_SHIMMY_LEFT)
@@ -585,17 +586,17 @@ void lara_col_slopeshimmy(ItemInfo* item, CollisionInfo* coll)
shimmy.z -= slopeData.Offset.x / 2;
}
- auto probeShimmy = GetCollision(shimmy.x, shimmy.y, shimmy.z, item->RoomNumber);
+ auto probeShimmy = GetPointCollision(shimmy, item->RoomNumber);
bool cancelShimmy = true;
- if (probeShimmy.BottomBlock->Flags.Monkeyswing)
+ if (probeShimmy.GetBottomSector().Flags.Monkeyswing)
{
- int yDiff = probeShimmy.Position.Ceiling - probeNow.Position.Ceiling;
+ int yDiff = probeShimmy.GetCeilingHeight() - probeNow.GetCeilingHeight();
int height;
short bridge = FindBridge(4, slopeData.GoalOrient, shimmy, &height, -CLICK(2.5f), -CLICK(1.5f));
- if ((SlopeCheck(probeShimmy.CeilingTilt, slopeData.Goal) && abs(yDiff) < 64) || bridge >= 0)
+ if ((SlopeCheck(GetSurfaceTilt(probeShimmy.GetCeilingNormal(), false).ToVector2(), slopeData.Goal) && abs(yDiff) < 64) || bridge >= 0)
cancelShimmy = false;
}
@@ -838,16 +839,16 @@ void SlopeHangExtra(ItemInfo* item, CollisionInfo* coll)
auto down = Vector3i(item->Pose.Position.x + slopeData.Offset.x, item->Pose.Position.y + CLICK(1), item->Pose.Position.z + slopeData.Offset.z);
- auto probeDown = GetCollision(down.x, down.y, down.z, item->RoomNumber);
+ auto probeDown = GetPointCollision(down, item->RoomNumber);
- int ceilDist = item->Pose.Position.y - probeDown.Position.Ceiling;
+ int ceilDist = item->Pose.Position.y - probeDown.GetCeilingHeight();
if (item->Animation.TargetState == LS_LADDER_IDLE) // Prevent going from hang to climb mode if slope is under ladder.
{
if (ceilDist >= CLICK(1) && ceilDist < CLICK(2))
{
- if ((probeDown.CeilingTilt.x / 3) == (slopeData.Goal.x / 3) ||
- (probeDown.CeilingTilt.y / 3) == (slopeData.Goal.y / 3))
+ if ((GetSurfaceTilt(probeDown.GetCeilingNormal(), false).ToVector2().x / 3) == (slopeData.Goal.x / 3) ||
+ (GetSurfaceTilt(probeDown.GetCeilingNormal(), false).ToVector2().y / 3) == (slopeData.Goal.y / 3))
{
item->Animation.TargetState = LS_HANG;
if (IsHeld(In::Forward))
@@ -863,8 +864,8 @@ void SlopeHangExtra(ItemInfo* item, CollisionInfo* coll)
{
if (ceilDist < CLICK(1))
{
- if ((probeDown.CeilingTilt.x / 3) == (goal.x / 3) ||
- (probeDown.CeilingTilt.z / 3) == (goal.y / 3))
+ if ((GetSurfaceTilt(probeDown.GetCeilingNormal(), false).ToVector2().x / 3) == (goal.x / 3) ||
+ (GetSurfaceTilt(probeDown.GetCeilingNormal(), false).ToVector2().z / 3) == (goal.y / 3))
{
SetAnimation(item, LA_REACH_TO_HANG, 21);
}
@@ -883,19 +884,19 @@ void SlopeReachExtra(ItemInfo* item, CollisionInfo* coll)
auto now = item->Pose.Position;
- auto probeNow = GetCollision(now.x, now.y, now.z, item->RoomNumber);
+ auto probeNow = GetPointCollision(now, item->RoomNumber);
- int ceilDist = item->Pose.Position.y - probeNow.Position.Ceiling;
+ int ceilDist = item->Pose.Position.y - probeNow.GetCeilingHeight();
- if (probeNow.BottomBlock->Flags.Monkeyswing && ceilDist <= CLICK(3.5f))
+ if (probeNow.GetBottomSector().Flags.Monkeyswing && ceilDist <= CLICK(3.5f))
{
int height;
short bridge = FindBridge(4, slopeData.GoalOrient, now, &height, -CLICK(4), -CLICK(2.5f));
- if (abs(probeNow.CeilingTilt.x) > 2 || abs(probeNow.CeilingTilt.y) > 2 || bridge >= 0)
+ if (abs(GetSurfaceTilt(probeNow.GetCeilingNormal(), false).ToVector2().x) > 2 || abs(GetSurfaceTilt(probeNow.GetCeilingNormal(), false).ToVector2().y) > 2 || bridge >= 0)
{
bool disableGrab = true;
- if (SlopeCheck(probeNow.CeilingTilt, slopeData.Goal) || bridge >= 0)
+ if (SlopeCheck(GetSurfaceTilt(probeNow.GetCeilingNormal(), false).ToVector2(), slopeData.Goal) || bridge >= 0)
{
if (abs(OrientDelta(item->Pose.Orientation.y, slopeData.GoalOrient)) < ANGLE(33.75f))
disableGrab = false;
@@ -918,17 +919,17 @@ void SlopeClimbExtra(ItemInfo* item, CollisionInfo* coll)
auto now = item->Pose.Position;
auto down = Vector3i(item->Pose.Position.x + slopeData.Offset.x, item->Pose.Position.y + CLICK(1), item->Pose.Position.z + slopeData.Offset.z);
- auto probeNow = GetCollision(now.x, now.y, now.z, item->RoomNumber);
- auto probeDown = GetCollision(down.x, down.y, down.z, item->RoomNumber);
+ auto probeNow = GetPointCollision(now, item->RoomNumber);
+ auto probeDown = GetPointCollision(down, item->RoomNumber);
// Block for ladder to overhead slope transition.
if (item->Animation.AnimNumber == LA_LADDER_IDLE)
{
if (IsHeld(In::Forward))
{
- int ceilDist = probeNow.Position.Ceiling - item->Pose.Position.y;
+ int ceilDist = probeNow.GetCeilingHeight() - item->Pose.Position.y;
- if (probeNow.BottomBlock->Flags.Monkeyswing && ceilDist >= -CLICK(4) && ceilDist <= -CLICK(3))
+ if (probeNow.GetBottomSector().Flags.Monkeyswing && ceilDist >= -CLICK(4) && ceilDist <= -CLICK(3))
{
short facing = item->Pose.Orientation.y + ANGLE(45.0f);
facing &= ANGLE(270.0f);
@@ -936,9 +937,9 @@ void SlopeClimbExtra(ItemInfo* item, CollisionInfo* coll)
int height;
short bridge = FindBridge(4, facing, now, &height, -CLICK(4), -CLICK(3));
- if (SlopeCheck(probeNow.CeilingTilt, slopeData.Goal) || bridge >= 0)
+ if (SlopeCheck(GetSurfaceTilt(probeNow.GetCeilingNormal(), false).ToVector2(), slopeData.Goal) || bridge >= 0)
{
- item->Pose.Position.y = probeNow.Position.Ceiling + 900;
+ item->Pose.Position.y = probeNow.GetCeilingHeight() + 900;
SetAnimation(item, LA_OVERHANG_LADDER_SLOPE_CONCAVE); // Ladder to overhead slope transition (concave).
}
}
@@ -946,9 +947,9 @@ void SlopeClimbExtra(ItemInfo* item, CollisionInfo* coll)
if (IsHeld(In::Back))
{
- int ceilDist = probeDown.Position.Ceiling - item->Pose.Position.y;
+ int ceilDist = probeDown.GetCeilingHeight() - item->Pose.Position.y;
- if (probeDown.BottomBlock->Flags.Monkeyswing && ceilDist >= 0 && ceilDist <= CLICK(1))
+ if (probeDown.GetBottomSector().Flags.Monkeyswing && ceilDist >= 0 && ceilDist <= CLICK(1))
{
short facing = item->Pose.Orientation.y + ANGLE(45.0f);
facing &= ANGLE(270.0f);
@@ -956,9 +957,9 @@ void SlopeClimbExtra(ItemInfo* item, CollisionInfo* coll)
int height;
short bridge = FindBridge(4, facing, down, &height, -CLICK(0.5f), -CLICK(0.25f));
- if (SlopeCheck(probeDown.CeilingTilt, slopeData.Goal) || bridge >= 0)
+ if (SlopeCheck(GetSurfaceTilt(probeDown.GetCeilingNormal(), false).ToVector2(), slopeData.Goal) || bridge >= 0)
{
- item->Pose.Position.y = probeDown.Position.Ceiling - 156;
+ item->Pose.Position.y = probeDown.GetCeilingHeight() - 156;
SetAnimation(item, LA_OVERHANG_LADDER_SLOPE_CONVEX); // Ladder to underlying slope transition (convex).
}
}
@@ -993,15 +994,15 @@ void SlopeClimbDownExtra(ItemInfo* item, CollisionInfo* coll)
auto down = Vector3i(item->Pose.Position.x + slopeData.Offset.x, item->Pose.Position.y + CLICK(1), item->Pose.Position.z + slopeData.Offset.z);
- auto probeDown = GetCollision(down.x, down.y, down.z, item->RoomNumber);
+ auto probeDown = GetPointCollision(down, item->RoomNumber);
if (item->Animation.AnimNumber == LA_LADDER_DOWN) // Make Lara stop before underlying slope ceiling at correct height.
{
if (IsHeld(In::Back))
{
- int ceilDist = probeDown.Position.Ceiling - item->Pose.Position.y;
+ int ceilDist = probeDown.GetCeilingHeight() - item->Pose.Position.y;
- if (probeDown.BottomBlock->Flags.Monkeyswing && ceilDist >= 0 && ceilDist <= CLICK(1))
+ if (probeDown.GetBottomSector().Flags.Monkeyswing && ceilDist >= 0 && ceilDist <= CLICK(1))
{
short facing = item->Pose.Orientation.y + ANGLE(45.0f);
facing &= ANGLE(270.0f);
@@ -1009,9 +1010,9 @@ void SlopeClimbDownExtra(ItemInfo* item, CollisionInfo* coll)
int height;
short bridge = FindBridge(4, facing, down, &height, -CLICK(0.5f), -CLICK(0.25f));
- if (SlopeCheck(probeDown.CeilingTilt, slopeData.Goal) || bridge >= 0)
+ if (SlopeCheck(GetSurfaceTilt(probeDown.GetCeilingNormal(), false).ToVector2(), slopeData.Goal) || bridge >= 0)
{
- item->Pose.Position.y = probeDown.Position.Ceiling - 156;
+ item->Pose.Position.y = probeDown.GetCeilingHeight() - 156;
item->Animation.TargetState = LS_LADDER_IDLE;
}
}
@@ -1056,14 +1057,14 @@ void SlopeMonkeyExtra(ItemInfo* item, CollisionInfo* coll)
auto now = item->Pose.Position;
auto down = Vector3i(item->Pose.Position.x + slopeData.Offset.x, item->Pose.Position.y + CLICK(1), item->Pose.Position.z + slopeData.Offset.z);
- auto probeNow = GetCollision(now.x, now.y, now.z, item->RoomNumber);
- auto probeDown = GetCollision(down.x, down.y, down.z, item->RoomNumber);
+ auto probeNow = GetPointCollision(now, item->RoomNumber);
+ auto probeDown = GetPointCollision(down, item->RoomNumber);
if (item->Animation.AnimNumber == LA_REACH_TO_MONKEY && !GetFrameIndex(item, 0)) // Manage proper grabbing of monkey slope on forward jump.
{
- int ceilDist = item->Pose.Position.y - probeNow.Position.Ceiling;
+ int ceilDist = item->Pose.Position.y - probeNow.GetCeilingHeight();
- if (probeNow.BottomBlock->Flags.Monkeyswing && ceilDist <= CLICK(3.5f))
+ if (probeNow.GetBottomSector().Flags.Monkeyswing && ceilDist <= CLICK(3.5f))
{
short facing = item->Pose.Orientation.y + ANGLE(45.0f);
facing &= 0xC000;
@@ -1071,11 +1072,11 @@ void SlopeMonkeyExtra(ItemInfo* item, CollisionInfo* coll)
int height;
short bridge = FindBridge(4, facing, now, &height, -CLICK(3.5f), -CLICK(2.5f));
- if (SlopeCheck(probeNow.CeilingTilt, slopeData.Goal) || bridge >= 0)
+ if (SlopeCheck(GetSurfaceTilt(probeNow.GetCeilingNormal(), false).ToVector2(), slopeData.Goal) || bridge >= 0)
{
lara->Context.NextCornerPos.Orientation.z = AlignToGrab(item);
- /*int ceiling = GetCollision(probeNow.Block, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z).Position.Ceiling;
+ /*int ceiling = GetCollision(probeNow.Block, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z).GetCeilingHeight();
item->Pose.Position.y = ceiling + HEIGHT_ADJUST;*/
SetAnimation(item, LA_OVERHANG_HANG_SWING);
@@ -1085,7 +1086,7 @@ void SlopeMonkeyExtra(ItemInfo* item, CollisionInfo* coll)
if (IsHeld(In::Forward)) // Monkey to slope transitions.
{
- if (probeNow.BottomBlock->Flags.Monkeyswing &&
+ if (probeNow.GetBottomSector().Flags.Monkeyswing &&
((item->Animation.AnimNumber == LA_REACH_TO_MONKEY && GetFrameIndex(item, 0) >= 54) || item->Animation.AnimNumber == LA_MONKEY_IDLE))
{
if (abs(OrientDelta(slopeData.GoalOrient, item->Pose.Orientation.y)) <= ANGLE(30.0f) &&
@@ -1093,8 +1094,8 @@ void SlopeMonkeyExtra(ItemInfo* item, CollisionInfo* coll)
{
/*if (probeDown.BottomBlock->Flags.Monkeyswing)
{
- int ceiling = GetCollision(probeDown.Block, down.x, now.y, down.z).Position.Ceiling;
- int yDiff = ceiling - probeNow.Position.Ceiling;
+ int ceiling = GetCollision(probeDown.Block, down.x, now.y, down.z).GetCeilingHeight();
+ int yDiff = ceiling - probeNow.GetCeilingHeight();
int height;
short bridge = FindBridge(4, slopeData.GoalOrient, down, &height, -CLICK(7) >> 1, -CLICK(5) >> 1);
@@ -1124,19 +1125,19 @@ void SlopeMonkeyExtra(ItemInfo* item, CollisionInfo* coll)
// Additional overhang ladder tests.
int y = item->Pose.Position.y - coll->Setup.Height;
- auto probe = GetCollision(down.x, item->Pose.Position.y - coll->Setup.Height, down.z, item->RoomNumber);
+ auto probe = GetPointCollision(Vector3i(down.x, item->Pose.Position.y - coll->Setup.Height, down.z), item->RoomNumber);
- if (probe.BottomBlock->Flags.IsWallClimbable(GetClimbDirectionFlags(item->Pose.Orientation.y + ANGLE(180.0f))) &&
- probe.Position.Floor >= (item->Pose.Position.y - CLICK(1)) &&
- probe.Position.Ceiling <= (y - CLICK(1)))
+ if (probe.GetBottomSector().Flags.IsWallClimbable(GetClimbDirectionFlags(item->Pose.Orientation.y + ANGLE(180.0f))) &&
+ probe.GetFloorHeight() >= (item->Pose.Position.y - CLICK(1)) &&
+ probe.GetCeilingHeight() <= (y - CLICK(1)))
{
// Primary checks succeeded, now do C-shaped secondary probing.
- probe = GetCollision(down.x, y, down.z, probe.RoomNumber);
- probe = GetCollision(down.x, y - CLICK(2), down.z, probe.RoomNumber);
- probe = GetCollision(now.x, y - CLICK(2), now.z, probe.RoomNumber);
+ probe = GetPointCollision(Vector3i(down.x, y, down.z), probe.GetRoomNumber());
+ probe = GetPointCollision(Vector3i(down.x, y - CLICK(2), down.z), probe.GetRoomNumber());
+ probe = GetPointCollision(Vector3i(now.x, y - CLICK(2), now.z), probe.GetRoomNumber());
- if (probe.Position.Floor <= (y - CLICK(1)) ||
- probe.Position.Ceiling >= (y - CLICK(1)))
+ if (probe.GetFloorHeight() <= (y - CLICK(1)) ||
+ probe.GetCeilingHeight() >= (y - CLICK(1)))
{
if (item->Animation.TargetState != LS_LADDER_IDLE)
{
diff --git a/TombEngine/Game/Lara/lara_tests.cpp b/TombEngine/Game/Lara/lara_tests.cpp
index a1328e0d2..ce6a61776 100644
--- a/TombEngine/Game/Lara/lara_tests.cpp
+++ b/TombEngine/Game/Lara/lara_tests.cpp
@@ -5,6 +5,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/control.h"
#include "Game/control/los.h"
#include "Game/items.h"
@@ -22,6 +23,7 @@
#include "Specific/trutils.h"
using namespace TEN::Collision::Floordata;
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Entities::Player;
using namespace TEN::Input;
using namespace TEN::Math;
@@ -46,14 +48,14 @@ bool TestValidLedge(ItemInfo* item, CollisionInfo* coll, bool ignoreHeadroom, bo
int y = item->Pose.Position.y - coll->Setup.Height;
// Get frontal collision data
- auto frontLeft = GetCollision(item->Pose.Position.x + xl, y, item->Pose.Position.z + zl, GetRoomVector(item->Location, Vector3i(item->Pose.Position.x, y, item->Pose.Position.z)).RoomNumber);
- auto frontRight = GetCollision(item->Pose.Position.x + xr, y, item->Pose.Position.z + zr, GetRoomVector(item->Location, Vector3i(item->Pose.Position.x, y, item->Pose.Position.z)).RoomNumber);
+ auto frontLeft = GetPointCollision(Vector3i(item->Pose.Position.x + xl, y, item->Pose.Position.z + zl), GetRoomVector(item->Location, Vector3i(item->Pose.Position.x, y, item->Pose.Position.z)).RoomNumber);
+ auto frontRight = GetPointCollision(Vector3i(item->Pose.Position.x + xr, y, item->Pose.Position.z + zr), GetRoomVector(item->Location, Vector3i(item->Pose.Position.x, y, item->Pose.Position.z)).RoomNumber);
// If any of the frontal collision results intersects item bounds, return false, because there is material intersection.
// This check helps to filter out cases when Lara is formally facing corner but ledge check returns true because probe distance is fixed.
- if (frontLeft.Position.Floor < (item->Pose.Position.y - CLICK(0.5f)) || frontRight.Position.Floor < (item->Pose.Position.y - CLICK(0.5f)))
+ if (frontLeft.GetFloorHeight() < (item->Pose.Position.y - CLICK(0.5f)) || frontRight.GetFloorHeight() < (item->Pose.Position.y - CLICK(0.5f)))
return false;
- if (frontLeft.Position.Ceiling > (item->Pose.Position.y - coll->Setup.Height) || frontRight.Position.Ceiling > (item->Pose.Position.y - coll->Setup.Height))
+ if (frontLeft.GetCeilingHeight() >(item->Pose.Position.y - coll->Setup.Height) || frontRight.GetCeilingHeight() > (item->Pose.Position.y - coll->Setup.Height))
return false;
//g_Renderer.AddDebugSphere(Vector3(item->pos.Position.x + xl, left, item->pos.Position.z + zl), 64, Vector4::One, RendererDebugPage::CollisionStats);
@@ -66,8 +68,8 @@ bool TestValidLedge(ItemInfo* item, CollisionInfo* coll, bool ignoreHeadroom, bo
int zf = phd_cos(coll->NearestLedgeAngle) * (coll->Setup.Radius * 1.2f);
// Get floor heights at both points
- auto left = GetCollision(item->Pose.Position.x + xf + xl, y, item->Pose.Position.z + zf + zl, GetRoomVector(item->Location, Vector3i(item->Pose.Position.x, y, item->Pose.Position.z)).RoomNumber).Position.Floor;
- auto right = GetCollision(item->Pose.Position.x + xf + xr, y, item->Pose.Position.z + zf + zr, GetRoomVector(item->Location, Vector3i(item->Pose.Position.x, y, item->Pose.Position.z)).RoomNumber).Position.Floor;
+ auto left = GetPointCollision(Vector3i(item->Pose.Position.x + xf + xl, y, item->Pose.Position.z + zf + zl), GetRoomVector(item->Location, Vector3i(item->Pose.Position.x, y, item->Pose.Position.z)).RoomNumber).GetFloorHeight();
+ auto right = GetPointCollision(Vector3i(item->Pose.Position.x + xf + xr, y, item->Pose.Position.z + zf + zr), GetRoomVector(item->Location, Vector3i(item->Pose.Position.x, y, item->Pose.Position.z)).RoomNumber).GetFloorHeight();
// If specified, limit vertical search zone only to nearest height
if (heightLimit && (abs(left - y) > CLICK(0.5f) || abs(right - y) > CLICK(0.5f)))
@@ -214,7 +216,7 @@ bool TestLaraHang(ItemInfo* item, CollisionInfo* coll)
z += testShift.y;
}
- if (TestLaraNearClimbableWall(item, GetCollision(x, item->Pose.Position.y, z, item->RoomNumber).BottomBlock))
+ if (TestLaraNearClimbableWall(item, &GetPointCollision(Vector3i(x, item->Pose.Position.y, z), item->RoomNumber).GetBottomSector()))
{
if (!TestLaraHangOnClimbableWall(item, coll))
verticalShift = 0; // Ignore vertical shift if ladder is encountered next block
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 22869a549..1112ed12e 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -51,13 +51,13 @@ namespace TEN::Collision::PointCollision
// Set bottom sector pointer.
auto* bottomSectorPtr = &GetSector();
- auto roomNumberBelow = bottomSectorPtr->GetRoomNumberBelow(_position);
+ auto roomNumberBelow = bottomSectorPtr->GetNextRoomNumber(_position, true);
while (roomNumberBelow.has_value())
{
auto& room = g_Level.Rooms[roomNumberBelow.value_or(bottomSectorPtr->RoomNumber)];
bottomSectorPtr = Room::GetSector(&room, _position.x - room.x, _position.z - room.z);
- roomNumberBelow = bottomSectorPtr->GetRoomNumberBelow(_position);
+ roomNumberBelow = bottomSectorPtr->GetNextRoomNumber(_position, true);
}
_bottomSectorPtr = bottomSectorPtr;
@@ -71,13 +71,13 @@ namespace TEN::Collision::PointCollision
// Set top sector pointer.
auto* topSectorPtr = &GetSector();
- auto roomNumberAbove = topSectorPtr->GetRoomNumberAbove(_position);
+ auto roomNumberAbove = topSectorPtr->GetNextRoomNumber(_position, false);
while (roomNumberAbove.has_value())
{
auto& room = g_Level.Rooms[roomNumberAbove.value_or(topSectorPtr->RoomNumber)];
topSectorPtr = Room::GetSector(&room, _position.x - room.x, _position.z - room.z);
- roomNumberAbove = topSectorPtr->GetRoomNumberAbove(_position);
+ roomNumberAbove = topSectorPtr->GetNextRoomNumber(_position, false);
}
_topSectorPtr = topSectorPtr;
@@ -308,7 +308,7 @@ namespace TEN::Collision::PointCollision
static int GetProbeRoomNumber(const Vector3i& pos, const RoomVector& location, const Vector3i& probePos)
{
// Conduct L-shaped room traversal.
- short probeRoomNumber = GetRoom(location, Vector3i(pos.x, probePos.y, pos.z)).RoomNumber;
+ short probeRoomNumber = GetRoomVector(location, Vector3i(pos.x, probePos.y, pos.z)).RoomNumber;
GetFloor(probePos.x, probePos.y, probePos.z, &probeRoomNumber);
return probeRoomNumber;
diff --git a/TombEngine/Game/collision/collide_item.cpp b/TombEngine/Game/collision/collide_item.cpp
index fafe69c2f..e70424c7a 100644
--- a/TombEngine/Game/collision/collide_item.cpp
+++ b/TombEngine/Game/collision/collide_item.cpp
@@ -4,6 +4,8 @@
#include "Game/animation.h"
#include "Game/control/los.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/floordata.h"
+#include "Game/collision/PointCollision.h"
#include "Game/collision/sphere.h"
#include "Game/effects/debris.h"
#include "Game/effects/effects.h"
@@ -20,6 +22,8 @@
#include "Scripting/Include/ScriptInterfaceGame.h"
#include "Sound/sound.h"
+using namespace TEN::Collision::Floordata;
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Math;
using namespace TEN::Renderer;
@@ -413,7 +417,7 @@ bool AlignLaraPosition(const Vector3i& offset, ItemInfo* item, ItemInfo* laraIte
auto pos = Vector3::Transform(offset.ToVector3(), rotMatrix);
auto target = item->Pose.Position.ToVector3() + pos;
- int height = GetCollision(target.x, target.y, target.z, laraItem->RoomNumber).Position.Floor;
+ int height = GetPointCollision(target, laraItem->RoomNumber).GetFloorHeight();
if ((laraItem->Pose.Position.y - height) <= CLICK(2))
{
laraItem->Pose.Position = Vector3i(target);
@@ -442,7 +446,7 @@ bool MoveLaraPosition(const Vector3i& offset, ItemInfo* item, ItemInfo* laraItem
else
{
// Prevent picking up items which can result in so called "flare pickup bug"
- int height = GetCollision(target.Position.x, target.Position.y, target.Position.z, laraItem->RoomNumber).Position.Floor;
+ int height = GetPointCollision(target.Position, laraItem->RoomNumber).GetFloorHeight();
if (abs(height - laraItem->Pose.Position.y) <= CLICK(2))
return Move3DPosTo3DPos(laraItem, laraItem->Pose, target, LARA_ALIGN_VELOCITY, ANGLE(2.0f));
}
@@ -898,13 +902,13 @@ void ItemPushBridge(ItemInfo& item, CollisionInfo& coll)
ShiftItem(&item, &coll);
}
-void CollideBridgeItems(ItemInfo& item, CollisionInfo& coll, const CollisionResult& pointColl)
+void CollideBridgeItems(ItemInfo& item, CollisionInfo& coll, PointCollisionData& pointColl)
{
// Store offset for bridge item into shifts if it exists.
- if (coll.LastBridgeItemNumber == pointColl.Position.Bridge &&
+ if (coll.LastBridgeItemNumber == pointColl.GetFloorBridgeItemNumber() &&
coll.LastBridgeItemNumber != NO_ITEM)
{
- auto& bridgeItem = g_Level.Items[pointColl.Position.Bridge];
+ auto& bridgeItem = g_Level.Items[pointColl.GetFloorBridgeItemNumber()];
auto deltaPos = bridgeItem.Pose.Position - coll.LastBridgeItemPose.Position;
auto deltaOrient = bridgeItem.Pose.Orientation - coll.LastBridgeItemPose.Orientation;
@@ -944,7 +948,7 @@ void CollideBridgeItems(ItemInfo& item, CollisionInfo& coll, const CollisionResu
coll.LastBridgeItemNumber = NO_ITEM;
}
- coll.LastBridgeItemNumber = pointColl.Position.Bridge;
+ coll.LastBridgeItemNumber = pointColl.GetFloorBridgeItemNumber();
}
void CollideSolidStatics(ItemInfo* item, CollisionInfo* coll)
@@ -1286,39 +1290,42 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
{
auto* item = &g_Level.Items[itemNumber];
- auto prevPointProbe = GetCollision(x, y, z, item->RoomNumber);
- auto pointProbe = GetCollision(item);
+ auto prevPointColl = GetPointCollision(Vector3i(x, y, z), item->RoomNumber);
+ auto pointColl = GetPointCollision(*item);
+
+ // TODO: Use floor normal directly.
+ auto floorTilt = GetSurfaceTilt(pointColl.GetFloorNormal(), true);
auto bounds = GameBoundingBox(item);
int radius = bounds.GetHeight();
item->Pose.Position.y += radius;
- if (item->Pose.Position.y >= pointProbe.Position.Floor)
+ if (item->Pose.Position.y >= pointColl.GetFloorHeight())
{
int bs = 0;
- if (pointProbe.Position.FloorSlope && prevPointProbe.Position.Floor < pointProbe.Position.Floor)
+ if (pointColl.IsIllegalFloor() && prevPointColl.GetFloorHeight() < pointColl.GetFloorHeight())
{
int yAngle = (long)((unsigned short)item->Pose.Orientation.y);
- if (pointProbe.FloorTilt.x < 0)
+ if (floorTilt.x < 0)
{
if (yAngle >= ANGLE(180.0f))
bs = 1;
}
- else if (pointProbe.FloorTilt.x > 0)
+ else if (floorTilt.x > 0)
{
if (yAngle <= ANGLE(180.0f))
bs = 1;
}
- if (pointProbe.FloorTilt.y < 0)
+ if (floorTilt.y < 0)
{
if (yAngle >= ANGLE(90.0f) && yAngle <= ANGLE(270.0f))
bs = 1;
}
- else if (pointProbe.FloorTilt.y > 0)
+ else if (floorTilt.y > 0)
{
if (yAngle <= ANGLE(90.0f) || yAngle >= ANGLE(270.0f))
bs = 1;
@@ -1327,7 +1334,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
// If last position of item was also below this floor height, we've hit a wall, else we've hit a floor.
- if (y > (pointProbe.Position.Floor + 32) && bs == 0 &&
+ if (y > (pointColl.GetFloorHeight() + 32) && bs == 0 &&
(((x / BLOCK(1)) != (item->Pose.Position.x / BLOCK(1))) ||
((z / BLOCK(1)) != (item->Pose.Position.z / BLOCK(1)))))
{
@@ -1367,14 +1374,14 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
item->Pose.Position.z = z;
}
// Hit a steep slope?
- else if (pointProbe.Position.FloorSlope)
+ else if (pointColl.IsIllegalFloor())
{
// Need to know which direction the slope is.
item->Animation.Velocity.z -= (item->Animation.Velocity.z / 4);
// Hit angle = ANGLE(90.0f)
- if (pointProbe.FloorTilt.x < 0 && ((abs(pointProbe.FloorTilt.x)) - (abs(pointProbe.FloorTilt.y)) >= 2))
+ if (floorTilt.x < 0 && ((abs(floorTilt.x)) - (abs(floorTilt.y)) >= 2))
{
if (((unsigned short)item->Pose.Orientation.y) > ANGLE(180.0f))
{
@@ -1386,7 +1393,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
{
if (item->Animation.Velocity.z < 32)
{
- item->Animation.Velocity.z -= pointProbe.FloorTilt.x * 2;
+ item->Animation.Velocity.z -= floorTilt.x * 2;
if ((unsigned short)item->Pose.Orientation.y > ANGLE(90.0f) && (unsigned short)item->Pose.Orientation.y < ANGLE(270.0f))
{
item->Pose.Orientation.y -= ANGLE(22.5f);
@@ -1408,7 +1415,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
}
}
// Hit angle = ANGLE(270.0f)
- else if (pointProbe.FloorTilt.x > 0 && ((abs(pointProbe.FloorTilt.x)) - (abs(pointProbe.FloorTilt.y)) >= 2))
+ else if (floorTilt.x > 0 && ((abs(floorTilt.x)) - (abs(floorTilt.y)) >= 2))
{
if (((unsigned short)item->Pose.Orientation.y) < ANGLE(180.0f))
{
@@ -1420,7 +1427,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
{
if (item->Animation.Velocity.z < 32)
{
- item->Animation.Velocity.z += pointProbe.FloorTilt.x * 2;
+ item->Animation.Velocity.z += floorTilt.x * 2;
if ((unsigned short)item->Pose.Orientation.y > ANGLE(270.0f) || (unsigned short)item->Pose.Orientation.y < ANGLE(90.0f))
{
item->Pose.Orientation.y -= ANGLE(22.5f);
@@ -1442,7 +1449,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
}
}
// Hit angle = 0
- else if (pointProbe.FloorTilt.y < 0 && ((abs(pointProbe.FloorTilt.y)) - (abs(pointProbe.FloorTilt.x)) >= 2))
+ else if (floorTilt.y < 0 && ((abs(floorTilt.y)) - (abs(floorTilt.x)) >= 2))
{
if (((unsigned short)item->Pose.Orientation.y) > ANGLE(90.0f) && ((unsigned short)item->Pose.Orientation.y) < ANGLE(270.0f))
{
@@ -1454,7 +1461,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
{
if (item->Animation.Velocity.z < 32)
{
- item->Animation.Velocity.z -= pointProbe.FloorTilt.y * 2;
+ item->Animation.Velocity.z -= floorTilt.y * 2;
if ((unsigned short)item->Pose.Orientation.y < ANGLE(180.0f))
{
@@ -1477,7 +1484,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
}
}
// Hit angle = ANGLE(180.0f)
- else if (pointProbe.FloorTilt.y > 0 && ((abs(pointProbe.FloorTilt.y)) - (abs(pointProbe.FloorTilt.x)) >= 2))
+ else if (floorTilt.y > 0 && ((abs(floorTilt.y)) - (abs(floorTilt.x)) >= 2))
{
if (((unsigned short)item->Pose.Orientation.y) > ANGLE(270.0f) || ((unsigned short)item->Pose.Orientation.y) < ANGLE(90.0f))
{
@@ -1489,7 +1496,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
{
if (item->Animation.Velocity.z < 32)
{
- item->Animation.Velocity.z += pointProbe.FloorTilt.y * 2;
+ item->Animation.Velocity.z += floorTilt.y * 2;
if ((unsigned short)item->Pose.Orientation.y > ANGLE(180.0f))
{
@@ -1511,7 +1518,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
item->Animation.Velocity.y = 0;
}
}
- else if (pointProbe.FloorTilt.x < 0 && pointProbe.FloorTilt.y < 0) // Hit angle = 0x2000
+ else if (floorTilt.x < 0 && floorTilt.y < 0) // Hit angle = 0x2000
{
if (((unsigned short)item->Pose.Orientation.y) > ANGLE(135.0f) && ((unsigned short)item->Pose.Orientation.y) < ANGLE(315.0f))
{
@@ -1523,7 +1530,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
{
if (item->Animation.Velocity.z < 32)
{
- item->Animation.Velocity.z += -pointProbe.FloorTilt.x + -pointProbe.FloorTilt.y;
+ item->Animation.Velocity.z += -floorTilt.x + -floorTilt.y;
if ((unsigned short)item->Pose.Orientation.y > ANGLE(45.0f) && (unsigned short)item->Pose.Orientation.y < ANGLE(225.0f))
{
item->Pose.Orientation.y -= ANGLE(22.5f);
@@ -1545,7 +1552,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
}
}
// Hit angle = ANGLE(135.0f)
- else if (pointProbe.FloorTilt.x < 0 && pointProbe.FloorTilt.y > 0)
+ else if (floorTilt.x < 0 && floorTilt.y > 0)
{
if (((unsigned short)item->Pose.Orientation.y) > ANGLE(225.0f) || ((unsigned short)item->Pose.Orientation.y) < ANGLE(45.0f))
{
@@ -1557,7 +1564,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
{
if (item->Animation.Velocity.z < 32)
{
- item->Animation.Velocity.z += (-pointProbe.FloorTilt.x) + pointProbe.FloorTilt.y;
+ item->Animation.Velocity.z += (-floorTilt.x) + floorTilt.y;
if ((unsigned short)item->Pose.Orientation.y < ANGLE(315.0f) && (unsigned short)item->Pose.Orientation.y > ANGLE(135.0f))
{
item->Pose.Orientation.y -= ANGLE(22.5f);
@@ -1579,7 +1586,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
}
}
// Hit angle = ANGLE(225.5f)
- else if (pointProbe.FloorTilt.x > 0 && pointProbe.FloorTilt.y > 0)
+ else if (floorTilt.x > 0 && floorTilt.y > 0)
{
if (((unsigned short)item->Pose.Orientation.y) > ANGLE(315.0f) || ((unsigned short)item->Pose.Orientation.y) < ANGLE(135.0f))
{
@@ -1591,7 +1598,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
{
if (item->Animation.Velocity.z < 32)
{
- item->Animation.Velocity.z += pointProbe.FloorTilt.x + pointProbe.FloorTilt.y;
+ item->Animation.Velocity.z += floorTilt.x + floorTilt.y;
if ((unsigned short)item->Pose.Orientation.y < ANGLE(45.0f) || (unsigned short)item->Pose.Orientation.y > ANGLE(225.5f))
{
item->Pose.Orientation.y -= ANGLE(22.5f);
@@ -1613,7 +1620,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
}
}
// Hit angle = ANGLE(315.0f)
- else if (pointProbe.FloorTilt.x > 0 && pointProbe.FloorTilt.y < 0)
+ else if (floorTilt.x > 0 && floorTilt.y < 0)
{
if (((unsigned short)item->Pose.Orientation.y) > ANGLE(45.0f) && ((unsigned short)item->Pose.Orientation.y) < ANGLE(225.5f))
{
@@ -1625,7 +1632,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
{
if (item->Animation.Velocity.z < 32)
{
- item->Animation.Velocity.z += pointProbe.FloorTilt.x + (-pointProbe.FloorTilt.y);
+ item->Animation.Velocity.z += floorTilt.x + (-floorTilt.y);
if ((unsigned short)item->Pose.Orientation.y < ANGLE(135.0f) || (unsigned short)item->Pose.Orientation.y > ANGLE(315.0f))
{
item->Pose.Orientation.y -= ANGLE(22.5f);
@@ -1686,7 +1693,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
}
}
- item->Pose.Position.y = pointProbe.Position.Floor;
+ item->Pose.Position.y = pointColl.GetFloorHeight();
}
}
// Check for on top of object.
@@ -1694,8 +1701,8 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
{
if (yv >= 0)
{
- prevPointProbe = GetCollision(item->Pose.Position.x, y, item->Pose.Position.z, item->RoomNumber);
- pointProbe = GetCollision(item);
+ prevPointColl = GetPointCollision(Vector3i(item->Pose.Position.x, y, item->Pose.Position.z), item->RoomNumber);
+ pointColl = GetPointCollision(*item);
// Bounce off floor.
@@ -1703,7 +1710,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
// was always set to 0 by GetHeight() function which was called before the check.
// Possibly a mistake or unfinished feature by Core? -- Lwmte, 27.08.21
- if (item->Pose.Position.y >= prevPointProbe.Position.Floor)
+ if (item->Pose.Position.y >= prevPointColl.GetFloorHeight())
{
// Hit the floor; bounce and slow down.
if (item->Animation.Velocity.y > 0)
@@ -1737,17 +1744,17 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
}
}
- item->Pose.Position.y = prevPointProbe.Position.Floor;
+ item->Pose.Position.y = prevPointColl.GetFloorHeight();
}
}
// else
{
// Bounce off ceiling.
- pointProbe = GetCollision(item);
+ pointColl = GetPointCollision(*item);
- if (item->Pose.Position.y < pointProbe.Position.Ceiling)
+ if (item->Pose.Position.y < pointColl.GetCeilingHeight())
{
- if (y < pointProbe.Position.Ceiling &&
+ if (y < pointColl.GetCeilingHeight() &&
(((x / BLOCK(1)) != (item->Pose.Position.x / BLOCK(1))) ||
((z / BLOCK(1)) != (item->Pose.Position.z / BLOCK(1)))))
{
@@ -1776,7 +1783,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
item->Pose.Position.z = z;
}
else
- item->Pose.Position.y = pointProbe.Position.Ceiling;
+ item->Pose.Position.y = pointColl.GetCeilingHeight();
if (item->Animation.Velocity.y < 0)
item->Animation.Velocity.y = -item->Animation.Velocity.y;
@@ -1784,14 +1791,14 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
}
}
- pointProbe = GetCollision(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->RoomNumber);
+ pointColl = GetPointCollision(*item);
- if (pointProbe.RoomNumber != item->RoomNumber)
+ if (pointColl.GetRoomNumber() != item->RoomNumber)
{
- if (item->ObjectNumber == ID_GRENADE && TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, pointProbe.RoomNumber))
+ if (item->ObjectNumber == ID_GRENADE && TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, pointColl.GetRoomNumber()))
Splash(item);
- ItemNewRoom(itemNumber, pointProbe.RoomNumber);
+ ItemNewRoom(itemNumber, pointColl.GetRoomNumber());
}
item->Pose.Position.y -= radius;
diff --git a/TombEngine/Game/collision/collide_item.h b/TombEngine/Game/collision/collide_item.h
index 31a275928..9f10dc584 100644
--- a/TombEngine/Game/collision/collide_item.h
+++ b/TombEngine/Game/collision/collide_item.h
@@ -1,12 +1,15 @@
#pragma once
#include "Math/Math.h"
+namespace TEN::Collision::PointCollision { class PointCollisionData; };
class FloorInfo;
struct CollisionInfo;
struct CollisionResult;
struct ItemInfo;
struct MESH_INFO;
+using namespace TEN::Collision::PointCollision;
+
constexpr auto MAX_COLLIDED_OBJECTS = 1024;
constexpr auto ITEM_RADIUS_YMAX = BLOCK(3);
@@ -45,7 +48,7 @@ void ItemPushBridge(ItemInfo& item, CollisionInfo& coll);
bool CollideSolidBounds(ItemInfo* item, const GameBoundingBox& box, const Pose& pose, CollisionInfo* coll);
void CollideSolidStatics(ItemInfo* item, CollisionInfo* coll);
-void CollideBridgeItems(ItemInfo& item, CollisionInfo& coll, const CollisionResult& pointColl);
+void CollideBridgeItems(ItemInfo& item, CollisionInfo& coll, PointCollisionData& pointColl);
void AIPickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll);
void ObjectCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll);
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index fcc5bb7ae..f13c1881f 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -100,12 +100,12 @@ bool TestItemRoomCollisionAABB(ItemInfo* item)
auto test = [item](short x, short y, short z, bool floor)
{
- auto collPos = GetCollision(x, y, z, item->RoomNumber).Position;
+ auto pointColl = GetPointCollision(Vector3i(x, y, z), item->RoomNumber);
if (floor)
- return (y > collPos.Floor);
+ return (y > pointColl.GetFloorHeight());
else
- return (y < collPos.Ceiling);
+ return (y < pointColl.GetCeilingHeight());
};
bool collided =
@@ -124,12 +124,10 @@ bool TestItemRoomCollisionAABB(ItemInfo* item)
static CollisionResult ConvertPointCollDataToCollResult(PointCollisionData& pointColl)
{
auto collResult = CollisionResult{};
-
collResult.Coordinates = pointColl.GetPosition();
collResult.RoomNumber = pointColl.GetRoomNumber();
collResult.Block = &pointColl.GetSector();
collResult.BottomBlock = &pointColl.GetBottomSector();
-
collResult.Position.Floor = pointColl.GetFloorHeight();
collResult.Position.Ceiling = pointColl.GetCeilingHeight();
collResult.Position.Bridge = pointColl.GetFloorBridgeItemNumber();
@@ -139,8 +137,6 @@ static CollisionResult ConvertPointCollDataToCollResult(PointCollisionData& poin
collResult.Position.DiagonalStep = pointColl.IsDiagonalFloorStep();
collResult.FloorNormal = pointColl.GetFloorNormal();
collResult.CeilingNormal = pointColl.GetCeilingNormal();
-
- // NOTE: Bridge tilts ignored by old method.
collResult.FloorTilt = GetSurfaceTilt(collResult.FloorNormal, true).ToVector2();
collResult.CeilingTilt = GetSurfaceTilt(collResult.CeilingNormal, false).ToVector2();
@@ -161,24 +157,26 @@ CollisionResult GetCollision(const ItemInfo* item, short headingAngle, float for
return ConvertPointCollDataToCollResult(pointColl);
}
-// NOTE: Deprecated. Use GetPointCollision().
-CollisionResult GetCollision(int x, int y, int z, short roomNumber)
+static CollisionPosition GetCollisionPositionData(PointCollisionData& pointColl)
{
- auto pointColl = GetPointCollision(Vector3i(x, y, z), roomNumber);
- return ConvertPointCollDataToCollResult(pointColl);
+ auto collPos = CollisionPosition{};
+ collPos.Floor = pointColl.GetFloorHeight();
+ collPos.Ceiling = pointColl.GetCeilingHeight();
+ collPos.Bridge = pointColl.GetFloorBridgeItemNumber();
+ collPos.SplitAngle = pointColl.GetBottomSector().FloorSurface.SplitAngle;
+ collPos.FloorSlope = pointColl.IsIllegalFloor();
+ collPos.CeilingSlope = pointColl.IsIllegalCeiling();
+ collPos.DiagonalStep = pointColl.IsDiagonalFloorStep();
+
+ return collPos;
}
-void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, bool resetRoom)
-{
- GetCollisionInfo(coll, item, Vector3i::Zero, resetRoom);
-}
-
-static void SetSectorAttribs(CollisionPosition& sectorAttribs, const CollisionSetup& collSetup, const CollisionResult& pointColl,
+static void SetSectorAttribs(CollisionPosition& sectorAttribs, const CollisionSetup& collSetup, PointCollisionData& pointColl,
const Vector3i& probePos, int realRoomNumber)
{
constexpr auto ASPECT_ANGLE_DELTA_MAX = ANGLE(90.0f);
- auto floorNormal = pointColl.FloorNormal;
+ auto floorNormal = pointColl.GetFloorNormal();
short aspectAngle = Geometry::GetSurfaceAspectAngle(floorNormal);
short aspectAngleDelta = Geometry::GetShortestAngle(collSetup.ForwardAngle, aspectAngle);
@@ -205,14 +203,14 @@ static void SetSectorAttribs(CollisionPosition& sectorAttribs, const CollisionSe
}
else if (collSetup.BlockDeathFloorDown &&
sectorAttribs.Floor >= CLICK(0.5f) &&
- pointColl.BottomBlock->Flags.Death)
+ pointColl.GetBottomSector().Flags.Death)
{
sectorAttribs.Floor = MAX_HEIGHT;
}
else if (collSetup.BlockMonkeySwingEdge)
{
- auto pointColl = GetCollision(probePos.x, probePos.y + collSetup.Height, probePos.z, realRoomNumber);
- if (!pointColl.BottomBlock->Flags.Monkeyswing)
+ auto pointColl = GetPointCollision(probePos, realRoomNumber, Vector3::UnitY, collSetup.Height);
+ if (!pointColl.GetBottomSector().Flags.Monkeyswing)
sectorAttribs.Floor = MAX_HEIGHT;
}
}
@@ -328,12 +326,12 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
// TEST 1: TILT AND NEAREST LEDGE CALCULATION
- auto collResult = GetCollision(probePos.x, item->Pose.Position.y, probePos.z, realRoomNumber);
+ auto pointColl = GetPointCollision(Vector3i(probePos.x, item->Pose.Position.y, probePos.z), realRoomNumber);
- coll->FloorNormal = collResult.FloorNormal;
- coll->CeilingNormal = collResult.CeilingNormal;
- coll->FloorTilt = collResult.FloorTilt;
- coll->CeilingTilt = collResult.CeilingTilt;
+ coll->FloorNormal = pointColl.GetFloorNormal();
+ coll->CeilingNormal = pointColl.GetCeilingNormal();
+ coll->FloorTilt = GetSurfaceTilt(pointColl.GetFloorNormal(), true).ToVector2();
+ coll->CeilingTilt = GetSurfaceTilt(pointColl.GetCeilingNormal(), false).ToVector2();
coll->NearestLedgeAngle = GetNearestLedgeAngle(item, coll, coll->NearestLedgeDistance);
// Debug angle and distance
@@ -342,8 +340,8 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
// TEST 2: CENTERPOINT PROBE
- collResult = GetCollision(probePos.x, probePos.y, probePos.z, realRoomNumber);
- int topRoomNumber = collResult.RoomNumber; // Keep top room number as we need it to re-probe from origin room.
+ pointColl = GetPointCollision(probePos, realRoomNumber);
+ int topRoomNumber = pointColl.GetRoomNumber(); // Keep top room number as we need it to re-probe from origin room.
if (doPlayerCollision)
{
@@ -355,8 +353,8 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
}
else
{
- height = collResult.Position.Floor;
- ceiling = GetCeiling(collResult.Block, probePos.x, probePos.y - item->Animation.Velocity.y, probePos.z);
+ height = pointColl.GetFloorHeight();
+ ceiling = GetCeiling(&pointColl.GetSector(), probePos.x, probePos.y - item->Animation.Velocity.y, probePos.z);
}
if (height != NO_HEIGHT)
@@ -365,12 +363,12 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
if (ceiling != NO_HEIGHT)
ceiling -= probePos.y;
- coll->Middle = collResult.Position;
+ coll->Middle = GetCollisionPositionData(pointColl);
coll->Middle.Floor = height;
coll->Middle.Ceiling = ceiling;
- // Additionally calculate bridge shifts, if present.
- CollideBridgeItems(*item, *coll, collResult);
+ // Additionally calculate bridge shifts if present.
+ CollideBridgeItems(*item, *coll, pointColl);
// TEST 3: FRONTAL PROBE
@@ -379,7 +377,7 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
g_Renderer.AddDebugSphere(probePos.ToVector3(), 32, Vector4(1, 0, 0, 1), RendererDebugPage::CollisionStats);
- collResult = GetCollision(probePos.x, probePos.y, probePos.z, topRoomNumber);
+ pointColl = GetPointCollision(probePos, topRoomNumber);
if (doPlayerCollision)
{
@@ -398,8 +396,8 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
}
else
{
- height = collResult.Position.Floor;
- ceiling = GetCeiling(collResult.Block, probePos.x, probePos.y - item->Animation.Velocity.y, probePos.z);
+ height = pointColl.GetFloorHeight();
+ ceiling = GetCeiling(&pointColl.GetSector(), probePos.x, probePos.y - item->Animation.Velocity.y, probePos.z);
}
if (height != NO_HEIGHT)
@@ -408,7 +406,7 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
if (ceiling != NO_HEIGHT)
ceiling -= probePos.y;
- coll->Front = collResult.Position;
+ coll->Front = GetCollisionPositionData(pointColl);
coll->Front.Floor = height;
coll->Front.Ceiling = ceiling;
@@ -419,13 +417,13 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
}
else
{
- height = GetCollision(probePos.x + xFront, probePos.y, probePos.z + zFront, topRoomNumber).Position.Floor;
+ height = GetPointCollision(Vector3i(probePos.x + xFront, probePos.y, probePos.z + zFront), topRoomNumber).GetFloorHeight();
}
if (height != NO_HEIGHT)
height -= (doPlayerCollision ? entityPos.y : probePos.y);
- SetSectorAttribs(coll->Front, coll->Setup, collResult, probePos, realRoomNumber);
+ SetSectorAttribs(coll->Front, coll->Setup, pointColl, probePos, realRoomNumber);
// TEST 4: MIDDLE-LEFT PROBE
@@ -434,7 +432,7 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
g_Renderer.AddDebugSphere(probePos.ToVector3(), 32, Vector4(0, 0, 1, 1), RendererDebugPage::CollisionStats);
- collResult = GetCollision(probePos.x, probePos.y, probePos.z, item->RoomNumber);
+ pointColl = GetPointCollision(probePos, item->RoomNumber);
if (doPlayerCollision)
{
@@ -446,8 +444,8 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
}
else
{
- height = collResult.Position.Floor;
- ceiling = GetCeiling(collResult.Block, probePos.x, probePos.y - item->Animation.Velocity.y, probePos.z);
+ height = pointColl.GetFloorHeight();
+ ceiling = GetCeiling(&pointColl.GetSector(), probePos.x, probePos.y - item->Animation.Velocity.y, probePos.z);
}
if (height != NO_HEIGHT)
@@ -456,15 +454,16 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
if (ceiling != NO_HEIGHT)
ceiling -= probePos.y;
- coll->MiddleLeft = collResult.Position;
+ coll->MiddleLeft = GetCollisionPositionData(pointColl);
coll->MiddleLeft.Floor = height;
coll->MiddleLeft.Ceiling = ceiling;
- SetSectorAttribs(coll->MiddleLeft, coll->Setup, collResult, probePos, realRoomNumber);
+ SetSectorAttribs(coll->MiddleLeft, coll->Setup, pointColl, probePos, realRoomNumber);
// TEST 5: FRONT-LEFT PROBE
- collResult = GetCollision(probePos.x, probePos.y, probePos.z, topRoomNumber); // Use plain X/Z values here as proposed by Choco.
+ // Use plain X/Z values.
+ pointColl = GetPointCollision(probePos, topRoomNumber);
if (doPlayerCollision)
{
@@ -476,8 +475,8 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
}
else
{
- height = collResult.Position.Floor;
- ceiling = GetCeiling(collResult.Block, probePos.x, probePos.y - item->Animation.Velocity.y, probePos.z);
+ height = pointColl.GetFloorHeight();
+ ceiling = GetCeiling(&pointColl.GetSector(), probePos.x, probePos.y - item->Animation.Velocity.y, probePos.z);
}
if (height != NO_HEIGHT)
@@ -486,11 +485,11 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
if (ceiling != NO_HEIGHT)
ceiling -= probePos.y;
- coll->FrontLeft = collResult.Position;
+ coll->FrontLeft = GetCollisionPositionData(pointColl);
coll->FrontLeft.Floor = height;
coll->FrontLeft.Ceiling = ceiling;
- SetSectorAttribs(coll->FrontLeft, coll->Setup, collResult, probePos, realRoomNumber);
+ SetSectorAttribs(coll->FrontLeft, coll->Setup, pointColl, probePos, realRoomNumber);
// TEST 6: MIDDLE-RIGHT PROBE
@@ -499,7 +498,7 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
g_Renderer.AddDebugSphere(probePos.ToVector3(), 32, Vector4(0, 1, 0, 1), RendererDebugPage::CollisionStats);
- collResult = GetCollision(probePos.x, probePos.y, probePos.z, item->RoomNumber);
+ pointColl = GetPointCollision(probePos, item->RoomNumber);
if (doPlayerCollision)
{
@@ -511,8 +510,8 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
}
else
{
- height = collResult.Position.Floor;
- ceiling = GetCeiling(collResult.Block, probePos.x, probePos.y - item->Animation.Velocity.y, probePos.z);
+ height = pointColl.GetFloorHeight();
+ ceiling = GetCeiling(&pointColl.GetSector(), probePos.x, probePos.y - item->Animation.Velocity.y, probePos.z);
}
if (height != NO_HEIGHT)
@@ -521,15 +520,15 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
if (ceiling != NO_HEIGHT)
ceiling -= probePos.y;
- coll->MiddleRight = collResult.Position;
+ coll->MiddleRight = GetCollisionPositionData(pointColl);
coll->MiddleRight.Floor = height;
coll->MiddleRight.Ceiling = ceiling;
- SetSectorAttribs(coll->MiddleRight, coll->Setup, collResult, probePos, realRoomNumber);
+ SetSectorAttribs(coll->MiddleRight, coll->Setup, pointColl, probePos, realRoomNumber);
// TEST 7: FRONT-RIGHT PROBE
- collResult = GetCollision(probePos.x, probePos.y, probePos.z, topRoomNumber);
+ pointColl = GetPointCollision(probePos, topRoomNumber);
if (doPlayerCollision)
{
@@ -541,8 +540,8 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
}
else
{
- height = collResult.Position.Floor;
- ceiling = GetCeiling(collResult.Block, probePos.x, probePos.y - item->Animation.Velocity.y, probePos.z);
+ height = pointColl.GetFloorHeight();
+ ceiling = GetCeiling(&pointColl.GetSector(), probePos.x, probePos.y - item->Animation.Velocity.y, probePos.z);
}
if (height != NO_HEIGHT)
@@ -551,11 +550,11 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
if (ceiling != NO_HEIGHT)
ceiling -= probePos.y;
- coll->FrontRight = collResult.Position;
+ coll->FrontRight = GetCollisionPositionData(pointColl);
coll->FrontRight.Floor = height;
coll->FrontRight.Ceiling = ceiling;
- SetSectorAttribs(coll->FrontRight, coll->Setup, collResult, probePos, realRoomNumber);
+ SetSectorAttribs(coll->FrontRight, coll->Setup, pointColl, probePos, realRoomNumber);
// TEST 8: SOLID STATIC MESHES
@@ -730,6 +729,11 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
}
}
+void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, bool resetRoom)
+{
+ GetCollisionInfo(coll, item, Vector3i::Zero, resetRoom);
+}
+
void AlignEntityToSurface(ItemInfo* item, const Vector2& ellipse, float alpha, short constraintAngle)
{
// Reduce ellipse axis lengths for stability.
@@ -855,11 +859,11 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance)
// Get front floor block
auto room = GetRoomVector(item->Location, Vector3i(ffpX, y, ffpZ)).RoomNumber;
- auto block = GetCollision(ffpX, y, ffpZ, room).Block;
+ auto sectorPtr = &GetPointCollision(Vector3i(ffpX, y, ffpZ), room).GetSector();
// Get front floor surface heights
- auto floorHeight = GetSurfaceHeight(RoomVector(block->RoomNumber, y), ffpX, ffpZ, true).value_or(NO_HEIGHT);
- auto ceilingHeight = GetSurfaceHeight(RoomVector(block->RoomNumber, y), ffpX, ffpZ, false).value_or(NO_HEIGHT);
+ auto floorHeight = GetSurfaceHeight(RoomVector(sectorPtr->RoomNumber, y), ffpX, ffpZ, true).value_or(NO_HEIGHT);
+ auto ceilingHeight = GetSurfaceHeight(RoomVector(sectorPtr->RoomNumber, y), ffpX, ffpZ, false).value_or(NO_HEIGHT);
// If probe landed inside wall (i.e. both floor/ceiling heights are NO_HEIGHT), make a fake
// ledge for algorithm to further succeed.
@@ -872,7 +876,7 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance)
int height = useCeilingLedge ? ceilingHeight : floorHeight;
// Determine if there is a bridge in front.
- auto bridge = block->GetInsideBridgeItemNumber(Vector3i(ffpX, height, ffpZ), true, y == height);
+ auto bridge = sectorPtr->GetInsideBridgeItemNumber(Vector3i(ffpX, height, ffpZ), true, y == height);
// Determine floor probe offset.
// This must be slightly in front of own coll radius so no bridge misfires occur.
@@ -885,7 +889,7 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance)
// Get true room number and block, based on derived height
room = GetRoomVector(item->Location, Vector3i(fpX, height, fpZ)).RoomNumber;
- block = GetCollision(fpX, height, fpZ, room).Block;
+ sectorPtr = &GetPointCollision(Vector3i(fpX, height, fpZ), room).GetSector();
// We don't need actual corner heights to build planes, so just use normalized value here.
auto fY = height - 1;
@@ -943,7 +947,7 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance)
else
{
// Determine if we should use floor or ceiling split angle based on early tests.
- auto splitAngle = (useCeilingLedge ? TO_RAD(block->CeilingSurface.SplitAngle) : TO_RAD(block->FloorSurface.SplitAngle));
+ auto splitAngle = (useCeilingLedge ? TO_RAD(sectorPtr->CeilingSurface.SplitAngle) : TO_RAD(sectorPtr->FloorSurface.SplitAngle));
// Get horizontal block corner coordinates.
auto fX = floor(eX / BLOCK(1)) * BLOCK(1) - 1;
@@ -971,7 +975,7 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance)
};
// If split angle exists, take split plane into account too.
- auto useSplitAngle = (useCeilingLedge ? block->IsSurfaceSplit(false) : block->IsSurfaceSplit(true));
+ auto useSplitAngle = (useCeilingLedge ? sectorPtr->IsSurfaceSplit(false) : sectorPtr->IsSurfaceSplit(true));
// Find closest block edge plane.
for (int i = 0; i < (useSplitAngle ? 5 : 4); i++)
@@ -998,7 +1002,7 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance)
if (i == 4)
{
- auto usedSectorPlane = useCeilingLedge ? block->GetSurfaceTriangleID(eX, eZ, false) : block->GetSurfaceTriangleID(eX, eZ, true);
+ auto usedSectorPlane = useCeilingLedge ? sectorPtr->GetSurfaceTriangleID(eX, eZ, false) : sectorPtr->GetSurfaceTriangleID(eX, eZ, true);
result[p] = FROM_RAD(splitAngle) + ANGLE(usedSectorPlane * 180.0f) + ANGLE(90.0f);
}
else
@@ -1100,19 +1104,19 @@ int GetCeiling(FloorInfo* floor, int x, int y, int z)
int GetDistanceToFloor(int itemNumber, bool precise)
{
- auto* item = &g_Level.Items[itemNumber];
+ const auto& item = g_Level.Items[itemNumber];
- auto pointColl = GetCollision(item);
+ auto pointColl = GetPointCollision(item);
// HACK: Remove item from bridge objects temporarily.
- pointColl.Block->RemoveBridge(itemNumber);
- int height = GetFloorHeight(pointColl.Block, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z);
- pointColl.Block->AddBridge(itemNumber);
+ pointColl.GetSector().RemoveBridge(itemNumber);
+ int height = GetFloorHeight(&pointColl.GetSector(), item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z);
+ pointColl.GetSector().AddBridge(itemNumber);
- auto bounds = GameBoundingBox(item);
+ auto bounds = GameBoundingBox(&item);
int minHeight = precise ? bounds.Y2 : 0;
- return (minHeight + item->Pose.Position.y - height);
+ return (minHeight + item.Pose.Position.y - height);
}
int GetWaterSurface(int x, int y, int z, short roomNumber)
@@ -1122,9 +1126,9 @@ int GetWaterSurface(int x, int y, int z, short roomNumber)
if (TestEnvironment(ENV_FLAG_WATER, roomPtr))
{
- while (sectorPtr->GetRoomNumberAbove(Vector3i(x, y, z)).value_or(NO_ROOM) != NO_ROOM)
+ while (sectorPtr->GetNextRoomNumber(Vector3i(x, y, z), false).value_or(NO_ROOM) != NO_ROOM)
{
- roomPtr = &g_Level.Rooms[sectorPtr->GetRoomNumberAbove(Vector3i(x, y, z)).value_or(sectorPtr->RoomNumber)];
+ roomPtr = &g_Level.Rooms[sectorPtr->GetNextRoomNumber(Vector3i(x, y, z), false).value_or(sectorPtr->RoomNumber)];
if (!TestEnvironment(ENV_FLAG_WATER, roomPtr))
return (sectorPtr->GetSurfaceHeight(x, z, false));
@@ -1135,9 +1139,9 @@ int GetWaterSurface(int x, int y, int z, short roomNumber)
}
else
{
- while (sectorPtr->GetRoomNumberBelow(Vector3i(x, y, z)).value_or(NO_ROOM) != NO_ROOM)
+ while (sectorPtr->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(NO_ROOM) != NO_ROOM)
{
- roomPtr = &g_Level.Rooms[sectorPtr->GetRoomNumberBelow(Vector3i(x, y, z)).value_or(sectorPtr->RoomNumber)];
+ roomPtr = &g_Level.Rooms[sectorPtr->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(sectorPtr->RoomNumber)];
if (TestEnvironment(ENV_FLAG_WATER, roomPtr))
return (sectorPtr->GetSurfaceHeight(x, z, true));
@@ -1198,7 +1202,7 @@ int GetWaterDepth(int x, int y, int z, short roomNumber)
}
sectorPtr = &roomPtr->floor[zFloor + (xFloor * roomPtr->zSize)];
- adjoiningRoomNumber = sectorPtr->WallPortalRoomNumber;
+ adjoiningRoomNumber = sectorPtr->SidePortalRoomNumber;
if (adjoiningRoomNumber != NO_ROOM)
{
roomNumber = adjoiningRoomNumber;
@@ -1210,9 +1214,9 @@ int GetWaterDepth(int x, int y, int z, short roomNumber)
if (TestEnvironment(ENV_FLAG_WATER, roomPtr) ||
TestEnvironment(ENV_FLAG_SWAMP, roomPtr))
{
- while (sectorPtr->GetRoomNumberAbove(Vector3i(x, y, z)).value_or(NO_ROOM) != NO_ROOM)
+ while (sectorPtr->GetNextRoomNumber(Vector3i(x, y, z), false).value_or(NO_ROOM) != NO_ROOM)
{
- roomPtr = &g_Level.Rooms[sectorPtr->GetRoomNumberAbove(Vector3i(x, y, z)).value_or(sectorPtr->RoomNumber)];
+ roomPtr = &g_Level.Rooms[sectorPtr->GetNextRoomNumber(Vector3i(x, y, z), false).value_or(sectorPtr->RoomNumber)];
if (!TestEnvironment(ENV_FLAG_WATER, roomPtr) &&
!TestEnvironment(ENV_FLAG_SWAMP, roomPtr))
@@ -1229,9 +1233,9 @@ int GetWaterDepth(int x, int y, int z, short roomNumber)
}
else
{
- while (sectorPtr->GetRoomNumberBelow(Vector3i(x, y, z)).value_or(NO_ROOM) != NO_ROOM)
+ while (sectorPtr->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(NO_ROOM) != NO_ROOM)
{
- roomPtr = &g_Level.Rooms[sectorPtr->GetRoomNumberBelow(Vector3i(x, y, z)).value_or(sectorPtr->RoomNumber)];
+ roomPtr = &g_Level.Rooms[sectorPtr->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(sectorPtr->RoomNumber)];
if (TestEnvironment(ENV_FLAG_WATER, roomPtr) ||
TestEnvironment(ENV_FLAG_SWAMP, roomPtr))
@@ -1298,7 +1302,7 @@ int GetWaterHeight(int x, int y, int z, short roomNumber)
}
sectorPtr = &roomPtr->floor[zBlock + (xBlock * roomPtr->zSize)];
- adjoiningRoomNumber = sectorPtr->WallPortalRoomNumber;
+ adjoiningRoomNumber = sectorPtr->SidePortalRoomNumber;
if (adjoiningRoomNumber != NO_ROOM)
{
@@ -1314,9 +1318,9 @@ int GetWaterHeight(int x, int y, int z, short roomNumber)
if (TestEnvironment(ENV_FLAG_WATER, roomPtr) ||
TestEnvironment(ENV_FLAG_SWAMP, roomPtr))
{
- while (sectorPtr->GetRoomNumberAbove(Vector3i(x, y, z)).value_or(NO_ROOM) != NO_ROOM)
+ while (sectorPtr->GetNextRoomNumber(Vector3i(x, y, z), false).value_or(NO_ROOM) != NO_ROOM)
{
- auto* room = &g_Level.Rooms[sectorPtr->GetRoomNumberAbove(Vector3i(x, y, z)).value_or(sectorPtr->RoomNumber)];
+ auto* room = &g_Level.Rooms[sectorPtr->GetNextRoomNumber(Vector3i(x, y, z), false).value_or(sectorPtr->RoomNumber)];
if (!TestEnvironment(ENV_FLAG_WATER, room) &&
!TestEnvironment(ENV_FLAG_SWAMP, room))
@@ -1329,11 +1333,11 @@ int GetWaterHeight(int x, int y, int z, short roomNumber)
return GetPointCollision(Vector3i(x, y, z), sectorPtr->RoomNumber).GetSector().GetSurfaceHeight(Vector3i(x, y, z), false);
}
- else if (sectorPtr->GetRoomNumberBelow(Vector3i(x, y, z)).value_or(NO_ROOM) != NO_ROOM)
+ else if (sectorPtr->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(NO_ROOM) != NO_ROOM)
{
- while (sectorPtr->GetRoomNumberBelow(Vector3i(x, y, z)).value_or(NO_ROOM) != NO_ROOM)
+ while (sectorPtr->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(NO_ROOM) != NO_ROOM)
{
- auto* roomPtr2 = &g_Level.Rooms[sectorPtr->GetRoomNumberBelow(Vector3i(x, y, z)).value_or(sectorPtr->RoomNumber)];
+ auto* roomPtr2 = &g_Level.Rooms[sectorPtr->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(sectorPtr->RoomNumber)];
if (TestEnvironment(ENV_FLAG_WATER, roomPtr2) ||
TestEnvironment(ENV_FLAG_SWAMP, roomPtr2))
@@ -1357,12 +1361,12 @@ int GetWaterHeight(ItemInfo* item)
bool TestEnvironment(RoomEnvFlags environmentType, int x, int y, int z, int roomNumber)
{
- return TestEnvironment(environmentType, GetCollision(x, y, z, roomNumber).RoomNumber);
+ return TestEnvironment(environmentType, GetPointCollision(Vector3i(x, y, z), roomNumber).GetRoomNumber());
}
-bool TestEnvironment(RoomEnvFlags environmentType, Vector3i pos, int roomNumber)
+bool TestEnvironment(RoomEnvFlags environmentType, const Vector3i& pos, int roomNumber)
{
- return TestEnvironment(environmentType, GetCollision(pos.x, pos.y, pos.z, roomNumber).RoomNumber);
+ return TestEnvironment(environmentType, GetPointCollision(pos, roomNumber).GetRoomNumber());
}
bool TestEnvironment(RoomEnvFlags environmentType, const ItemInfo* item)
diff --git a/TombEngine/Game/collision/collide_room.h b/TombEngine/Game/collision/collide_room.h
index 58936b2d8..2b36d8dca 100644
--- a/TombEngine/Game/collision/collide_room.h
+++ b/TombEngine/Game/collision/collide_room.h
@@ -43,13 +43,13 @@ enum class CornerType
struct CollisionPosition
{
- int Floor;
- int Ceiling;
- int Bridge;
- float SplitAngle;
- bool FloorSlope;
- bool CeilingSlope;
- bool DiagonalStep;
+ int Floor = 0;
+ int Ceiling = 0;
+ int Bridge = 0;
+ float SplitAngle = 0.0f;
+ bool FloorSlope = false;
+ bool CeilingSlope = false;
+ bool DiagonalStep = false;
bool HasDiagonalSplit() { return ((SplitAngle == (45.0f * RADIAN)) || (SplitAngle == (135.0f * RADIAN))); }
bool HasFlippedDiagonalSplit() { return (HasDiagonalSplit() && (SplitAngle != (45.0f * RADIAN))); }
@@ -138,10 +138,9 @@ struct CollisionInfo
// NOTE: All overloads deprecated. Use GetPointCollision().
CollisionResult GetCollision(const ItemInfo* item);
CollisionResult GetCollision(const ItemInfo* item, short headingAngle, float forward, float down = 0.0f, float right = 0.0f);
-CollisionResult GetCollision(int x, int y, int z, short roomNumber);
-void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offset, bool resetRoom = false);
void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, bool resetRoom = false);
+void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offset, bool resetRoom = false);
int GetQuadrant(short angle);
short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance);
@@ -165,8 +164,9 @@ void SnapItemToGrid(ItemInfo* item, CollisionInfo* coll);
void AlignEntityToSurface(ItemInfo* item, const Vector2& ellipse, float alpha = 0.75f, short constraintAngle = ANGLE(70.0f));
+// TODO: Deprecated.
bool TestEnvironment(RoomEnvFlags environmentType, int x, int y, int z, int roomNumber);
-bool TestEnvironment(RoomEnvFlags environmentType, Vector3i pos, int roomNumber);
+bool TestEnvironment(RoomEnvFlags environmentType, const Vector3i& pos, int roomNumber);
bool TestEnvironment(RoomEnvFlags environmentType, const ItemInfo* item);
bool TestEnvironment(RoomEnvFlags environmentType, int roomNumber);
bool TestEnvironment(RoomEnvFlags environmentType, ROOM_INFO* room);
diff --git a/TombEngine/Game/control/box.cpp b/TombEngine/Game/control/box.cpp
index 820cd1406..14a718ded 100644
--- a/TombEngine/Game/control/box.cpp
+++ b/TombEngine/Game/control/box.cpp
@@ -2129,7 +2129,7 @@ void AdjustStopperFlag(ItemInfo* item, int direction)
x = item->Pose.Position.x + BLOCK(1) * phd_sin(direction);
z = item->Pose.Position.z + BLOCK(1) * phd_cos(direction);
- room = &g_Level.Rooms[GetCollision(x, item->Pose.Position.y, z, item->RoomNumber).RoomNumber];
+ room = &g_Level.Rooms[GetPointCollision(Vector3i(x, item->Pose.Position.y, z), item->RoomNumber).GetRoomNumber()];
floor = GetSector(room, x - room->x, z - room->z);
floor->Stopper = !floor->Stopper;
diff --git a/TombEngine/Game/control/trigger.cpp b/TombEngine/Game/control/trigger.cpp
index 7a9443d12..6f4aad9eb 100644
--- a/TombEngine/Game/control/trigger.cpp
+++ b/TombEngine/Game/control/trigger.cpp
@@ -314,12 +314,12 @@ void RefreshCamera(short type, short* data)
short* GetTriggerIndex(FloorInfo* floor, int x, int y, int z)
{
- auto bottomBlock = GetCollision(x, y, z, floor->RoomNumber).BottomBlock;
+ const auto& bottomSector = GetPointCollision(Vector3i(x, y, z), floor->RoomNumber).GetBottomSector();
- if (bottomBlock->TriggerIndex == -1)
+ if (bottomSector.TriggerIndex == -1)
return nullptr;
- return &g_Level.FloorData[bottomBlock->TriggerIndex];
+ return &g_Level.FloorData[bottomSector.TriggerIndex];
}
short* GetTriggerIndex(ItemInfo* item)
diff --git a/TombEngine/Game/effects/drip.cpp b/TombEngine/Game/effects/drip.cpp
index 01609b5f0..ad6ee12e2 100644
--- a/TombEngine/Game/effects/drip.cpp
+++ b/TombEngine/Game/effects/drip.cpp
@@ -3,6 +3,7 @@
#include "Game/collision/collide_room.h"
#include "Game/collision/floordata.h"
+#include "Game/collision/PointCollision.h"
#include "Game/effects/effects.h"
#include "Game/effects/Ripple.h"
#include "Game/effects/weather.h"
@@ -12,6 +13,7 @@
#include "Specific/clock.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Effects::Environment;
using namespace TEN::Effects::Ripple;
using namespace TEN::Collision::Floordata;
@@ -111,11 +113,11 @@ namespace TEN::Effects::Drip
drip.Velocity += Weather.Wind();
int prevRoomNumber = drip.RoomNumber;
- auto pointColl = GetCollision(drip.Position.x, drip.Position.y, drip.Position.z, drip.RoomNumber);
+ auto pointColl = GetPointCollision(drip.Position, drip.RoomNumber);
// Update position.
drip.Position += drip.Velocity;
- drip.RoomNumber = pointColl.RoomNumber;
+ drip.RoomNumber = pointColl.GetRoomNumber();
// Update size and color.
float alpha = 1.0f - (drip.Life / drip.LifeMax);
@@ -131,7 +133,7 @@ namespace TEN::Effects::Drip
float waterHeight = GetWaterHeight(drip.Position.x, drip.Position.y, drip.Position.z, drip.RoomNumber);
SpawnRipple(
Vector3(drip.Position.x, waterHeight - RIPPLE_HEIGHT_OFFSET, drip.Position.z),
- pointColl.RoomNumber,
+ pointColl.GetRoomNumber(),
Random::GenerateFloat(RIPPLE_SIZE_WATER_MIN, RIPPLE_SIZE_WATER_MAX),
(int)RippleFlags::SlowFade | (int)RippleFlags::LowOpacity);
}
@@ -140,20 +142,20 @@ namespace TEN::Effects::Drip
continue;
}
// Hit floor; spawn ripple.
- else if (drip.Position.y >= pointColl.Position.Floor)
+ else if (drip.Position.y >= pointColl.GetFloorHeight())
{
SpawnRipple(
- Vector3(drip.Position.x, pointColl.Position.Floor - RIPPLE_HEIGHT_OFFSET, drip.Position.z),
- pointColl.RoomNumber,
+ Vector3(drip.Position.x, pointColl.GetFloorHeight() - RIPPLE_HEIGHT_OFFSET, drip.Position.z),
+ pointColl.GetRoomNumber(),
Random::GenerateFloat(RIPPLE_SIZE_GROUND_MIN, RIPPLE_SIZE_GROUND_MAX),
(int)RippleFlags::SlowFade | (int)RippleFlags::LowOpacity | (int)RippleFlags::OnGround,
- pointColl.FloorNormal);
+ pointColl.GetFloorNormal());
drip.Life = 0.0f;
continue;
}
// Hit ceiling; deactivate.
- else if (drip.Position.y <= pointColl.Position.Ceiling)
+ else if (drip.Position.y <= pointColl.GetCeilingHeight())
{
drip.Life = 0.0f;
continue;
diff --git a/TombEngine/Game/effects/effects.cpp b/TombEngine/Game/effects/effects.cpp
index 9913a9486..1cd9b2eb7 100644
--- a/TombEngine/Game/effects/effects.cpp
+++ b/TombEngine/Game/effects/effects.cpp
@@ -4,6 +4,7 @@
#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/effects/Blood.h"
#include "Game/effects/Bubble.h"
#include "Game/effects/Drip.h"
@@ -25,6 +26,7 @@
#include "Specific/clock.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Effects::Blood;
using namespace TEN::Effects::Bubble;
using namespace TEN::Effects::Drip;
@@ -1073,11 +1075,15 @@ void UpdateSplashes()
short DoBloodSplat(int x, int y, int z, short speed, short direction, short roomNumber)
{
- short probedRoomNumber = GetCollision(x, y, z, roomNumber).RoomNumber;
+ short probedRoomNumber = GetPointCollision(Vector3i(x, y, z), roomNumber).GetRoomNumber();
if (TestEnvironment(ENV_FLAG_WATER, probedRoomNumber))
+ {
SpawnUnderwaterBlood(Vector3(x, y, z), probedRoomNumber, speed);
+ }
else
+ {
TriggerBlood(x, y, z, direction >> 4, speed);
+ }
return 0;
}
diff --git a/TombEngine/Game/effects/footprint.cpp b/TombEngine/Game/effects/footprint.cpp
index cb0bd1717..d990792d9 100644
--- a/TombEngine/Game/effects/footprint.cpp
+++ b/TombEngine/Game/effects/footprint.cpp
@@ -4,6 +4,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
#include "Game/collision/floordata.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/control.h"
#include "Game/effects/effects.h"
#include "Game/items.h"
@@ -16,6 +17,7 @@
#include "Specific/level.h"
using namespace TEN::Collision::Floordata;
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Math;
namespace TEN::Effects::Footprint
@@ -100,7 +102,7 @@ namespace TEN::Effects::Footprint
constexpr auto FOOT_OFFSET = Vector3i(0, HEIGHT_OFFSET, 0);
auto footPos = GetJointPosition(item, jointIndex, FOOT_OFFSET);
- int floorHeight = GetCollision(footPos.x, footPos.y - CLICK(1), footPos.z, item.RoomNumber).Position.Floor;
+ int floorHeight = GetPointCollision(footPos, item.RoomNumber, -Vector3::UnitY, CLICK(1)).GetFloorHeight();
bool canSpawn = (abs(footPos.y - floorHeight) < ABS_FLOOR_BOUND);
auto pos = Vector3(footPos.x, floorHeight - SURFACE_OFFSET, footPos.z);
@@ -112,16 +114,16 @@ namespace TEN::Effects::Footprint
constexpr auto ABS_FLOOR_BOUND = CLICK(0.5f);
// Get point collision at every vertex point.
- auto pointColl0 = GetCollision(vertexPoints[0].x, pos.y - CLICK(1), vertexPoints[0].z, item.RoomNumber);
- auto pointColl1 = GetCollision(vertexPoints[1].x, pos.y - CLICK(1), vertexPoints[1].z, item.RoomNumber);
- auto pointColl2 = GetCollision(vertexPoints[2].x, pos.y - CLICK(1), vertexPoints[2].z, item.RoomNumber);
- auto pointColl3 = GetCollision(vertexPoints[3].x, pos.y - CLICK(1), vertexPoints[3].z, item.RoomNumber);
+ auto pointColl0 = GetPointCollision(Vector3i(vertexPoints[0].x, pos.y - CLICK(1), vertexPoints[0].z), item.RoomNumber);
+ auto pointColl1 = GetPointCollision(Vector3i(vertexPoints[1].x, pos.y - CLICK(1), vertexPoints[1].z), item.RoomNumber);
+ auto pointColl2 = GetPointCollision(Vector3i(vertexPoints[2].x, pos.y - CLICK(1), vertexPoints[2].z), item.RoomNumber);
+ auto pointColl3 = GetPointCollision(Vector3i(vertexPoints[3].x, pos.y - CLICK(1), vertexPoints[3].z), item.RoomNumber);
// Don't spawn footprint if floor heights at vertex points are outside upper/lower floor height bound.
- if ((abs(pointColl0.Position.Floor - pointColl1.Position.Floor) > ABS_FLOOR_BOUND) ||
- (abs(pointColl1.Position.Floor - pointColl2.Position.Floor) > ABS_FLOOR_BOUND) ||
- (abs(pointColl2.Position.Floor - pointColl3.Position.Floor) > ABS_FLOOR_BOUND) ||
- (abs(pointColl3.Position.Floor - pointColl0.Position.Floor) > ABS_FLOOR_BOUND))
+ if ((abs(pointColl0.GetFloorHeight() - pointColl1.GetFloorHeight()) > ABS_FLOOR_BOUND) ||
+ (abs(pointColl1.GetFloorHeight() - pointColl2.GetFloorHeight()) > ABS_FLOOR_BOUND) ||
+ (abs(pointColl2.GetFloorHeight() - pointColl3.GetFloorHeight()) > ABS_FLOOR_BOUND) ||
+ (abs(pointColl3.GetFloorHeight() - pointColl0.GetFloorHeight()) > ABS_FLOOR_BOUND))
{
return false;
}
@@ -163,15 +165,15 @@ namespace TEN::Effects::Footprint
// Slightly randomize 2D position.
posData.Position += Vector3(Random::GenerateFloat(-5.0f, 5.0f), 0.0f, Random::GenerateFloat(-5.0f, 5.0f));
- auto pointColl = GetCollision(posData.Position.x, posData.Position.y - CLICK(1), posData.Position.z, item.RoomNumber);
+ auto pointColl = GetPointCollision(posData.Position, item.RoomNumber, -Vector3::UnitY, CLICK(1));
// Don't process material if foot hit bridge object.
// TODO: Handle bridges once bridge collision is less stupid.
- if (pointColl.Position.Bridge >= 0)
+ if (pointColl.GetFloorBridgeItemNumber() >= 0)
return;
// Get and emit footstep sound for floor material.
- auto sfx = GetFootprintSfx(pointColl.BottomBlock->GetSurfaceMaterial(pointColl.Coordinates.x, pointColl.Coordinates.z, true));
+ auto sfx = GetFootprintSfx(pointColl.GetBottomSector().GetSurfaceMaterial(pointColl.GetPosition().x, pointColl.GetPosition().z, true));
if (sfx != SOUND_EFFECTS::SFX_TR4_LARA_FOOTSTEPS) // HACK: Must be here until reference WAD2 is revised.
{
auto pose = item.Pose;
@@ -179,10 +181,10 @@ namespace TEN::Effects::Footprint
}
// Check floor material.
- if (!TestMaterial(pointColl.BottomBlock->GetSurfaceMaterial(pointColl.Coordinates.x, pointColl.Coordinates.z, true), FootprintMaterials))
+ if (!TestMaterial(pointColl.GetBottomSector().GetSurfaceMaterial(pointColl.GetPosition().x, pointColl.GetPosition().z, true), FootprintMaterials))
return;
- auto vertexPoints = GetFootprintVertexPoints(item, posData.Position, pointColl.FloorNormal);
+ auto vertexPoints = GetFootprintVertexPoints(item, posData.Position, pointColl.GetFloorNormal());
// Test floor continuity.
if (!TestFootprintFloor(item, posData.Position, vertexPoints))
diff --git a/TombEngine/Game/effects/hair.cpp b/TombEngine/Game/effects/hair.cpp
index 4a27ba83a..cb9a0514f 100644
--- a/TombEngine/Game/effects/hair.cpp
+++ b/TombEngine/Game/effects/hair.cpp
@@ -3,6 +3,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/collision/sphere.h"
#include "Game/control/control.h"
#include "Game/effects/weather.h"
@@ -14,6 +15,7 @@
#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Effects::Environment;
using TEN::Renderer::g_Renderer;
@@ -253,8 +255,8 @@ namespace TEN::Effects::Hair
{
constexpr auto VELOCITY_COEFF = 0.75f;
- auto pointColl = GetCollision(segment.Position.x, segment.Position.y, segment.Position.z, roomNumber);
- int floorHeight = pointColl.Position.Floor;
+ auto pointColl = GetPointCollision(segment.Position, roomNumber);
+ int floorHeight = pointColl.GetFloorHeight();
Segments[0].Velocity = segment.Position;
segment.Position += segment.Velocity * VELOCITY_COEFF;
@@ -263,7 +265,7 @@ namespace TEN::Effects::Hair
if (isOnLand)
{
// Let wind affect position.
- if (TestEnvironment(ENV_FLAG_WIND, pointColl.RoomNumber))
+ if (TestEnvironment(ENV_FLAG_WIND, pointColl.GetRoomNumber()))
segment.Position += Weather.Wind() * 2;
// Apply gravity.
diff --git a/TombEngine/Game/effects/item_fx.cpp b/TombEngine/Game/effects/item_fx.cpp
index b3a203a0c..09a127024 100644
--- a/TombEngine/Game/effects/item_fx.cpp
+++ b/TombEngine/Game/effects/item_fx.cpp
@@ -3,6 +3,7 @@
#include "Game/collision/collide_room.h"
#include "Game/collision/floordata.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/control.h"
#include "Game/effects/effects.h"
#include "Game/effects/smoke.h"
@@ -13,6 +14,7 @@
#include "Specific/clock.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Effects::Smoke;
namespace TEN::Effects::Items
@@ -70,7 +72,7 @@ namespace TEN::Effects::Items
if (item->HitPoints < 0)
return;
- auto height = GetCollision(item->Pose.Position.x, 32000, item->Pose.Position.z, item->RoomNumber).Position.Floor;
+ auto height = GetPointCollision(Vector3i(item->Pose.Position.x, 32000, item->Pose.Position.z), item->RoomNumber).GetFloorHeight();
if (item->Floor == height)
{
item->HitPoints = -1;
diff --git a/TombEngine/Game/effects/weather.cpp b/TombEngine/Game/effects/weather.cpp
index 443968e6e..3536fa663 100644
--- a/TombEngine/Game/effects/weather.cpp
+++ b/TombEngine/Game/effects/weather.cpp
@@ -3,6 +3,7 @@
#include "Game/camera.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/effects/effects.h"
#include "Game/effects/Ripple.h"
#include "Game/effects/tomb4fx.h"
@@ -13,6 +14,7 @@
#include "Specific/level.h"
#include "Scripting/Include/ScriptInterfaceLevel.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Effects::Ripple;
using namespace TEN::Math::Random;
@@ -278,19 +280,19 @@ namespace TEN::Effects::Environment
if (p.Type == WeatherType::None)
continue;
- CollisionResult coll;
+ auto pointColl = GetPointCollision(p.Position, p.Room);
bool collisionCalculated = false;
if (p.CollisionCheckDelay <= 0)
{
- coll = GetCollision(p.Position.x, p.Position.y, p.Position.z, p.Room);
+ pointColl = GetPointCollision(p.Position, p.Room);
// Determine collision checking frequency based on nearest floor/ceiling surface position.
// If floor and ceiling is too far, don't do precise collision checks, instead doing it
// every 5th frame. If particle approaches floor or ceiling, make checks more frequent.
// This allows to avoid unnecessary thousands of calls to GetCollisionResult for every particle.
- auto coeff = std::min(std::max(0.0f, (coll.Position.Floor - p.Position.y)), std::max(0.0f, (p.Position.y - coll.Position.Ceiling)));
+ auto coeff = std::min(std::max(0.0f, (pointColl.GetFloorHeight() - p.Position.y)), std::max(0.0f, (p.Position.y - pointColl.GetCeilingHeight())));
p.CollisionCheckDelay = std::min(floor(coeff / std::max(std::numeric_limits::denorm_min(), p.Velocity.y)), WEATHER_PARTICLES_MAX_COLL_CHECK_DELAY);
collisionCalculated = true;
}
@@ -305,17 +307,19 @@ namespace TEN::Effects::Environment
{
if (!collisionCalculated)
{
- coll = GetCollision(p.Position.x, p.Position.y, p.Position.z, p.Room);
+ pointColl = GetPointCollision(p.Position, p.Room);
collisionCalculated = true;
}
- if (coll.RoomNumber == p.Room)
+ if (pointColl.GetRoomNumber() == p.Room)
{
p.Enabled = false; // Not landed on door, so out of room bounds - delete
continue;
}
else
- p.Room = coll.RoomNumber;
+ {
+ p.Room = pointColl.GetRoomNumber();
+ }
}
// If collision was updated, process with position checks.
@@ -325,8 +329,8 @@ namespace TEN::Effects::Environment
// If particle is inside water or swamp, count it as "inSubstance".
// If particle got below floor or above ceiling, count it as "landed".
- bool inSubstance = g_Level.Rooms[coll.RoomNumber].flags & (ENV_FLAG_WATER | ENV_FLAG_SWAMP);
- bool landed = (coll.Position.Floor <= p.Position.y) || (coll.Position.Ceiling >= p.Position.y);
+ bool inSubstance = g_Level.Rooms[pointColl.GetRoomNumber()].flags & (ENV_FLAG_WATER | ENV_FLAG_SWAMP);
+ bool landed = (pointColl.GetFloorHeight() <= p.Position.y) || (pointColl.GetCeilingHeight() >= p.Position.y);
if (inSubstance || landed)
{
@@ -478,9 +482,9 @@ namespace TEN::Effects::Environment
if (g_Level.Rooms[outsideRoom].flags & (ENV_FLAG_WATER | ENV_FLAG_SWAMP))
continue;
- auto coll = GetCollision(xPos, yPos, zPos, outsideRoom);
+ auto pointColl = GetPointCollision(Vector3i(xPos, yPos, zPos), outsideRoom);
- if (!(coll.Position.Ceiling < yPos || coll.Block->GetNextRoomNumber(Vector3i(xPos, yPos, zPos), false).has_value()))
+ if (!(pointColl.GetCeilingHeight() < yPos || pointColl.GetSector().GetNextRoomNumber(Vector3i(xPos, yPos, zPos), false).has_value()))
continue;
auto part = WeatherParticle();
diff --git a/TombEngine/Game/items.cpp b/TombEngine/Game/items.cpp
index 69403000a..c4d6973d2 100644
--- a/TombEngine/Game/items.cpp
+++ b/TombEngine/Game/items.cpp
@@ -3,6 +3,7 @@
#include "Game/collision/floordata.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/control.h"
#include "Game/control/volume.h"
#include "Game/effects/effects.h"
@@ -26,6 +27,7 @@
#include "Specific/trutils.h"
using namespace TEN::Collision::Floordata;
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Collision::Room;
using namespace TEN::Control::Volumes;
using namespace TEN::Effects::Items;
@@ -803,10 +805,9 @@ bool UpdateItemRoom(short itemNumber)
{
auto* item = &g_Level.Items[itemNumber];
- auto roomNumber = GetCollision(item->Pose.Position.x,
- item->Pose.Position.y - CLICK(2),
- item->Pose.Position.z,
- item->RoomNumber).RoomNumber;
+ auto roomNumber = GetPointCollision(
+ Vector3i(item->Pose.Position.x, item->Pose.Position.y - CLICK(2), item->Pose.Position.z),
+ item->RoomNumber).GetRoomNumber();
if (roomNumber != item->RoomNumber)
{
diff --git a/TombEngine/Game/missile.cpp b/TombEngine/Game/missile.cpp
index b1449629b..d8891afa0 100644
--- a/TombEngine/Game/missile.cpp
+++ b/TombEngine/Game/missile.cpp
@@ -60,12 +60,12 @@ void ControlMissile(short fxNumber)
fx.pos.Translate(fx.pos.Orientation, fx.speed);
- auto pointColl = GetCollision(fx.pos.Position.x, fx.pos.Position.y, fx.pos.Position.z, fx.roomNumber);
+ auto pointColl = GetPointCollision(fx.pos.Position, fx.roomNumber);
auto hasHitPlayer = ItemNearLara(fx.pos.Position, hitRadius);
// Check whether something was hit.
- if (fx.pos.Position.y >= pointColl.Position.Floor ||
- fx.pos.Position.y <= pointColl.Position.Ceiling ||
+ if (fx.pos.Position.y >= pointColl.GetFloorHeight() ||
+ fx.pos.Position.y <= pointColl.GetCeilingHeight() ||
hasHitPlayer)
{
if (fx.objectNumber == ID_KNIFETHROWER_KNIFE ||
@@ -113,8 +113,8 @@ void ControlMissile(short fxNumber)
KillEffect(fxNumber);
}
- if (pointColl.RoomNumber != fx.roomNumber)
- EffectNewRoom(fxNumber, pointColl.RoomNumber);
+ if (pointColl.GetRoomNumber() != fx.roomNumber)
+ EffectNewRoom(fxNumber, pointColl.GetRoomNumber());
if (fx.objectNumber == ID_KNIFETHROWER_KNIFE)
fx.pos.Orientation.z += ANGLE(30.0f); // Update knife rotation over time.
diff --git a/TombEngine/Game/pickup/pickup.cpp b/TombEngine/Game/pickup/pickup.cpp
index 2207a8c7e..d48d8a746 100644
--- a/TombEngine/Game/pickup/pickup.cpp
+++ b/TombEngine/Game/pickup/pickup.cpp
@@ -5,6 +5,7 @@
#include "Game/animation.h"
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
+#include "Game/collision/PointCollision.h"
#include "Game/effects/debris.h"
#include "Game/Gui.h"
#include "Game/Hud/Hud.h"
@@ -30,6 +31,7 @@
#include "Specific/level.h"
#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Entities::Generic;
using namespace TEN::Hud;
using namespace TEN::Input;
@@ -849,7 +851,7 @@ void DropPickups(ItemInfo* item)
// Also collect objects which are around.
bool collidedWithObjects = GetCollidedObjects(item, extents.Length(), true, CollidedItems, CollidedMeshes, true);
- short startAngle = ANGLE(Random::GenerateInt(0, 3) * 90); // Randomize start corner.
+ short startAngle = ANGLE(Random::GenerateInt(0, 3) * 90.0f); // Randomize start corner.
// Iterate through 4 corners and find best-fitting position, which is not inside a wall, not on a slope
// and also does not significantly differ in height to an object centerpoint height.
@@ -858,31 +860,31 @@ void DropPickups(ItemInfo* item)
for (int corner = 0; corner < 4; corner++)
{
auto angle = item->Pose.Orientation;
- angle.y += startAngle + corner * ANGLE(90);
+ angle.y += startAngle + corner * ANGLE(90.0f);
// At first, do an inside-wall test at an extended extent point to make sure player can correctly align.
auto candidatePos = Geometry::TranslatePoint(origin, angle, extents * 1.2f);
candidatePos.y = yPos;
- auto collPoint = GetCollision(candidatePos.x, candidatePos.y, candidatePos.z, item->RoomNumber);
+ auto collPoint = GetPointCollision(candidatePos, item->RoomNumber);
// If position is inside a wall or on a slope, don't use it.
- if (collPoint.Position.Floor == NO_HEIGHT || collPoint.Position.FloorSlope)
+ if (collPoint.GetFloorHeight() == NO_HEIGHT || collPoint.IsIllegalFloor())
continue;
// Remember floor position for a tested point.
- int candidateYPos = collPoint.Position.Floor;
+ int candidateYPos = collPoint.GetFloorHeight();
// Now repeat the same test for original extent point to make sure it's also valid.
candidatePos = Geometry::TranslatePoint(origin, angle, extents);
candidatePos.y = yPos;
- collPoint = GetCollision(candidatePos.x, candidatePos.y, candidatePos.z, item->RoomNumber);
+ collPoint = GetPointCollision(candidatePos, item->RoomNumber);
// If position is inside a wall or on a slope, don't use it.
- if (collPoint.Position.Floor == NO_HEIGHT || collPoint.Position.FloorSlope)
+ if (collPoint.GetFloorHeight() == NO_HEIGHT || collPoint.IsIllegalFloor())
continue;
// If position is not in the same room, don't use it.
- if (collPoint.RoomNumber != item->RoomNumber)
+ if (collPoint.GetRoomNumber() != item->RoomNumber)
continue;
// Setup a dummy sphere with 1-click diameter for item and static mesh collision tests.
@@ -923,16 +925,16 @@ void DropPickups(ItemInfo* item)
// Finally, do height difference tests. If difference is more than one and a half click,
// most likely it's hanging in the air or submerged, so bypass the corner.
- if (abs(collPoint.Position.Floor - yPos) > CLICK(1.5f))
+ if (abs(collPoint.GetFloorHeight() - yPos) > CLICK(1.5f))
continue;
// If height difference between extent points is more than one click, it means it landed
// on a step, so let's search for other position.
- if (abs(collPoint.Position.Floor - candidateYPos) >= CLICK(1.0f))
+ if (abs(collPoint.GetFloorHeight() - candidateYPos) >= CLICK(1.0f))
continue;
origin = candidatePos;
- origin.y = collPoint.Position.Floor;
+ origin.y = collPoint.GetFloorHeight();
break;
}
diff --git a/TombEngine/Game/room.cpp b/TombEngine/Game/room.cpp
index 4f374bb1d..85da187fc 100644
--- a/TombEngine/Game/room.cpp
+++ b/TombEngine/Game/room.cpp
@@ -2,6 +2,7 @@
#include "Game/room.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/control.h"
#include "Game/control/lot.h"
#include "Game/control/volume.h"
@@ -13,6 +14,7 @@
using namespace TEN::Math;
using namespace TEN::Collision::Floordata;
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Renderer;
using namespace TEN::Utils;
@@ -154,18 +156,18 @@ int IsRoomOutside(int x, int y, int z)
(y > room.maxceiling && y < room.minfloor) &&
(z > (room.z + BLOCK(1)) && z < (room.z + (room.zSize - 1) * BLOCK(1))))
{
- auto pointColl = GetCollision(x, y, z, roomNumber);
+ auto pointColl = GetPointCollision(Vector3i(x, y, z), roomNumber);
- if (pointColl.Position.Floor == NO_HEIGHT || y > pointColl.Position.Floor)
+ if (pointColl.GetFloorHeight() == NO_HEIGHT || y > pointColl.GetFloorHeight())
return NO_ROOM;
- if (y < pointColl.Position.Ceiling)
+ if (y < pointColl.GetCeilingHeight())
return NO_ROOM;
if (TestEnvironmentFlags(ENV_FLAG_WATER, room.flags) ||
TestEnvironmentFlags(ENV_FLAG_WIND, room.flags))
{
- return pointColl.RoomNumber;
+ return pointColl.GetRoomNumber();
}
return NO_ROOM;
diff --git a/TombEngine/Objects/Effects/enemy_missile.cpp b/TombEngine/Objects/Effects/enemy_missile.cpp
index 0d4c47484..f11fdeddf 100644
--- a/TombEngine/Objects/Effects/enemy_missile.cpp
+++ b/TombEngine/Objects/Effects/enemy_missile.cpp
@@ -3,6 +3,7 @@
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/control.h"
#include "Game/effects/debris.h"
#include "Game/effects/effects.h"
@@ -17,6 +18,7 @@
#include "Renderer/RendererEnums.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Effects::Items;
using namespace TEN::Entities::Creatures::TR3;
using namespace TEN::Entities::TR4;
@@ -221,9 +223,9 @@ namespace TEN::Entities::Effects
fx.pos.Position.y += -((fx.speed * phd_sin(fx.pos.Orientation.x))) + fx.fallspeed;
fx.pos.Position.z += speed * phd_cos(fx.pos.Orientation.y);
- auto pointColl = GetCollision(fx.pos.Position.x, fx.pos.Position.y, fx.pos.Position.z, fx.roomNumber);
+ auto pointColl = GetPointCollision(fx.pos.Position, fx.roomNumber);
- if (fx.pos.Position.y >= pointColl.Position.Floor || fx.pos.Position.y <= pointColl.Position.Ceiling)
+ if (fx.pos.Position.y >= pointColl.GetFloorHeight() || fx.pos.Position.y <= pointColl.GetCeilingHeight())
{
fx.pos.Position = prevPos;
@@ -361,8 +363,8 @@ namespace TEN::Entities::Effects
}
else
{
- if (pointColl.RoomNumber != fx.roomNumber)
- EffectNewRoom(fxNumber, pointColl.RoomNumber);
+ if (pointColl.GetRoomNumber() != fx.roomNumber)
+ EffectNewRoom(fxNumber, pointColl.GetRoomNumber());
auto deltaPos = prevPos - fx.pos.Position;
diff --git a/TombEngine/Objects/Effects/tr5_electricity.cpp b/TombEngine/Objects/Effects/tr5_electricity.cpp
index 7068c36d7..973a41402 100644
--- a/TombEngine/Objects/Effects/tr5_electricity.cpp
+++ b/TombEngine/Objects/Effects/tr5_electricity.cpp
@@ -4,6 +4,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/collision/sphere.h"
#include "Game/control/control.h"
#include "Game/effects/effects.h"
@@ -17,6 +18,7 @@
#include "Specific/clock.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Effects::Items;
using namespace TEN::Effects::Ripple;
@@ -220,10 +222,9 @@ void ElectricityWiresControl(short itemNumber)
for (int j = 0; j < collObj->nmeshes; j++)
{
auto collPos = GetJointPosition(collItem, j);
+ auto pointCollJointRoom = GetPointCollision(collPos, collItem->RoomNumber).GetRoomNumber();
- auto collJointRoom = GetCollision(collPos.x, collPos.y, collPos.z, collItem->RoomNumber).RoomNumber;
-
- if (!isWaterNearby && isTouchingWater && roomNumber == collJointRoom)
+ if (!isWaterNearby && isTouchingWater && roomNumber == pointCollJointRoom)
isWaterNearby = true;
}
diff --git a/TombEngine/Objects/TR1/Entity/tr1_doppelganger.cpp b/TombEngine/Objects/TR1/Entity/tr1_doppelganger.cpp
index 26cffbd02..5eb580d48 100644
--- a/TombEngine/Objects/TR1/Entity/tr1_doppelganger.cpp
+++ b/TombEngine/Objects/TR1/Entity/tr1_doppelganger.cpp
@@ -3,6 +3,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/control.h"
#include "Game/control/lot.h"
#include "Game/items.h"
@@ -11,6 +12,8 @@
#include "Game/misc.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
+
namespace TEN::Entities::Creatures::TR1
{
ItemInfo* FindDoppelgangerReference(const ItemInfo& item, int objectNumber)
@@ -60,7 +63,7 @@ namespace TEN::Entities::Creatures::TR1
(referencePtr->Pose.Position.x * 2) - LaraItem->Pose.Position.x,
LaraItem->Pose.Position.y,
(referencePtr->Pose.Position.z * 2) - LaraItem->Pose.Position.z);
- item.Floor = GetCollision(pos.x, pos.y, pos.z, item.RoomNumber).Position.Floor;
+ item.Floor = GetPointCollision(pos, item.RoomNumber).GetFloorHeight();
// Animate doppelganger, mirroring player's position.
item.Animation.AnimNumber = LaraItem->Animation.AnimNumber;
diff --git a/TombEngine/Objects/TR2/Entity/Dragon.cpp b/TombEngine/Objects/TR2/Entity/Dragon.cpp
index da70668e5..9e7c233e2 100644
--- a/TombEngine/Objects/TR2/Entity/Dragon.cpp
+++ b/TombEngine/Objects/TR2/Entity/Dragon.cpp
@@ -3,6 +3,7 @@
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
+#include "Game/collision/PointCollision.h"
#include "Game/collision/sphere.h"
#include "Game/control/lot.h"
#include "Game/effects/effects.h"
@@ -16,6 +17,7 @@
#include "Specific/clock.h"
#include "Specific/Input/Input.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Input;
using namespace TEN::Math;
@@ -333,15 +335,15 @@ namespace TEN::Entities::Creatures::TR2
{
if (GetFrameNumber(item) == GetFrameCount(item.Animation.AnimNumber))
{
- auto pointColl = GetCollision(pos, item.RoomNumber);
+ auto pointColl = GetPointCollision(pos, item.RoomNumber);
- if (pointColl.Position.Floor == NO_HEIGHT)
+ if (pointColl.GetFloorHeight() == NO_HEIGHT)
{
pos.y -= CLICK(0.5f);
}
else
{
- pos.y = pointColl.Position.Floor - CLICK(0.5f);
+ pos.y = pointColl.GetFloorHeight() - CLICK(0.5f);
}
auto pose = Pose(pos, EulerAngles::Identity);
diff --git a/TombEngine/Objects/TR2/Trap/tr2_spinningblade.cpp b/TombEngine/Objects/TR2/Trap/tr2_spinningblade.cpp
index 9c16dfea7..adb472b24 100644
--- a/TombEngine/Objects/TR2/Trap/tr2_spinningblade.cpp
+++ b/TombEngine/Objects/TR2/Trap/tr2_spinningblade.cpp
@@ -3,6 +3,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/control.h"
#include "Game/effects/effects.h"
#include "Game/items.h"
@@ -11,6 +12,8 @@
#include "Sound/sound.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
+
void InitializeSpinningBlade(short itemNumber)
{
auto* item = &g_Level.Items[itemNumber];
@@ -30,7 +33,7 @@ void SpinningBladeControl(short itemNumber)
int x = item->Pose.Position.x + BLOCK(3) * phd_sin(item->Pose.Orientation.y) / 2;
int z = item->Pose.Position.z + BLOCK(3) * phd_cos(item->Pose.Orientation.y) / 2;
- int floorHeight = GetCollision(x, item->Pose.Position.y, z, item->RoomNumber).Position.Floor;
+ int floorHeight = GetPointCollision(Vector3i(x, item->Pose.Position.y, z), item->RoomNumber).GetFloorHeight();
if (floorHeight == NO_HEIGHT)
item->Animation.TargetState = 1;
}
diff --git a/TombEngine/Objects/TR2/Vehicles/skidoo.cpp b/TombEngine/Objects/TR2/Vehicles/skidoo.cpp
index b8e5dea9f..795170420 100644
--- a/TombEngine/Objects/TR2/Vehicles/skidoo.cpp
+++ b/TombEngine/Objects/TR2/Vehicles/skidoo.cpp
@@ -4,6 +4,7 @@
#include "Game/animation.h"
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
+#include "Game/collision/PointCollision.h"
#include "Game/collision/sphere.h"
#include "Game/effects/effects.h"
#include "Game/effects/simple_particle.h"
@@ -21,6 +22,7 @@
#include "Math/Math.h"
#include "Sound/sound.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Input;
using namespace TEN::Math;
@@ -773,8 +775,8 @@ namespace TEN::Entities::Vehicles
x = 0;
z = 0;
- auto probe = GetCollision(old->x, pos->y, pos->z, skidooItem->RoomNumber);
- if (probe.Position.Floor < (old->y - CLICK(1)))
+ auto probe = GetPointCollision(Vector3i(old->x, pos->y, pos->z), skidooItem->RoomNumber);
+ if (probe.GetFloorHeight() < (old->y - CLICK(1)))
{
if (pos->z > old->z)
z = -shiftZ - 1;
@@ -782,8 +784,8 @@ namespace TEN::Entities::Vehicles
z = BLOCK(1) - shiftZ;
}
- probe = GetCollision(pos->x, pos->y, old->z, skidooItem->RoomNumber);
- if (probe.Position.Floor < (old->y - CLICK(1)))
+ probe = GetPointCollision(Vector3i(pos->x, pos->y, old->z), skidooItem->RoomNumber);
+ if (probe.GetFloorHeight() < (old->y - CLICK(1)))
{
if (pos->x > old->x)
x = -shiftX - 1;
diff --git a/TombEngine/Objects/TR2/Vehicles/speedboat.cpp b/TombEngine/Objects/TR2/Vehicles/speedboat.cpp
index 30e424ef3..5d90ae406 100644
--- a/TombEngine/Objects/TR2/Vehicles/speedboat.cpp
+++ b/TombEngine/Objects/TR2/Vehicles/speedboat.cpp
@@ -4,6 +4,7 @@
#include "Game/animation.h"
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
+#include "Game/collision/PointCollision.h"
#include "Game/collision/sphere.h"
#include "Game/effects/effects.h"
#include "Game/effects/simple_particle.h"
@@ -17,6 +18,7 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Input;
namespace TEN::Entities::Vehicles
@@ -237,19 +239,19 @@ namespace TEN::Entities::Vehicles
int x = speedboatItem->Pose.Position.x + SPEEDBOAT_DISMOUNT_DISTANCE * phd_sin(angle);
int y = speedboatItem->Pose.Position.y;
int z = speedboatItem->Pose.Position.z + SPEEDBOAT_DISMOUNT_DISTANCE * phd_cos(angle);
- auto probe = GetCollision(x, y, z, speedboatItem->RoomNumber);
+ auto probe = GetPointCollision(Vector3i(x, y, z), speedboatItem->RoomNumber);
- if ((probe.Position.Floor - speedboatItem->Pose.Position.y) < -CLICK(2))
+ if ((probe.GetFloorHeight() - speedboatItem->Pose.Position.y) < -CLICK(2))
return false;
- if (probe.Position.FloorSlope ||
- probe.Position.Floor == NO_HEIGHT)
+ if (probe.IsIllegalFloor() ||
+ probe.GetFloorHeight() == NO_HEIGHT)
{
return false;
}
- if ((probe.Position.Floor - probe.Position.Ceiling) < LARA_HEIGHT ||
- (probe.Position.Ceiling - speedboatItem->Pose.Position.y) > -LARA_HEIGHT)
+ if ((probe.GetFloorHeight() - probe.GetCeilingHeight()) < LARA_HEIGHT ||
+ (probe.GetCeilingHeight() - speedboatItem->Pose.Position.y) > -LARA_HEIGHT)
{
return false;
}
@@ -281,15 +283,15 @@ namespace TEN::Entities::Vehicles
int x = laraItem->Pose.Position.x + 360 * phd_sin(laraItem->Pose.Orientation.y);
int y = laraItem->Pose.Position.y - 90;
int z = laraItem->Pose.Position.z + 360 * phd_cos(laraItem->Pose.Orientation.y);
- auto probe = GetCollision(x, y, z, laraItem->RoomNumber);
+ auto probe = GetPointCollision(Vector3i(x, y, z), laraItem->RoomNumber);
- if (probe.Position.Floor >= (y - CLICK(1)))
+ if (probe.GetFloorHeight() >= (y - CLICK(1)))
{
laraItem->Pose.Position.x = x;
laraItem->Pose.Position.z = z;
- if (probe.RoomNumber != laraItem->RoomNumber)
- ItemNewRoom(laraItem->Index, probe.RoomNumber);
+ if (probe.GetRoomNumber() != laraItem->RoomNumber)
+ ItemNewRoom(laraItem->Index, probe.GetRoomNumber());
}
laraItem->Pose.Position.y = y;
@@ -373,8 +375,8 @@ namespace TEN::Entities::Vehicles
x = 0;
z = 0;
- auto probe = GetCollision(old->x, pos->y, pos->z, speedboatItem->RoomNumber);
- if (probe.Position.Floor < (old->y - CLICK(1)))
+ auto probe = GetPointCollision(Vector3i(old->x, pos->y, pos->z), speedboatItem->RoomNumber);
+ if (probe.GetFloorHeight() < (old->y - CLICK(1)))
{
if (pos->z > old->z)
z = -shiftZ - 1;
@@ -382,8 +384,8 @@ namespace TEN::Entities::Vehicles
z = BLOCK(1) - shiftZ;
}
- probe = GetCollision(pos->x, pos->y, old->z, speedboatItem->RoomNumber);
- if (probe.Position.Floor < (old->y - CLICK(1)))
+ probe = GetPointCollision(Vector3i(pos->x, pos->y, old->z), speedboatItem->RoomNumber);
+ if (probe.GetFloorHeight() < (old->y - CLICK(1)))
{
if (pos->x > old->x)
x = -shiftX - 1;
@@ -815,7 +817,7 @@ namespace TEN::Entities::Vehicles
int heightFrontLeft = GetVehicleWaterHeight(speedboatItem, SPEEDBOAT_FRONT, -SPEEDBOAT_SIDE, true, &frontLeft);
int heightFrontRight = GetVehicleWaterHeight(speedboatItem, SPEEDBOAT_FRONT, SPEEDBOAT_SIDE, true, &frontRight);
- auto probe = GetCollision(speedboatItem);
+ auto probe = GetPointCollision(*speedboatItem);
if (lara->Context.Vehicle == itemNumber)
{
@@ -823,7 +825,7 @@ namespace TEN::Entities::Vehicles
TestTriggers(speedboatItem, false);
}
- auto water = GetWaterHeight(speedboatItem->Pose.Position.x, speedboatItem->Pose.Position.y, speedboatItem->Pose.Position.z, probe.RoomNumber);
+ auto water = GetWaterHeight(speedboatItem->Pose.Position.x, speedboatItem->Pose.Position.y, speedboatItem->Pose.Position.z, probe.GetRoomNumber());
speedboat->Water = water;
bool noTurn = true;
@@ -864,9 +866,9 @@ namespace TEN::Entities::Vehicles
speedboat->TurnRate = 0;
}
- speedboatItem->Floor = probe.Position.Floor - 5;
+ speedboatItem->Floor = probe.GetFloorHeight() - 5;
if (speedboat->Water == NO_HEIGHT)
- speedboat->Water = probe.Position.Floor;
+ speedboat->Water = probe.GetFloorHeight();
else
speedboat->Water -= 5;
@@ -878,14 +880,18 @@ namespace TEN::Entities::Vehicles
if (ofs - speedboatItem->Animation.Velocity.y > 32 && speedboatItem->Animation.Velocity.y == 0 && water != NO_HEIGHT)
SpeedboatSplash(speedboatItem, ofs - speedboatItem->Animation.Velocity.y, water);
- probe.Position.Floor = (frontLeft.y + frontRight.y);
- if (probe.Position.Floor < 0)
- probe.Position.Floor = -(abs(probe.Position.Floor) / 2);
+ int floorHeight = (frontLeft.y + frontRight.y);
+ if (floorHeight < 0)
+ {
+ floorHeight = -(abs(floorHeight) / 2);
+ }
else
- probe.Position.Floor /= 2;
+ {
+ floorHeight /= 2;
+ }
- short xRot = phd_atan(SPEEDBOAT_FRONT, speedboatItem->Pose.Position.y - probe.Position.Floor);
- short zRot = phd_atan(SPEEDBOAT_SIDE, probe.Position.Floor - frontLeft.y);
+ short xRot = phd_atan(SPEEDBOAT_FRONT, speedboatItem->Pose.Position.y - floorHeight);
+ short zRot = phd_atan(SPEEDBOAT_SIDE, floorHeight - frontLeft.y);
speedboatItem->Pose.Orientation.x += ((xRot - speedboatItem->Pose.Orientation.x) / 2);
speedboatItem->Pose.Orientation.z += ((zRot - speedboatItem->Pose.Orientation.z) / 2);
@@ -899,10 +905,10 @@ namespace TEN::Entities::Vehicles
{
SpeedboatAnimation(speedboatItem, laraItem, collide);
- if (probe.RoomNumber != speedboatItem->RoomNumber)
+ if (probe.GetRoomNumber() != speedboatItem->RoomNumber)
{
- ItemNewRoom(lara->Context.Vehicle, probe.RoomNumber);
- ItemNewRoom(laraItem->Index, probe.RoomNumber);
+ ItemNewRoom(lara->Context.Vehicle, probe.GetRoomNumber());
+ ItemNewRoom(laraItem->Index, probe.GetRoomNumber());
}
laraItem->Pose = speedboatItem->Pose;
@@ -930,8 +936,8 @@ namespace TEN::Entities::Vehicles
}
else
{
- if (probe.RoomNumber != speedboatItem->RoomNumber)
- ItemNewRoom(itemNumber, probe.RoomNumber);
+ if (probe.GetRoomNumber() != speedboatItem->RoomNumber)
+ ItemNewRoom(itemNumber, probe.GetRoomNumber());
speedboatItem->Pose.Orientation.z += speedboat->LeanAngle;
}
@@ -941,7 +947,7 @@ namespace TEN::Entities::Vehicles
if (speedboatItem->Animation.Velocity.z && (water - 5) == speedboatItem->Pose.Position.y)
{
- auto roomNumber = probe.Block->GetNextRoomNumber(speedboatItem->Pose.Position.x, speedboatItem->Pose.Position.z, true);
+ auto roomNumber = probe.GetSector().GetNextRoomNumber(speedboatItem->Pose.Position.x, speedboatItem->Pose.Position.z, true);
if (roomNumber.has_value() &&
(TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, *roomNumber) || TestEnvironment(RoomEnvFlags::ENV_FLAG_SWAMP, *roomNumber)))
{
diff --git a/TombEngine/Objects/TR3/Entity/Shiva.cpp b/TombEngine/Objects/TR3/Entity/Shiva.cpp
index c7e5d6641..1b07d640a 100644
--- a/TombEngine/Objects/TR3/Entity/Shiva.cpp
+++ b/TombEngine/Objects/TR3/Entity/Shiva.cpp
@@ -4,6 +4,7 @@
#include "Game/animation.h"
#include "Game/camera.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/box.h"
#include "Game/effects/effects.h"
#include "Game/itemdata/creature_info.h"
@@ -17,6 +18,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Math;
namespace TEN::Entities::Creatures::TR3
@@ -339,7 +341,7 @@ namespace TEN::Entities::Creatures::TR3
{
int x = item->Pose.Position.x + BLOCK(1) * phd_sin(item->Pose.Orientation.y + ANGLE(180.0f));
int z = item->Pose.Position.z + BLOCK(1) * phd_cos(item->Pose.Orientation.y + ANGLE(180.0f));
- auto box = GetCollision(x, item->Pose.Position.y, z, item->RoomNumber).BottomBlock->Box;
+ auto box = GetPointCollision(Vector3i(x, item->Pose.Position.y, z), item->RoomNumber).GetBottomSector().Box;
if (box != NO_BOX && !(g_Level.Boxes[box].flags & BLOCKABLE) && !creature.Flags)
item->Animation.TargetState = SHIVA_STATE_WALK_BACK;
diff --git a/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp b/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp
index a4eaaba5a..12bdf11a7 100644
--- a/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp
+++ b/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp
@@ -3,6 +3,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/box.h"
#include "Game/control/lot.h"
#include "Game/collision/sphere.h"
@@ -17,6 +18,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Math;
namespace TEN::Entities::Creatures::TR3
@@ -163,7 +165,7 @@ namespace TEN::Entities::Creatures::TR3
int y = item->Pose.Position.y;
int z = item->Pose.Position.z + BLOCK(1) * phd_cos(item->Pose.Orientation.y + laraAI.angle);
- int height = GetCollision(x, y, z, item->RoomNumber).Position.Floor;
+ int height = GetPointCollision(Vector3i(x, y, z), item->RoomNumber).GetFloorHeight();
bool cover = (item->Pose.Position.y > (height + CLICK(3)) && item->Pose.Position.y < (height + CLICK(4.5f)) && laraAI.distance > pow(BLOCK(1), 2));
auto* enemy = creature->Enemy;
diff --git a/TombEngine/Objects/TR3/Entity/tr3_tony.cpp b/TombEngine/Objects/TR3/Entity/tr3_tony.cpp
index 4359ac2d8..efc5feef8 100644
--- a/TombEngine/Objects/TR3/Entity/tr3_tony.cpp
+++ b/TombEngine/Objects/TR3/Entity/tr3_tony.cpp
@@ -4,6 +4,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/box.h"
#include "Game/control/lot.h"
#include "Game/effects/effects.h"
@@ -18,6 +19,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Effects::Items;
using namespace TEN::Effects::Boss;
@@ -412,10 +414,10 @@ namespace TEN::Entities::Creatures::TR3
break;
}
- auto probe = GetCollision(fx.pos.Position.x, fx.pos.Position.y, fx.pos.Position.z, fx.roomNumber);
+ auto pointColl = GetPointCollision(fx.pos.Position, fx.roomNumber);
- if (fx.pos.Position.y >= probe.Position.Floor ||
- fx.pos.Position.y < probe.Position.Ceiling)
+ if (fx.pos.Position.y >= pointColl.GetFloorHeight() ||
+ fx.pos.Position.y < pointColl.GetCeilingHeight())
{
Vector3i pos;
int debrisCount = type == TonyFlameType::InFront ? 7 : 3;
@@ -427,13 +429,13 @@ namespace TEN::Entities::Creatures::TR3
for (int x = 0; x < 2; x++)
TriggerExplosionSparks(prevPos.x, prevPos.y, prevPos.z, 3, -1, 0, fx.roomNumber);
- probe = GetCollision(LaraItem); // TODO: Deal with LaraItem global.
- pos.y = probe.Position.Ceiling + CLICK(1);
+ pointColl = GetPointCollision(*LaraItem); // TODO: Deal with LaraItem global.
+ pos.y = pointColl.GetCeilingHeight() + CLICK(1);
pos.x = LaraItem->Pose.Position.x + (GetRandomControl() & 1023) - CLICK(2);
pos.z = LaraItem->Pose.Position.z + (GetRandomControl() & 1023) - CLICK(2);
- TriggerExplosionSparks(pos.x, pos.y, pos.z, 3, -2, 0, probe.RoomNumber);
- TriggerFireBall(nullptr, TonyFlameType::ShowerFromCeiling, &pos, probe.RoomNumber, 0, 0); // Fallthrough is intended.
+ TriggerExplosionSparks(pos.x, pos.y, pos.z, 3, -2, 0, pointColl.GetRoomNumber());
+ TriggerFireBall(nullptr, TonyFlameType::ShowerFromCeiling, &pos, pointColl.GetRoomNumber(), 0, 0); // Fallthrough is intended.
case TonyFlameType::InFront:
case TonyFlameType::ShowerFromCeiling:
@@ -450,7 +452,7 @@ namespace TEN::Entities::Creatures::TR3
return;
}
- if (TestEnvironment(ENV_FLAG_WATER, probe.RoomNumber))
+ if (TestEnvironment(ENV_FLAG_WATER, pointColl.GetRoomNumber()))
{
KillEffect(fxNumber);
return;
@@ -468,7 +470,7 @@ namespace TEN::Entities::Creatures::TR3
}
}
- if (probe.RoomNumber != fx.roomNumber)
+ if (pointColl.GetRoomNumber() != fx.roomNumber)
EffectNewRoom(fxNumber, LaraItem->RoomNumber);
if (LightIntensityTable[fx.flag1])
diff --git a/TombEngine/Objects/TR3/Trap/train.cpp b/TombEngine/Objects/TR3/Trap/train.cpp
index 84c2b521a..54617dd04 100644
--- a/TombEngine/Objects/TR3/Trap/train.cpp
+++ b/TombEngine/Objects/TR3/Trap/train.cpp
@@ -6,6 +6,7 @@
#include "Game/control/control.h"
#include "Game/collision/collide_room.h"
#include "Game/collision/collide_item.h"
+#include "Game/collision/PointCollision.h"
#include "Game/collision/floordata.h"
#include "Game/collision/sphere.h"
#include "Game/effects/effects.h"
@@ -16,6 +17,8 @@
#include "Sound/sound.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
+
constexpr auto TRAIN_VEL = 260;
long TrainTestHeight(ItemInfo* item, long x, long z, short* roomNumber)
@@ -28,12 +31,11 @@ long TrainTestHeight(ItemInfo* item, long x, long z, short* roomNumber)
auto pos = Vector3i(
round(item->Pose.Position.x + ((z * sinY) + (x * cosY))),
round(item->Pose.Position.y - ((z * sinX) + (x * sinZ))),
- round(item->Pose.Position.z + ((z * cosY) - (x * sinY)))
- );
- auto probe = GetCollision(pos.x, pos.y, pos.z, item->RoomNumber);
+ round(item->Pose.Position.z + ((z * cosY) - (x * sinY))));
+ auto pointColl = GetPointCollision(pos, item->RoomNumber);
- *roomNumber = probe.RoomNumber;
- return probe.Position.Floor;
+ *roomNumber = pointColl.GetRoomNumber();
+ return pointColl.GetFloorHeight();
}
void TrainControl(short itemNumber)
@@ -84,7 +86,7 @@ void TrainControl(short itemNumber)
ForcedFixedCamera.x = item->Pose.Position.x + BLOCK(8) * sinY;
ForcedFixedCamera.z = item->Pose.Position.z + BLOCK(8) * cosY;
- ForcedFixedCamera.y = GetCollision(ForcedFixedCamera.x, item->Pose.Position.y - CLICK(2), ForcedFixedCamera.z, item->RoomNumber).Position.Floor;
+ ForcedFixedCamera.y = GetPointCollision(Vector3i(ForcedFixedCamera.x, item->Pose.Position.y - CLICK(2), ForcedFixedCamera.z), item->RoomNumber).GetFloorHeight();
ForcedFixedCamera.RoomNumber = roomNumber;
UseForcedFixedCamera = 1;
diff --git a/TombEngine/Objects/TR3/Vehicles/big_gun.cpp b/TombEngine/Objects/TR3/Vehicles/big_gun.cpp
index e758af3a6..b27904790 100644
--- a/TombEngine/Objects/TR3/Vehicles/big_gun.cpp
+++ b/TombEngine/Objects/TR3/Vehicles/big_gun.cpp
@@ -4,8 +4,9 @@
#include "Game/animation.h"
#include "Game/camera.h"
#include "Game/control/box.h"
-#include "Game/collision/collide_room.h"
#include "Game/collision/collide_item.h"
+#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/effects/effects.h"
#include "Game/effects/tomb4fx.h"
#include "Game/items.h"
@@ -20,6 +21,7 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Input;
namespace TEN::Entities::Vehicles
@@ -126,8 +128,8 @@ namespace TEN::Entities::Vehicles
auto* projectileItem = &g_Level.Items[itemNumber];
projectileItem->ObjectNumber = ID_ROCKET;
auto pos = GetJointPosition(bigGunItem, BigGunBite);
- auto probe = GetCollision(pos.x, pos.y, pos.z, bigGunItem->RoomNumber);
- projectileItem->RoomNumber = probe.RoomNumber;
+ auto pointColl = GetPointCollision(pos, bigGunItem->RoomNumber);
+ projectileItem->RoomNumber = pointColl.GetRoomNumber();
projectileItem->Pose.Position = pos;
projectileItem->Pose.Orientation = EulerAngles(
-((bigGun->XOrientFrame - 32) * ANGLE(1.0f)),
diff --git a/TombEngine/Objects/TR3/Vehicles/kayak.cpp b/TombEngine/Objects/TR3/Vehicles/kayak.cpp
index ecaf80943..38b3b1423 100644
--- a/TombEngine/Objects/TR3/Vehicles/kayak.cpp
+++ b/TombEngine/Objects/TR3/Vehicles/kayak.cpp
@@ -5,6 +5,7 @@
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/control.h"
#include "Game/effects/effects.h"
#include "Game/items.h"
@@ -18,6 +19,7 @@
#include "Specific/level.h"
#include "Specific/Input/Input.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Input;
namespace TEN::Entities::Vehicles
@@ -212,7 +214,7 @@ namespace TEN::Entities::Vehicles
int x = kayakItem->Pose.Position.x + (zOffset * sinY) + (xOffset * cosY);
int z = kayakItem->Pose.Position.z + (zOffset * cosY) - (xOffset * sinY);
- int probedRoomNumber = GetCollision(x, kayakItem->Pose.Position.y, z, kayakItem->RoomNumber).RoomNumber;
+ int probedRoomNumber = GetPointCollision(Vector3i(x, kayakItem->Pose.Position.y, z), kayakItem->RoomNumber).GetRoomNumber();
int waterHeight = GetWaterHeight(x, kayakItem->Pose.Position.y, z, probedRoomNumber);
//if (waterHeight != NO_HEIGHT)
@@ -405,8 +407,8 @@ namespace TEN::Entities::Vehicles
x = 0;
z = 0;
- auto probe = GetCollision(old->x, pos->y, pos->z, kayakItem->RoomNumber);
- if (probe.Position.Floor < (old->y - CLICK(1)))
+ auto probe = GetPointCollision(Vector3i(old->x, pos->y, pos->z), kayakItem->RoomNumber);
+ if (probe.GetFloorHeight() < (old->y - CLICK(1)))
{
if (pos->z > old->z)
z = -zShift - 1;
@@ -414,8 +416,8 @@ namespace TEN::Entities::Vehicles
z = BLOCK(1) - zShift;
}
- probe = GetCollision(pos->x, pos->y, old->z, kayakItem->RoomNumber);
- if (probe.Position.Floor < (old->y - CLICK(1)))
+ probe = GetPointCollision(Vector3i(pos->x, pos->y, old->z), kayakItem->RoomNumber);
+ if (probe.GetFloorHeight() < (old->y - CLICK(1)))
{
if (pos->x > old->x)
x = -xShift - 1;
diff --git a/TombEngine/Objects/TR3/Vehicles/quad_bike.cpp b/TombEngine/Objects/TR3/Vehicles/quad_bike.cpp
index 8e199aacb..648d6484e 100644
--- a/TombEngine/Objects/TR3/Vehicles/quad_bike.cpp
+++ b/TombEngine/Objects/TR3/Vehicles/quad_bike.cpp
@@ -3,8 +3,9 @@
#include "Game/animation.h"
#include "Game/camera.h"
-#include "Game/collision/collide_room.h"
#include "Game/collision/collide_item.h"
+#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/effects/effects.h"
#include "Game/effects/simple_particle.h"
#include "Game/effects/tomb4fx.h"
@@ -22,6 +23,7 @@
#include "Specific/level.h"
#include "Specific/Input/Input.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Input;
using namespace TEN::Math;
@@ -236,19 +238,19 @@ namespace TEN::Entities::Vehicles
int y = quadBikeItem->Pose.Position.y;
int z = quadBikeItem->Pose.Position.z + CLICK(2) * phd_cos(angle);
- auto collResult = GetCollision(x, y, z, quadBikeItem->RoomNumber);
+ auto pointColl = GetPointCollision(Vector3i(x, y, z), quadBikeItem->RoomNumber);
- if (collResult.Position.FloorSlope ||
- collResult.Position.Floor == NO_HEIGHT)
+ if (pointColl.IsIllegalFloor() ||
+ pointColl.GetFloorHeight() == NO_HEIGHT)
{
return false;
}
- if (abs(collResult.Position.Floor - quadBikeItem->Pose.Position.y) > CLICK(2))
+ if (abs(pointColl.GetFloorHeight() - quadBikeItem->Pose.Position.y) > CLICK(2))
return false;
- if ((collResult.Position.Ceiling - quadBikeItem->Pose.Position.y) > -LARA_HEIGHT ||
- (collResult.Position.Floor - collResult.Position.Ceiling) < LARA_HEIGHT)
+ if ((pointColl.GetCeilingHeight() - quadBikeItem->Pose.Position.y) > -LARA_HEIGHT ||
+ (pointColl.GetFloorHeight() - pointColl.GetCeilingHeight()) < LARA_HEIGHT)
{
return false;
}
@@ -343,7 +345,6 @@ namespace TEN::Entities::Vehicles
static int DoQuadShift(ItemInfo* quadBikeItem, Vector3i* pos, Vector3i* old)
{
- CollisionResult probe;
int x = pos->x / BLOCK(1);
int z = pos->z / BLOCK(1);
int oldX = old->x / BLOCK(1);
@@ -387,8 +388,8 @@ namespace TEN::Entities::Vehicles
x = 0;
z = 0;
- probe = GetCollision(old->x, pos->y, pos->z, quadBikeItem->RoomNumber);
- if (probe.Position.Floor < (old->y - CLICK(1)))
+ auto pointColl = GetPointCollision(Vector3i(old->x, pos->y, pos->z), quadBikeItem->RoomNumber);
+ if (pointColl.GetFloorHeight() < (old->y - CLICK(1)))
{
if (pos->z > old->z)
z = -shiftZ - 1;
@@ -396,8 +397,8 @@ namespace TEN::Entities::Vehicles
z = BLOCK(1) - shiftZ;
}
- probe = GetCollision(pos->x, pos->y, old->z, quadBikeItem->RoomNumber);
- if (probe.Position.Floor < (old->y - CLICK(1)))
+ pointColl = GetPointCollision(Vector3i(pos->x, pos->y, old->z), quadBikeItem->RoomNumber);
+ if (pointColl.GetFloorHeight() < (old->y - CLICK(1)))
{
if (pos->x > old->x)
x = -shiftX - 1;
diff --git a/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp b/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp
index 51e7f878c..c73754806 100644
--- a/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp
+++ b/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp
@@ -4,6 +4,7 @@
#include "Game/animation.h"
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
+#include "Game/collision/PointCollision.h"
#include "Game/collision/sphere.h"
#include "Game/effects/Bubble.h"
#include "Game/effects/effects.h"
@@ -19,6 +20,7 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Effects::Bubble;
using namespace TEN::Input;
@@ -262,7 +264,7 @@ namespace TEN::Entities::Vehicles
x = 0;
z = 0;
- int height = GetCollision(old->x, pos->y, pos->z, rBoatItem->RoomNumber).Position.Floor;
+ int height = GetPointCollision(Vector3i(old->x, pos->y, pos->z), rBoatItem->RoomNumber).GetFloorHeight();
if (height < (old->y - CLICK(1)))
{
if (pos->z > old->z)
@@ -271,7 +273,7 @@ namespace TEN::Entities::Vehicles
z = BLOCK(1) - zShift;
}
- height = GetCollision(pos->x, pos->y, old->z, rBoatItem->RoomNumber).Position.Floor;
+ height = GetPointCollision(Vector3i(pos->x, pos->y, old->z), rBoatItem->RoomNumber).GetFloorHeight();
if (height < (old->y - CLICK(1)))
{
if (pos->x > old->x)
@@ -604,16 +606,16 @@ namespace TEN::Entities::Vehicles
int y = sBoatItem->Pose.Position.y;
int z = sBoatItem->Pose.Position.z + BLOCK(1) * phd_cos(angle);
- auto collResult = GetCollision(x, y, z, sBoatItem->RoomNumber);
+ auto pointColl = GetPointCollision(Vector3i(x, y, z), sBoatItem->RoomNumber);
- if ((collResult.Position.Floor - sBoatItem->Pose.Position.y) < -512)
+ if ((pointColl.GetFloorHeight() - sBoatItem->Pose.Position.y) < -512)
return false;
- if (collResult.Position.FloorSlope || collResult.Position.Floor == NO_HEIGHT)
+ if (pointColl.IsIllegalFloor() || pointColl.GetFloorHeight() == NO_HEIGHT)
return false;
- if ((collResult.Position.Ceiling - sBoatItem->Pose.Position.y) > -LARA_HEIGHT ||
- (collResult.Position.Floor - collResult.Position.Ceiling) < LARA_HEIGHT)
+ if ((pointColl.GetCeilingHeight() - sBoatItem->Pose.Position.y) > -LARA_HEIGHT ||
+ (pointColl.GetFloorHeight() - pointColl.GetCeilingHeight()) < LARA_HEIGHT)
{
return false;
}
@@ -786,14 +788,14 @@ namespace TEN::Entities::Vehicles
int y = laraItem->Pose.Position.y - 90;
int z = laraItem->Pose.Position.z + 360 * phd_cos(laraItem->Pose.Orientation.y);
- auto probe = GetCollision(x, y, z, laraItem->RoomNumber);
- if (probe.Position.Floor >= (y - CLICK(1)))
+ auto probe = GetPointCollision(Vector3i(x, y, z), laraItem->RoomNumber);
+ if (probe.GetFloorHeight() >= (y - CLICK(1)))
{
laraItem->Pose.Position.x = x;
laraItem->Pose.Position.z = z;
- if (probe.RoomNumber != laraItem->RoomNumber)
- ItemNewRoom(laraItem->Index, probe.RoomNumber);
+ if (probe.GetRoomNumber() != laraItem->RoomNumber)
+ ItemNewRoom(laraItem->Index, probe.GetRoomNumber());
}
laraItem->Pose.Position.y = y;
@@ -824,8 +826,8 @@ namespace TEN::Entities::Vehicles
TestTriggers(rBoatItem, true);
}
- auto probe = GetCollision(rBoatItem);
- int water = GetWaterHeight(rBoatItem->Pose.Position.x, rBoatItem->Pose.Position.y, rBoatItem->Pose.Position.z, probe.RoomNumber);
+ auto probe = GetPointCollision(*rBoatItem);
+ int water = GetWaterHeight(rBoatItem->Pose.Position.x, rBoatItem->Pose.Position.y, rBoatItem->Pose.Position.z, probe.GetRoomNumber());
rBoat->Water = water;
if (lara->Context.Vehicle == itemNumber && laraItem->HitPoints > 0)
@@ -861,7 +863,7 @@ namespace TEN::Entities::Vehicles
rBoat->TurnRate = 0;
}
- height = probe.Position.Floor;
+ height = probe.GetFloorHeight();
rBoatItem->Floor = height - 5;
if (rBoat->Water == NO_HEIGHT)
@@ -895,10 +897,10 @@ namespace TEN::Entities::Vehicles
{
RubberBoatAnimation(rBoatItem, laraItem, collide);
- if (probe.RoomNumber != rBoatItem->RoomNumber)
+ if (probe.GetRoomNumber() != rBoatItem->RoomNumber)
{
- ItemNewRoom(itemNumber, probe.RoomNumber);
- ItemNewRoom(laraItem->Index, probe.RoomNumber);
+ ItemNewRoom(itemNumber, probe.GetRoomNumber());
+ ItemNewRoom(laraItem->Index, probe.GetRoomNumber());
}
rBoatItem->Pose.Orientation.z += rBoat->LeanAngle;
@@ -914,8 +916,8 @@ namespace TEN::Entities::Vehicles
}
else
{
- if (probe.RoomNumber != rBoatItem->RoomNumber)
- ItemNewRoom(itemNumber, probe.RoomNumber);
+ if (probe.GetRoomNumber() != rBoatItem->RoomNumber)
+ ItemNewRoom(itemNumber, probe.GetRoomNumber());
rBoatItem->Pose.Orientation.z += rBoat->LeanAngle;
}
@@ -933,7 +935,7 @@ namespace TEN::Entities::Vehicles
DoRubberBoatDismount(rBoatItem, laraItem);
- short probedRoomNumber = GetCollision(rBoatItem->Pose.Position.x, rBoatItem->Pose.Position.y + 128, rBoatItem->Pose.Position.z, rBoatItem->RoomNumber).RoomNumber;
+ short probedRoomNumber = GetPointCollision(Vector3i(rBoatItem->Pose.Position.x, rBoatItem->Pose.Position.y + 128, rBoatItem->Pose.Position.z), rBoatItem->RoomNumber).GetRoomNumber();
height = GetWaterHeight(rBoatItem->Pose.Position.x, rBoatItem->Pose.Position.y + 128, rBoatItem->Pose.Position.z, probedRoomNumber);
if (height > rBoatItem->Pose.Position.y + 32 || height == NO_HEIGHT)
height = 0;
@@ -941,7 +943,7 @@ namespace TEN::Entities::Vehicles
height = 1;
auto prop = GetJointPosition(rBoatItem, 2, Vector3i(0, 0, -80));
- probedRoomNumber = GetCollision(prop.x, prop.y, prop.z, rBoatItem->RoomNumber).RoomNumber;
+ probedRoomNumber = GetPointCollision(prop, rBoatItem->RoomNumber).GetRoomNumber();
if (rBoatItem->Animation.Velocity.z &&
height < prop.y &&
@@ -968,7 +970,7 @@ namespace TEN::Entities::Vehicles
}
else
{
- height = GetCollision(prop.x, prop.y, prop.z, rBoatItem->RoomNumber).Position.Floor;
+ height = GetPointCollision(prop, rBoatItem->RoomNumber).GetFloorHeight();
if (prop.y > height &&
!TestEnvironment(ENV_FLAG_WATER, probedRoomNumber))
{
diff --git a/TombEngine/Objects/TR3/Vehicles/upv.cpp b/TombEngine/Objects/TR3/Vehicles/upv.cpp
index fdea14fe2..b05b4f156 100644
--- a/TombEngine/Objects/TR3/Vehicles/upv.cpp
+++ b/TombEngine/Objects/TR3/Vehicles/upv.cpp
@@ -6,6 +6,7 @@
#include "Game/collision/sphere.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/box.h"
#include "Game/control/los.h"
#include "Game/effects/Bubble.h"
@@ -26,6 +27,7 @@
#include "Specific/level.h"
#include "Specific/Input/Input.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Effects::Bubble;
using namespace TEN::Effects::Streamer;
using namespace TEN::Input;
@@ -311,7 +313,7 @@ namespace TEN::Entities::Vehicles
if (Random::TestProbability(1 / 2.0f))
{
auto bubblePos = Random::GeneratePointInSphere(sphere);
- int probedRoomNumber = GetCollision(bubblePos.x, bubblePos.y, bubblePos.z, UPVItem->RoomNumber).RoomNumber;
+ int probedRoomNumber = GetPointCollision(bubblePos, UPVItem->RoomNumber).GetRoomNumber();
for (int i = 0; i < 3; i++)
SpawnBubble(bubblePos, probedRoomNumber, (int)BubbleFlags::HighAmplitude);
@@ -358,12 +360,12 @@ namespace TEN::Entities::Vehicles
int z = UPVItem->Pose.Position.z + velocity * phd_cos(moveAngle);
int y = UPVItem->Pose.Position.y - UPV_DISMOUNT_DISTANCE * phd_sin(-UPVItem->Pose.Orientation.x);
- auto probe = GetCollision(x, y, z, UPVItem->RoomNumber);
- if ((probe.Position.Floor - probe.Position.Ceiling) < CLICK(1) ||
- probe.Position.Floor < y ||
- probe.Position.Ceiling > y ||
- probe.Position.Floor == NO_HEIGHT ||
- probe.Position.Ceiling == NO_HEIGHT)
+ auto probe = GetPointCollision(Vector3i(x, y, z), UPVItem->RoomNumber);
+ if ((probe.GetFloorHeight() - probe.GetCeilingHeight()) < CLICK(1) ||
+ probe.GetFloorHeight() < y ||
+ probe.GetCeilingHeight() > y ||
+ probe.GetFloorHeight() == NO_HEIGHT ||
+ probe.GetCeilingHeight() == NO_HEIGHT)
{
return false;
}
@@ -849,7 +851,7 @@ namespace TEN::Entities::Vehicles
auto* UPV = GetUPVInfo(UPVItem);
auto oldPos = UPVItem->Pose;
- auto probe = GetCollision(UPVItem);
+ auto probe = GetPointCollision(*UPVItem);
if (!(UPV->Flags & UPV_FLAG_DEAD))
{
@@ -869,7 +871,7 @@ namespace TEN::Entities::Vehicles
TranslateItem(UPVItem, UPVItem->Pose.Orientation, UPVItem->Animation.Velocity.z);
}
- int newHeight = GetCollision(UPVItem).Position.Floor;
+ int newHeight = GetPointCollision(*UPVItem).GetFloorHeight();
int waterHeight = GetWaterHeight(UPVItem);
if ((newHeight - waterHeight) < UPV_HEIGHT || (newHeight < UPVItem->Pose.Position.y - UPV_HEIGHT / 2) ||
@@ -879,7 +881,7 @@ namespace TEN::Entities::Vehicles
UPVItem->Animation.Velocity.z = 0;
}
- UPVItem->Floor = probe.Position.Floor;
+ UPVItem->Floor = probe.GetFloorHeight();
if (UPV->Flags & UPV_FLAG_CONTROL && !(UPV->Flags & UPV_FLAG_DEAD))
{
@@ -898,7 +900,7 @@ namespace TEN::Entities::Vehicles
UPV->Flags |= UPV_FLAG_SURFACE;
}
else if ((waterHeight - UPVItem->Pose.Position.y) >= -UPV_WATER_SURFACE_DISTANCE && waterHeight != NO_HEIGHT &&
- (laraItem->Pose.Position.y - probe.Position.Ceiling) >= CLICK(1))
+ (laraItem->Pose.Position.y - probe.GetCeilingHeight()) >= CLICK(1))
{
UPVItem->Pose.Position.y = waterHeight + UPV_WATER_SURFACE_DISTANCE;
@@ -963,10 +965,10 @@ namespace TEN::Entities::Vehicles
}
}
- if (probe.RoomNumber != UPVItem->RoomNumber)
+ if (probe.GetRoomNumber() != UPVItem->RoomNumber)
{
- ItemNewRoom(lara->Context.Vehicle, probe.RoomNumber);
- ItemNewRoom(laraItem->Index, probe.RoomNumber);
+ ItemNewRoom(lara->Context.Vehicle, probe.GetRoomNumber());
+ ItemNewRoom(laraItem->Index, probe.GetRoomNumber());
}
laraItem->Pose = UPVItem->Pose;
@@ -991,8 +993,8 @@ namespace TEN::Entities::Vehicles
{
AnimateItem(laraItem);
- if (probe.RoomNumber != UPVItem->RoomNumber)
- ItemNewRoom(lara->Context.Vehicle, probe.RoomNumber);
+ if (probe.GetRoomNumber() != UPVItem->RoomNumber)
+ ItemNewRoom(lara->Context.Vehicle, probe.GetRoomNumber());
BackgroundCollision(UPVItem, laraItem);
diff --git a/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp b/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp
index ea22508c9..b201ba54a 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp
@@ -2,6 +2,7 @@
#include "Objects/TR4/Entity/tr4_baboon.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/box.h"
#include "Game/control/lot.h"
#include "Game/control/control.h"
@@ -15,6 +16,7 @@
#include "Game/Setup.h"
#include "Math/Math.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Effects::Environment;
using namespace TEN::Math;
@@ -512,9 +514,9 @@ namespace TEN::Entities::TR4
pos.y = item->Pose.Position.y;
- auto probe = GetCollision(pos.x, pos.y, pos.z, item->RoomNumber);
- item->Floor = probe.Position.Floor;
- TestTriggers(pos.x, pos.y, pos.z, probe.RoomNumber, true);
+ auto probe = GetPointCollision(pos, item->RoomNumber);
+ item->Floor = probe.GetFloorHeight();
+ TestTriggers(pos.x, pos.y, pos.z, probe.GetRoomNumber(), true);
item->TriggerFlags = 1;
}
diff --git a/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp b/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp
index 2feee2dcb..f1f808d8b 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp
@@ -3,6 +3,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/box.h"
#include "Game/control/control.h"
#include "Game/control/lot.h"
@@ -18,6 +19,7 @@
#include "Math/Math.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Math;
/*
@@ -359,15 +361,15 @@ namespace TEN::Entities::TR4
x += dx;
z += dz;
- int height1 = GetCollision(x, y, z, item->RoomNumber).Position.Floor;
+ int height1 = GetPointCollision(Vector3i(x, y, z), item->RoomNumber).GetFloorHeight();
x += dx;
z += dz;
- int height2 = GetCollision(x, y, z, item->RoomNumber).Position.Floor;
+ int height2 = GetPointCollision(Vector3i(x, y, z), item->RoomNumber).GetFloorHeight();
x += dx;
z += dz;
- int height3 = GetCollision(x, y, z, item->RoomNumber).Position.Floor;
+ int height3 = GetPointCollision(Vector3i(x, y, z), item->RoomNumber).GetFloorHeight();
int height = 0;
bool canJump1Sector = true;
@@ -421,11 +423,11 @@ namespace TEN::Entities::TR4
item->ItemFlags[1] = item->RoomNumber;
- CollisionResult probe;
+ auto probe = GetPointCollision(*item);
if (item->HitPoints <= 0)
{
- item->Floor = GetCollision(item).Position.Floor;
+ item->Floor = GetPointCollision(*item).GetFloorHeight();
currentCreature->LOT.IsMonkeying = false;
switch (item->Animation.ActiveState)
@@ -575,7 +577,7 @@ namespace TEN::Entities::TR4
x = item->Pose.Position.x + dx;
y = item->Pose.Position.y;
z = item->Pose.Position.z + dz;
- int height4 = GetCollision(x, y, z, item->RoomNumber).Position.Floor;
+ int height4 = GetPointCollision(Vector3i(x, y, z), item->RoomNumber).GetFloorHeight();
dx = 942 * phd_sin(item->Pose.Orientation.y + ANGLE(78.75f));
dz = 942 * phd_cos(item->Pose.Orientation.y + ANGLE(78.75f));
@@ -583,7 +585,7 @@ namespace TEN::Entities::TR4
x = item->Pose.Position.x + dx;
y = item->Pose.Position.y;
z = item->Pose.Position.z + dz;
- int height5 = GetCollision(x, y, z, item->RoomNumber).Position.Floor;
+ int height5 = GetPointCollision(Vector3i(x, y, z), item->RoomNumber).GetFloorHeight();
if (abs(height5 - item->Pose.Position.y) > CLICK(1))
jump = false;
@@ -600,7 +602,7 @@ namespace TEN::Entities::TR4
x = item->Pose.Position.x + dx;
y = item->Pose.Position.y;
z = item->Pose.Position.z + dz;
- int height6 = GetCollision(x, y, z, item->RoomNumber).Position.Floor;
+ int height6 = GetPointCollision(Vector3i(x, y, z), item->RoomNumber).GetFloorHeight();
dx = 942 * phd_sin(item->Pose.Orientation.y - ANGLE(78.75f));
dz = 942 * phd_cos(item->Pose.Orientation.y - ANGLE(78.75f));
@@ -608,7 +610,7 @@ namespace TEN::Entities::TR4
x = item->Pose.Position.x + dx;
y = item->Pose.Position.y;
z = item->Pose.Position.z + dz;
- int height7 = GetCollision(x, y, z, item->RoomNumber).Position.Floor;
+ int height7 = GetPointCollision(Vector3i(x, y, z), item->RoomNumber).GetFloorHeight();
if (abs(height7 - item->Pose.Position.y) > CLICK(1) ||
(height6 + CLICK(2)) >= item->Pose.Position.y)
@@ -715,8 +717,8 @@ namespace TEN::Entities::TR4
if (currentCreature->MonkeySwingAhead)
{
- probe = GetCollision(item);
- if (probe.Position.Ceiling == probe.Position.Floor - CLICK(6))
+ probe = GetPointCollision(*item);
+ if (probe.GetCeilingHeight() == probe.GetFloorHeight() - CLICK(6))
{
if (item->TestMeshSwapFlags(MESHSWAPFLAGS_BADDY_EMPTY))
{
@@ -950,7 +952,7 @@ namespace TEN::Entities::TR4
joint1 = 0;
joint2 = 0;
- probe = GetCollision(item);
+ probe = GetPointCollision(*item);
if (laraAI.ahead && laraAI.distance < pow(682, 2) &&
(LaraItem->Animation.ActiveState == LS_MONKEY_IDLE ||
@@ -965,7 +967,7 @@ namespace TEN::Entities::TR4
}
else if (item->BoxNumber != currentCreature->LOT.TargetBox &&
currentCreature->MonkeySwingAhead ||
- probe.Position.Ceiling != (probe.Position.Floor - CLICK(6)))
+ probe.GetCeilingHeight() != (probe.GetFloorHeight() - CLICK(6)))
{
item->Animation.TargetState = BADDY_STATE_MONKEY_FORWARD;
}
@@ -989,9 +991,9 @@ namespace TEN::Entities::TR4
if (item->BoxNumber == currentCreature->LOT.TargetBox ||
!currentCreature->MonkeySwingAhead)
{
- probe = GetCollision(item);
+ probe = GetPointCollision(*item);
- if (probe.Position.Ceiling == probe.Position.Floor - CLICK(6))
+ if (probe.GetCeilingHeight() == probe.GetFloorHeight() - CLICK(6))
item->Animation.TargetState = BADDY_STATE_MONKEY_IDLE;
}
diff --git a/TombEngine/Objects/TR4/Entity/tr4_enemy_jeep.cpp b/TombEngine/Objects/TR4/Entity/tr4_enemy_jeep.cpp
index b37d4f247..ead8f8949 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_enemy_jeep.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_enemy_jeep.cpp
@@ -3,6 +3,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/box.h"
#include "Game/control/lot.h"
#include "Game/control/trigger.h"
@@ -17,6 +18,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Math;
namespace TEN::Entities::TR4
@@ -98,7 +100,7 @@ namespace TEN::Entities::TR4
int dx = 682 * phd_sin(item->Pose.Orientation.y);
int dz = 682 * phd_cos(item->Pose.Orientation.y);
- int height1 = GetCollision(x - dz, y, z - dx, item->RoomNumber).Position.Floor;
+ int height1 = GetPointCollision(Vector3i(x - dz, y, z - dx), item->RoomNumber).GetFloorHeight();
if (abs(item->Pose.Position.y - height1) > CLICK(3))
{
item->Pose.Position.x += dz / 64;
@@ -107,7 +109,7 @@ namespace TEN::Entities::TR4
height1 = y;
}
- int height2 = GetCollision(x + dz, y, z - dx, item->RoomNumber).Position.Floor;
+ int height2 = GetPointCollision(Vector3i(x + dz, y, z - dx), item->RoomNumber).GetFloorHeight();
if (abs(item->Pose.Position.y - height2) > CLICK(3))
{
item->Pose.Orientation.y -= ANGLE(2.0f);
@@ -118,11 +120,11 @@ namespace TEN::Entities::TR4
short zRot = phd_atan(1364, height2 - height1);
- int height3 = GetCollision(x + dx, y, z + dz, item->RoomNumber).Position.Floor;
+ int height3 = GetPointCollision(Vector3i(x + dx, y, z + dz), item->RoomNumber).GetFloorHeight();
if (abs(y - height3) > CLICK(3))
height3 = y;
- int height4 = GetCollision(x - dx, y, z - dz, item->RoomNumber).Position.Floor;
+ int height4 = GetPointCollision(Vector3i(x - dx, y, z - dz), item->RoomNumber).GetFloorHeight();
if (abs(y - height4) > CLICK(3))
height4 = y;
@@ -358,13 +360,15 @@ namespace TEN::Entities::TR4
creature->MaxTurn = 0;
AnimateItem(item);
- auto probe = GetCollision(item);
- item->Floor = probe.Position.Floor;
- if (item->RoomNumber != probe.RoomNumber)
- ItemNewRoom(itemNumber, probe.RoomNumber);
+ auto probe = GetPointCollision(*item);
+ item->Floor = probe.GetFloorHeight();
+ if (item->RoomNumber != probe.GetRoomNumber())
+ ItemNewRoom(itemNumber, probe.GetRoomNumber());
if (item->Pose.Position.y < item->Floor)
+ {
item->Animation.IsAirborne = true;
+ }
else
{
item->Pose.Position.y = item->Floor;
diff --git a/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp b/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp
index 59ed96052..2b48d98b3 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp
@@ -3,6 +3,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/collision/sphere.h"
#include "Game/control/box.h"
#include "Game/control/control.h"
@@ -16,6 +17,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Math;
namespace TEN::Entities::TR4
@@ -251,14 +253,14 @@ namespace TEN::Entities::TR4
int y = horseItem->Pose.Position.y;
int z = horseItem->Pose.Position.z + 341 * phd_cos(horseItem->Pose.Orientation.y);
- auto probe = GetCollision(x, y, z, item->RoomNumber);
- int height1 = probe.Position.Floor;
+ auto probe = GetPointCollision(Vector3i(x, y, z), item->RoomNumber);
+ int height1 = probe.GetFloorHeight();
x = horseItem->Pose.Position.x - 341 * phd_sin(horseItem->Pose.Orientation.y);
y = horseItem->Pose.Position.y;
z = horseItem->Pose.Position.z - 341 * phd_cos(horseItem->Pose.Orientation.y);
- int height2 = GetCollision(x, y, z, probe.RoomNumber).Position.Floor;
+ int height2 = GetPointCollision(Vector3i(x, y, z), probe.GetRoomNumber()).GetFloorHeight();
xRot = phd_atan(682, height2 - height1);
}
diff --git a/TombEngine/Objects/TR4/Entity/tr4_sas.cpp b/TombEngine/Objects/TR4/Entity/tr4_sas.cpp
index 9c4d8a199..65633f6a2 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_sas.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_sas.cpp
@@ -4,6 +4,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/box.h"
#include "Game/control/control.h"
#include "Game/control/volume.h"
@@ -23,6 +24,7 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Control::Volumes;
using namespace TEN::Input;
using namespace TEN::Math;
@@ -655,7 +657,7 @@ namespace TEN::Entities::TR4
auto pos = GetJointPosition(&item, SasGunBite);
grenadeItem->Pose.Position = pos;
- auto floorHeight = GetCollision(pos.x, pos.y, pos.z, grenadeItem->RoomNumber).Position.Floor;
+ auto floorHeight = GetPointCollision(pos, grenadeItem->RoomNumber).GetFloorHeight();
if (floorHeight < pos.y)
{
grenadeItem->Pose.Position = Vector3i(item.Pose.Position.x, pos.y, item.Pose.Position.z);
diff --git a/TombEngine/Objects/TR4/Entity/tr4_setha.cpp b/TombEngine/Objects/TR4/Entity/tr4_setha.cpp
index b57bdf826..ef0742ccc 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_setha.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_setha.cpp
@@ -5,6 +5,7 @@
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/control.h"
#include "Game/effects/effects.h"
#include "Game/effects/spark.h"
@@ -20,6 +21,7 @@
#include "Specific/clock.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Effects::Items;
using namespace TEN::Effects::Spark;
using namespace TEN::Math;
@@ -129,19 +131,19 @@ namespace TEN::Entities::TR4
int dx = 870 * phd_sin(item->Pose.Orientation.y);
int dz = 870 * phd_cos(item->Pose.Orientation.y);
- int ceiling = GetCollision(x, y, z, item->RoomNumber).Position.Ceiling;
+ int ceiling = GetPointCollision(Vector3i(x, y, z), item->RoomNumber).GetCeilingHeight();
x += dx;
z += dz;
- int height1 = GetCollision(x, y, z, item->RoomNumber).Position.Floor;
+ int height1 = GetPointCollision(Vector3i(x, y, z), item->RoomNumber).GetFloorHeight();
x += dx;
z += dz;
- int height2 = GetCollision(x, y, z, item->RoomNumber).Position.Floor;
+ int height2 = GetPointCollision(Vector3i(x, y, z), item->RoomNumber).GetFloorHeight();
x += dx;
z += dz;
- int height3 = GetCollision(x, y, z, item->RoomNumber).Position.Floor;
+ int height3 = GetPointCollision(Vector3i(x, y, z), item->RoomNumber).GetFloorHeight();
bool canJump = false;
if ((y < (height1 - CLICK(1.5f)) || y < (height2 - CLICK(1.5f))) &&
@@ -152,7 +154,7 @@ namespace TEN::Entities::TR4
x = item->Pose.Position.x - dx;
z = item->Pose.Position.z - dz;
- int height4 = GetCollision(x, y, z, item->RoomNumber).Position.Floor;
+ int height4 = GetPointCollision(Vector3i(x, y, z), item->RoomNumber).GetFloorHeight();
AI_INFO AI;
short angle = 0;
diff --git a/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp b/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp
index e39adb3d5..6f346fabb 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp
@@ -3,6 +3,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/collision/floordata.h"
#include "Game/control/box.h"
#include "Game/control/lot.h"
@@ -20,6 +21,7 @@
#include "Math/Math.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Math;
namespace TEN::Entities::TR4
@@ -148,7 +150,7 @@ namespace TEN::Entities::TR4
auto* fx = &EffectList[fxNumber];
fx->pos.Position.x = (byte)GetRandomControl() + item->Pose.Position.x - 128;
- fx->pos.Position.y = GetCollision(item).Position.Floor;
+ fx->pos.Position.y = GetPointCollision(*item).GetFloorHeight();
fx->pos.Position.z = (byte)GetRandomControl() + item->Pose.Position.z - 128;
fx->roomNumber = item->RoomNumber;
fx->pos.Orientation.y = 2 * GetRandomControl();
@@ -223,15 +225,15 @@ namespace TEN::Entities::TR4
x += dx;
z += dz;
- int height1 = GetCollision(x, y, z, item->RoomNumber).Position.Floor;
+ int height1 = GetPointCollision(Vector3i(x, y, z), item->RoomNumber).GetFloorHeight();
x += dx;
z += dz;
- int height2 = GetCollision(x, y, z, item->RoomNumber).Position.Floor;
+ int height2 = GetPointCollision(Vector3i(x, y, z), item->RoomNumber).GetFloorHeight();
x += dx;
z += dz;
- int height3 = GetCollision(x, y, z, item->RoomNumber).Position.Floor;
+ int height3 = GetPointCollision(Vector3i(x, y, z), item->RoomNumber).GetFloorHeight();
int height = 0;
bool canJump1Block = true;
@@ -338,7 +340,7 @@ namespace TEN::Entities::TR4
x = item->Pose.Position.x + dx;
y = item->Pose.Position.y;
z = item->Pose.Position.z + dz;
- int height4 = GetCollision(x, y, z, item->RoomNumber).Position.Floor;
+ int height4 = GetPointCollision(Vector3i(x, y, z), item->RoomNumber).GetFloorHeight();
dx = 870 * phd_sin(item->Pose.Orientation.y + ANGLE(78.75f));
dz = 870 * phd_cos(item->Pose.Orientation.y + ANGLE(78.75f));
@@ -346,7 +348,7 @@ namespace TEN::Entities::TR4
x = item->Pose.Position.x + dx;
y = item->Pose.Position.y;
z = item->Pose.Position.z + dz;
- int height5 = GetCollision(x, y, z, item->RoomNumber).Position.Floor;
+ int height5 = GetPointCollision(Vector3i(x, y, z), item->RoomNumber).GetFloorHeight();
if (abs(height5 - item->Pose.Position.y) > CLICK(1))
jumpRight = false;
@@ -364,7 +366,7 @@ namespace TEN::Entities::TR4
x = item->Pose.Position.x + dx;
y = item->Pose.Position.y;
z = item->Pose.Position.z + dz;
- int height6 = GetCollision(x, y, z, item->RoomNumber).Position.Floor;
+ int height6 = GetPointCollision(Vector3i(x, y, z), item->RoomNumber).GetFloorHeight();
dx = 870 * phd_sin(item->Pose.Orientation.y - ANGLE(78.75f));
dz = 870 * phd_cos(item->Pose.Orientation.y - ANGLE(78.75f));
@@ -372,7 +374,7 @@ namespace TEN::Entities::TR4
x = item->Pose.Position.x + dx;
y = item->Pose.Position.y;
z = item->Pose.Position.z + dz;
- int height7 = GetCollision(x, y, z, item->RoomNumber).Position.Floor;
+ int height7 = GetPointCollision(Vector3i(x, y, z), item->RoomNumber).GetFloorHeight();
if (abs(height7 - item->Pose.Position.y) > CLICK(1) || height6 + CLICK(2) >= item->Pose.Position.y)
jumpLeft = false;
@@ -557,7 +559,7 @@ namespace TEN::Entities::TR4
creature->LOT.IsJumping = true;
- if (GetCollision(item).Position.Floor > item->Pose.Position.y + BLOCK(1))
+ if (GetPointCollision(*item).GetFloorHeight() > item->Pose.Position.y + BLOCK(1))
{
item->Animation.AnimNumber = Objects[ID_SKELETON].animIndex + 44;
item->Animation.FrameNumber = GetAnimData(item).frameBase;
@@ -641,8 +643,8 @@ namespace TEN::Entities::TR4
auto pos = GetJointPosition(item, 16);
- auto floor = GetCollision(x, y, z, item->RoomNumber).Block;
- if (floor->Stopper)
+ auto& sector = GetPointCollision(Vector3i(x, y, z), item->RoomNumber).GetSector();
+ if (sector.Stopper)
{
for (int i = 0; i < room->mesh.size(); i++)
{
@@ -654,7 +656,7 @@ namespace TEN::Entities::TR4
{
ShatterObject(0, staticMesh, -128, LaraItem->RoomNumber, 0);
SoundEffect(SFX_TR4_SMASH_ROCK, &item->Pose);
- floor->Stopper = false;
+ sector.Stopper = false;
TestTriggers(item, true);
break;
}
@@ -702,7 +704,7 @@ namespace TEN::Entities::TR4
case SKELETON_STATE_JUMP_FORWARD_1_BLOCK:
if (item->Animation.AnimNumber == Objects[item->ObjectNumber].animIndex + 43)
{
- if (GetCollision(item).Position.Floor > (item->Pose.Position.y + CLICK(5)))
+ if (GetPointCollision(*item).GetFloorHeight() > (item->Pose.Position.y + CLICK(5)))
{
item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + 44;
item->Animation.FrameNumber = GetAnimData(item).frameBase;
@@ -717,7 +719,7 @@ namespace TEN::Entities::TR4
case SKELETON_STATE_JUMP_CONTINUE:
case SKELETON_STATE_JUMP_START:
- if (GetCollision(item).Position.Floor <= item->Pose.Position.y)
+ if (GetPointCollision(*item).GetFloorHeight() <= item->Pose.Position.y)
{
if (item->Active)
{
@@ -750,7 +752,7 @@ namespace TEN::Entities::TR4
creature->LOT.IsJumping = false;
- if (GetCollision(item).Position.Floor <= (item->Pose.Position.y + BLOCK(1)))
+ if (GetPointCollision(*item).GetFloorHeight() <= (item->Pose.Position.y + BLOCK(1)))
{
if (Random::TestProbability(1 / 32.0f))
item->Animation.TargetState = 14;
diff --git a/TombEngine/Objects/TR4/Entity/tr4_sphinx.cpp b/TombEngine/Objects/TR4/Entity/tr4_sphinx.cpp
index b50c351fa..5fd89bdb2 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_sphinx.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_sphinx.cpp
@@ -2,6 +2,7 @@
#include "Objects/TR4/Entity/tr4_sphinx.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/box.h"
#include "Game/effects/debris.h"
#include "Game/effects/effects.h"
@@ -13,6 +14,8 @@
#include "Sound/sound.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
+
namespace TEN::Entities::TR4
{
constexpr auto SPHINX_ATTACK_DAMAGE = 200;
@@ -78,11 +81,11 @@ namespace TEN::Entities::TR4
int y = item->Pose.Position.y;
int z = item->Pose.Position.z + 614 * phd_cos(item->Pose.Orientation.y);
- auto probe = GetCollision(x, y, z, item->RoomNumber);
+ auto pointColl = GetPointCollision(Vector3i(x, y, z), item->RoomNumber);
- int height1 = probe.Position.Floor;
+ int height1 = pointColl.GetFloorHeight();
- if (item->Animation.ActiveState == SPHINX_STATE_RUN_FORWARD && probe.Block->Stopper)
+ if (item->Animation.ActiveState == SPHINX_STATE_RUN_FORWARD && pointColl.GetSector().Stopper)
{
auto* room = &g_Level.Rooms[item->RoomNumber];
@@ -97,8 +100,6 @@ namespace TEN::Entities::TR4
ShatterObject(nullptr, mesh, -64, item->RoomNumber, 0);
SoundEffect(SFX_TR4_SMASH_ROCK, &item->Pose);
- probe.Block = false;
-
TestTriggers(x, y, z, item->RoomNumber, true);
}
}
@@ -108,7 +109,7 @@ namespace TEN::Entities::TR4
y = item->Pose.Position.y;
z = item->Pose.Position.z - 614 * phd_cos(item->Pose.Orientation.y);
- int height2 = GetCollision(x, y, z, item->RoomNumber).Position.Floor;
+ int height2 = GetPointCollision(Vector3i(x, y, z), item->RoomNumber).GetFloorHeight();
phd_atan(1228, height2 - height1);
diff --git a/TombEngine/Objects/TR4/Entity/tr4_von_croy.cpp b/TombEngine/Objects/TR4/Entity/tr4_von_croy.cpp
index 0a0731328..96b7d8ed6 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_von_croy.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_von_croy.cpp
@@ -3,6 +3,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/box.h"
#include "Game/control/lot.h"
#include "Game/effects/effects.h"
@@ -16,6 +17,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Math;
namespace TEN::Entities::TR4
@@ -170,20 +172,20 @@ namespace TEN::Entities::TR4
x += dx;
z += dz;
- int height1 = GetCollision(x, item->Pose.Position.y, z, item->RoomNumber).Position.Floor;
+ int height1 = GetPointCollision(Vector3i(x, item->Pose.Position.y, z), item->RoomNumber).GetFloorHeight();
x += dx;
z += dz;
- int height2 = GetCollision(x, item->Pose.Position.y, z, item->RoomNumber).Position.Floor;
+ int height2 = GetPointCollision(Vector3i(x, item->Pose.Position.y, z), item->RoomNumber).GetFloorHeight();
x += dx;
z += dz;
- int height3 = GetCollision(x, item->Pose.Position.y, z, item->RoomNumber).Position.Floor;
+ int height3 = GetPointCollision(Vector3i(x, item->Pose.Position.y, z), item->RoomNumber).GetFloorHeight();
x += dx;
z += dz;
- auto probe = GetCollision(x, item->Pose.Position.y, z, item->RoomNumber);
- int height4 = probe.Position.Floor;
+ auto probe = GetPointCollision(Vector3i(x, item->Pose.Position.y, z), item->RoomNumber);
+ int height4 = probe.GetFloorHeight();
bool canJump1block = true;
if (item->BoxNumber == LaraItem->BoxNumber ||
@@ -419,13 +421,17 @@ namespace TEN::Entities::TR4
if (creature->MonkeySwingAhead)
{
- probe = GetCollision(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, probe.RoomNumber);
- if (probe.Position.Ceiling == (probe.Position.Floor - 1536))
+ probe = GetPointCollision(item->Pose.Position, probe.GetRoomNumber());
+ if (probe.GetCeilingHeight() == (probe.GetFloorHeight() - 1536))
{
if (item->TestMeshSwapFlags(VonCroyKnifeSwapJoints))
+ {
item->Animation.TargetState = VON_CROY_STATE_TOGGLE_KNIFE;
+ }
else
+ {
item->Animation.TargetState = VON_CROY_STATE_START_MONKEY;
+ }
break;
}
@@ -598,8 +604,8 @@ namespace TEN::Entities::TR4
item->Animation.TargetState = VON_CROY_STATE_MONKEY;
else
{
- probe = GetCollision(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, probe.RoomNumber);
- if (probe.Position.Ceiling == probe.Position.Floor - 1536)
+ probe = GetPointCollision(item->Pose.Position, probe.GetRoomNumber());
+ if (probe.GetCeilingHeight() == probe.GetFloorHeight() - 1536)
item->Animation.TargetState = VON_CROY_STATE_IDLE;
}
@@ -612,8 +618,8 @@ namespace TEN::Entities::TR4
if (item->BoxNumber == creature->LOT.TargetBox || !creature->MonkeySwingAhead)
{
- probe = GetCollision(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, probe.RoomNumber);
- if (probe.Position.Ceiling == (probe.Position.Floor - BLOCK(1.5f)))
+ probe = GetPointCollision(item->Pose.Position, probe.GetRoomNumber());
+ if (probe.GetCeilingHeight() == (probe.GetFloorHeight() - BLOCK(1.5f)))
item->Animation.TargetState = VON_CROY_STATE_START_MONKEY;
}
diff --git a/TombEngine/Objects/TR4/Object/tr4_senet.cpp b/TombEngine/Objects/TR4/Object/tr4_senet.cpp
index 46e633d71..f923e964c 100644
--- a/TombEngine/Objects/TR4/Object/tr4_senet.cpp
+++ b/TombEngine/Objects/TR4/Object/tr4_senet.cpp
@@ -12,7 +12,9 @@
#include "Specific/level.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Input;
int SenetPiecesNumber[6];
@@ -123,7 +125,7 @@ void GameSticksControl(short itemNumber)
else
item2->Pose.Position.z -= 128;
- probedRoomNumber = GetCollision(item2->Pose.Position.x, item2->Pose.Position.y - 32, item2->Pose.Position.z, item2->RoomNumber).RoomNumber;
+ probedRoomNumber = GetPointCollision(Vector3i(item2->Pose.Position.x, item2->Pose.Position.y - 32, item2->Pose.Position.z), item2->RoomNumber).GetRoomNumber();
if (item2->RoomNumber != probedRoomNumber)
ItemNewRoom(SenetPiecesNumber[ActivePiece], probedRoomNumber);
@@ -179,7 +181,7 @@ void GameSticksControl(short itemNumber)
item2->Pose.Position.x = SenetTargetX - BLOCK(4 * number) + BLOCK(7);
item2->Pose.Position.z = SenetTargetZ + BLOCK(i % 3);
- probedRoomNumber = GetCollision(item2->Pose.Position.x, item2->Pose.Position.y - 32, item2->Pose.Position.z, item2->RoomNumber).RoomNumber;
+ probedRoomNumber = GetPointCollision(Vector3i(item2->Pose.Position.x, item2->Pose.Position.y - 32, item2->Pose.Position.z), item2->RoomNumber).GetRoomNumber();
if (item2->RoomNumber != probedRoomNumber)
ItemNewRoom(SenetPiecesNumber[i], probedRoomNumber);
diff --git a/TombEngine/Objects/TR4/Vehicles/jeep.cpp b/TombEngine/Objects/TR4/Vehicles/jeep.cpp
index 8697f27bc..1a70f3fbe 100644
--- a/TombEngine/Objects/TR4/Vehicles/jeep.cpp
+++ b/TombEngine/Objects/TR4/Vehicles/jeep.cpp
@@ -4,6 +4,7 @@
#include "Game/animation.h"
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
+#include "Game/collision/PointCollision.h"
#include "Game/effects/effects.h"
#include "Game/effects/simple_particle.h"
#include "Game/effects/tomb4fx.h"
@@ -22,6 +23,7 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Input;
namespace TEN::Entities::Vehicles
@@ -372,16 +374,16 @@ namespace TEN::Entities::Vehicles
int y = jeepItem->Pose.Position.y;
int z = jeepItem->Pose.Position.z - JEEP_DISMOUNT_DISTANCE * phd_cos(angle);
- auto probe = GetCollision(x, y, z, jeepItem->RoomNumber);
+ auto probe = GetPointCollision(Vector3i(x, y, z), jeepItem->RoomNumber);
- if (probe.Position.FloorSlope || probe.Position.Floor == NO_HEIGHT)
+ if (probe.IsIllegalFloor() || probe.GetFloorHeight() == NO_HEIGHT)
return false;
- if (abs(probe.Position.Floor - jeepItem->Pose.Position.y) > BLOCK(1 / 2.0f))
+ if (abs(probe.GetFloorHeight() - jeepItem->Pose.Position.y) > BLOCK(1 / 2.0f))
return false;
- if ((probe.Position.Ceiling - jeepItem->Pose.Position.y) > -LARA_HEIGHT ||
- (probe.Position.Floor - probe.Position.Ceiling) < LARA_HEIGHT)
+ if ((probe.GetCeilingHeight() - jeepItem->Pose.Position.y) > -LARA_HEIGHT ||
+ (probe.GetFloorHeight() - probe.GetCeilingHeight()) < LARA_HEIGHT)
{
return false;
}
diff --git a/TombEngine/Objects/TR4/Vehicles/motorbike.cpp b/TombEngine/Objects/TR4/Vehicles/motorbike.cpp
index 60d276cab..25012ecac 100644
--- a/TombEngine/Objects/TR4/Vehicles/motorbike.cpp
+++ b/TombEngine/Objects/TR4/Vehicles/motorbike.cpp
@@ -5,6 +5,7 @@
#include "Game/animation.h"
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/control.h"
#include "Game/effects/effects.h"
#include "Game/effects/simple_particle.h"
@@ -23,6 +24,7 @@
#include "Specific/level.h"
using std::vector;
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Input;
using namespace TEN::Math::Random;
@@ -259,7 +261,7 @@ namespace TEN::Entities::Vehicles
x = 0;
z = 0;
- int floorHeight = GetCollision(old->x, pos->y, pos->z, motorbikeItem->RoomNumber).Position.Floor;
+ int floorHeight = GetPointCollision(Vector3i(old->x, pos->y, pos->z), motorbikeItem->RoomNumber).GetFloorHeight();
if (floorHeight < (old->y - CLICK(1)))
{
if (pos->z > old->z)
@@ -268,7 +270,7 @@ namespace TEN::Entities::Vehicles
z = BLOCK(1) - shiftZ;
}
- floorHeight = GetCollision(pos->x, pos->y, old->z, motorbikeItem->RoomNumber).Position.Floor;
+ floorHeight = GetPointCollision(Vector3i(pos->x, pos->y, old->z), motorbikeItem->RoomNumber).GetFloorHeight();
if (floorHeight < (old->y - CLICK(1)))
{
if (pos->x > old->x)
diff --git a/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp b/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp
index e489eca4e..1d4a94fd2 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp
@@ -3,6 +3,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/box.h"
#include "Game/effects/effects.h"
#include "Game/effects/Electricity.h"
@@ -20,6 +21,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Effects::Electricity;
using namespace TEN::Effects::Items;
using namespace TEN::Effects::Spark;
@@ -144,17 +146,17 @@ namespace TEN::Entities::Creatures::TR5
x += dx;
z += dz;
- int height1 = GetCollision(x, item.Pose.Position.y, z, item.RoomNumber).Position.Floor;
+ int height1 = GetPointCollision(Vector3i(x, item.Pose.Position.y, z), item.RoomNumber).GetFloorHeight();
x += dx;
z += dz;
- int height2 = GetCollision(x, item.Pose.Position.y, z, item.RoomNumber).Position.Floor;
+ int height2 = GetPointCollision(Vector3i(x, item.Pose.Position.y, z), item.RoomNumber).GetFloorHeight();
x += dx;
z += dz;
- auto pointColl = GetCollision(x, item.Pose.Position.y, z, item.RoomNumber);
- int roomNumber = pointColl.RoomNumber;
- int height3 = pointColl.Position.Floor;
+ auto pointColl = GetPointCollision(Vector3i(x, item.Pose.Position.y, z), item.RoomNumber);
+ int roomNumber = pointColl.GetRoomNumber();
+ int height3 = pointColl.GetFloorHeight();
bool canJump1block = true;
if (item.BoxNumber == LaraItem->BoxNumber ||
@@ -220,7 +222,7 @@ namespace TEN::Entities::Creatures::TR5
if (randomIndex == 5 || randomIndex == 7 || randomIndex == 10)
{
auto pos2 = Vector3::Zero;
- auto pointColl2 = GetCollision(pos2.x, pos2.y, pos2.z, item.RoomNumber);
+ auto pointColl2 = GetPointCollision(pos2, item.RoomNumber);
switch (randomIndex)
{
@@ -230,9 +232,9 @@ namespace TEN::Entities::Creatures::TR5
case 7:
pos2 = GetJointPosition(&item, 6, Vector3i(0, 0, 50)).ToVector3();
- pointColl2 = GetCollision(pos2.x, pos2.y, pos2.z, item.RoomNumber);
+ pointColl2 = GetPointCollision(pos2, item.RoomNumber);
- if (TestEnvironment(ENV_FLAG_WATER, pointColl2.RoomNumber) && item.HitPoints > 0)
+ if (TestEnvironment(ENV_FLAG_WATER, pointColl2.GetRoomNumber()) && item.HitPoints > 0)
{
DropPickups(&item);
DoDamage(&item, INT_MAX);
@@ -379,11 +381,11 @@ namespace TEN::Entities::Creatures::TR5
}
else
{
- pointColl = GetCollision(item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z, roomNumber);
- roomNumber = pointColl.RoomNumber;
- height = pointColl.Position.Floor;
+ pointColl = GetPointCollision(item.Pose.Position, roomNumber);
+ roomNumber = pointColl.GetRoomNumber();
+ height = pointColl.GetFloorHeight();
- if (pointColl.Position.Ceiling == (height - BLOCK(1.5f)))
+ if (pointColl.GetCeilingHeight() == (height - BLOCK(1.5f)))
item.Animation.TargetState = CYBORG_STATE_START_END_MONKEY;
else
item.Animation.TargetState = CYBORG_STATE_WALK;
@@ -481,11 +483,11 @@ namespace TEN::Entities::Creatures::TR5
if (item.BoxNumber == creature.LOT.TargetBox ||
!creature.MonkeySwingAhead)
{
- pointColl = GetCollision(item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z, roomNumber);
- roomNumber = pointColl.RoomNumber;
- height = pointColl.Position.Floor;
+ pointColl = GetPointCollision(item.Pose.Position, roomNumber);
+ roomNumber = pointColl.GetRoomNumber();
+ height = pointColl.GetFloorHeight();
- if (pointColl.Position.Ceiling == height - BLOCK(1.5f), 2)
+ if (pointColl.GetCeilingHeight() == height - BLOCK(1.5f), 2)
item.Animation.TargetState = CYBORG_STATE_IDLE;
}
else
@@ -503,11 +505,11 @@ namespace TEN::Entities::Creatures::TR5
if (item.BoxNumber == creature.LOT.TargetBox ||
!creature.MonkeySwingAhead)
{
- pointColl = GetCollision(item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z, roomNumber);
- roomNumber = pointColl.RoomNumber;
- height = pointColl.Position.Floor;
+ pointColl = GetPointCollision(item.Pose.Position, roomNumber);
+ roomNumber = pointColl.GetRoomNumber();
+ height = pointColl.GetFloorHeight();
- if (pointColl.Position.Ceiling == height - BLOCK(1.5f), 2)
+ if (pointColl.GetCeilingHeight() == height - BLOCK(1.5f), 2)
item.Animation.TargetState = CYBORG_STATE_START_END_MONKEY;
}
@@ -583,9 +585,9 @@ namespace TEN::Entities::Creatures::TR5
else if (item.Animation.ActiveState == CYBORG_STATE_DEATH && LaraItem->Effect.Type == EffectType::None)
{
auto pos = GetJointPosition(LaraItem, LM_RFOOT);
- auto footProbeRight = GetCollision(pos.x, pos.y, pos.z, LaraItem->RoomNumber);
+ auto footProbeRight = GetPointCollision(pos, LaraItem->RoomNumber);
pos = GetJointPosition(LaraItem, LM_LFOOT);
- auto footProbeLeft = GetCollision(pos.x, pos.y, pos.z, LaraItem->RoomNumber);
+ auto footProbeLeft = GetPointCollision(pos, LaraItem->RoomNumber);
short roomNumberLeft = LaraItem->RoomNumber;
GetFloor(pos.x, pos.y, pos.z, &roomNumberLeft);
@@ -599,8 +601,8 @@ namespace TEN::Entities::Creatures::TR5
short flipNumber = g_Level.Rooms[item.RoomNumber].flipNumber;
- if (TestEnvironment(ENV_FLAG_WATER, footProbeLeft.RoomNumber) ||
- TestEnvironment(ENV_FLAG_WATER, footProbeRight.RoomNumber))
+ if (TestEnvironment(ENV_FLAG_WATER, footProbeLeft.GetRoomNumber()) ||
+ TestEnvironment(ENV_FLAG_WATER, footProbeRight.GetRoomNumber()))
{
if (roomLeft->flipNumber == flipNumber || roomRight->flipNumber == flipNumber)
{
diff --git a/TombEngine/Objects/TR5/Entity/tr5_guard.cpp b/TombEngine/Objects/TR5/Entity/tr5_guard.cpp
index e02a89ca0..ce1cc5591 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_guard.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_guard.cpp
@@ -1149,15 +1149,15 @@ namespace TEN::Entities::Creatures::TR5
x += dx;
z += dz;
- int height1 = GetCollision(x, y, z, item->RoomNumber).Position.Floor;
+ int height1 = GetPointCollision(Vector3i(x, y, z), item->RoomNumber).GetFloorHeight();
x += dx;
z += dz;
- int height2 = GetCollision(x, y, z, item->RoomNumber).Position.Floor;
+ int height2 = GetPointCollision(Vector3i(x, y, z), item->RoomNumber).GetFloorHeight();
x += dx;
z += dz;
- int height3 = GetCollision(x, y, z, item->RoomNumber).Position.Floor;
+ int height3 = GetPointCollision(Vector3i(x, y, z), item->RoomNumber).GetFloorHeight();
int height = 0;
bool canJump1Sector = true;
diff --git a/TombEngine/Objects/TR5/Object/tr5_bodypart.cpp b/TombEngine/Objects/TR5/Object/tr5_bodypart.cpp
index 4ad272ffc..33baf715d 100644
--- a/TombEngine/Objects/TR5/Object/tr5_bodypart.cpp
+++ b/TombEngine/Objects/TR5/Object/tr5_bodypart.cpp
@@ -1,5 +1,6 @@
#include "framework.h"
#include "tr5_bodypart.h"
+
#include "Game/effects/effects.h"
#include "Math/Math.h"
#include "Sound/sound.h"
@@ -7,10 +8,12 @@
#include "Game/Lara/lara.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/items.h"
#include "Game/effects/tomb4fx.h"
#include "Math/Random.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Math::Random;
constexpr int BODY_PART_LIFE = 64;
@@ -76,18 +79,18 @@ void ControlBodyPart(short fxNumber)
TriggerFireFlame(fx->pos.Position.x, fx->pos.Position.y, fx->pos.Position.z, FlameType::Medium);
}
- auto pointColl = GetCollision(fx->pos.Position.x, fx->pos.Position.y, fx->pos.Position.z, fx->roomNumber);
+ auto pointColl = GetPointCollision(fx->pos.Position, fx->roomNumber);
if (!fx->counter)
{
- if (fx->pos.Position.y < pointColl.Position.Ceiling)
+ if (fx->pos.Position.y < pointColl.GetCeilingHeight())
{
- fx->pos.Position.y = pointColl.Position.Ceiling;
+ fx->pos.Position.y = pointColl.GetCeilingHeight();
fx->fallspeed = -fx->fallspeed;
fx->speed -= (fx->speed / 8);
}
- if (fx->pos.Position.y >= pointColl.Position.Floor)
+ if (fx->pos.Position.y >= pointColl.GetFloorHeight())
{
if (fx->flag2 & BODY_NO_BOUNCE)
{
@@ -119,7 +122,7 @@ void ControlBodyPart(short fxNumber)
return;
}
- if (y <= pointColl.Position.Floor)
+ if (y <= pointColl.GetFloorHeight())
{
// Remove if touched floor (no bounce mode).
if (fx->flag2 & BODY_PART_EXPLODE)
@@ -201,19 +204,19 @@ void ControlBodyPart(short fxNumber)
}
}
- if (pointColl.RoomNumber != fx->roomNumber)
+ if (pointColl.GetRoomNumber() != fx->roomNumber)
{
- if (TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, pointColl.RoomNumber) &&
+ if (TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, pointColl.GetRoomNumber()) &&
!TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, fx->roomNumber))
{
- int waterHeight = GetWaterHeight(fx->pos.Position.x, fx->pos.Position.y, fx->pos.Position.z, pointColl.RoomNumber);
+ int waterHeight = GetWaterHeight(fx->pos.Position.x, fx->pos.Position.y, fx->pos.Position.z, pointColl.GetRoomNumber());
SplashSetup.y = waterHeight - 1;
SplashSetup.x = fx->pos.Position.x;
SplashSetup.z = fx->pos.Position.z;
SplashSetup.splashPower = fx->fallspeed;
SplashSetup.innerRadius = 48;
- SetupSplash(&SplashSetup, pointColl.RoomNumber);
+ SetupSplash(&SplashSetup, pointColl.GetRoomNumber());
// Remove if touched water.
if (fx->flag2 & BODY_PART_EXPLODE)
@@ -223,6 +226,6 @@ void ControlBodyPart(short fxNumber)
}
}
- EffectNewRoom(fxNumber, pointColl.RoomNumber);
+ EffectNewRoom(fxNumber, pointColl.GetRoomNumber());
}
}
\ No newline at end of file
diff --git a/TombEngine/Objects/TR5/Object/tr5_missile.cpp b/TombEngine/Objects/TR5/Object/tr5_missile.cpp
index 93bdbe42b..4ee9a44af 100644
--- a/TombEngine/Objects/TR5/Object/tr5_missile.cpp
+++ b/TombEngine/Objects/TR5/Object/tr5_missile.cpp
@@ -2,6 +2,7 @@
#include "tr5_missile.h"
#include "Game/items.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/collision/sphere.h"
#include "Game/effects/tomb4fx.h"
#include "Game/effects/effects.h"
@@ -15,6 +16,7 @@
#include "Game/effects/item_fx.h"
#include "Math/Math.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Effects::Items;
using namespace TEN::Math;
@@ -106,9 +108,9 @@ void MissileControl(short itemNumber)
fx->pos.Position.y += fx->speed * phd_sin(-fx->pos.Orientation.x);
fx->pos.Position.z += c * phd_cos(fx->pos.Orientation.y);
- auto probe = GetCollision(fx->pos.Position.x, fx->pos.Position.y, fx->pos.Position.z, fx->roomNumber);
+ auto probe = GetPointCollision(fx->pos.Position, fx->roomNumber);
- if (fx->pos.Position.y >= probe.Position.Floor || fx->pos.Position.y <= probe.Position.Ceiling)
+ if (fx->pos.Position.y >= probe.GetFloorHeight() || fx->pos.Position.y <= probe.GetCeilingHeight())
{
fx->pos.Position.x = x;
fx->pos.Position.y = y;
@@ -182,8 +184,8 @@ void MissileControl(short itemNumber)
}
else
{
- if (probe.RoomNumber != fx->roomNumber)
- EffectNewRoom(itemNumber, probe.RoomNumber);
+ if (probe.GetRoomNumber() != fx->roomNumber)
+ EffectNewRoom(itemNumber, probe.GetRoomNumber());
if (GlobalCounter & 1)
{
diff --git a/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp b/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp
index 7f04f59c3..67c9b2bbd 100644
--- a/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp
+++ b/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp
@@ -4,6 +4,7 @@
#include "Game/animation.h"
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
+#include "Game/collision/PointCollision.h"
#include "Game/collision/sphere.h"
#include "Game/control/control.h"
#include "Game/effects/effects.h"
@@ -15,6 +16,8 @@
#include "Sound/sound.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
+
constexpr auto ROLLING_BALL_MAX_VELOCITY = BLOCK(3);
void RollingBallCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
@@ -66,7 +69,7 @@ void RollingBallControl(short itemNumber)
item->Pose.Position.z += item->ItemFlags[1] / hDivider;
item->Animation.Velocity.z = Vector3i::Distance(item->Pose.Position, oldPos.Position);
- int dh = GetCollision(item).Position.Floor - bigRadius;
+ int dh = GetPointCollision(*item).GetFloorHeight() - bigRadius;
if (item->Pose.Position.y > dh)
{
@@ -106,20 +109,20 @@ void RollingBallControl(short itemNumber)
int leftX = item->Pose.Position.x - smallRadius;
int leftZ = item->Pose.Position.z;
- auto frontFloor = GetCollision(frontX, item->Pose.Position.y, frontZ, item->RoomNumber);
- auto backFloor = GetCollision(backX, item->Pose.Position.y, backZ, item->RoomNumber);
- auto rightFloor = GetCollision(rightX, item->Pose.Position.y, rightZ, item->RoomNumber);
- auto leftFloor = GetCollision(leftX, item->Pose.Position.y, leftZ, item->RoomNumber);
+ auto frontFloor = GetPointCollision(Vector3i(frontX, item->Pose.Position.y, frontZ), item->RoomNumber);
+ auto backFloor = GetPointCollision(Vector3i(backX, item->Pose.Position.y, backZ), item->RoomNumber);
+ auto rightFloor = GetPointCollision(Vector3i(rightX, item->Pose.Position.y, rightZ), item->RoomNumber);
+ auto leftFloor = GetPointCollision(Vector3i(leftX, item->Pose.Position.y, leftZ), item->RoomNumber);
- int frontHeight = frontFloor.Position.Floor - bigRadius;
- int backHeight = backFloor.Position.Floor - bigRadius;
- int rightHeight = rightFloor.Position.Floor - bigRadius;
- int leftHeight = leftFloor.Position.Floor - bigRadius;
+ int frontHeight = frontFloor.GetFloorHeight() - bigRadius;
+ int backHeight = backFloor.GetFloorHeight() - bigRadius;
+ int rightHeight = rightFloor.GetFloorHeight() - bigRadius;
+ int leftHeight = leftFloor.GetFloorHeight() - bigRadius;
- int frontCeiling = frontFloor.Position.Ceiling + bigRadius;
- int backCeiling = backFloor.Position.Ceiling + bigRadius;
- int rightCeiling = rightFloor.Position.Ceiling + bigRadius;
- int leftCeiling = leftFloor.Position.Ceiling + bigRadius;
+ int frontCeiling = frontFloor.GetCeilingHeight() + bigRadius;
+ int backCeiling = backFloor.GetCeilingHeight() + bigRadius;
+ int rightCeiling = rightFloor.GetCeilingHeight() + bigRadius;
+ int leftCeiling = leftFloor.GetCeilingHeight() + bigRadius;
frontX = item->Pose.Position.x;
frontZ = item->Pose.Position.z + bigRadius;
@@ -130,20 +133,20 @@ void RollingBallControl(short itemNumber)
leftX = item->Pose.Position.x - bigRadius;
leftZ = item->Pose.Position.z;
- auto fronFarFloor = GetCollision(frontX, item->Pose.Position.y, frontZ, item->RoomNumber);
- auto backFarFloor = GetCollision(backX, item->Pose.Position.y, backZ, item->RoomNumber);
- auto rightFarFloor = GetCollision(rightX, item->Pose.Position.y, rightZ, item->RoomNumber);
- auto leftFarFloor = GetCollision(leftX, item->Pose.Position.y, leftZ, item->RoomNumber);
+ auto fronFarFloor = GetPointCollision(Vector3i(frontX, item->Pose.Position.y, frontZ), item->RoomNumber);
+ auto backFarFloor = GetPointCollision(Vector3i(backX, item->Pose.Position.y, backZ), item->RoomNumber);
+ auto rightFarFloor = GetPointCollision(Vector3i(rightX, item->Pose.Position.y, rightZ), item->RoomNumber);
+ auto leftFarFloor = GetPointCollision(Vector3i(leftX, item->Pose.Position.y, leftZ), item->RoomNumber);
- int frontFarHeight = fronFarFloor.Position.Floor - bigRadius;
- int backFarHeight = backFarFloor.Position.Floor - bigRadius;
- int rightFarHeight = rightFarFloor.Position.Floor - bigRadius;
- int leftFarHeight = leftFarFloor.Position.Floor - bigRadius;
+ int frontFarHeight = fronFarFloor.GetFloorHeight() - bigRadius;
+ int backFarHeight = backFarFloor.GetFloorHeight() - bigRadius;
+ int rightFarHeight = rightFarFloor.GetFloorHeight() - bigRadius;
+ int leftFarHeight = leftFarFloor.GetFloorHeight() - bigRadius;
- int frontFarCeiling = fronFarFloor.Position.Ceiling + bigRadius;
- int backFarCeiling = backFarFloor.Position.Ceiling + bigRadius;
- int rightFarCeiling = rightFarFloor.Position.Ceiling + bigRadius;
- int leftFarCeiling = leftFarFloor.Position.Ceiling + bigRadius;
+ int frontFarCeiling = fronFarFloor.GetCeilingHeight() + bigRadius;
+ int backFarCeiling = backFarFloor.GetCeilingHeight() + bigRadius;
+ int rightFarCeiling = rightFarFloor.GetCeilingHeight() + bigRadius;
+ int leftFarCeiling = leftFarFloor.GetCeilingHeight() + bigRadius;
if (item->Pose.Position.y - dh > -CLICK(1) ||
item->Pose.Position.y - frontFarHeight >= CLICK(2) ||
@@ -406,12 +409,12 @@ void ClassicRollingBallControl(short itemNum)
AnimateItem(item);
- auto coll = GetCollision(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->RoomNumber);
+ auto pointColl = GetPointCollision(*item);
- item->Floor = coll.Position.Floor;
+ item->Floor = pointColl.GetFloorHeight();
- if (item->RoomNumber != coll.RoomNumber)
- ItemNewRoom(itemNum, coll.RoomNumber);
+ if (item->RoomNumber != pointColl.GetRoomNumber())
+ ItemNewRoom(itemNum, pointColl.GetRoomNumber());
if (item->Pose.Position.y >= item->Floor - CLICK(1))
{
@@ -443,8 +446,8 @@ void ClassicRollingBallControl(short itemNum)
int x = item->Pose.Position.x + dist * phd_sin(item->Pose.Orientation.y);
int z = item->Pose.Position.z + dist * phd_cos(item->Pose.Orientation.y);
- int y1 = GetCollision(x, item->Pose.Position.y, z, item->RoomNumber).Position.Floor;
- int y2 = GetCollision(x, item->Pose.Position.y - ydist, z, item->RoomNumber).Position.Ceiling;
+ int y1 = GetPointCollision(Vector3i(x, item->Pose.Position.y, z), item->RoomNumber).GetFloorHeight();
+ int y2 = GetPointCollision(Vector3i(x, item->Pose.Position.y - ydist, z), item->RoomNumber).GetCeilingHeight();
if (y1 < item->Pose.Position.y || y2 > (item->Pose.Position.y - ydist))
{
diff --git a/TombEngine/Objects/Utils/VehicleHelpers.cpp b/TombEngine/Objects/Utils/VehicleHelpers.cpp
index d007215fc..d1c2a8081 100644
--- a/TombEngine/Objects/Utils/VehicleHelpers.cpp
+++ b/TombEngine/Objects/Utils/VehicleHelpers.cpp
@@ -2,6 +2,7 @@
#include "Objects/Utils/VehicleHelpers.h"
#include "Game/collision/collide_item.h"
+#include "Game/collision/PointCollision.h"
#include "Game/collision/sphere.h"
#include "Game/effects/simple_particle.h"
#include "Game/effects/Streamer.h"
@@ -15,6 +16,7 @@
#include "Sound/sound.h"
#include "Specific/Input/Input.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Effects::Streamer;
using namespace TEN::Hud;
using namespace TEN::Input;
@@ -154,15 +156,15 @@ namespace TEN::Entities::Vehicles
pos->z = vehicleItem->Pose.Position.z + (forward * cosY) - (right * sinY);
// Get collision a bit higher to be able to detect bridges.
- auto probe = GetCollision(pos->x, pos->y - CLICK(2), pos->z, vehicleItem->RoomNumber);
+ auto probe = GetPointCollision(Vector3i(pos->x, pos->y - CLICK(2), pos->z), vehicleItem->RoomNumber);
- if (pos->y < probe.Position.Ceiling || probe.Position.Ceiling == NO_HEIGHT)
+ if (pos->y < probe.GetCeilingHeight() || probe.GetCeilingHeight() == NO_HEIGHT)
return NO_HEIGHT;
- if (pos->y > probe.Position.Floor && clamp)
- pos->y = probe.Position.Floor;
+ if (pos->y > probe.GetFloorHeight() && clamp)
+ pos->y = probe.GetFloorHeight();
- return probe.Position.Floor;
+ return probe.GetFloorHeight();
}
int GetVehicleWaterHeight(ItemInfo* vehicleItem, int forward, int right, bool clamp, Vector3i* pos)
@@ -175,12 +177,12 @@ namespace TEN::Entities::Vehicles
point = Vector3::Transform(point, world);
*pos = Vector3i(point);
- auto pointColl = GetCollision(pos->x, pos->y, pos->z, vehicleItem->RoomNumber);
- int height = GetWaterHeight(pos->x, pos->y, pos->z, pointColl.RoomNumber);
+ auto pointColl = GetPointCollision(*pos, vehicleItem->RoomNumber);
+ int height = GetWaterHeight(pos->x, pos->y, pos->z, pointColl.GetRoomNumber());
if (height == NO_HEIGHT)
{
- height = pointColl.Position.Floor;
+ height = pointColl.GetFloorHeight();
if (height == NO_HEIGHT)
return height;
}
From 4ee1dda75f41f4c4177ab2840dc4896877b40cf1 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Fri, 23 Feb 2024 20:41:22 +1100
Subject: [PATCH 058/410] Remove last remnants of GetCollision() and related
structs; remove old collision functions
---
TombEngine/Game/Lara/PlayerContext.cpp | 146 ++++++++--------
TombEngine/Game/Lara/PlayerContextData.h | 6 +-
TombEngine/Game/Lara/lara.cpp | 2 +-
TombEngine/Game/Lara/lara_collide.cpp | 6 +-
TombEngine/Game/Lara/lara_helpers.cpp | 16 +-
TombEngine/Game/Lara/lara_one_gun.cpp | 20 +--
TombEngine/Game/Lara/lara_one_gun.h | 1 +
TombEngine/Game/Lara/lara_overhang.cpp | 8 +-
TombEngine/Game/Lara/lara_tests.cpp | 162 ++++++++----------
TombEngine/Game/Lara/lara_tests.h | 2 -
TombEngine/Game/collision/PointCollision.cpp | 5 +-
TombEngine/Game/collision/collide_room.cpp | 50 +-----
TombEngine/Game/collision/collide_room.h | 105 +++++-------
TombEngine/Game/control/box.cpp | 36 ++--
TombEngine/Game/control/trigger.cpp | 8 +-
TombEngine/Game/control/volume.cpp | 4 +-
TombEngine/Game/control/volume.h | 4 +-
TombEngine/Game/effects/bubble.cpp | 2 +-
TombEngine/Game/effects/effects.cpp | 14 +-
TombEngine/Game/pickup/pickup.cpp | 14 +-
TombEngine/Objects/Effects/flame_emitters.cpp | 16 +-
.../Object/Pushable/PushableCollision.cpp | 2 +-
.../Object/Pushable/PushableObject.cpp | 2 +-
.../Generic/Object/Pushable/PushableStack.cpp | 8 +-
.../Objects/TR1/Entity/tr1_doppelganger.cpp | 6 +-
TombEngine/Objects/TR1/Trap/DamoclesSword.cpp | 8 +-
.../Objects/TR2/Trap/tr2_spinningblade.cpp | 10 +-
TombEngine/Objects/TR2/Vehicles/skidoo.cpp | 34 ++--
TombEngine/Objects/TR2/Vehicles/speedboat.cpp | 6 +-
.../Objects/TR3/Entity/tr3_scuba_diver.cpp | 11 +-
TombEngine/Objects/TR3/Object/corpse.cpp | 8 +-
.../Objects/TR3/Trap/ElectricCleaner.cpp | 2 +-
TombEngine/Objects/TR3/Trap/train.cpp | 2 +-
TombEngine/Objects/TR3/Vehicles/kayak.cpp | 24 +--
TombEngine/Objects/TR3/Vehicles/minecart.cpp | 27 +--
TombEngine/Objects/TR3/Vehicles/quad_bike.cpp | 28 +--
TombEngine/Objects/TR4/Entity/Wraith.cpp | 18 +-
.../TR4/Object/tr4_clockwork_beetle.cpp | 5 +-
TombEngine/Objects/TR4/Object/tr4_mapper.cpp | 5 +-
TombEngine/Objects/TR4/Trap/SpikyCeiling.cpp | 13 +-
TombEngine/Objects/TR4/Trap/SpikyWall.cpp | 26 +--
.../Objects/TR4/Trap/tr4_joby_spikes.cpp | 9 +-
.../Objects/TR4/Trap/tr4_slicerdicer.cpp | 5 +-
.../Objects/TR4/Trap/tr4_teethspike.cpp | 5 +-
TombEngine/Objects/TR4/Vehicles/motorbike.cpp | 28 +--
.../Objects/TR5/Entity/tr5_submarine.cpp | 15 +-
.../Objects/TR5/Object/tr5_rollingball.cpp | 2 +-
.../TR5/Object/tr5_twoblockplatform.cpp | 11 +-
TombEngine/Objects/TR5/Trap/LaserBarrier.cpp | 6 +-
TombEngine/Objects/TR5/Trap/ZipLine.cpp | 10 +-
.../Objects/TR5/Trap/tr5_fallingceiling.cpp | 11 +-
51 files changed, 484 insertions(+), 490 deletions(-)
diff --git a/TombEngine/Game/Lara/PlayerContext.cpp b/TombEngine/Game/Lara/PlayerContext.cpp
index 633ee93e8..2ba92b6cc 100644
--- a/TombEngine/Game/Lara/PlayerContext.cpp
+++ b/TombEngine/Game/Lara/PlayerContext.cpp
@@ -3,6 +3,7 @@
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/collision/floordata.h"
#include "Game/control/los.h"
#include "Game/items.h"
@@ -14,6 +15,7 @@
#include "Specific/Input/Input.h"
using namespace TEN::Collision::Floordata;
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Input;
namespace TEN::Entities::Player
@@ -35,8 +37,8 @@ namespace TEN::Entities::Player
const auto& player = GetLaraInfo(item);
// Get point collision.
- auto pointColl = GetCollision(&item, 0, 0, -coll.Setup.Height / 2); // NOTE: Height offset required for correct bridge collision.
- int relFloorHeight = pointColl.Position.Floor - item.Pose.Position.y;
+ auto pointColl = GetPointCollision(item, 0, 0, -coll.Setup.Height / 2); // NOTE: Height offset required for correct bridge collision.
+ int relFloorHeight = pointColl.GetFloorHeight() - item.Pose.Position.y;
// 1) Test if player is already aligned with floor.
if (relFloorHeight == 0)
@@ -61,8 +63,8 @@ namespace TEN::Entities::Player
constexpr auto UPPER_FLOOR_BOUND_DOWN = CLICK(0.75f);
// Get point collision.
- auto pointColl = GetCollision(&item, 0, 0, -coll.Setup.Height / 2); // NOTE: Height offset required for correct bridge collision.
- int relFloorHeight = pointColl.Position.Floor - item.Pose.Position.y;
+ auto pointColl = GetPointCollision(item, 0, 0, -coll.Setup.Height / 2); // NOTE: Height offset required for correct bridge collision.
+ int relFloorHeight = pointColl.GetFloorHeight() - item.Pose.Position.y;
// Determine appropriate floor bounds.
int lowerFloorBound = isGoingUp ? LOWER_FLOOR_BOUND_UP : LOWER_FLOOR_BOUND_DOWN;
@@ -167,30 +169,30 @@ namespace TEN::Entities::Player
int playerHeight = isCrawling ? LARA_HEIGHT_CRAWL : coll.Setup.Height;
// Get point collision.
- auto pointColl = GetCollision(&item, setup.HeadingAngle, OFFSET_RADIUS(playerRadius), -playerHeight);
+ auto pointColl = GetPointCollision(item, setup.HeadingAngle, OFFSET_RADIUS(playerRadius), -playerHeight);
int vPos = item.Pose.Position.y;
int vPosTop = vPos - playerHeight;
// Calculate slope aspect delta angle.
- short aspectAngle = Geometry::GetSurfaceAspectAngle(pointColl.FloorNormal);
+ short aspectAngle = Geometry::GetSurfaceAspectAngle(pointColl.GetFloorNormal());
short aspectAngleDelta = Geometry::GetShortestAngle(setup.HeadingAngle, aspectAngle);
- // 1) Check for slippery slope below floor (if applicable).
- if (setup.TestSlipperySlopeBelow &&
- (pointColl.Position.FloorSlope && abs(aspectAngleDelta) <= SLOPE_ASPECT_ANGLE_DELTA_MAX))
+ // 1) Check for illegal slope below floor (if applicable).
+ if (setup.TestIllegalFloorBelow &&
+ (pointColl.IsIllegalFloor() && abs(aspectAngleDelta) <= SLOPE_ASPECT_ANGLE_DELTA_MAX))
{
return false;
}
- // 1) Check for slippery slope above floor (if applicable).
- if (setup.TestSlipperySlopeAbove &&
- (pointColl.Position.FloorSlope && abs(aspectAngleDelta) >= SLOPE_ASPECT_ANGLE_DELTA_MAX))
+ // 1) Check for illegal slope above floor (if applicable).
+ if (setup.TestIllegalFloorAbove &&
+ (pointColl.IsIllegalFloor() && abs(aspectAngleDelta) >= SLOPE_ASPECT_ANGLE_DELTA_MAX))
{
return false;
}
// 3) Check for death floor (if applicable).
- if (setup.TestDeathFloor && pointColl.Block->Flags.Death)
+ if (setup.TestDeathFloor && pointColl.GetSector().Flags.Death)
return false;
// LOS setup at upper floor bound.
@@ -200,9 +202,9 @@ namespace TEN::Entities::Player
item.Pose.Position.z,
item.RoomNumber);
auto target0 = GameVector(
- pointColl.Coordinates.x,
+ pointColl.GetPosition().x,
(vPos + setup.UpperFloorBound) - 1,
- pointColl.Coordinates.z,
+ pointColl.GetPosition().z,
item.RoomNumber);
// LOS setup at lowest ceiling bound (player height).
@@ -212,9 +214,9 @@ namespace TEN::Entities::Player
item.Pose.Position.z,
item.RoomNumber);
auto target1 = GameVector(
- pointColl.Coordinates.x,
+ pointColl.GetPosition().x,
vPosTop + 1,
- pointColl.Coordinates.z,
+ pointColl.GetPosition().z,
item.RoomNumber);
// Calculate LOS direction.
@@ -232,9 +234,9 @@ namespace TEN::Entities::Player
if (!LOS(&origin0, &target0) || !LOS(&origin1, &target1))
return false;
- int relFloorHeight = pointColl.Position.Floor - vPos;
- int relCeilHeight = pointColl.Position.Ceiling - vPos;
- int floorToCeilHeight = abs(pointColl.Position.Ceiling - pointColl.Position.Floor);
+ int relFloorHeight = pointColl.GetFloorHeight() - vPos;
+ int relCeilHeight = pointColl.GetCeilingHeight() - vPos;
+ int floorToCeilHeight = abs(pointColl.GetCeilingHeight() - pointColl.GetFloorHeight());
// 6) Assess point collision.
if (relFloorHeight <= setup.LowerFloorBound && // Floor height is above lower floor bound.
@@ -400,12 +402,12 @@ namespace TEN::Entities::Player
return false;
// Get point collision.
- auto pointColl = GetCollision(&item, 0, 0, -coll.Setup.Height / 2); // NOTE: Offset required for correct bridge collision.
- int relFloorHeight = pointColl.Position.Floor - item.Pose.Position.y;
+ auto pointColl = GetPointCollision(item, 0, 0, -coll.Setup.Height / 2); // NOTE: Offset required for correct bridge collision.
+ int relFloorHeight = pointColl.GetFloorHeight() - item.Pose.Position.y;
// 2) Assess point collision.
if (abs(relFloorHeight) <= ABS_FLOOR_BOUND && // Floor height is within upper/lower floor bounds.
- pointColl.Position.FloorSlope) // Floor is a slippery slope.
+ pointColl.IsIllegalFloor()) // Floor is a slippery slope.
{
return true;
}
@@ -432,8 +434,8 @@ namespace TEN::Entities::Player
float radius = TestState(item.Animation.ActiveState, CROUCH_STATES) ? LARA_RADIUS_CRAWL : LARA_RADIUS;
// Get center point collision.
- auto pointCollCenter = GetCollision(&item, 0, 0.0f, -LARA_HEIGHT / 2);
- int floorToCeilHeightCenter = abs(pointCollCenter.Position.Ceiling - pointCollCenter.Position.Floor);
+ auto pointCollCenter = GetPointCollision(item, 0, 0.0f, -LARA_HEIGHT / 2);
+ int floorToCeilHeightCenter = abs(pointCollCenter.GetCeilingHeight() - pointCollCenter.GetFloorHeight());
// Assess center point collision.
if (floorToCeilHeightCenter < LARA_HEIGHT || // Floor-to-ceiling height isn't too wide.
@@ -445,9 +447,9 @@ namespace TEN::Entities::Player
// TODO: Check whether < or <= and > or >=.
// Get front point collision.
- auto pointCollFront = GetCollision(&item, item.Pose.Orientation.y, radius, -coll.Setup.Height);
- int floorToCeilHeightFront = abs(pointCollFront.Position.Ceiling - pointCollFront.Position.Floor);
- int relFloorHeightFront = abs(pointCollFront.Position.Floor - pointCollCenter.Position.Floor);
+ auto pointCollFront = GetPointCollision(item, item.Pose.Orientation.y, radius, -coll.Setup.Height);
+ int floorToCeilHeightFront = abs(pointCollFront.GetCeilingHeight() - pointCollFront.GetFloorHeight());
+ int relFloorHeightFront = abs(pointCollFront.GetFloorHeight() - pointCollCenter.GetFloorHeight());
// Assess front point collision.
if (relFloorHeightFront <= CRAWL_STEPUP_HEIGHT && // Floor is within upper/lower floor bounds.
@@ -458,9 +460,9 @@ namespace TEN::Entities::Player
}
// Get back point collision.
- auto pointCollBack = GetCollision(&item, item.Pose.Orientation.y, -radius, -coll.Setup.Height);
- int floorToCeilHeightBack = abs(pointCollBack.Position.Ceiling - pointCollBack.Position.Floor);
- int relFloorHeightBack = abs(pointCollBack.Position.Floor - pointCollCenter.Position.Floor);
+ auto pointCollBack = GetPointCollision(item, item.Pose.Orientation.y, -radius, -coll.Setup.Height);
+ int floorToCeilHeightBack = abs(pointCollBack.GetCeilingHeight() - pointCollBack.GetFloorHeight());
+ int relFloorHeightBack = abs(pointCollBack.GetFloorHeight() - pointCollCenter.GetFloorHeight());
// Assess back point collision.
if (relFloorHeightBack <= CRAWL_STEPUP_HEIGHT && // Floor is within upper/lower floor bounds.
@@ -526,22 +528,22 @@ namespace TEN::Entities::Player
// TODO: Extend point collision struct to also find water depths.
float dist = 0.0f;
- auto pointColl0 = GetCollision(&item);
+ auto pointColl0 = GetPointCollision(item);
// 3) Test continuity of path.
while (dist < PROBE_DIST_MAX)
{
// Get point collision.
dist += STEP_DIST;
- auto pointColl1 = GetCollision(&item, item.Pose.Orientation.y, dist, -LARA_HEIGHT_CRAWL);
+ auto pointColl1 = GetPointCollision(item, item.Pose.Orientation.y, dist, -LARA_HEIGHT_CRAWL);
- int floorHeightDelta = abs(pointColl0.Position.Floor - pointColl1.Position.Floor);
- int floorToCeilHeight = abs(pointColl1.Position.Ceiling - pointColl1.Position.Floor);
+ int floorHeightDelta = abs(pointColl0.GetFloorHeight() - pointColl1.GetFloorHeight());
+ int floorToCeilHeight = abs(pointColl1.GetCeilingHeight() - pointColl1.GetFloorHeight());
// Assess point collision.
if (floorHeightDelta > FLOOR_BOUND || // Avoid floor height delta beyond crawl stepup threshold.
floorToCeilHeight <= FLOOR_TO_CEIL_HEIGHT_MAX || // Avoid narrow spaces.
- pointColl1.Position.FloorSlope) // Avoid slippery floor slopes.
+ pointColl1.IsIllegalFloor()) // Avoid slippery floor slopes.
{
return false;
}
@@ -580,8 +582,8 @@ namespace TEN::Entities::Player
constexpr auto UPPER_CEIL_BOUND = -MONKEY_STEPUP_HEIGHT;
// Get point collision.
- auto pointColl = GetCollision(&item);
- int relCeilHeight = pointColl.Position.Ceiling - (item.Pose.Position.y - LARA_HEIGHT_MONKEY);
+ auto pointColl = GetPointCollision(item);
+ int relCeilHeight = pointColl.GetCeilingHeight() - (item.Pose.Position.y - LARA_HEIGHT_MONKEY);
// Assess point collision.
if (relCeilHeight <= LOWER_CEIL_BOUND && // Ceiling height is above lower ceiling bound.
@@ -604,14 +606,14 @@ namespace TEN::Entities::Player
return true;
// Get point collision.
- auto pointColl = GetCollision(&item);
+ auto pointColl = GetPointCollision(item);
// 2) Test for slippery ceiling slope and check if overhang climb is disabled.
- if (pointColl.Position.CeilingSlope && !g_GameFlow->HasOverhangClimb())
+ if (pointColl.IsIllegalCeiling() && !g_GameFlow->HasOverhangClimb())
return true;
// 3) Assess point collision.
- int relCeilHeight = pointColl.Position.Ceiling - (item.Pose.Position.y - LARA_HEIGHT_MONKEY);
+ int relCeilHeight = pointColl.GetCeilingHeight() - (item.Pose.Position.y - LARA_HEIGHT_MONKEY);
if (abs(relCeilHeight) > ABS_CEIL_BOUND) // Ceiling height is within lower/upper ceiling bound.
return true;
@@ -630,9 +632,9 @@ namespace TEN::Entities::Player
return false;
// Get point collision.
- auto pointColl = GetCollision(&item);
- int relCeilHeight = pointColl.Position.Ceiling - (item.Pose.Position.y - LARA_HEIGHT_MONKEY);
- int floorToCeilHeight = abs(pointColl.Position.Ceiling - pointColl.Position.Floor);
+ auto pointColl = GetPointCollision(item);
+ int relCeilHeight = pointColl.GetCeilingHeight() - (item.Pose.Position.y - LARA_HEIGHT_MONKEY);
+ int floorToCeilHeight = abs(pointColl.GetCeilingHeight() - pointColl.GetFloorHeight());
// 2) Assess collision with ceiling.
if (relCeilHeight < 0 &&
@@ -658,14 +660,14 @@ namespace TEN::Entities::Player
constexpr auto PLAYER_HEIGHT = LARA_HEIGHT_MONKEY;
// Get point collision.
- auto pointColl = GetCollision(&item, setup.HeadingAngle, OFFSET_RADIUS(coll.Setup.Radius));
+ auto pointColl = GetPointCollision(item, setup.HeadingAngle, OFFSET_RADIUS(coll.Setup.Radius));
// 1) Test if ceiling is monkey swing.
- if (!pointColl.BottomBlock->Flags.Monkeyswing)
+ if (!pointColl.GetBottomSector().Flags.Monkeyswing)
return false;
- // 2) Test for ceiling slippery slope.
- if (pointColl.Position.CeilingSlope)
+ // 2) Test for illegal ceiling.
+ if (pointColl.IsIllegalCeiling())
return false;
int vPos = item.Pose.Position.y;
@@ -678,9 +680,9 @@ namespace TEN::Entities::Player
item.Pose.Position.z,
item.RoomNumber);
auto target0 = GameVector(
- pointColl.Coordinates.x,
+ pointColl.GetPosition().x,
vPos - 1,
- pointColl.Coordinates.z,
+ pointColl.GetPosition().z,
item.RoomNumber);
// Raycast setup at lower ceiling bound.
@@ -690,9 +692,9 @@ namespace TEN::Entities::Player
item.Pose.Position.z,
item.RoomNumber);
auto target1 = GameVector(
- pointColl.Coordinates.x,
+ pointColl.GetPosition().x,
(vPosTop + setup.LowerCeilingBound) + 1,
- pointColl.Coordinates.z,
+ pointColl.GetPosition().z,
item.RoomNumber);
// Prepare data for static object LOS.
@@ -712,9 +714,9 @@ namespace TEN::Entities::Player
// TODO: Assess static object geometry ray collision.
- int relFloorHeight = pointColl.Position.Floor - vPos;
- int relCeilHeight = pointColl.Position.Ceiling - vPosTop;
- int floorToCeilHeight = abs(pointColl.Position.Ceiling - pointColl.Position.Floor);
+ int relFloorHeight = pointColl.GetFloorHeight() - vPos;
+ int relCeilHeight = pointColl.GetCeilingHeight() - vPosTop;
+ int floorToCeilHeight = abs(pointColl.GetCeilingHeight() - pointColl.GetFloorHeight());
// 4) Assess point collision.
if (relFloorHeight > 0 && // Floor is within highest floor bound (player base).
@@ -782,8 +784,8 @@ namespace TEN::Entities::Player
return false;
// Get point collision.
- auto pointColl = GetCollision(&item, 0, 0, -coll.Setup.Height / 2);
- int relFloorHeight = pointColl.Position.Floor - item.Pose.Position.y;
+ auto pointColl = GetPointCollision(item, 0, 0, -coll.Setup.Height / 2);
+ int relFloorHeight = pointColl.GetFloorHeight() - item.Pose.Position.y;
// 2) Assess point collision.
if (relFloorHeight > UPPER_FLOOR_BOUND) // Floor height is below upper floor bound.
@@ -805,11 +807,11 @@ namespace TEN::Entities::Player
return true;
// Get point collision.
- auto pointColl = GetCollision(&item);
+ auto pointColl = GetPointCollision(item);
int vPos = item.Pose.Position.y;
// 3) Assess point collision.
- if ((pointColl.Position.Floor - vPos) <= projVerticalVel) // Floor height is above projected vertical position.
+ if ((pointColl.GetFloorHeight() - vPos) <= projVerticalVel) // Floor height is above projected vertical position.
return true;
return false;
@@ -848,9 +850,9 @@ namespace TEN::Entities::Player
return false;*/
// Get point collision.
- auto pointColl = GetCollision(&item, setup.HeadingAngle, setup.Distance, -coll.Setup.Height);
- int relFloorHeight = pointColl.Position.Floor - item.Pose.Position.y;
- int relCeilHeight = pointColl.Position.Ceiling - item.Pose.Position.y;
+ auto pointColl = GetPointCollision(item, setup.HeadingAngle, setup.Distance, -coll.Setup.Height);
+ int relFloorHeight = pointColl.GetFloorHeight() - item.Pose.Position.y;
+ int relCeilHeight = pointColl.GetCeilingHeight() - item.Pose.Position.y;
// 4) Assess point collision.
if (relFloorHeight >= -STEPUP_HEIGHT && // Floor is within highest floor bound.
@@ -923,11 +925,11 @@ namespace TEN::Entities::Player
return IsRunJumpQueueableState(item.Animation.TargetState);
// Get point collision.
- auto pointColl = GetCollision(&item, item.Pose.Orientation.y, BLOCK(1), -coll.Setup.Height);
+ auto pointColl = GetPointCollision(item, item.Pose.Orientation.y, BLOCK(1), -coll.Setup.Height);
int lowerCeilingBound = (LOWER_CEIL_BOUND_BASE - coll.Setup.Height);
- int relFloorHeight = pointColl.Position.Floor - item.Pose.Position.y;
- int relCeilHeight = pointColl.Position.Ceiling - item.Pose.Position.y;
+ int relFloorHeight = pointColl.GetFloorHeight() - item.Pose.Position.y;
+ int relCeilHeight = pointColl.GetCeilingHeight() - item.Pose.Position.y;
// 2) Assess point collision for possible running jump ahead.
if (relCeilHeight < lowerCeilingBound || // Ceiling height is above lower ceiling bound.
@@ -993,7 +995,7 @@ namespace TEN::Entities::Player
// TODO: Broken on diagonal slides?
- auto pointColl = GetCollision(&item);
+ auto pointColl = GetPointCollision(item);
//short aspectAngle = GetLaraSlideHeadingAngle(item, coll);
//short slopeAngle = Geometry::GetSurfaceSlopeAngle(GetSurfaceNormal(pointColl.FloorTilt, true));
@@ -1002,8 +1004,8 @@ namespace TEN::Entities::Player
bool CanCrawlspaceDive(const ItemInfo& item, const CollisionInfo& coll)
{
- auto pointColl = GetCollision(&item, coll.Setup.ForwardAngle, coll.Setup.Radius, -coll.Setup.Height);
- return (abs(pointColl.Position.Ceiling - pointColl.Position.Floor) < LARA_HEIGHT || IsInLowSpace(item, coll));
+ auto pointColl = GetPointCollision(item, coll.Setup.ForwardAngle, coll.Setup.Radius, -coll.Setup.Height);
+ return (abs(pointColl.GetCeilingHeight() - pointColl.GetFloorHeight()) < LARA_HEIGHT || IsInLowSpace(item, coll));
}
bool CanPerformLedgeJump(const ItemInfo& item, const CollisionInfo& coll)
@@ -1031,8 +1033,8 @@ namespace TEN::Entities::Player
// TODO: Assess static object geometry ray collision.
// Get point collision.
- auto pointColl = GetCollision(&item);
- int relCeilHeight = pointColl.Position.Ceiling - (item.Pose.Position.y - LARA_HEIGHT_STRETCH);
+ auto pointColl = GetPointCollision(item);
+ int relCeilHeight = pointColl.GetCeilingHeight() - (item.Pose.Position.y - LARA_HEIGHT_STRETCH);
// 3) Assess point collision.
if (relCeilHeight >= -coll.Setup.Height) // Ceiling height is below upper ceiling bound.
@@ -1045,10 +1047,10 @@ namespace TEN::Entities::Player
{
const auto& player = GetLaraInfo(item);
- auto pointColl = GetCollision(&item);
+ auto pointColl = GetPointCollision(item);
if (player.Control.Tightrope.CanDismount && // Dismount is allowed.
- pointColl.Position.Floor == item.Pose.Position.y) // Floor is level with player.
+ pointColl.GetFloorHeight() == item.Pose.Position.y) // Floor is level with player.
{
return true;
}
diff --git a/TombEngine/Game/Lara/PlayerContextData.h b/TombEngine/Game/Lara/PlayerContextData.h
index c53dcbd8b..8e3b315e2 100644
--- a/TombEngine/Game/Lara/PlayerContextData.h
+++ b/TombEngine/Game/Lara/PlayerContextData.h
@@ -8,9 +8,9 @@ namespace TEN::Entities::Player
int LowerFloorBound = 0;
int UpperFloorBound = 0;
- bool TestSlipperySlopeBelow = true;
- bool TestSlipperySlopeAbove = true;
- bool TestDeathFloor = true;
+ bool TestIllegalFloorBelow = true;
+ bool TestIllegalFloorAbove = true;
+ bool TestDeathFloor = true;
};
struct MonkeySwingMovementSetupData
diff --git a/TombEngine/Game/Lara/lara.cpp b/TombEngine/Game/Lara/lara.cpp
index 128ce7143..9268b5f46 100644
--- a/TombEngine/Game/Lara/lara.cpp
+++ b/TombEngine/Game/Lara/lara.cpp
@@ -404,7 +404,7 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
if (DebugMode)
{
- DrawNearbyPathfinding(GetCollision(item).BottomBlock->Box);
+ DrawNearbyPathfinding(GetPointCollision(*item).GetBottomSector().Box);
DrawNearbySectorFlags(*item);
}
}
diff --git a/TombEngine/Game/Lara/lara_collide.cpp b/TombEngine/Game/Lara/lara_collide.cpp
index 26d6cfa2e..358dc2c1d 100644
--- a/TombEngine/Game/Lara/lara_collide.cpp
+++ b/TombEngine/Game/Lara/lara_collide.cpp
@@ -4,6 +4,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
#include "Game/collision/collide_item.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/control.h"
#include "Game/effects/effects.h"
#include "Game/items.h"
@@ -19,6 +20,7 @@
#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
#include "Scripting/Include/ScriptInterfaceLevel.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Entities::Player;
using namespace TEN::Input;
@@ -486,10 +488,10 @@ void LaraSurfaceCollision(ItemInfo* item, CollisionInfo* coll)
item->Pose.Orientation.y -= ANGLE(5.0f);
}
- auto pointColl = GetCollision(item);
+ auto pointColl = GetPointCollision(*item);
int waterHeight = GetWaterHeight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->RoomNumber);
- if ((pointColl.Position.Floor - item->Pose.Position.y) < SWIM_WATER_DEPTH)
+ if ((pointColl.GetFloorHeight() - item->Pose.Position.y) < SWIM_WATER_DEPTH)
TestPlayerWaterStepOut(item, coll);
}
diff --git a/TombEngine/Game/Lara/lara_helpers.cpp b/TombEngine/Game/Lara/lara_helpers.cpp
index 9f1712f07..51c6dbe79 100644
--- a/TombEngine/Game/Lara/lara_helpers.cpp
+++ b/TombEngine/Game/Lara/lara_helpers.cpp
@@ -162,9 +162,9 @@ void HandlePlayerStatusEffects(ItemInfo& item, WaterStatus waterStatus, PlayerWa
const auto& vehicleItem = g_Level.Items[player.Context.Vehicle];
if (vehicleItem.ObjectNumber == ID_UPV)
{
- auto pointColl = GetCollision(&item, 0, 0, CLICK(1));
+ auto pointColl = GetPointCollision(item, 0, 0, CLICK(1));
- water.IsCold = (water.IsCold || TestEnvironment(ENV_FLAG_COLD, pointColl.RoomNumber));
+ water.IsCold = (water.IsCold || TestEnvironment(ENV_FLAG_COLD, pointColl.GetRoomNumber()));
if (water.IsCold)
{
player.Status.Exposure--;
@@ -1324,20 +1324,20 @@ static short GetLegacySlideHeadingAngle(const Vector3& floorNormal)
short GetPlayerSlideHeadingAngle(ItemInfo* item, CollisionInfo* coll)
{
short headingAngle = coll->Setup.ForwardAngle;
- auto pointColl = GetCollision(item);
+ auto pointColl = GetPointCollision(*item);
// Ground is flat.
- if (pointColl.FloorTilt == Vector2::Zero)
+ if (pointColl.GetFloorNormal() == -Vector3::UnitY)
return coll->Setup.ForwardAngle;
// Return slide heading angle.
if (g_GameFlow->HasSlideExtended())
{
- return Geometry::GetSurfaceAspectAngle(pointColl.FloorNormal);
+ return Geometry::GetSurfaceAspectAngle(pointColl.GetFloorNormal());
}
else
{
- return GetLegacySlideHeadingAngle(pointColl.FloorNormal);
+ return GetLegacySlideHeadingAngle(pointColl.GetFloorNormal());
}
}
@@ -1526,7 +1526,7 @@ void ModulateLaraSlideVelocity(ItemInfo* item, CollisionInfo* coll)
if (g_GameFlow->HasSlideExtended())
{
- auto probe = GetCollision(item);
+ auto probe = GetPointCollision(*item);
short minSlideAngle = ANGLE(33.75f);
//short steepness = Geometry::GetSurfaceSlopeAngle(probe.FloorTilt);
//short direction = Geometry::GetSurfaceAspectAngle(probe.FloorTilt);
@@ -1547,7 +1547,7 @@ void ModulateLaraSlideVelocity(ItemInfo* item, CollisionInfo* coll)
void AlignLaraToSurface(ItemInfo* item, float alpha)
{
// Determine relative orientation adhering to floor normal.
- auto floorNormal = GetCollision(item).FloorNormal;
+ auto floorNormal = GetPointCollision(*item).GetFloorNormal();
auto orient = Geometry::GetRelOrientToNormal(item->Pose.Orientation.y, floorNormal);
// Apply extra rotation according to alpha.
diff --git a/TombEngine/Game/Lara/lara_one_gun.cpp b/TombEngine/Game/Lara/lara_one_gun.cpp
index b9917a70f..aa16a6d1a 100644
--- a/TombEngine/Game/Lara/lara_one_gun.cpp
+++ b/TombEngine/Game/Lara/lara_one_gun.cpp
@@ -1422,20 +1422,20 @@ bool EmitFromProjectile(ItemInfo& projectile, ProjectileType type)
return true;
}
-bool TestProjectileNewRoom(ItemInfo& item, const CollisionResult& coll)
+bool TestProjectileNewRoom(ItemInfo& item, PointCollisionData& pointColl)
{
// Check if projectile changed room.
- if (item.RoomNumber == coll.RoomNumber)
+ if (item.RoomNumber == pointColl.GetRoomNumber())
return false;
// If currently in water and previously on land, spawn ripple.
- if (TestEnvironment(ENV_FLAG_WATER, item.RoomNumber) != TestEnvironment(ENV_FLAG_WATER, coll.RoomNumber))
+ if (TestEnvironment(ENV_FLAG_WATER, item.RoomNumber) != TestEnvironment(ENV_FLAG_WATER, pointColl.GetRoomNumber()))
{
const auto& player = GetLaraInfo(item);
- int floorDiff = abs(coll.Position.Floor - item.Pose.Position.y);
- int ceilingDiff = abs(coll.Position.Ceiling - item.Pose.Position.y);
- int yPoint = (floorDiff > ceilingDiff) ? coll.Position.Ceiling : coll.Position.Floor;
+ int floorDiff = abs(pointColl.GetFloorHeight() - item.Pose.Position.y);
+ int ceilingDiff = abs(pointColl.GetCeilingHeight() - item.Pose.Position.y);
+ int yPoint = (floorDiff > ceilingDiff) ? pointColl.GetCeilingHeight() : pointColl.GetFloorHeight();
if (player.Control.Weapon.GunType != LaraWeaponType::GrenadeLauncher && player.Control.Weapon.GunType != LaraWeaponType::RocketLauncher)
{
@@ -1451,7 +1451,7 @@ bool TestProjectileNewRoom(ItemInfo& item, const CollisionResult& coll)
}
}
- ItemNewRoom(item.Index, coll.RoomNumber);
+ ItemNewRoom(item.Index, pointColl.GetRoomNumber());
return true;
}
@@ -1479,7 +1479,7 @@ void ExplodeProjectile(ItemInfo& item, const Vector3i& prevPos)
void HandleProjectile(ItemInfo& projectile, ItemInfo& emitter, const Vector3i& prevPos, ProjectileType type, int damage)
{
- auto pointColl = GetCollision(&projectile);
+ auto pointColl = GetPointCollision(projectile);
bool hasHit = false;
bool hasHitNotByEmitter = false;
@@ -1489,8 +1489,8 @@ void HandleProjectile(ItemInfo& projectile, ItemInfo& emitter, const Vector3i& p
// For non-grenade projectiles, check for room collision.
if (type < ProjectileType::Grenade)
{
- if (pointColl.Position.Floor < projectile.Pose.Position.y ||
- pointColl.Position.Ceiling > projectile.Pose.Position.y)
+ if (pointColl.GetFloorHeight() < projectile.Pose.Position.y ||
+ pointColl.GetCeilingHeight() > projectile.Pose.Position.y)
{
hasHit = hasHitNotByEmitter = true;
}
diff --git a/TombEngine/Game/Lara/lara_one_gun.h b/TombEngine/Game/Lara/lara_one_gun.h
index 382d76567..b583b7eba 100644
--- a/TombEngine/Game/Lara/lara_one_gun.h
+++ b/TombEngine/Game/Lara/lara_one_gun.h
@@ -39,6 +39,7 @@ void HarpoonBoltControl(short itemNumber);
void FireGrenade(ItemInfo& laraItem);
void GrenadeControl(short itemNumber);
void FireRocket(ItemInfo& laraItem);
+void FireRocket(ItemInfo& laraItem);
void RocketControl(short itemNumber);
void FireCrossbow(ItemInfo& laraItem, const std::optional& pose = std::nullopt);
void FireCrossBowFromLaserSight(ItemInfo& laraItem, GameVector* origin, GameVector* target);
diff --git a/TombEngine/Game/Lara/lara_overhang.cpp b/TombEngine/Game/Lara/lara_overhang.cpp
index a558b4035..a9b81c427 100644
--- a/TombEngine/Game/Lara/lara_overhang.cpp
+++ b/TombEngine/Game/Lara/lara_overhang.cpp
@@ -371,7 +371,7 @@ void lara_col_slopeclimb(ItemInfo* item, CollisionInfo* coll)
if (GetClimbFlags(&probeUp.GetBottomSector()) & slopeData.ClimbOrient &&
InStrip(item->Pose.Position.x, item->Pose.Position.z, item->Pose.Orientation.y, CLICK(3), CLICK(4)))
{
- //if (GetCollision(probeUp.Block, up.x, up.y, up.z).GetCeilingHeight() - item->Pose.Position.y <= (BLOCK(1.5f) - 80)) // Check if a wall is actually there.
+ //if (GetPointCollision(probeUp.Block, up.x, up.y, up.z).GetCeilingHeight() - item->Pose.Position.y <= (BLOCK(1.5f) - 80)) // Check if a wall is actually there.
//{
// AlignToEdge(item, FORWARD_ALIGNMENT);
// SetAnimation(item, LA_OVERHANG_SLOPE_LADDER_CONVEX_START);
@@ -416,7 +416,7 @@ void lara_col_slopeclimb(ItemInfo* item, CollisionInfo* coll)
}
else if (IsHeld(In::Back))
{
- //if ((GetClimbFlags(GetCollision(probeNow.Block, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z).BottomBlock) & slopeData.ClimbOrient) &&
+ //if ((GetClimbFlags(GetPointCollision(probeNow.Block, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z).BottomBlock) & slopeData.ClimbOrient) &&
// InStrip(item->Pose.Position.x, item->Pose.Position.z, item->Pose.Orientation.y, 0, CLICK(1)))
//{
// AlignToEdge(item, BACKWARD_ALIGNMENT);
@@ -1076,7 +1076,7 @@ void SlopeMonkeyExtra(ItemInfo* item, CollisionInfo* coll)
{
lara->Context.NextCornerPos.Orientation.z = AlignToGrab(item);
- /*int ceiling = GetCollision(probeNow.Block, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z).GetCeilingHeight();
+ /*int ceiling = GetPointCollision(probeNow.Block, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z).GetCeilingHeight();
item->Pose.Position.y = ceiling + HEIGHT_ADJUST;*/
SetAnimation(item, LA_OVERHANG_HANG_SWING);
@@ -1094,7 +1094,7 @@ void SlopeMonkeyExtra(ItemInfo* item, CollisionInfo* coll)
{
/*if (probeDown.BottomBlock->Flags.Monkeyswing)
{
- int ceiling = GetCollision(probeDown.Block, down.x, now.y, down.z).GetCeilingHeight();
+ int ceiling = GetPointCollision(probeDown.Block, down.x, now.y, down.z).GetCeilingHeight();
int yDiff = ceiling - probeNow.GetCeilingHeight();
int height;
diff --git a/TombEngine/Game/Lara/lara_tests.cpp b/TombEngine/Game/Lara/lara_tests.cpp
index ce6a61776..40e83998b 100644
--- a/TombEngine/Game/Lara/lara_tests.cpp
+++ b/TombEngine/Game/Lara/lara_tests.cpp
@@ -452,7 +452,7 @@ bool TestLaraClimbIdle(ItemInfo* item, CollisionInfo* coll)
bool TestLaraNearClimbableWall(ItemInfo* item, FloorInfo* floor)
{
if (floor == nullptr)
- floor = GetCollision(item).BottomBlock;
+ floor = &GetPointCollision(*item).GetBottomSector();
return ((256 << (GetQuadrant(item->Pose.Orientation.y))) & GetClimbFlags(floor));
}
@@ -525,7 +525,7 @@ bool TestLaraValidHangPosition(ItemInfo* item, CollisionInfo* coll)
// Get incoming ledge height and own Lara's upper bound.
// First one will be negative while first one is positive.
// Difference between two indicates difference in height between ledges.
- auto frontFloor = GetCollision(item, lara->Control.MoveAngle, coll->Setup.Radius + CLICK(0.5f), -LARA_HEIGHT).Position.Floor;
+ auto frontFloor = GetPointCollision(*item, lara->Control.MoveAngle, coll->Setup.Radius + CLICK(0.5f), -LARA_HEIGHT).GetFloorHeight();
auto laraUpperBound = item->Pose.Position.y - coll->Setup.Height;
// If difference is above 1/2 click, return false (ledge is out of reach).
@@ -584,7 +584,7 @@ CornerType TestLaraHangCorner(ItemInfo* item, CollisionInfo* coll, float testAng
item->Pose = cornerResult.RealPositionResult;
lara->Context.NextCornerPos.Position = Vector3i(
item->Pose.Position.x,
- GetCollision(item, item->Pose.Orientation.y, coll->Setup.Radius + 16, -(coll->Setup.Height + CLICK(0.5f))).Position.Floor + abs(bounds.Y1),
+ GetPointCollision(*item, item->Pose.Orientation.y, coll->Setup.Radius + 16, -(coll->Setup.Height + CLICK(0.5f))).GetFloorHeight() + abs(bounds.Y1),
item->Pose.Position.z
);
lara->Context.NextCornerPos.Orientation.y = item->Pose.Orientation.y;
@@ -642,7 +642,7 @@ CornerType TestLaraHangCorner(ItemInfo* item, CollisionInfo* coll, float testAng
// Store next position
item->Pose = cornerResult.RealPositionResult;
lara->Context.NextCornerPos.Position.x = item->Pose.Position.x;
- lara->Context.NextCornerPos.Position.y = GetCollision(item, item->Pose.Orientation.y, coll->Setup.Radius * 1.25f, -(abs(bounds.Y1) + LARA_HEADROOM)).Position.Floor + abs(bounds.Y1);
+ lara->Context.NextCornerPos.Position.y = GetPointCollision(*item, item->Pose.Orientation.y, coll->Setup.Radius * 1.25f, -(abs(bounds.Y1) + LARA_HEADROOM)).GetFloorHeight() + abs(bounds.Y1);
lara->Context.NextCornerPos.Position.z = item->Pose.Position.z;
lara->Context.NextCornerPos.Orientation.y = item->Pose.Orientation.y;
lara->Control.MoveAngle = item->Pose.Orientation.y;
@@ -747,11 +747,11 @@ bool TestHangSwingIn(ItemInfo* item, CollisionInfo* coll)
auto* lara = GetLaraInfo(item);
int y = item->Pose.Position.y;
- auto probe = GetCollision(item, item->Pose.Orientation.y, OFFSET_RADIUS(coll->Setup.Radius));
+ auto probe = GetPointCollision(*item, item->Pose.Orientation.y, OFFSET_RADIUS(coll->Setup.Radius));
- if ((probe.Position.Floor - y) > 0 &&
- (probe.Position.Ceiling - y) < -CLICK(1.6f) &&
- probe.Position.Floor != NO_HEIGHT)
+ if ((probe.GetFloorHeight() - y) > 0 &&
+ (probe.GetCeilingHeight() - y) < -CLICK(1.6f) &&
+ probe.GetFloorHeight() != NO_HEIGHT)
{
return true;
}
@@ -854,32 +854,22 @@ bool LaraPositionOnLOS(ItemInfo* item, short angle, int distance)
int LaraFloorFront(ItemInfo* item, short angle, int distance)
{
- return LaraCollisionFront(item, angle, distance).Position.Floor;
+ auto pointColl = GetPointCollision(*item, angle, distance, -LARA_HEIGHT);
+
+ if (pointColl.GetFloorHeight() == NO_HEIGHT)
+ return pointColl.GetFloorHeight();
+
+ return (pointColl.GetFloorHeight() - item->Pose.Position.y);
}
int LaraCeilingFront(ItemInfo* item, short angle, int distance, int height)
{
- return LaraCeilingCollisionFront(item, angle, distance, height).Position.Ceiling;
-}
+ auto pointColl = GetPointCollision(*item, angle, distance, -height);
-CollisionResult LaraCollisionFront(ItemInfo* item, short angle, int distance)
-{
- auto probe = GetCollision(item, angle, distance, -LARA_HEIGHT);
+ if (pointColl.GetCeilingHeight() == NO_HEIGHT)
+ return pointColl.GetCeilingHeight();
- if (probe.Position.Floor != NO_HEIGHT)
- probe.Position.Floor -= item->Pose.Position.y;
-
- return probe;
-}
-
-CollisionResult LaraCeilingCollisionFront(ItemInfo* item, short angle, int distance, int height)
-{
- auto probe = GetCollision(item, angle, distance, -height);
-
- if (probe.Position.Ceiling != NO_HEIGHT)
- probe.Position.Ceiling += height - item->Pose.Position.y;
-
- return probe;
+ return ((pointColl.GetCeilingHeight() + height) - item->Pose.Position.y);
}
bool TestPlayerWaterStepOut(ItemInfo* item, CollisionInfo* coll)
@@ -887,17 +877,17 @@ bool TestPlayerWaterStepOut(ItemInfo* item, CollisionInfo* coll)
auto& player = GetLaraInfo(*item);
// Get point collision.
- auto pointColl = GetCollision(item);
+ auto pointColl = GetPointCollision(*item);
int vPos = item->Pose.Position.y;
if (coll->CollisionType == CT_FRONT ||
- pointColl.Position.FloorSlope ||
- (pointColl.Position.Floor - vPos) <= 0)
+ pointColl.IsIllegalFloor() ||
+ (pointColl.GetFloorHeight() - vPos) <= 0)
{
return false;
}
- if ((pointColl.Position.Floor - vPos) >= -CLICK(0.5f))
+ if ((pointColl.GetFloorHeight() - vPos) >= -CLICK(0.5f))
{
SetAnimation(item, LA_STAND_IDLE);
}
@@ -907,7 +897,7 @@ bool TestPlayerWaterStepOut(ItemInfo* item, CollisionInfo* coll)
item->Animation.TargetState = LS_IDLE;
}
- item->Pose.Position.y = pointColl.Position.Floor;
+ item->Pose.Position.y = pointColl.GetFloorHeight();
UpdateLaraRoom(item, -(STEPUP_HEIGHT - 3));
ResetPlayerLean(item);
@@ -963,8 +953,8 @@ bool TestLaraWaterClimbOut(ItemInfo* item, CollisionInfo* coll)
if (coll->HitStatic)
return false;
- auto probe = GetCollision(item, coll->Setup.ForwardAngle, CLICK(2), -CLICK(1));
- int headroom = probe.Position.Floor - probe.Position.Ceiling;
+ auto probe = GetPointCollision(*item, coll->Setup.ForwardAngle, CLICK(2), -CLICK(1));
+ int headroom = probe.GetFloorHeight() - probe.GetCeilingHeight();
if (frontFloor <= -CLICK(1))
{
@@ -1097,8 +1087,8 @@ void TestLaraWaterDepth(ItemInfo* item, CollisionInfo* coll)
{
auto& player = GetLaraInfo(*item);
- auto pointColl = GetCollision(item);
- int waterDepth = GetWaterDepth(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, pointColl.RoomNumber);
+ auto pointColl = GetPointCollision(*item);
+ int waterDepth = GetWaterDepth(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, pointColl.GetRoomNumber());
if (waterDepth == NO_HEIGHT)
{
@@ -1111,7 +1101,7 @@ void TestLaraWaterDepth(ItemInfo* item, CollisionInfo* coll)
SetAnimation(item, LA_UNDERWATER_TO_STAND);
ResetPlayerLean(item);
item->Animation.TargetState = LS_IDLE;
- item->Pose.Position.y = pointColl.Position.Floor;
+ item->Pose.Position.y = pointColl.GetFloorHeight();
item->Animation.IsAirborne = false;
item->Animation.Velocity.y = 0.0f;
item->Animation.Velocity.z = 0.0f;
@@ -1204,12 +1194,12 @@ std::optional TestLaraVaultTolerance(ItemInfo* item, CollisionI
auto* lara = GetLaraInfo(item);
int distance = OFFSET_RADIUS(coll->Setup.Radius);
- auto probeFront = GetCollision(item, coll->NearestLedgeAngle, distance, -coll->Setup.Height);
- auto probeMiddle = GetCollision(item);
+ auto probeFront = GetPointCollision(*item, coll->NearestLedgeAngle, distance, -coll->Setup.Height);
+ auto probeMiddle = GetPointCollision(*item);
bool isSwamp = TestEnvironment(ENV_FLAG_SWAMP, item);
bool swampTooDeep = testSetup.CheckSwampDepth ? (isSwamp && lara->Context.WaterSurfaceDist < -CLICK(3)) : isSwamp;
- int y = isSwamp ? item->Pose.Position.y : probeMiddle.Position.Floor; // HACK: Avoid cheese when in the midst of performing a step. Can be done better. @Sezz 2022.04.08
+ int y = isSwamp ? item->Pose.Position.y : probeMiddle.GetFloorHeight(); // HACK: Avoid cheese when in the midst of performing a step. Can be done better. @Sezz 2022.04.08
// Check swamp depth (if applicable).
if (swampTooDeep)
@@ -1222,27 +1212,27 @@ std::optional TestLaraVaultTolerance(ItemInfo* item, CollisionI
// Raise y position of point/room probe by increments of CLICK(0.5f) to find potential vault ledge.
int yOffset = testSetup.LowerFloorBound;
- while (((probeFront.Position.Ceiling - y) > -coll->Setup.Height || // Ceiling is below Lara's height...
- abs(probeFront.Position.Ceiling - probeFront.Position.Floor) <= testSetup.ClampMin || // OR clamp is too small
- abs(probeFront.Position.Ceiling - probeFront.Position.Floor) > testSetup.ClampMax) && // OR clamp is too large (future-proofing; not possible right now).
+ while (((probeFront.GetCeilingHeight() - y) > -coll->Setup.Height || // Ceiling is below Lara's height...
+ abs(probeFront.GetCeilingHeight() - probeFront.GetFloorHeight()) <= testSetup.ClampMin || // OR clamp is too small
+ abs(probeFront.GetCeilingHeight() - probeFront.GetFloorHeight()) > testSetup.ClampMax) && // OR clamp is too large (future-proofing; not possible right now).
yOffset > (testSetup.UpperFloorBound - coll->Setup.Height)) // Offset is not too high.
{
- probeFront = GetCollision(item, coll->NearestLedgeAngle, distance, yOffset);
+ probeFront = GetPointCollision(*item, coll->NearestLedgeAngle, distance, yOffset);
yOffset -= std::max(CLICK(0.5f), testSetup.ClampMin);
}
// Discard walls.
- if (probeFront.Position.Floor == NO_HEIGHT)
+ if (probeFront.GetFloorHeight() == NO_HEIGHT)
return std::nullopt;
// Assess point/room collision.
- if ((probeFront.Position.Floor - y) < testSetup.LowerFloorBound && // Within lower floor bound.
- (probeFront.Position.Floor - y) >= testSetup.UpperFloorBound && // Within upper floor bound.
- abs(probeFront.Position.Ceiling - probeFront.Position.Floor) > testSetup.ClampMin && // Within clamp min.
- abs(probeFront.Position.Ceiling - probeFront.Position.Floor) <= testSetup.ClampMax && // Within clamp max.
- abs(probeMiddle.Position.Ceiling - probeFront.Position.Floor) >= testSetup.GapMin) // Gap is optically permissive.
+ if ((probeFront.GetFloorHeight() - y) < testSetup.LowerFloorBound && // Within lower floor bound.
+ (probeFront.GetFloorHeight() - y) >= testSetup.UpperFloorBound && // Within upper floor bound.
+ abs(probeFront.GetCeilingHeight() - probeFront.GetFloorHeight()) > testSetup.ClampMin && // Within clamp min.
+ abs(probeFront.GetCeilingHeight() - probeFront.GetFloorHeight()) <= testSetup.ClampMax && // Within clamp max.
+ abs(probeMiddle.GetCeilingHeight() - probeFront.GetFloorHeight()) >= testSetup.GapMin) // Gap is optically permissive.
{
- return VaultTestResult{ probeFront.Position.Floor };
+ return VaultTestResult{ probeFront.GetFloorHeight() };
}
return std::nullopt;
@@ -1392,20 +1382,20 @@ std::optional TestLaraLadderAutoJump(ItemInfo* item, CollisionI
int y = item->Pose.Position.y;
int distance = OFFSET_RADIUS(coll->Setup.Radius);
- auto probeFront = GetCollision(item, coll->NearestLedgeAngle, distance, -coll->Setup.Height);
- auto probeMiddle = GetCollision(item);
+ auto probeFront = GetPointCollision(*item, coll->NearestLedgeAngle, distance, -coll->Setup.Height);
+ auto probeMiddle = GetPointCollision(*item);
// Check ledge angle.
if (!TestValidLedgeAngle(item, coll))
return std::nullopt;
if (lara->Control.CanClimbLadder && // Ladder sector flag set.
- (probeMiddle.Position.Ceiling - y) <= -CLICK(6.5f) && // Within lowest middle ceiling bound. (Synced with TestLaraLadderMount())
- ((probeFront.Position.Floor - y) <= -CLICK(6.5f) || // Floor height is appropriate, OR
- (probeFront.Position.Ceiling - y) > -CLICK(6.5f)) && // Ceiling height is appropriate. (Synced with TestLaraLadderMount())
+ (probeMiddle.GetCeilingHeight() - y) <= -CLICK(6.5f) && // Within lowest middle ceiling bound. (Synced with TestLaraLadderMount())
+ ((probeFront.GetFloorHeight() - y) <= -CLICK(6.5f) || // Floor height is appropriate, OR
+ (probeFront.GetCeilingHeight() - y) > -CLICK(6.5f)) && // Ceiling height is appropriate. (Synced with TestLaraLadderMount())
coll->NearestLedgeDistance <= coll->Setup.Radius) // Appropriate distance from wall.
{
- return VaultTestResult{ probeMiddle.Position.Ceiling, false, true, true };
+ return VaultTestResult{ probeMiddle.GetCeilingHeight(), false, true, true };
}
return std::nullopt;
@@ -1417,18 +1407,18 @@ std::optional TestLaraLadderMount(ItemInfo* item, CollisionInfo
int y = item->Pose.Position.y;
int distance = OFFSET_RADIUS(coll->Setup.Radius);
- auto probeFront = GetCollision(item, coll->NearestLedgeAngle, distance, -coll->Setup.Height);
- auto probeMiddle = GetCollision(item);
+ auto probeFront = GetPointCollision(*item, coll->NearestLedgeAngle, distance, -coll->Setup.Height);
+ auto probeMiddle = GetPointCollision(*item);
// Check ledge angle.
if (!TestValidLedgeAngle(item, coll))
return std::nullopt;
if (lara->Control.CanClimbLadder && // Ladder sector flag set.
- (probeMiddle.Position.Ceiling - y) <= -CLICK(4.5f) && // Within lower middle ceiling bound.
- (probeMiddle.Position.Ceiling - y) > -CLICK(6.5f) && // Within upper middle ceiling bound.
- (probeMiddle.Position.Floor - y) > -CLICK(6.5f) && // Within upper middle floor bound. (Synced with TestLaraAutoJump())
- (probeFront.Position.Ceiling - y) <= -CLICK(4.5f) && // Within lowest front ceiling bound.
+ (probeMiddle.GetCeilingHeight() - y) <= -CLICK(4.5f) && // Within lower middle ceiling bound.
+ (probeMiddle.GetCeilingHeight() - y) > -CLICK(6.5f) && // Within upper middle ceiling bound.
+ (probeMiddle.GetFloorHeight() - y) > -CLICK(6.5f) && // Within upper middle floor bound. (Synced with TestLaraAutoJump())
+ (probeFront.GetCeilingHeight() - y) <= -CLICK(4.5f) && // Within lowest front ceiling bound.
coll->NearestLedgeDistance <= coll->Setup.Radius) // Appropriate distance from wall.
{
return VaultTestResult{ NO_HEIGHT, true, true, false };
@@ -1442,13 +1432,13 @@ std::optional TestLaraMonkeyAutoJump(ItemInfo* item, CollisionI
auto* lara = GetLaraInfo(item);
int y = item->Pose.Position.y;
- auto probe = GetCollision(item);
+ auto probe = GetPointCollision(*item);
if (lara->Control.CanMonkeySwing && // Monkey swing sector flag set.
- (probe.Position.Ceiling - y) < -LARA_HEIGHT_MONKEY && // Within lower ceiling bound.
- (probe.Position.Ceiling - y) >= -CLICK(7)) // Within upper ceiling bound.
+ (probe.GetCeilingHeight() - y) < -LARA_HEIGHT_MONKEY && // Within lower ceiling bound.
+ (probe.GetCeilingHeight() - y) >= -CLICK(7)) // Within upper ceiling bound.
{
- return VaultTestResult{ probe.Position.Ceiling, false, false, true };
+ return VaultTestResult{ probe.GetCeilingHeight(), false, false, true };
}
return std::nullopt;
@@ -1608,15 +1598,15 @@ bool TestAndDoLaraLadderClimb(ItemInfo* item, CollisionInfo* coll)
CrawlVaultTestResult TestLaraCrawlVaultTolerance(ItemInfo* item, CollisionInfo* coll, CrawlVaultTestSetup testSetup)
{
int y = item->Pose.Position.y;
- auto probeA = GetCollision(item, item->Pose.Orientation.y, testSetup.CrossDist, -LARA_HEIGHT_CRAWL); // Crossing.
- auto probeB = GetCollision(item, item->Pose.Orientation.y, testSetup.DestDist, -LARA_HEIGHT_CRAWL); // Approximate destination.
- auto probeMiddle = GetCollision(item);
+ auto probeA = GetPointCollision(*item, item->Pose.Orientation.y, testSetup.CrossDist, -LARA_HEIGHT_CRAWL); // Crossing.
+ auto probeB = GetPointCollision(*item, item->Pose.Orientation.y, testSetup.DestDist, -LARA_HEIGHT_CRAWL); // Approximate destination.
+ auto probeMiddle = GetPointCollision(*item);
- bool isSlope = testSetup.CheckSlope ? probeB.Position.FloorSlope : false;
- bool isDeath = testSetup.CheckDeath ? probeB.Block->Flags.Death : false;
+ bool isSlope = testSetup.CheckSlope ? probeB.IsIllegalFloor() : false;
+ bool isDeath = testSetup.CheckDeath ? probeB.GetSector().Flags.Death : false;
// Discard walls.
- if (probeA.Position.Floor == NO_HEIGHT || probeB.Position.Floor == NO_HEIGHT)
+ if (probeA.GetFloorHeight() == NO_HEIGHT || probeB.GetFloorHeight() == NO_HEIGHT)
return CrawlVaultTestResult{ false };
// Check for slope or death sector (if applicable).
@@ -1624,14 +1614,14 @@ CrawlVaultTestResult TestLaraCrawlVaultTolerance(ItemInfo* item, CollisionInfo*
return CrawlVaultTestResult{ false };
// Assess point/room collision.
- if ((probeA.Position.Floor - y) <= testSetup.LowerFloorBound && // Within lower floor bound.
- (probeA.Position.Floor - y) >= testSetup.UpperFloorBound && // Within upper floor bound.
- abs(probeA.Position.Ceiling - probeA.Position.Floor) > testSetup.ClampMin && // Crossing clamp limit.
- abs(probeB.Position.Ceiling - probeB.Position.Floor) > testSetup.ClampMin && // Destination clamp limit.
- abs(probeMiddle.Position.Ceiling - probeA.Position.Floor) >= testSetup.GapMin && // Gap is optically permissive (going up).
- abs(probeA.Position.Ceiling - probeMiddle.Position.Floor) >= testSetup.GapMin && // Gap is optically permissive (going down).
- abs(probeA.Position.Floor - probeB.Position.Floor) <= testSetup.FloorBound && // Crossing/destination floor height difference suggests continuous crawl surface.
- (probeA.Position.Ceiling - y) < -testSetup.GapMin) // Ceiling height is permissive.
+ if ((probeA.GetFloorHeight() - y) <= testSetup.LowerFloorBound && // Within lower floor bound.
+ (probeA.GetFloorHeight() - y) >= testSetup.UpperFloorBound && // Within upper floor bound.
+ abs(probeA.GetCeilingHeight() - probeA.GetFloorHeight()) > testSetup.ClampMin && // Crossing clamp limit.
+ abs(probeB.GetCeilingHeight() - probeB.GetFloorHeight()) > testSetup.ClampMin && // Destination clamp limit.
+ abs(probeMiddle.GetCeilingHeight() - probeA.GetFloorHeight()) >= testSetup.GapMin && // Gap is optically permissive (going up).
+ abs(probeA.GetCeilingHeight() - probeMiddle.GetFloorHeight()) >= testSetup.GapMin && // Gap is optically permissive (going down).
+ abs(probeA.GetFloorHeight() - probeB.GetFloorHeight()) <= testSetup.FloorBound && // Crossing/destination floor height difference suggests continuous crawl surface.
+ (probeA.GetCeilingHeight() - y) < -testSetup.GapMin) // Ceiling height is permissive.
{
return CrawlVaultTestResult{ true };
}
@@ -1765,14 +1755,14 @@ bool TestLaraCrawlToHang(ItemInfo* item, CollisionInfo* coll)
{
int y = item->Pose.Position.y;
int distance = CLICK(1.2f);
- auto probe = GetCollision(item, item->Pose.Orientation.y + ANGLE(180.0f), distance, -LARA_HEIGHT_CRAWL);
+ auto probe = GetPointCollision(*item, item->Pose.Orientation.y + ANGLE(180.0f), distance, -LARA_HEIGHT_CRAWL);
bool objectCollided = TestLaraObjectCollision(item, item->Pose.Orientation.y + ANGLE(180.0f), CLICK(1.2f), -LARA_HEIGHT_CRAWL);
if (!objectCollided && // No obstruction.
- (probe.Position.Floor - y) >= LARA_HEIGHT_STRETCH && // Highest floor bound.
- (probe.Position.Ceiling - y) <= -CLICK(0.75f) && // Gap is optically permissive.
- probe.Position.Floor != NO_HEIGHT)
+ (probe.GetFloorHeight() - y) >= LARA_HEIGHT_STRETCH && // Highest floor bound.
+ (probe.GetCeilingHeight() - y) <= -CLICK(0.75f) && // Gap is optically permissive.
+ probe.GetFloorHeight() != NO_HEIGHT)
{
return true;
}
diff --git a/TombEngine/Game/Lara/lara_tests.h b/TombEngine/Game/Lara/lara_tests.h
index 4ddebea69..1081a1d79 100644
--- a/TombEngine/Game/Lara/lara_tests.h
+++ b/TombEngine/Game/Lara/lara_tests.h
@@ -34,8 +34,6 @@ bool TestLaraFacingCorner(const ItemInfo* item, short headingAngle, float dist);
bool LaraPositionOnLOS(ItemInfo* item, short angle, int distance);
int LaraFloorFront(ItemInfo* item, short angle, int distance);
int LaraCeilingFront(ItemInfo* item, short angle, int distance, int height);
-CollisionResult LaraCollisionFront(ItemInfo* item, short angle, int distance);
-CollisionResult LaraCeilingCollisionFront(ItemInfo* item, short angle, int distance, int height);
bool TestPlayerWaterStepOut(ItemInfo* item, CollisionInfo* coll);
bool TestLaraWaterClimbOut(ItemInfo* item, CollisionInfo* coll);
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 1112ed12e..42e34c183 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -14,6 +14,9 @@ using namespace TEN::Collision::Floordata;
using namespace TEN::Collision::Room;
using namespace TEN::Math;
+// TODO
+// BUG: Grabbing diagonal ledges stopped working. Lara deflects. Minor error somewhere.
+
namespace TEN::Collision::PointCollision
{
PointCollisionData::PointCollisionData(const Vector3i& pos, int roomNumber)
@@ -339,7 +342,7 @@ namespace TEN::Collision::PointCollision
{
// TEMP HACK
// GetPointCollision() takes arguments for a *current* position and room number.
- // However, since some calls to the old GetCollision() function had *projected*
+ // However, since some calls to the old GetPointCollision() function had *projected*
// positions passed to it, the room number had be corrected to account for such cases.
// These are primarily found in camera.cpp.
short correctedRoomNumber = roomNumber;
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index f13c1881f..e1fe0f465 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -121,45 +121,9 @@ bool TestItemRoomCollisionAABB(ItemInfo* item)
return collided;
}
-static CollisionResult ConvertPointCollDataToCollResult(PointCollisionData& pointColl)
+static CollisionPositionData GetCollisionPositionData(PointCollisionData& pointColl)
{
- auto collResult = CollisionResult{};
- collResult.Coordinates = pointColl.GetPosition();
- collResult.RoomNumber = pointColl.GetRoomNumber();
- collResult.Block = &pointColl.GetSector();
- collResult.BottomBlock = &pointColl.GetBottomSector();
- collResult.Position.Floor = pointColl.GetFloorHeight();
- collResult.Position.Ceiling = pointColl.GetCeilingHeight();
- collResult.Position.Bridge = pointColl.GetFloorBridgeItemNumber();
- collResult.Position.SplitAngle = pointColl.GetBottomSector().FloorSurface.SplitAngle;
- collResult.Position.FloorSlope = collResult.Position.Bridge == NO_ITEM && pointColl.IsIllegalFloor();
- collResult.Position.CeilingSlope = pointColl.IsIllegalCeiling();
- collResult.Position.DiagonalStep = pointColl.IsDiagonalFloorStep();
- collResult.FloorNormal = pointColl.GetFloorNormal();
- collResult.CeilingNormal = pointColl.GetCeilingNormal();
- collResult.FloorTilt = GetSurfaceTilt(collResult.FloorNormal, true).ToVector2();
- collResult.CeilingTilt = GetSurfaceTilt(collResult.CeilingNormal, false).ToVector2();
-
- return collResult;
-}
-
-// NOTE: Deprecated. Use GetPointCollision().
-CollisionResult GetCollision(const ItemInfo* item)
-{
- auto pointColl = GetPointCollision(*item);
- return ConvertPointCollDataToCollResult(pointColl);
-}
-
-// NOTE: Deprecated. Use GetPointCollision().
-CollisionResult GetCollision(const ItemInfo* item, short headingAngle, float forward, float down, float right)
-{
- auto pointColl = GetPointCollision(*item, headingAngle, forward, down, right);
- return ConvertPointCollDataToCollResult(pointColl);
-}
-
-static CollisionPosition GetCollisionPositionData(PointCollisionData& pointColl)
-{
- auto collPos = CollisionPosition{};
+ auto collPos = CollisionPositionData{};
collPos.Floor = pointColl.GetFloorHeight();
collPos.Ceiling = pointColl.GetCeilingHeight();
collPos.Bridge = pointColl.GetFloorBridgeItemNumber();
@@ -171,7 +135,7 @@ static CollisionPosition GetCollisionPositionData(PointCollisionData& pointColl)
return collPos;
}
-static void SetSectorAttribs(CollisionPosition& sectorAttribs, const CollisionSetup& collSetup, PointCollisionData& pointColl,
+static void SetSectorAttribs(CollisionPositionData& sectorAttribs, const CollisionSetupData& collSetup, PointCollisionData& pointColl,
const Vector3i& probePos, int realRoomNumber)
{
constexpr auto ASPECT_ANGLE_DELTA_MAX = ANGLE(90.0f);
@@ -740,10 +704,10 @@ void AlignEntityToSurface(ItemInfo* item, const Vector2& ellipse, float alpha, s
auto reducedEllipse = ellipse * 0.75f;
// Probe heights at points around entity.
- int frontHeight = GetCollision(item, item->Pose.Orientation.y, reducedEllipse.y).Position.Floor;
- int backHeight = GetCollision(item, item->Pose.Orientation.y + ANGLE(180.0f), reducedEllipse.y).Position.Floor;
- int leftHeight = GetCollision(item, item->Pose.Orientation.y - ANGLE(90.0f), reducedEllipse.x).Position.Floor;
- int rightHeight = GetCollision(item, item->Pose.Orientation.y + ANGLE(90.0f), reducedEllipse.x).Position.Floor;
+ int frontHeight = GetPointCollision(*item, item->Pose.Orientation.y, reducedEllipse.y).GetFloorHeight();
+ int backHeight = GetPointCollision(*item, item->Pose.Orientation.y + ANGLE(180.0f), reducedEllipse.y).GetFloorHeight();
+ int leftHeight = GetPointCollision(*item, item->Pose.Orientation.y - ANGLE(90.0f), reducedEllipse.x).GetFloorHeight();
+ int rightHeight = GetPointCollision(*item, item->Pose.Orientation.y + ANGLE(90.0f), reducedEllipse.x).GetFloorHeight();
// Calculate height deltas.
int forwardHeightDelta = backHeight - frontHeight;
diff --git a/TombEngine/Game/collision/collide_room.h b/TombEngine/Game/collision/collide_room.h
index 2b36d8dca..363545bc5 100644
--- a/TombEngine/Game/collision/collide_room.h
+++ b/TombEngine/Game/collision/collide_room.h
@@ -1,13 +1,14 @@
#pragma once
-
#include "Math/Math.h"
#include "Objects/game_object_ids.h"
-struct ItemInfo;
-class FloorInfo;
-struct ROOM_INFO;
-struct MESH_INFO;
enum RoomEnvFlags;
+class FloorInfo;
+struct ItemInfo;
+struct MESH_INFO;
+struct ROOM_INFO;
+
+using namespace TEN::Math;
constexpr auto NO_LOWER_BOUND = -NO_HEIGHT; // Used by coll->Setup.LowerFloorBound.
constexpr auto NO_UPPER_BOUND = NO_HEIGHT; // Used by coll->Setup.UpperFloorBound.
@@ -41,7 +42,7 @@ enum class CornerType
Outer
};
-struct CollisionPosition
+struct CollisionPositionData
{
int Floor = 0;
int Ceiling = 0;
@@ -55,43 +56,26 @@ struct CollisionPosition
bool HasFlippedDiagonalSplit() { return (HasDiagonalSplit() && (SplitAngle != (45.0f * RADIAN))); }
};
-// Deprecated. Use PointCollisionData.
-struct CollisionResult
+struct CollisionSetupData
{
- Vector3i Coordinates;
- int RoomNumber;
+ CollisionProbeMode Mode = CollisionProbeMode::Quadrants; // Probe rotation mode
+ int Radius = 0; // Collision bounds horizontal size
+ int Height = 0; // Collision bounds vertical size
+ short ForwardAngle = 0; // Forward angle direction
- FloorInfo* Block;
- FloorInfo* BottomBlock;
+ int LowerFloorBound = 0; // Borderline floor step-up height
+ int UpperFloorBound = 0; // Borderline floor step-down height
+ int LowerCeilingBound = 0; // Borderline ceiling step-up height
+ int UpperCeilingBound = 0; // Borderline ceiling step-down height
- CollisionPosition Position;
- Vector2 FloorTilt; // x = x, y = z
- Vector2 CeilingTilt; // x = x, y = z
-
- Vector3 FloorNormal;
- Vector3 CeilingNormal;
-};
-
-struct CollisionSetup
-{
- CollisionProbeMode Mode; // Probe rotation mode
- int Radius; // Collision bounds horizontal size
- int Height; // Collision bounds vertical size
- short ForwardAngle; // Forward angle direction
-
- int LowerFloorBound; // Borderline floor step-up height
- int UpperFloorBound; // Borderline floor step-down height
- int LowerCeilingBound; // Borderline ceiling step-up height
- int UpperCeilingBound; // Borderline ceiling step-down height
-
- bool BlockFloorSlopeUp; // Treat steep slopes as walls
- bool BlockFloorSlopeDown; // Treat steep slopes as pits
- bool BlockCeilingSlope; // Treat steep slopes on ceilings as walls
- bool BlockDeathFloorDown; // Treat death sectors as pits
- bool BlockMonkeySwingEdge; // Treat non-monkey sectors as walls
+ bool BlockFloorSlopeUp = false; // Treat steep slopes as walls
+ bool BlockFloorSlopeDown = false; // Treat steep slopes as pits
+ bool BlockCeilingSlope = false; // Treat steep slopes on ceilings as walls
+ bool BlockDeathFloorDown = false; // Treat death sectors as pits
+ bool BlockMonkeySwingEdge = false; // Treat non-monkey sectors as walls
- bool EnableObjectPush; // Can be pushed by objects
- bool EnableSpasm; // Convulse when pushed
+ bool EnableObjectPush = false; // Can be pushed by objects
+ bool EnableSpasm = false; // Convulse when pushed
// Preserve previous parameters to restore later.
Vector3i PrevPosition = Vector3i::Zero;
@@ -103,29 +87,30 @@ struct CollisionSetup
struct CollisionInfo
{
- CollisionSetup Setup; // In parameters
+ CollisionSetupData Setup = {}; // In parameters
- CollisionPosition Middle;
- CollisionPosition MiddleLeft;
- CollisionPosition MiddleRight;
- CollisionPosition Front;
- CollisionPosition FrontLeft;
- CollisionPosition FrontRight;
+ CollisionPositionData Middle = {};
+ CollisionPositionData MiddleLeft = {};
+ CollisionPositionData MiddleRight = {};
+ CollisionPositionData Front = {};
+ CollisionPositionData FrontLeft = {};
+ CollisionPositionData FrontRight = {};
- Pose Shift = Pose::Zero;
- CollisionType CollisionType;
- Vector3 FloorNormal;
- Vector3 CeilingNormal;
- Vector2 FloorTilt; // x = x, y = z
- Vector2 CeilingTilt; // x = x, y = z
- short NearestLedgeAngle;
- float NearestLedgeDistance;
+ CollisionType CollisionType = CT_NONE;
+ Pose Shift = Pose::Zero;
- int LastBridgeItemNumber;
- Pose LastBridgeItemPose;
+ Vector3 FloorNormal = Vector3::Zero;
+ Vector3 CeilingNormal = Vector3::Zero;
+ Vector2 FloorTilt = Vector2::Zero; // NOTE: Deprecated.
+ Vector2 CeilingTilt = Vector2::Zero; // NOTE: Deprecated.
+ short NearestLedgeAngle = 0;
+ float NearestLedgeDistance = 0.0f;
- bool HitStatic;
- bool HitTallObject;
+ int LastBridgeItemNumber = 0;
+ Pose LastBridgeItemPose = Pose::Zero;
+
+ bool HitStatic = false;
+ bool HitTallObject = false;
bool TriangleAtRight() { return ((MiddleRight.SplitAngle != 0.0f) && (MiddleRight.SplitAngle == Middle.SplitAngle)); }
bool TriangleAtLeft() { return ((MiddleLeft.SplitAngle != 0.0f) && (MiddleLeft.SplitAngle == Middle.SplitAngle)); }
@@ -135,10 +120,6 @@ struct CollisionInfo
[[nodiscard]] bool TestItemRoomCollisionAABB(ItemInfo* item);
-// NOTE: All overloads deprecated. Use GetPointCollision().
-CollisionResult GetCollision(const ItemInfo* item);
-CollisionResult GetCollision(const ItemInfo* item, short headingAngle, float forward, float down = 0.0f, float right = 0.0f);
-
void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, bool resetRoom = false);
void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offset, bool resetRoom = false);
int GetQuadrant(short angle);
diff --git a/TombEngine/Game/control/box.cpp b/TombEngine/Game/control/box.cpp
index 14a718ded..6db0d80c7 100644
--- a/TombEngine/Game/control/box.cpp
+++ b/TombEngine/Game/control/box.cpp
@@ -613,22 +613,28 @@ void CreatureUnderwater(ItemInfo* item, int depth)
waterLevel = 0;
}
else
+ {
waterHeight = GetWaterHeight(item);
+ }
int y = waterHeight + waterLevel;
if (item->Pose.Position.y < y)
{
- int height = GetCollision(item).Position.Floor;
+ int height = GetPointCollision(*item).GetFloorHeight();
item->Pose.Position.y = y;
if (y > height)
item->Pose.Position.y = height;
if (item->Pose.Orientation.x > ANGLE(2.0f))
+ {
item->Pose.Orientation.x -= ANGLE(2.0f);
+ }
else if (item->Pose.Orientation.x > 0)
+ {
item->Pose.Orientation.x = 0;
+ }
}
}
@@ -636,7 +642,7 @@ void CreatureFloat(short itemNumber)
{
auto* item = &g_Level.Items[itemNumber];
- auto pointColl = GetCollision(item);
+ auto pointColl = GetPointCollision(*item);
item->HitPoints = NOT_TARGETABLE;
item->Pose.Orientation.x = 0;
@@ -654,9 +660,9 @@ void CreatureFloat(short itemNumber)
AnimateItem(item);
- item->Floor = pointColl.Position.Floor;
- if (pointColl.RoomNumber != item->RoomNumber)
- ItemNewRoom(itemNumber, pointColl.RoomNumber);
+ item->Floor = pointColl.GetFloorHeight();
+ if (pointColl.GetRoomNumber() != item->RoomNumber)
+ ItemNewRoom(itemNumber, pointColl.GetRoomNumber());
if (item->Pose.Position.y <= waterLevel)
{
@@ -2193,18 +2199,18 @@ bool CanCreatureJump(ItemInfo& item, JumpDistance jumpDistType)
}
int vPos = item.Pose.Position.y;
- auto pointCollA = GetCollision(&item, item.Pose.Orientation.y, stepDist);
- auto pointCollB = GetCollision(&item, item.Pose.Orientation.y, stepDist * 2);
- auto pointCollC = GetCollision(&item, item.Pose.Orientation.y, stepDist * 3);
+ auto pointCollA = GetPointCollision(item, item.Pose.Orientation.y, stepDist);
+ auto pointCollB = GetPointCollision(item, item.Pose.Orientation.y, stepDist * 2);
+ auto pointCollC = GetPointCollision(item, item.Pose.Orientation.y, stepDist * 3);
switch (jumpDistType)
{
default:
case JumpDistance::Block1:
if (item.BoxNumber == creature.Enemy->BoxNumber ||
- vPos >= (pointCollA.Position.Floor - STEPUP_HEIGHT) ||
- vPos >= (pointCollB.Position.Floor + CLICK(1)) ||
- vPos <= (pointCollB.Position.Floor - CLICK(1)))
+ vPos >= (pointCollA.GetFloorHeight() - STEPUP_HEIGHT) ||
+ vPos >= (pointCollB.GetFloorHeight() + CLICK(1)) ||
+ vPos <= (pointCollB.GetFloorHeight() - CLICK(1)))
{
return false;
}
@@ -2213,10 +2219,10 @@ bool CanCreatureJump(ItemInfo& item, JumpDistance jumpDistType)
case JumpDistance::Block2:
if (item.BoxNumber == creature.Enemy->BoxNumber ||
- vPos >= (pointCollA.Position.Floor - STEPUP_HEIGHT) ||
- vPos >= (pointCollB.Position.Floor - STEPUP_HEIGHT) ||
- vPos >= (pointCollC.Position.Floor + CLICK(1)) ||
- vPos <= (pointCollC.Position.Floor - CLICK(1)))
+ vPos >= (pointCollA.GetFloorHeight() - STEPUP_HEIGHT) ||
+ vPos >= (pointCollB.GetFloorHeight() - STEPUP_HEIGHT) ||
+ vPos >= (pointCollC.GetFloorHeight() + CLICK(1)) ||
+ vPos <= (pointCollC.GetFloorHeight() - CLICK(1)))
{
return false;
}
diff --git a/TombEngine/Game/control/trigger.cpp b/TombEngine/Game/control/trigger.cpp
index 6f4aad9eb..616ed1e46 100644
--- a/TombEngine/Game/control/trigger.cpp
+++ b/TombEngine/Game/control/trigger.cpp
@@ -843,8 +843,8 @@ void TestTriggers(int x, int y, int z, short roomNumber, bool heavy, int heavyFl
void ProcessSectorFlags(ItemInfo* item)
{
- auto pointColl = GetCollision(item);
- auto* sectorPtr = GetCollision(item).BottomBlock;
+ auto pointColl = GetPointCollision(*item);
+ auto* sectorPtr = &GetPointCollision(*item).GetBottomSector();
bool isPlayer = item->IsLara();
@@ -872,7 +872,7 @@ void ProcessSectorFlags(ItemInfo* item)
GetLaraInfo(item)->Control.WaterStatus != WaterStatus::Dry)
{
// To allow both lava and rapids in same level, also check floor material flag.
- if (sectorPtr->GetSurfaceMaterial(pointColl.Coordinates.x, pointColl.Coordinates.z, true) == MaterialType::Water &&
+ if (sectorPtr->GetSurfaceMaterial(pointColl.GetPosition().x, pointColl.GetPosition().z, true) == MaterialType::Water &&
Objects[ID_KAYAK_LARA_ANIMS].loaded)
{
KayakLaraRapidsDrown(item);
@@ -885,7 +885,7 @@ void ProcessSectorFlags(ItemInfo* item)
}
else if (Objects[item->ObjectNumber].intelligent && item->HitPoints != NOT_TARGETABLE)
{
- if (sectorPtr->GetSurfaceMaterial(pointColl.Coordinates.x, pointColl.Coordinates.z, true) == MaterialType::Water ||
+ if (sectorPtr->GetSurfaceMaterial(pointColl.GetPosition().x, pointColl.GetPosition().z, true) == MaterialType::Water ||
TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, sectorPtr->RoomNumber))
{
DoDamage(item, INT_MAX); // TODO: Implement correct rapids behaviour for other objects!
diff --git a/TombEngine/Game/control/volume.cpp b/TombEngine/Game/control/volume.cpp
index 310ef84b9..26c15b40b 100644
--- a/TombEngine/Game/control/volume.cpp
+++ b/TombEngine/Game/control/volume.cpp
@@ -49,7 +49,7 @@ namespace TEN::Control::Volumes
}
}
- BoundingOrientedBox ConstructRoughBox(ItemInfo& item, const CollisionSetup& coll)
+ BoundingOrientedBox ConstructRoughBox(ItemInfo& item, const CollisionSetupData& coll)
{
auto pBounds = GameBoundingBox(&item).ToBoundingOrientedBox(item.Pose);
auto pos = Vector3(item.Pose.Position.x, pBounds.Center.y, item.Pose.Position.z);
@@ -244,7 +244,7 @@ namespace TEN::Control::Volumes
TestVolumes(roomNumber, box, ActivatorFlags::Static, mesh);
}
- void TestVolumes(short itemNumber, const CollisionSetup* coll)
+ void TestVolumes(short itemNumber, const CollisionSetupData* coll)
{
auto& item = g_Level.Items[itemNumber];
auto box = (coll != nullptr) ?
diff --git a/TombEngine/Game/control/volume.h b/TombEngine/Game/control/volume.h
index 9d9fc6a84..2c050364e 100644
--- a/TombEngine/Game/control/volume.h
+++ b/TombEngine/Game/control/volume.h
@@ -4,7 +4,7 @@
#include "Game/Setup.h"
#include "Renderer/Renderer.h"
-struct CollisionSetup;
+struct CollisionSetupData;
namespace TEN::Control::Volumes
{
@@ -39,7 +39,7 @@ namespace TEN::Control::Volumes
};
void TestVolumes(short roomNumber, const BoundingOrientedBox& box, ActivatorFlags activatorFlag, Activator activator);
- void TestVolumes(short itemNumber, const CollisionSetup* coll = nullptr);
+ void TestVolumes(short itemNumber, const CollisionSetupData* coll = nullptr);
void TestVolumes(short roomNumber, MESH_INFO* mesh);
void TestVolumes(CAMERA_INFO* camera);
diff --git a/TombEngine/Game/effects/bubble.cpp b/TombEngine/Game/effects/bubble.cpp
index 58f10ccf4..7a51a81b3 100644
--- a/TombEngine/Game/effects/bubble.cpp
+++ b/TombEngine/Game/effects/bubble.cpp
@@ -147,7 +147,7 @@ namespace TEN::Effects::Bubble
if (bubble.Life <= 0.0f)
continue;
- // Update room number. TODO: Should use GetCollision(), but calling it for each bubble is very inefficient.
+ // Update room number. TODO: Should use GetPointCollision(), but calling it for each bubble is very inefficient.
auto roomVector = RoomVector(bubble.RoomNumber, int(bubble.Position.y - bubble.Gravity));
int roomNumber = GetRoomVector(roomVector, Vector3i(bubble.Position.x, bubble.Position.y - bubble.Gravity, bubble.Position.z)).RoomNumber;
int prevRoomNumber = bubble.RoomNumber;
diff --git a/TombEngine/Game/effects/effects.cpp b/TombEngine/Game/effects/effects.cpp
index 1cd9b2eb7..33a36982e 100644
--- a/TombEngine/Game/effects/effects.cpp
+++ b/TombEngine/Game/effects/effects.cpp
@@ -1261,15 +1261,15 @@ void SpawnPlayerWaterSurfaceEffects(const ItemInfo& item, int waterHeight, int w
return;
// Get point collision.
- auto pointColl0 = GetCollision(&item, 0, 0, -(LARA_HEIGHT / 2));
- auto pointColl1 = GetCollision(&item, 0, 0, item.Animation.Velocity.y);
+ auto pointColl0 = GetPointCollision(item, 0, 0, -(LARA_HEIGHT / 2));
+ auto pointColl1 = GetPointCollision(item, 0, 0, item.Animation.Velocity.y);
// In swamp; return early.
- if (TestEnvironment(ENV_FLAG_SWAMP, pointColl1.RoomNumber))
+ if (TestEnvironment(ENV_FLAG_SWAMP, pointColl1.GetRoomNumber()))
return;
- bool isWater0 = TestEnvironment(ENV_FLAG_WATER, pointColl0.RoomNumber);
- bool isWater1 = TestEnvironment(ENV_FLAG_WATER, pointColl1.RoomNumber);
+ bool isWater0 = TestEnvironment(ENV_FLAG_WATER, pointColl0.GetRoomNumber());
+ bool isWater1 = TestEnvironment(ENV_FLAG_WATER, pointColl1.GetRoomNumber());
// Spawn splash.
if (!isWater0 && isWater1 &&
@@ -1282,7 +1282,7 @@ void SpawnPlayerWaterSurfaceEffects(const ItemInfo& item, int waterHeight, int w
SplashSetup.innerRadius = 16;
SplashSetup.splashPower = item.Animation.Velocity.z;
- SetupSplash(&SplashSetup, pointColl0.RoomNumber);
+ SetupSplash(&SplashSetup, pointColl0.GetRoomNumber());
SplashCount = 16;
}
// Spawn ripple.
@@ -1307,7 +1307,7 @@ void SpawnPlayerWaterSurfaceEffects(const ItemInfo& item, int waterHeight, int w
void Splash(ItemInfo* item)
{
- int probedRoomNumber = GetCollision(item).RoomNumber;
+ int probedRoomNumber = GetPointCollision(*item).GetRoomNumber();
if (!TestEnvironment(ENV_FLAG_WATER, probedRoomNumber))
return;
diff --git a/TombEngine/Game/pickup/pickup.cpp b/TombEngine/Game/pickup/pickup.cpp
index d48d8a746..9618c1a5b 100644
--- a/TombEngine/Game/pickup/pickup.cpp
+++ b/TombEngine/Game/pickup/pickup.cpp
@@ -844,7 +844,7 @@ void DropPickups(ItemInfo* item)
auto bounds = GameBoundingBox(item);
auto extents = bounds.GetExtents();
auto origin = Geometry::TranslatePoint(item->Pose.Position.ToVector3(), item->Pose.Orientation, bounds.GetCenter());
- auto yPos = GetCollision(item).Position.Floor;
+ auto yPos = GetPointCollision(*item).GetFloorHeight();
origin.y = yPos; // Initialize drop origin Y point as floor height at centerpoint, in case all corner tests fail.
@@ -1088,19 +1088,19 @@ void InitializePickup(short itemNumber)
if (triggerFlags == 0)
{
// Automatically align pickups to the floor surface.
- auto pointColl = GetCollision(item);
- int bridgeItemNumber = pointColl.Block->GetInsideBridgeItemNumber(item->Pose.Position, true, true);
+ auto pointColl = GetPointCollision(*item);
+ int bridgeItemNumber = pointColl.GetSector().GetInsideBridgeItemNumber(item->Pose.Position, true, true);
if (bridgeItemNumber != NO_ITEM)
{
// If pickup is within bridge item, most likely it means it is
// below pushable or raising block, so ignore its collision.
- pointColl.Block->RemoveBridge(bridgeItemNumber);
- pointColl = GetCollision(item);
- pointColl.Block->AddBridge(bridgeItemNumber);
+ pointColl.GetSector().RemoveBridge(bridgeItemNumber);
+ pointColl = GetPointCollision(*item);
+ pointColl.GetSector().AddBridge(bridgeItemNumber);
}
- item->Pose.Position.y = pointColl.Position.Floor - bounds.Y2;
+ item->Pose.Position.y = pointColl.GetFloorHeight() - bounds.Y2;
AlignEntityToSurface(item, Vector2(Objects[item->ObjectNumber].radius));
}
}
diff --git a/TombEngine/Objects/Effects/flame_emitters.cpp b/TombEngine/Objects/Effects/flame_emitters.cpp
index 7fd725ce7..37ccc5465 100644
--- a/TombEngine/Objects/Effects/flame_emitters.cpp
+++ b/TombEngine/Objects/Effects/flame_emitters.cpp
@@ -4,6 +4,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/collision/sphere.h"
#include "Game/effects/effects.h"
#include "Game/effects/Electricity.h"
@@ -20,6 +21,7 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Effects::Electricity;
using namespace TEN::Effects::Environment;
using namespace TEN::Effects::Items;
@@ -266,21 +268,21 @@ namespace TEN::Entities::Effects
item->Pose.Position.x += phd_sin(item->Pose.Orientation.y - ANGLE(180)) * (CLICK(1) / FPS);
item->Pose.Position.z += phd_cos(item->Pose.Orientation.y - ANGLE(180)) * (CLICK(1) / FPS);
- auto pointColl = GetCollision(item);
+ auto pointColl = GetPointCollision(*item);
- if (TestEnvironment(ENV_FLAG_WATER, pointColl.RoomNumber) ||
- pointColl.Position.Floor - item->Pose.Position.y > CLICK(2) ||
- pointColl.Position.Floor == NO_HEIGHT)
+ if (TestEnvironment(ENV_FLAG_WATER, pointColl.GetRoomNumber()) ||
+ pointColl.GetFloorHeight() - item->Pose.Position.y > CLICK(2) ||
+ pointColl.GetFloorHeight() == NO_HEIGHT)
{
Weather.Flash(255, 128, 0, 0.03f);
KillItem(itemNumber);
return;
}
- if (item->RoomNumber != pointColl.RoomNumber)
- ItemNewRoom(itemNumber, pointColl.RoomNumber);
+ if (item->RoomNumber != pointColl.GetRoomNumber())
+ ItemNewRoom(itemNumber, pointColl.GetRoomNumber());
- item->Pose.Position.y = pointColl.Position.Floor;
+ item->Pose.Position.y = pointColl.GetFloorHeight();
if (Wibble & 7)
TriggerFireFlame(item->Pose.Position.x, item->Pose.Position.y - 32, item->Pose.Position.z, FlameType::Medium);
diff --git a/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp b/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
index d2eac7afb..d9a06eb94 100644
--- a/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
+++ b/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
@@ -104,7 +104,7 @@ namespace TEN::Entities::Generic
// Check for stopper flag.
/*if (collisionResult.Block->Stopper)
{
- if (collisionResult.Position.Floor <= pushableItem.Pose.Position.y)
+ if (collisionResult.GetFloorHeight() <= pushableItem.Pose.Position.y)
return false;
}*/
diff --git a/TombEngine/Objects/Generic/Object/Pushable/PushableObject.cpp b/TombEngine/Objects/Generic/Object/Pushable/PushableObject.cpp
index e96226e1b..57d9658fe 100644
--- a/TombEngine/Objects/Generic/Object/Pushable/PushableObject.cpp
+++ b/TombEngine/Objects/Generic/Object/Pushable/PushableObject.cpp
@@ -104,7 +104,7 @@ namespace TEN::Entities::Generic
// Update bridge.
AddPushableStackBridge(pushableItem, false);
- int probeRoomNumber = GetCollision(&pushableItem).RoomNumber;
+ int probeRoomNumber = GetPointCollision(pushableItem).GetRoomNumber();
AddPushableStackBridge(pushableItem, true);
// Update room number.
diff --git a/TombEngine/Objects/Generic/Object/Pushable/PushableStack.cpp b/TombEngine/Objects/Generic/Object/Pushable/PushableStack.cpp
index a8995ae3b..833efe10d 100644
--- a/TombEngine/Objects/Generic/Object/Pushable/PushableStack.cpp
+++ b/TombEngine/Objects/Generic/Object/Pushable/PushableStack.cpp
@@ -2,12 +2,14 @@
#include "Objects/Generic/Object/Pushable/PushableStack.h"
#include "Game/collision/floordata.h"
+#include "Game/collision/PointCollision.h"
#include "Game/Setup.h"
#include "Objects/Generic/Object/Pushable/PushableBridge.h"
#include "Objects/Generic/Object/Pushable/PushableObject.h"
#include "Specific/level.h"
using namespace TEN::Collision::Floordata;
+using namespace TEN::Collision::PointCollision;
namespace TEN::Entities::Generic
{
@@ -44,8 +46,8 @@ namespace TEN::Entities::Generic
int x = pushableItem.Pose.Position.x;
int z = pushableItem.Pose.Position.z;
- auto pointColl = GetCollision(&pushableItem);
- int y = pointColl.Position.Floor;
+ auto pointColl = GetPointCollision(pushableItem);
+ int y = pointColl.GetFloorHeight();
stackGroups.emplace(Vector3i(x, y, z), std::vector()).first->second.push_back(itemNumber);
}
@@ -144,7 +146,7 @@ namespace TEN::Entities::Generic
return pushabelStackFound;
// Otherwise, check room below.
- //auto collisionResult = GetCollision(pushableItem.Pose.Position.x, pushableItem.Pose.Position.y, pushableItem.Pose.Position.z, pushableItem.RoomNumber);
+ //auto collisionResult = GetPointCollision(pushableItem.Pose.Position.x, pushableItem.Pose.Position.y, pushableItem.Pose.Position.z, pushableItem.RoomNumber);
//auto roomNumberBelow = collisionResult.Block->GetRoomNumberBelow(pushableItem.Pose.Position.x, pushableItem.Pose.Position.y, pushableItem.Pose.Position.z).value();
//pushabelStackFound = FindPushableStackInRoom(itemNumber, roomNumberBelow);
diff --git a/TombEngine/Objects/TR1/Entity/tr1_doppelganger.cpp b/TombEngine/Objects/TR1/Entity/tr1_doppelganger.cpp
index 5eb580d48..d91999010 100644
--- a/TombEngine/Objects/TR1/Entity/tr1_doppelganger.cpp
+++ b/TombEngine/Objects/TR1/Entity/tr1_doppelganger.cpp
@@ -56,7 +56,7 @@ namespace TEN::Entities::Creatures::TR1
{
case 0:
{
- int laraFloorHeight = GetCollision(LaraItem).Position.Floor;
+ int laraFloorHeight = GetPointCollision(*LaraItem).GetFloorHeight();
// Get floor heights for comparison.
auto pos = Vector3i(
@@ -113,7 +113,7 @@ namespace TEN::Entities::Creatures::TR1
}
TestTriggers(&item, true);
- item.Floor = GetCollision(&item).Position.Floor;
+ item.Floor = GetPointCollision(item).GetFloorHeight();
if (item.Pose.Position.y >= item.Floor)
{
@@ -137,7 +137,7 @@ namespace TEN::Entities::Creatures::TR1
break;
}
- ItemNewRoom(itemNumber, GetCollision(&item).RoomNumber);
+ ItemNewRoom(itemNumber, GetPointCollision(item).GetRoomNumber());
AnimateItem(&item);
}
}
diff --git a/TombEngine/Objects/TR1/Trap/DamoclesSword.cpp b/TombEngine/Objects/TR1/Trap/DamoclesSword.cpp
index 25290c7c3..50b1cccec 100644
--- a/TombEngine/Objects/TR1/Trap/DamoclesSword.cpp
+++ b/TombEngine/Objects/TR1/Trap/DamoclesSword.cpp
@@ -4,12 +4,14 @@
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/effects/effects.h"
#include "Game/Lara/lara.h"
#include "Game/Setup.h"
#include "Math/Math.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Math;
namespace TEN::Entities::Traps::TR1
@@ -59,10 +61,10 @@ namespace TEN::Entities::Traps::TR1
TranslateItem(&item, headingAngle, item.ItemFlags[1], item.Animation.Velocity.y);
int vPos = item.Pose.Position.y;
- auto pointColl = GetCollision(&item);
+ auto pointColl = GetPointCollision(item);
// Impale floor.
- if ((pointColl.Position.Floor - vPos) <= DAMOCLES_SWORD_IMPALE_DEPTH)
+ if ((pointColl.GetFloorHeight() - vPos) <= DAMOCLES_SWORD_IMPALE_DEPTH)
{
SoundEffect(SFX_TR1_DAMOCLES_ROOM_SWORD, &item.Pose);
float distance = Vector3::Distance(item.Pose.Position.ToVector3(), Camera.pos.ToVector3());
@@ -79,7 +81,7 @@ namespace TEN::Entities::Traps::TR1
}
// Scan for player.
- if (item.Pose.Position.y < GetCollision(&item).Position.Floor)
+ if (item.Pose.Position.y < GetPointCollision(item).GetFloorHeight())
{
item.Pose.Orientation.y += item.ItemFlags[0];
diff --git a/TombEngine/Objects/TR2/Trap/tr2_spinningblade.cpp b/TombEngine/Objects/TR2/Trap/tr2_spinningblade.cpp
index adb472b24..50a2800e4 100644
--- a/TombEngine/Objects/TR2/Trap/tr2_spinningblade.cpp
+++ b/TombEngine/Objects/TR2/Trap/tr2_spinningblade.cpp
@@ -58,13 +58,13 @@ void SpinningBladeControl(short itemNumber)
AnimateItem(item);
- auto probe = GetCollision(item);
+ auto pointColl = GetPointCollision(*item);
- item->Floor = probe.Position.Floor;
- item->Pose.Position.y = probe.Position.Floor;
+ item->Floor = pointColl.GetFloorHeight();
+ item->Pose.Position.y = pointColl.GetFloorHeight();
- if (probe.RoomNumber != item->RoomNumber)
- ItemNewRoom(itemNumber, probe.RoomNumber);
+ if (pointColl.GetRoomNumber() != item->RoomNumber)
+ ItemNewRoom(itemNumber, pointColl.GetRoomNumber());
if (isSpinning && item->Animation.ActiveState == 1)
item->Pose.Orientation.y += -ANGLE(180.0f);
diff --git a/TombEngine/Objects/TR2/Vehicles/skidoo.cpp b/TombEngine/Objects/TR2/Vehicles/skidoo.cpp
index 795170420..c72777c44 100644
--- a/TombEngine/Objects/TR2/Vehicles/skidoo.cpp
+++ b/TombEngine/Objects/TR2/Vehicles/skidoo.cpp
@@ -187,12 +187,12 @@ namespace TEN::Entities::Vehicles
else
angle = skidooItem->Pose.Orientation.y - ANGLE(90.0f);
- auto probe = GetCollision(skidooItem, angle, -SKIDOO_DISMOUNT_DISTANCE);
+ auto probe = GetPointCollision(*skidooItem, angle, -SKIDOO_DISMOUNT_DISTANCE);
- if ((probe.Position.FloorSlope || probe.Position.Floor == NO_HEIGHT) ||
- abs(probe.Position.Floor - skidooItem->Pose.Position.y) > CLICK(2) ||
- ((probe.Position.Ceiling - skidooItem->Pose.Position.y) > -LARA_HEIGHT ||
- (probe.Position.Floor - probe.Position.Ceiling) < LARA_HEIGHT))
+ if ((probe.IsIllegalFloor() || probe.GetFloorHeight() == NO_HEIGHT) ||
+ abs(probe.GetFloorHeight() - skidooItem->Pose.Position.y) > CLICK(2) ||
+ ((probe.GetCeilingHeight() - skidooItem->Pose.Position.y) > -LARA_HEIGHT ||
+ (probe.GetFloorHeight() - probe.GetCeilingHeight()) < LARA_HEIGHT))
{
return false;
}
@@ -280,7 +280,7 @@ namespace TEN::Entities::Vehicles
auto heightFrontLeft = GetVehicleHeight(skidooItem, SKIDOO_FRONT, -SKIDOO_SIDE, true, &frontLeft);
auto heightFrontRight = GetVehicleHeight(skidooItem, SKIDOO_FRONT, SKIDOO_SIDE, true, &frontRight);
- auto probe = GetCollision(skidooItem);
+ auto probe = GetPointCollision(*skidooItem);
TestTriggers(skidooItem, true);
TestTriggers(skidooItem, false);
@@ -302,7 +302,7 @@ namespace TEN::Entities::Vehicles
collide = 0;
}
- int height = probe.Position.Floor;
+ int height = probe.GetFloorHeight();
int pitch = 0;
if (skidooItem->Flags & IFLAG_INVISIBLE)
@@ -363,10 +363,10 @@ namespace TEN::Entities::Vehicles
if (skidooItem->Flags & IFLAG_INVISIBLE)
{
- if (probe.RoomNumber != skidooItem->RoomNumber)
+ if (probe.GetRoomNumber() != skidooItem->RoomNumber)
{
- ItemNewRoom(lara->Context.Vehicle, probe.RoomNumber);
- ItemNewRoom(laraItem->Index, probe.RoomNumber);
+ ItemNewRoom(lara->Context.Vehicle, probe.GetRoomNumber());
+ ItemNewRoom(laraItem->Index, probe.GetRoomNumber());
}
AnimateItem(laraItem);
@@ -379,10 +379,10 @@ namespace TEN::Entities::Vehicles
SkidooAnimation(skidooItem, laraItem, collide, dead);
- if (probe.RoomNumber != skidooItem->RoomNumber)
+ if (probe.GetRoomNumber() != skidooItem->RoomNumber)
{
- ItemNewRoom(lara->Context.Vehicle, probe.RoomNumber);
- ItemNewRoom(laraItem->Index, probe.RoomNumber);
+ ItemNewRoom(lara->Context.Vehicle, probe.GetRoomNumber());
+ ItemNewRoom(laraItem->Index, probe.GetRoomNumber());
}
if (laraItem->Animation.ActiveState != SKIDOO_STATE_FALLOFF)
@@ -692,8 +692,8 @@ namespace TEN::Entities::Vehicles
void DoSnowEffect(ItemInfo* skidooItem)
{
- auto pointColl = GetCollision(skidooItem);
- auto material = pointColl.BottomBlock->GetSurfaceMaterial(pointColl.Coordinates.x, pointColl.Coordinates.z, true);
+ auto pointColl = GetPointCollision(*skidooItem);
+ auto material = pointColl.GetBottomSector().GetSurfaceMaterial(pointColl.GetPosition().x, pointColl.GetPosition().z, true);
if (material != MaterialType::Ice && material != MaterialType::Snow)
return;
@@ -922,8 +922,8 @@ namespace TEN::Entities::Vehicles
if (heightFrontRight < (frontRightOld.y - CLICK(1)))
rotation += DoSkidooShift(skidooItem, &frontRight, &frontRightOld);
- auto probe = GetCollision(skidooItem);
- if (probe.Position.Floor < (skidooItem->Pose.Position.y - CLICK(1)))
+ auto probe = GetPointCollision(*skidooItem);
+ if (probe.GetFloorHeight() < (skidooItem->Pose.Position.y - CLICK(1)))
DoSkidooShift(skidooItem, (Vector3i*)&skidooItem->Pose, &oldPos);
skidoo->ExtraRotation = rotation;
diff --git a/TombEngine/Objects/TR2/Vehicles/speedboat.cpp b/TombEngine/Objects/TR2/Vehicles/speedboat.cpp
index 5d90ae406..162d6df91 100644
--- a/TombEngine/Objects/TR2/Vehicles/speedboat.cpp
+++ b/TombEngine/Objects/TR2/Vehicles/speedboat.cpp
@@ -549,11 +549,11 @@ namespace TEN::Entities::Vehicles
SpeedboatDoShift(speedboatItem, &f, &frontOld);
}
- auto probe = GetCollision(speedboatItem);
- auto height = GetWaterHeight(speedboatItem->Pose.Position.x, speedboatItem->Pose.Position.y - 5, speedboatItem->Pose.Position.z, probe.RoomNumber);
+ auto probe = GetPointCollision(*speedboatItem);
+ auto height = GetWaterHeight(speedboatItem->Pose.Position.x, speedboatItem->Pose.Position.y - 5, speedboatItem->Pose.Position.z, probe.GetRoomNumber());
if (height == NO_HEIGHT)
- height = GetFloorHeight(probe.Block, speedboatItem->Pose.Position.x, speedboatItem->Pose.Position.y - 5, speedboatItem->Pose.Position.z);
+ height = GetFloorHeight(&probe.GetSector(), speedboatItem->Pose.Position.x, speedboatItem->Pose.Position.y - 5, speedboatItem->Pose.Position.z);
if (height < (speedboatItem->Pose.Position.y - CLICK(0.5f)))
SpeedboatDoShift(speedboatItem, (Vector3i*)&speedboatItem->Pose, &old);
diff --git a/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp b/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp
index 0cd3f0306..802578b2d 100644
--- a/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp
+++ b/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp
@@ -2,6 +2,7 @@
#include "Objects/TR3/Entity/tr3_scuba_diver.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/box.h"
#include "Game/control/control.h"
#include "Game/control/los.h"
@@ -13,6 +14,8 @@
#include "Game/Setup.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
+
namespace TEN::Entities::Creatures::TR3
{
constexpr auto SCUBA_DIVER_ATTACK_DAMAGE = 50;
@@ -92,12 +95,12 @@ namespace TEN::Entities::Creatures::TR3
{
TranslateItem(item, item->Pose.Orientation, item->Animation.Velocity.z);
- auto probe = GetCollision(item);
+ auto probe = GetPointCollision(*item);
- if (item->RoomNumber != probe.RoomNumber)
- ItemNewRoom(itemNumber, probe.RoomNumber);
+ if (item->RoomNumber != probe.GetRoomNumber())
+ ItemNewRoom(itemNumber, probe.GetRoomNumber());
- item->Floor = GetCollision(item).Position.Floor;
+ item->Floor = GetPointCollision(*item).GetFloorHeight();
if (item->Pose.Position.y >= item->Floor)
KillItem(itemNumber);
}
diff --git a/TombEngine/Objects/TR3/Object/corpse.cpp b/TombEngine/Objects/TR3/Object/corpse.cpp
index 1deb1da4c..987c695f7 100644
--- a/TombEngine/Objects/TR3/Object/corpse.cpp
+++ b/TombEngine/Objects/TR3/Object/corpse.cpp
@@ -7,6 +7,7 @@
#include "Game/control/control.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/collision/floordata.h"
#include "Game/collision/sphere.h"
#include "Game/effects/effects.h"
@@ -18,6 +19,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Effects::Ripple;
using namespace TEN::Math::Random;
@@ -69,7 +71,7 @@ namespace TEN::Entities::TR3
bool isWater = TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, item.RoomNumber);
int VerticalVelCoeff = isWater ? 81.0f : 1.0f;
- int roomNumber = GetCollision(&item).RoomNumber;
+ int roomNumber = GetPointCollision(item).GetRoomNumber();
if (item.RoomNumber != roomNumber)
{
if (TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, roomNumber) &&
@@ -89,10 +91,10 @@ namespace TEN::Entities::TR3
ItemNewRoom(itemNumber, roomNumber);
}
- auto pointColl = GetCollision(&item);
+ auto pointColl = GetPointCollision(item);
item.Animation.IsAirborne = true;
- if (pointColl.Position.Floor < item.Pose.Position.y)
+ if (pointColl.GetFloorHeight() < item.Pose.Position.y)
{
if (!isWater)
{
diff --git a/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp b/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp
index 3f88cdc9d..b823d479a 100644
--- a/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp
+++ b/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp
@@ -413,7 +413,7 @@ namespace TEN::Entities::Traps
AnimateItem(&item);
- int probedRoomNumber = GetCollision(&item).RoomNumber;
+ int probedRoomNumber = GetPointCollision(item).GetRoomNumber();
if (item.RoomNumber != probedRoomNumber)
ItemNewRoom(itemNumber, probedRoomNumber);
diff --git a/TombEngine/Objects/TR3/Trap/train.cpp b/TombEngine/Objects/TR3/Trap/train.cpp
index 54617dd04..aab505f7a 100644
--- a/TombEngine/Objects/TR3/Trap/train.cpp
+++ b/TombEngine/Objects/TR3/Trap/train.cpp
@@ -67,7 +67,7 @@ void TrainControl(short itemNumber)
item->Pose.Position.y -= 32;// ?
- short probedRoomNumber = GetCollision(item).RoomNumber;
+ short probedRoomNumber = GetPointCollision(*item).GetRoomNumber();
if (probedRoomNumber != item->RoomNumber)
ItemNewRoom(itemNumber, probedRoomNumber);
diff --git a/TombEngine/Objects/TR3/Vehicles/kayak.cpp b/TombEngine/Objects/TR3/Vehicles/kayak.cpp
index 38b3b1423..5b26186bf 100644
--- a/TombEngine/Objects/TR3/Vehicles/kayak.cpp
+++ b/TombEngine/Objects/TR3/Vehicles/kayak.cpp
@@ -535,22 +535,22 @@ namespace TEN::Entities::Vehicles
kayakItem->Pose.Orientation.y += rot;
- auto probe = GetCollision(kayakItem);
- int probedRoomNum = probe.RoomNumber;
+ auto probe = GetPointCollision(*kayakItem);
+ int probedRoomNum = probe.GetRoomNumber();
height2 = GetWaterHeight(kayakItem->Pose.Position.x, kayakItem->Pose.Position.y, kayakItem->Pose.Position.z, probedRoomNum);
if (height2 == NO_HEIGHT)
- height2 = probe.Position.Floor;
+ height2 = probe.GetFloorHeight();
if (height2 < (kayakItem->Pose.Position.y - KAYAK_COLLIDE))
KayakDoShift(kayakItem, (Vector3i*)&kayakItem->Pose, &oldPos[8]);
- probe = GetCollision(kayakItem);
- probedRoomNum = probe.RoomNumber;
+ probe = GetPointCollision(*kayakItem);
+ probedRoomNum = probe.GetRoomNumber();
height2 = GetWaterHeight(kayakItem->Pose.Position.x, kayakItem->Pose.Position.y, kayakItem->Pose.Position.z, probedRoomNum);
if (height2 == NO_HEIGHT)
- height2 = probe.Position.Floor;
+ height2 = probe.GetFloorHeight();
if (height2 == NO_HEIGHT)
{
@@ -1081,13 +1081,13 @@ namespace TEN::Entities::Vehicles
KayakToBackground(kayakItem, laraItem);
TestTriggers(kayakItem, false);
- auto probe = GetCollision(kayakItem);
- int water = GetWaterHeight(kayakItem->Pose.Position.x, kayakItem->Pose.Position.y, kayakItem->Pose.Position.z, probe.RoomNumber);
+ auto probe = GetPointCollision(*kayakItem);
+ int water = GetWaterHeight(kayakItem->Pose.Position.x, kayakItem->Pose.Position.y, kayakItem->Pose.Position.z, probe.GetRoomNumber());
kayak->WaterHeight = water;
if (kayak->WaterHeight == NO_HEIGHT)
{
- water = probe.Position.Floor;
+ water = probe.GetFloorHeight();
kayak->WaterHeight = water;
kayak->TrueWater = false;
}
@@ -1108,10 +1108,10 @@ namespace TEN::Entities::Vehicles
if (lara->Context.Vehicle != NO_ITEM)
{
- if (kayakItem->RoomNumber != probe.RoomNumber)
+ if (kayakItem->RoomNumber != probe.GetRoomNumber())
{
- ItemNewRoom(lara->Context.Vehicle, probe.RoomNumber);
- ItemNewRoom(laraItem->Index, probe.RoomNumber);
+ ItemNewRoom(lara->Context.Vehicle, probe.GetRoomNumber());
+ ItemNewRoom(laraItem->Index, probe.GetRoomNumber());
}
laraItem->Pose.Position = kayakItem->Pose.Position;
diff --git a/TombEngine/Objects/TR3/Vehicles/minecart.cpp b/TombEngine/Objects/TR3/Vehicles/minecart.cpp
index d65f36303..b3ac6e8de 100644
--- a/TombEngine/Objects/TR3/Vehicles/minecart.cpp
+++ b/TombEngine/Objects/TR3/Vehicles/minecart.cpp
@@ -5,6 +5,7 @@
#include "Game/camera.h"
#include "Game/collision/sphere.h"
#include "Game/collision/collide_item.h"
+#include "Game/collision/PointCollision.h"
#include "Game/effects/effects.h"
#include "Game/effects/spark.h"
#include "Game/effects/tomb4fx.h"
@@ -20,6 +21,7 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Effects::Spark;
using namespace TEN::Input;
using namespace TEN::Math;
@@ -180,7 +182,7 @@ namespace TEN::Entities::Vehicles
// This allows creation of minecarts which will get to a point and stop forever.
auto mountType = GetVehicleMountType(minecartItem, laraItem, coll, MinecartMountTypes, MINECART_MOUNT_DISTANCE);
if (mountType == VehicleMountType::None ||
- GetCollision(minecartItem, minecartItem->Pose.Orientation.y, BLOCK(1)).BottomBlock->Flags.MinecartStop())
+ GetPointCollision(*minecartItem, minecartItem->Pose.Orientation.y, BLOCK(1)).GetBottomSector().Flags.MinecartStop())
{
ObjectCollision(itemNumber, laraItem, coll);
}
@@ -240,12 +242,13 @@ namespace TEN::Entities::Vehicles
static int GetMinecartCollision(ItemInfo* minecartItem, short angle, int distance)
{
- auto probe = GetCollision(minecartItem, angle, distance, -LARA_HEIGHT);
+ auto probe = GetPointCollision(*minecartItem, angle, distance, -LARA_HEIGHT);
- if (probe.Position.Floor != NO_HEIGHT)
- probe.Position.Floor -= minecartItem->Pose.Position.y;
+ if (probe.GetFloorHeight() == NO_HEIGHT)
+ return probe.GetFloorHeight();
+
+ return (probe.GetFloorHeight() - minecartItem->Pose.Position.y);
- return probe.Position.Floor;
}
static bool TestMinecartDismount(ItemInfo* laraItem, int direction)
@@ -259,16 +262,16 @@ namespace TEN::Entities::Vehicles
else
angle = minecartItem->Pose.Orientation.y - ANGLE(90.0f);
- auto probe = GetCollision(minecartItem, angle, -MINECART_DISMOUNT_DISTANCE);
+ auto probe = GetPointCollision(*minecartItem, angle, -MINECART_DISMOUNT_DISTANCE);
- if (probe.Position.FloorSlope || probe.Position.Floor == NO_HEIGHT)
+ if (probe.IsIllegalFloor() || probe.GetFloorHeight() == NO_HEIGHT)
return false;
- if (abs(probe.Position.Floor - minecartItem->Pose.Position.y) > CLICK(2))
+ if (abs(probe.GetFloorHeight() - minecartItem->Pose.Position.y) > CLICK(2))
return false;
- if ((probe.Position.Ceiling - minecartItem->Pose.Position.y) > -LARA_HEIGHT ||
- (probe.Position.Floor - probe.Position.Ceiling) < LARA_HEIGHT)
+ if ((probe.GetCeilingHeight() - minecartItem->Pose.Position.y) > -LARA_HEIGHT ||
+ (probe.GetFloorHeight() - probe.GetCeilingHeight()) < LARA_HEIGHT)
{
return false;
}
@@ -351,7 +354,7 @@ namespace TEN::Entities::Vehicles
auto* minecart = GetMinecartInfo(minecartItem);
auto* lara = GetLaraInfo(laraItem);
- auto flags = GetCollision(minecartItem).BottomBlock->Flags;
+ auto flags = GetPointCollision(*minecartItem).GetBottomSector().Flags;
if (minecart->StopDelayTime)
minecart->StopDelayTime--;
@@ -968,7 +971,7 @@ namespace TEN::Entities::Vehicles
if (lara->Context.Vehicle != NO_ITEM)
laraItem->Pose = minecartItem->Pose;
- short probedRoomNumber = GetCollision(minecartItem).RoomNumber;
+ short probedRoomNumber = GetPointCollision(*minecartItem).GetRoomNumber();
if (probedRoomNumber != minecartItem->RoomNumber)
{
ItemNewRoom(lara->Context.Vehicle, probedRoomNumber);
diff --git a/TombEngine/Objects/TR3/Vehicles/quad_bike.cpp b/TombEngine/Objects/TR3/Vehicles/quad_bike.cpp
index 648d6484e..15b4ce4f4 100644
--- a/TombEngine/Objects/TR3/Vehicles/quad_bike.cpp
+++ b/TombEngine/Objects/TR3/Vehicles/quad_bike.cpp
@@ -537,9 +537,9 @@ namespace TEN::Entities::Vehicles
else
quadBikeItem->Pose.Orientation.y += quadBike->TurnRate + quadBike->ExtraRotation;
- auto probe = GetCollision(quadBikeItem);
+ auto probe = GetPointCollision(*quadBikeItem);
int speed = 0;
- if (quadBikeItem->Pose.Position.y >= probe.Position.Floor)
+ if (quadBikeItem->Pose.Position.y >= probe.GetFloorHeight())
speed = quadBikeItem->Animation.Velocity.z * phd_cos(quadBikeItem->Pose.Orientation.x);
else
speed = quadBikeItem->Animation.Velocity.z;
@@ -636,8 +636,8 @@ namespace TEN::Entities::Vehicles
rot += rotAdd;
}
- probe = GetCollision(quadBikeItem);
- if (probe.Position.Floor < quadBikeItem->Pose.Position.y - CLICK(1))
+ probe = GetPointCollision(*quadBikeItem);
+ if (probe.GetFloorHeight() < quadBikeItem->Pose.Position.y - CLICK(1))
DoQuadShift(quadBikeItem, (Vector3i*)&quadBikeItem->Pose, &old);
quadBike->ExtraRotation = rot;
@@ -1095,7 +1095,7 @@ namespace TEN::Entities::Vehicles
bool collide = QuadDynamics(quadBikeItem, laraItem);
- auto probe = GetCollision(quadBikeItem);
+ auto probe = GetPointCollision(*quadBikeItem);
Vector3i frontLeft, frontRight;
auto floorHeightLeft = GetVehicleHeight(quadBikeItem, QBIKE_FRONT, -QBIKE_SIDE, false, &frontLeft);
@@ -1130,7 +1130,7 @@ namespace TEN::Entities::Vehicles
break;
default:
- drive = QuadUserControl(quadBikeItem, probe.Position.Floor, &pitch);
+ drive = QuadUserControl(quadBikeItem, probe.GetFloorHeight(), &pitch);
HandleVehicleSpeedometer(quadBikeItem->Animation.Velocity.z, MAX_VELOCITY / (float)VEHICLE_VELOCITY_SCALE);
break;
}
@@ -1154,7 +1154,7 @@ namespace TEN::Entities::Vehicles
quadBike->Pitch = 0;
}
- quadBikeItem->Floor = probe.Position.Floor;
+ quadBikeItem->Floor = probe.GetFloorHeight();
short rotAdd = quadBike->Velocity / 4;
quadBike->RearRot -= rotAdd;
@@ -1163,22 +1163,22 @@ namespace TEN::Entities::Vehicles
quadBike->LeftVerticalVelocity = DoQuadDynamics(floorHeightLeft, quadBike->LeftVerticalVelocity, (int*)&frontLeft.y);
quadBike->RightVerticalVelocity = DoQuadDynamics(floorHeightRight, quadBike->RightVerticalVelocity, (int*)&frontRight.y);
- quadBikeItem->Animation.Velocity.y = DoQuadDynamics(probe.Position.Floor, quadBikeItem->Animation.Velocity.y, (int*)&quadBikeItem->Pose.Position.y);
+ quadBikeItem->Animation.Velocity.y = DoQuadDynamics(probe.GetFloorHeight(), quadBikeItem->Animation.Velocity.y, (int*)&quadBikeItem->Pose.Position.y);
quadBike->Velocity = DoVehicleWaterMovement(quadBikeItem, laraItem, quadBike->Velocity, QBIKE_RADIUS, &quadBike->TurnRate, QBIKE_WAKE_OFFSET);
- probe.Position.Floor = (frontLeft.y + frontRight.y) / 2;
- short xRot = phd_atan(QBIKE_FRONT, quadBikeItem->Pose.Position.y - probe.Position.Floor);
- short zRot = phd_atan(QBIKE_SIDE, probe.Position.Floor - frontLeft.y);
+ int floorHeight = (frontLeft.y + frontRight.y) / 2;
+ short xRot = phd_atan(QBIKE_FRONT, quadBikeItem->Pose.Position.y - floorHeight);
+ short zRot = phd_atan(QBIKE_SIDE, floorHeight - frontLeft.y);
quadBikeItem->Pose.Orientation.x += ((xRot - quadBikeItem->Pose.Orientation.x) / 2);
quadBikeItem->Pose.Orientation.z += ((zRot - quadBikeItem->Pose.Orientation.z) / 2);
if (!(quadBike->Flags & QBIKE_FLAG_DEAD))
{
- if (probe.RoomNumber != quadBikeItem->RoomNumber)
+ if (probe.GetRoomNumber() != quadBikeItem->RoomNumber)
{
- ItemNewRoom(lara->Context.Vehicle, probe.RoomNumber);
- ItemNewRoom(laraItem->Index, probe.RoomNumber);
+ ItemNewRoom(lara->Context.Vehicle, probe.GetRoomNumber());
+ ItemNewRoom(laraItem->Index, probe.GetRoomNumber());
}
laraItem->Pose = quadBikeItem->Pose;
diff --git a/TombEngine/Objects/TR4/Entity/Wraith.cpp b/TombEngine/Objects/TR4/Entity/Wraith.cpp
index ccca9f896..790f0ed8c 100644
--- a/TombEngine/Objects/TR4/Entity/Wraith.cpp
+++ b/TombEngine/Objects/TR4/Entity/Wraith.cpp
@@ -2,6 +2,7 @@
#include "Objects/TR4/Entity/Wraith.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/flipeffect.h"
#include "Game/effects/effects.h"
#include "Game/effects/Electricity.h"
@@ -18,6 +19,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Effects::Items;
using namespace TEN::Effects::Electricity;
using namespace TEN::Effects::Streamer;
@@ -303,11 +305,11 @@ namespace TEN::Entities::TR4
item.Pose.Orientation.x += angleV;
}
- auto pointColl = GetCollision(&item);
+ auto pointColl = GetPointCollision(item);
bool hasHitWall = false;
- if (pointColl.Position.Floor < item.Pose.Position.y ||
- pointColl.Position.Ceiling > item.Pose.Position.y)
+ if (pointColl.GetFloorHeight() < item.Pose.Position.y ||
+ pointColl.GetCeilingHeight() > item.Pose.Position.y)
{
hasHitWall = true;
}
@@ -317,8 +319,8 @@ namespace TEN::Entities::TR4
item.Pose.Position.y += item.Animation.Velocity.z * phd_sin(item.Pose.Orientation.x);
item.Pose.Position.z += item.Animation.Velocity.z * phd_cos(item.Pose.Orientation.y);
- if (pointColl.RoomNumber != item.RoomNumber)
- ItemNewRoom(itemNumber, pointColl.RoomNumber);
+ if (pointColl.GetRoomNumber() != item.RoomNumber)
+ ItemNewRoom(itemNumber, pointColl.GetRoomNumber());
for (int linkItemNumber = g_Level.Rooms[item.RoomNumber].itemNumber; linkItemNumber != NO_ITEM; linkItemNumber = g_Level.Items[linkItemNumber].NextItem)
{
@@ -550,10 +552,10 @@ namespace TEN::Entities::TR4
}
// Check if WRAITH is below floor or above ceiling and spawn wall effect
- pointColl = GetCollision(&item);
+ pointColl = GetPointCollision(item);
- if (pointColl.Position.Floor < item.Pose.Position.y ||
- pointColl.Position.Ceiling > item.Pose.Position.y)
+ if (pointColl.GetFloorHeight() < item.Pose.Position.y ||
+ pointColl.GetCeilingHeight() > item.Pose.Position.y)
{
if (!hasHitWall)
WraithWallEffect(prevPos, item.Pose.Orientation.y - ANGLE(180.0f), item.ObjectNumber);
diff --git a/TombEngine/Objects/TR4/Object/tr4_clockwork_beetle.cpp b/TombEngine/Objects/TR4/Object/tr4_clockwork_beetle.cpp
index 5e141e1a9..b48269f15 100644
--- a/TombEngine/Objects/TR4/Object/tr4_clockwork_beetle.cpp
+++ b/TombEngine/Objects/TR4/Object/tr4_clockwork_beetle.cpp
@@ -6,8 +6,11 @@
#include "Game/animation.h"
#include "Sound/sound.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/effects/debris.h"
+using namespace TEN::Collision::PointCollision;
+
void ClockworkBeetleControl(short itemNumber)
{
auto* beetle = &g_Level.Items[itemNumber];
@@ -323,7 +326,7 @@ void UseClockworkBeetle(short flag)
item->Pose.Orientation.z = 0;
if (Lara.Inventory.BeetleLife)
- item->ItemFlags[0] = GetCollision(item).Block->Flags.MarkBeetle;
+ item->ItemFlags[0] = GetPointCollision(*item).GetSector().Flags.MarkBeetle;
else
item->ItemFlags[0] = 0;
diff --git a/TombEngine/Objects/TR4/Object/tr4_mapper.cpp b/TombEngine/Objects/TR4/Object/tr4_mapper.cpp
index 5238ef5ad..e12847de8 100644
--- a/TombEngine/Objects/TR4/Object/tr4_mapper.cpp
+++ b/TombEngine/Objects/TR4/Object/tr4_mapper.cpp
@@ -2,6 +2,7 @@
#include "Objects/TR4/Object/tr4_mapper.h"
#include "Specific/level.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/control.h"
#include "Sound/sound.h"
#include "Game/animation.h"
@@ -11,6 +12,8 @@
#include "Game/items.h"
#include "Renderer/RendererEnums.h"
+using namespace TEN::Collision::PointCollision;
+
namespace TEN::Entities::TR4
{
void InitializeMapper(short itemNumber)
@@ -35,7 +38,7 @@ namespace TEN::Entities::TR4
byte color = (GetRandomControl() & 0x1F) + 192;
TriggerDynamicLight(pos.x, pos.y, pos.z, (GetRandomControl() & 3) + 16, color, color, 0);
- int height = GetCollision(item).Position.Floor;
+ int height = GetPointCollision(*item).GetFloorHeight();
for (int i = 0; i < 2; i++)
{
diff --git a/TombEngine/Objects/TR4/Trap/SpikyCeiling.cpp b/TombEngine/Objects/TR4/Trap/SpikyCeiling.cpp
index e685b46bb..52bebb8fa 100644
--- a/TombEngine/Objects/TR4/Trap/SpikyCeiling.cpp
+++ b/TombEngine/Objects/TR4/Trap/SpikyCeiling.cpp
@@ -4,6 +4,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/collision/sphere.h"
#include "Game/control/control.h"
#include "Game/effects/effects.h"
@@ -12,6 +13,8 @@
#include "Sound/sound.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
+
namespace TEN::Entities::Traps
{
// NOTES:
@@ -39,9 +42,9 @@ namespace TEN::Entities::Traps
int lowerCeilBound = bounds.Y1;
// Get point collision.
- auto pointColl = GetCollision(&item);
- int relFloorHeight = pointColl.Position.Floor - item.Pose.Position.y;
- int relCeilHeight = pointColl.Position.Ceiling - item.Pose.Position.y;
+ auto pointColl = GetPointCollision(item);
+ int relFloorHeight = pointColl.GetFloorHeight() - item.Pose.Position.y;
+ int relCeilHeight = pointColl.GetCeilingHeight() - item.Pose.Position.y;
int verticalVel = item.ItemFlags[0];
@@ -57,8 +60,8 @@ namespace TEN::Entities::Traps
{
item.Pose.Position.y += verticalVel;
- if (pointColl.RoomNumber != item.RoomNumber)
- ItemNewRoom(itemNumber, pointColl.RoomNumber);
+ if (pointColl.GetRoomNumber() != item.RoomNumber)
+ ItemNewRoom(itemNumber, pointColl.GetRoomNumber());
SoundEffect(SFX_TR4_ROLLING_BALL, &item.Pose);
}
diff --git a/TombEngine/Objects/TR4/Trap/SpikyWall.cpp b/TombEngine/Objects/TR4/Trap/SpikyWall.cpp
index b7d4ba146..5049c604c 100644
--- a/TombEngine/Objects/TR4/Trap/SpikyWall.cpp
+++ b/TombEngine/Objects/TR4/Trap/SpikyWall.cpp
@@ -3,6 +3,7 @@
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/collision/sphere.h"
#include "Game/control/control.h"
#include "Game/effects/debris.h"
@@ -14,6 +15,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Math;
// NOTES:
@@ -47,8 +49,8 @@ namespace TEN::Entities::Traps
int forwardVel = item.ItemFlags[0];
auto bounds = GameBoundingBox(&item);
- auto pointColl0 = GetCollision(&item, item.Pose.Orientation.y, (forwardVel >= 0) ? bounds.Z2 : bounds.Z1, bounds.Y2);
- auto pointColl1 = GetCollision(&item, item.Pose.Orientation.y, (forwardVel >= 0) ? bounds.Z2 : bounds.Z1, bounds.Y2, (bounds.X2 - bounds.X1) / 2);
+ auto pointColl0 = GetPointCollision(item, item.Pose.Orientation.y, (forwardVel >= 0) ? bounds.Z2 : bounds.Z1, bounds.Y2);
+ auto pointColl1 = GetPointCollision(item, item.Pose.Orientation.y, (forwardVel >= 0) ? bounds.Z2 : bounds.Z1, bounds.Y2, (bounds.X2 - bounds.X1) / 2);
if (GetCollidedObjects(&item, CLICK(1), true, CollidedItems, CollidedMeshes, true))
{
@@ -76,18 +78,18 @@ namespace TEN::Entities::Traps
// Stop moving.
if (!item.TriggerFlags ||
- pointColl0.Block->IsWall(item.Pose.Position.x, item.Pose.Position.z) ||
- pointColl0.Block->Stopper ||
- pointColl1.Block->IsWall(item.Pose.Position.x, item.Pose.Position.z) ||
- pointColl1.Block->Stopper)
+ pointColl0.GetSector().IsWall(item.Pose.Position.x, item.Pose.Position.z) ||
+ pointColl0.GetSector().Stopper ||
+ pointColl1.GetSector().IsWall(item.Pose.Position.x, item.Pose.Position.z) ||
+ pointColl1.GetSector().Stopper)
{
auto& room = g_Level.Rooms[item.RoomNumber];
for (auto& mesh : room.mesh)
{
- if ((abs(pointColl0.Coordinates.x - mesh.pos.Position.x) < BLOCK(1) &&
- abs(pointColl0.Coordinates.z - mesh.pos.Position.z) < BLOCK(1)) ||
- abs(pointColl1.Coordinates.x - mesh.pos.Position.x) < BLOCK(1) &&
- abs(pointColl1.Coordinates.z - mesh.pos.Position.z) < BLOCK(1) &&
+ if ((abs(pointColl0.GetPosition().x - mesh.pos.Position.x) < BLOCK(1) &&
+ abs(pointColl0.GetPosition().z - mesh.pos.Position.z) < BLOCK(1)) ||
+ abs(pointColl1.GetPosition().x - mesh.pos.Position.x) < BLOCK(1) &&
+ abs(pointColl1.GetPosition().z - mesh.pos.Position.z) < BLOCK(1) &&
StaticObjects[mesh.staticNumber].shatterType != ShatterType::None)
{
if (mesh.HitPoints != 0)
@@ -109,8 +111,8 @@ namespace TEN::Entities::Traps
item.Pose.Position = Geometry::TranslatePoint(item.Pose.Position, item.Pose.Orientation.y, forwardVel);
item.Status = ITEM_ACTIVE;
- if (pointColl0.RoomNumber != item.RoomNumber)
- ItemNewRoom(itemNumber, pointColl0.RoomNumber);
+ if (pointColl0.GetRoomNumber() != item.RoomNumber)
+ ItemNewRoom(itemNumber, pointColl0.GetRoomNumber());
SoundEffect(SFX_TR4_ROLLING_BALL, &item.Pose);
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_joby_spikes.cpp b/TombEngine/Objects/TR4/Trap/tr4_joby_spikes.cpp
index 9512dc756..27a6b96e5 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_joby_spikes.cpp
+++ b/TombEngine/Objects/TR4/Trap/tr4_joby_spikes.cpp
@@ -2,6 +2,7 @@
#include "tr4_joby_spikes.h"
#include "Specific/level.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/control.h"
#include "Game/animation.h"
#include "Sound/sound.h"
@@ -9,6 +10,8 @@
#include "Game/effects/effects.h"
#include "Game/items.h"
+using namespace TEN::Collision::PointCollision;
+
namespace TEN::Entities::TR4
{
void InitializeJobySpikes(short itemNumber)
@@ -22,13 +25,13 @@ namespace TEN::Entities::TR4
item->Pose.Orientation.y = GetRandomControl() * 1024;
item->ItemFlags[2] = GetRandomControl() & 1;
- auto probe = GetCollision(item);
+ auto probe = GetPointCollision(*item);
// TODO: Check this optimized division.
- //v6 = 1321528399i64 * ((probe.Position.Floor - probe.Position.Ceiling) << 12);
+ //v6 = 1321528399i64 * ((probe.GetFloorHeight() - probe.GetCeilingHeight()) << 12);
//item->itemFlags[3] = (HIDWORD(v6) >> 31) + (SHIDWORD(v6) >> 10);
- item->ItemFlags[3] = (short)((probe.Position.Floor - probe.Position.Ceiling) * 1024 * 12 / 13);
+ item->ItemFlags[3] = (short)((probe.GetFloorHeight() - probe.GetCeilingHeight()) * 1024 * 12 / 13);
}
void JobySpikesControl(short itemNumber)
diff --git a/TombEngine/Objects/TR4/Trap/tr4_slicerdicer.cpp b/TombEngine/Objects/TR4/Trap/tr4_slicerdicer.cpp
index 34d56af4d..74fc1e265 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_slicerdicer.cpp
+++ b/TombEngine/Objects/TR4/Trap/tr4_slicerdicer.cpp
@@ -3,10 +3,13 @@
#include "Specific/level.h"
#include "Sound/sound.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/items.h"
#include "Game/animation.h"
#include "Math/Math.h"
+using namespace TEN::Collision::PointCollision;
+
namespace TEN::Entities::TR4
{
void InitializeSlicerDicer(short itemNumber)
@@ -38,7 +41,7 @@ namespace TEN::Entities::TR4
item->TriggerFlags += 170;
- auto probedRoomNumber = GetCollision(item).RoomNumber;
+ auto probedRoomNumber = GetPointCollision(*item).GetRoomNumber();
if (item->RoomNumber != probedRoomNumber)
ItemNewRoom(itemNumber, probedRoomNumber);
diff --git a/TombEngine/Objects/TR4/Trap/tr4_teethspike.cpp b/TombEngine/Objects/TR4/Trap/tr4_teethspike.cpp
index 463ef1ef8..87dcbb8eb 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_teethspike.cpp
+++ b/TombEngine/Objects/TR4/Trap/tr4_teethspike.cpp
@@ -3,6 +3,7 @@
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/effects/tomb4fx.h"
#include "Game/items.h"
#include "Game/Lara/lara.h"
@@ -11,6 +12,8 @@
#include "Specific/level.h"
#include "Math/Math.h"
+using namespace TEN::Collision::PointCollision;
+
namespace TEN::Entities::TR4
{
constexpr auto TEETH_SPIKE_HARM_DAMAGE_CONSTANT = 8;
@@ -150,7 +153,7 @@ namespace TEN::Entities::TR4
if (LaraItem->HitPoints <= 0 && Lara.Context.Vehicle == NO_ITEM)
{
- int heightFromFloor = GetCollision(LaraItem).Position.Floor - LaraItem->Pose.Position.y;
+ int heightFromFloor = GetPointCollision(*LaraItem).GetFloorHeight() - LaraItem->Pose.Position.y;
if (item->Pose.Position.y >= LaraItem->Pose.Position.y && heightFromFloor < CLICK(1) &&
intersection == ContainmentType::CONTAINS)
diff --git a/TombEngine/Objects/TR4/Vehicles/motorbike.cpp b/TombEngine/Objects/TR4/Vehicles/motorbike.cpp
index 25012ecac..d364c8368 100644
--- a/TombEngine/Objects/TR4/Vehicles/motorbike.cpp
+++ b/TombEngine/Objects/TR4/Vehicles/motorbike.cpp
@@ -608,7 +608,7 @@ namespace TEN::Entities::Vehicles
motorbike->MomentumAngle = motorbikeItem->Pose.Orientation.y;
}
- floorHeight = GetCollision(motorbikeItem).Position.Floor;
+ floorHeight = GetPointCollision(*motorbikeItem).GetFloorHeight();
if (motorbikeItem->Pose.Position.y >= floorHeight)
speed = motorbikeItem->Animation.Velocity.z * phd_cos(motorbikeItem->Pose.Orientation.x);
else
@@ -704,7 +704,7 @@ namespace TEN::Entities::Vehicles
if (rot1)
rot2 = rot1;
- floorHeight = GetCollision(motorbikeItem).Position.Floor;
+ floorHeight = GetPointCollision(*motorbikeItem).GetFloorHeight();
if (floorHeight < (motorbikeItem->Pose.Position.y - CLICK(1)))
DoMotorbikeShift(motorbikeItem, (Vector3i*)&motorbikeItem->Pose, &oldPos);
@@ -747,18 +747,18 @@ namespace TEN::Entities::Vehicles
auto* lara = GetLaraInfo(laraItem);
short angle = motorbikeItem->Pose.Orientation.y + ANGLE(90.0f);
- auto collResult = GetCollision(motorbikeItem, angle, MOTORBIKE_RADIUS);
+ auto collResult = GetPointCollision(*motorbikeItem, angle, MOTORBIKE_RADIUS);
- if (collResult.Position.FloorSlope || collResult.Position.Floor == NO_HEIGHT) // Was previously set to -NO_HEIGHT by TokyoSU -- Lwmte 23.08.21
+ if (collResult.IsIllegalFloor() || collResult.GetFloorHeight() == NO_HEIGHT) // Was previously set to -NO_HEIGHT by TokyoSU -- Lwmte 23.08.21
return false;
- if (abs(collResult.Position.Floor - motorbikeItem->Pose.Position.y) > CLICK(1))
+ if (abs(collResult.GetFloorHeight() - motorbikeItem->Pose.Position.y) > CLICK(1))
return false;
- if ((collResult.Position.Ceiling - motorbikeItem->Pose.Position.y) > -LARA_HEIGHT)
+ if ((collResult.GetCeilingHeight() - motorbikeItem->Pose.Position.y) > -LARA_HEIGHT)
return false;
- if ((collResult.Position.Floor - collResult.Position.Ceiling) < LARA_HEIGHT)
+ if ((collResult.GetFloorHeight() - collResult.GetCeilingHeight()) < LARA_HEIGHT)
return false;
return true;
@@ -1164,7 +1164,7 @@ namespace TEN::Entities::Vehicles
int heightFrontRight = GetVehicleHeight(motorbikeItem, MOTORBIKE_FRONT, CLICK(0.5f), true, &frontRight);
int heightFrontMiddle = GetVehicleHeight(motorbikeItem, -MOTORBIKE_FRONT, 0, true, &frontMiddle);
- auto probe = GetCollision(motorbikeItem);
+ auto probe = GetPointCollision(*motorbikeItem);
TestTriggers(motorbikeItem, true);
TestTriggers(motorbikeItem, false);
@@ -1189,7 +1189,7 @@ namespace TEN::Entities::Vehicles
DrawMotorbikeLight(motorbikeItem);
motorbikeItem->MeshBits.Set(MotorbikeHeadLightJoints);
- drive = MotorbikeUserControl(motorbikeItem, laraItem, probe.Position.Floor, &pitch);
+ drive = MotorbikeUserControl(motorbikeItem, laraItem, probe.GetFloorHeight(), &pitch);
HandleVehicleSpeedometer(motorbikeItem->Animation.Velocity.z, MOTORBIKE_ACCEL_MAX / (float)VEHICLE_VELOCITY_SCALE);
}
else
@@ -1226,14 +1226,14 @@ namespace TEN::Entities::Vehicles
if (motorbike->Velocity < MOTORBIKE_ACCEL_1)
DrawMotorBikeSmoke(motorbikeItem, laraItem);
- motorbikeItem->Floor = probe.Position.Floor;
+ motorbikeItem->Floor = probe.GetFloorHeight();
int rotation = motorbike->Velocity / 4;
motorbike->LeftWheelRotation -= rotation;
motorbike->RightWheelsRotation -= rotation;
int newY = motorbikeItem->Pose.Position.y;
- motorbikeItem->Animation.Velocity.y = DoMotorBikeDynamics(probe.Position.Floor, motorbikeItem->Animation.Velocity.y, &motorbikeItem->Pose.Position.y, 0);
+ motorbikeItem->Animation.Velocity.y = DoMotorBikeDynamics(probe.GetFloorHeight(), motorbikeItem->Animation.Velocity.y, &motorbikeItem->Pose.Position.y, 0);
motorbike->Velocity = DoVehicleWaterMovement(motorbikeItem, laraItem, motorbike->Velocity, MOTORBIKE_RADIUS, &motorbike->TurnRate, MOTORBIKE_WAKE_OFFSET);
int r1 = (frontRight.y + frontLeft.y) / 2;
@@ -1267,10 +1267,10 @@ namespace TEN::Entities::Vehicles
motorbikeItem->Pose.Orientation.x += (xRot - motorbikeItem->Pose.Orientation.x) / 4;
motorbikeItem->Pose.Orientation.z += (zRot - motorbikeItem->Pose.Orientation.z) / 4;
- if (probe.RoomNumber != motorbikeItem->RoomNumber)
+ if (probe.GetRoomNumber() != motorbikeItem->RoomNumber)
{
- ItemNewRoom(lara->Context.Vehicle, probe.RoomNumber);
- ItemNewRoom(laraItem->Index, probe.RoomNumber);
+ ItemNewRoom(lara->Context.Vehicle, probe.GetRoomNumber());
+ ItemNewRoom(laraItem->Index, probe.GetRoomNumber());
}
laraItem->Pose = motorbikeItem->Pose;
diff --git a/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp b/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp
index f617f9c76..3739b4108 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp
@@ -4,6 +4,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/box.h"
#include "Game/control/los.h"
#include "Game/effects/effects.h"
@@ -19,6 +20,8 @@
#include "Sound/sound.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
+
using namespace TEN::Math;
namespace TEN::Entities::Creatures::TR5
@@ -486,11 +489,11 @@ namespace TEN::Entities::Creatures::TR5
TranslateItem(item, item->Pose.Orientation, item->Animation.Velocity.z);
- auto probe = GetCollision(item);
+ auto probe = GetPointCollision(*item);
- if (item->Pose.Position.y < probe.Position.Floor &&
- item->Pose.Position.y > probe.Position.Ceiling &&
- TestEnvironment(ENV_FLAG_WATER, probe.RoomNumber))
+ if (item->Pose.Position.y < probe.GetFloorHeight() &&
+ item->Pose.Position.y > probe.GetCeilingHeight() &&
+ TestEnvironment(ENV_FLAG_WATER, probe.GetRoomNumber()))
{
if (ItemNearLara(item->Pose.Position, 200))
{
@@ -506,8 +509,8 @@ namespace TEN::Entities::Creatures::TR5
// if (ItemNearLara(&item->pos, 400) && Lara.anxiety < 0xE0)
// Lara.anxiety += 32;
- if (probe.RoomNumber != item->RoomNumber)
- ItemNewRoom(itemNumber, probe.RoomNumber);
+ if (probe.GetRoomNumber() != item->RoomNumber)
+ ItemNewRoom(itemNumber, probe.GetRoomNumber());
auto pos1 = GetJointPosition(item, 0, Vector3i(0, 0, -64));
auto pos2 = GetJointPosition(item, 0, Vector3i(0, 0, -64 << ((GlobalCounter & 1) + 2)));
diff --git a/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp b/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp
index 67c9b2bbd..da785bfd8 100644
--- a/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp
+++ b/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp
@@ -259,7 +259,7 @@ void RollingBallControl(short itemNumber)
}
}
- auto roomNumber = GetCollision(item).RoomNumber;
+ auto roomNumber = GetPointCollision(*item).GetRoomNumber();
if (item->RoomNumber != roomNumber)
{
diff --git a/TombEngine/Objects/TR5/Object/tr5_twoblockplatform.cpp b/TombEngine/Objects/TR5/Object/tr5_twoblockplatform.cpp
index 5fa94b726..220ac21c6 100644
--- a/TombEngine/Objects/TR5/Object/tr5_twoblockplatform.cpp
+++ b/TombEngine/Objects/TR5/Object/tr5_twoblockplatform.cpp
@@ -3,6 +3,7 @@
#include "Game/collision/collide_room.h"
#include "Game/collision/floordata.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/control.h"
#include "Game/items.h"
#include "Game/Lara/lara.h"
@@ -11,8 +12,8 @@
#include "Renderer/Renderer.h"
#include "Sound/sound.h"
-using namespace TEN::Renderer;
using namespace TEN::Collision::Floordata;
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Math;
using namespace TEN::Renderer;
@@ -85,14 +86,14 @@ namespace TEN::Entities::Generic
if (distToPortal <= speed)
UpdateBridgeItem(*item);
- auto probe = GetCollision(item);
+ auto probe = GetPointCollision(*item);
- item->Floor = probe.Position.Floor;
+ item->Floor = probe.GetFloorHeight();
- if (probe.RoomNumber != item->RoomNumber)
+ if (probe.GetRoomNumber() != item->RoomNumber)
{
UpdateBridgeItem(*item, true);
- ItemNewRoom(itemNumber, probe.RoomNumber);
+ ItemNewRoom(itemNumber, probe.GetRoomNumber());
UpdateBridgeItem(*item);
}
}
diff --git a/TombEngine/Objects/TR5/Trap/LaserBarrier.cpp b/TombEngine/Objects/TR5/Trap/LaserBarrier.cpp
index ad6020acf..bb716d60d 100644
--- a/TombEngine/Objects/TR5/Trap/LaserBarrier.cpp
+++ b/TombEngine/Objects/TR5/Trap/LaserBarrier.cpp
@@ -3,12 +3,14 @@
#include "Game/collision/collide_room.h"
#include "Game/collision/floordata.h"
+#include "Game/collision/PointCollision.h"
#include "Game/effects/effects.h"
#include "Game/effects/item_fx.h"
#include "Game/items.h"
#include "Game/Lara/lara.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Effects::Items;
namespace TEN::Traps::TR5
@@ -85,8 +87,8 @@ namespace TEN::Traps::TR5
auto& item = g_Level.Items[itemNumber];
// Initialize barrier height.
- auto pointColl = GetCollision(&item);
- float barrierHeight = item.Pose.Position.y - pointColl.Position.Ceiling;
+ auto pointColl = GetPointCollision(item);
+ float barrierHeight = item.Pose.Position.y - pointColl.GetCeilingHeight();
item.ItemFlags[0] = barrierHeight;
// Initialize barrier effect.
diff --git a/TombEngine/Objects/TR5/Trap/ZipLine.cpp b/TombEngine/Objects/TR5/Trap/ZipLine.cpp
index 252103105..d18a4dcd4 100644
--- a/TombEngine/Objects/TR5/Trap/ZipLine.cpp
+++ b/TombEngine/Objects/TR5/Trap/ZipLine.cpp
@@ -3,6 +3,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_item.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/box.h"
#include "Game/items.h"
#include "Game/Lara/lara.h"
@@ -12,6 +13,7 @@
#include "Sound/sound.h"
#include "Specific/Input/Input.h"
+using namespace TEN::Collision::PointCollision;
using namespace TEN::Input;
using namespace TEN::Math;
@@ -129,13 +131,13 @@ namespace TEN::Traps::TR5
zipLineItem.Pose.Position.y += ((int)zipLineItem.Animation.Velocity.y >> 2);
int vPos = zipLineItem.Pose.Position.y + CLICK(0.25f);
- auto pointColl = GetCollision(&zipLineItem, zipLineItem.Pose.Orientation.y, zipLineItem.Animation.Velocity.y);
+ auto pointColl = GetPointCollision(zipLineItem, zipLineItem.Pose.Orientation.y, zipLineItem.Animation.Velocity.y);
// Update zip line room number.
- if (pointColl.RoomNumber != zipLineItem.RoomNumber)
- ItemNewRoom(itemNumber, pointColl.RoomNumber);
+ if (pointColl.GetRoomNumber() != zipLineItem.RoomNumber)
+ ItemNewRoom(itemNumber, pointColl.GetRoomNumber());
- if (pointColl.Position.Floor <= (vPos + CLICK(1)) || pointColl.Position.Ceiling >= (vPos - CLICK(1)))
+ if (pointColl.GetFloorHeight() <= (vPos + CLICK(1)) || pointColl.GetCeilingHeight() >= (vPos - CLICK(1)))
{
// Dismount.
if (laraItem.Animation.ActiveState == LS_ZIP_LINE)
diff --git a/TombEngine/Objects/TR5/Trap/tr5_fallingceiling.cpp b/TombEngine/Objects/TR5/Trap/tr5_fallingceiling.cpp
index 7d722d741..ddb99803a 100644
--- a/TombEngine/Objects/TR5/Trap/tr5_fallingceiling.cpp
+++ b/TombEngine/Objects/TR5/Trap/tr5_fallingceiling.cpp
@@ -3,11 +3,14 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/PointCollision.h"
#include "Game/control/control.h"
#include "Game/items.h"
#include "Game/Lara/lara.h"
#include "Specific/level.h"
+using namespace TEN::Collision::PointCollision;
+
void FallingCeilingControl(short itemNumber)
{
auto* item = &g_Level.Items[itemNumber];
@@ -29,12 +32,12 @@ void FallingCeilingControl(short itemNumber)
RemoveActiveItem(itemNumber);
else
{
- auto probe = GetCollision(item);
+ auto probe = GetPointCollision(*item);
- item->Floor = probe.Position.Floor;
+ item->Floor = probe.GetFloorHeight();
- if (probe.RoomNumber != item->RoomNumber)
- ItemNewRoom(itemNumber, probe.RoomNumber);
+ if (probe.GetRoomNumber() != item->RoomNumber)
+ ItemNewRoom(itemNumber, probe.GetRoomNumber());
if (item->Animation.ActiveState == 1)
{
From 389ba72c44b83d9e365c48f5e5dda3656f877bfd Mon Sep 17 00:00:00 2001
From: Sezz
Date: Fri, 23 Feb 2024 21:56:33 +1100
Subject: [PATCH 059/410] Remove debug code
---
TombEngine/Game/Lara/lara.cpp | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/TombEngine/Game/Lara/lara.cpp b/TombEngine/Game/Lara/lara.cpp
index 9268b5f46..c8715618a 100644
--- a/TombEngine/Game/Lara/lara.cpp
+++ b/TombEngine/Game/Lara/lara.cpp
@@ -125,15 +125,6 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
}
}
- auto pointColl = GetPointCollision(*item, -Vector3::UnitY, coll->Setup.Height / 2);
-
- auto origin = item->Pose.Position + Vector3i(0, -BLOCK(1), 0);
- g_Renderer.AddDebugLine(origin.ToVector3(), Geometry::TranslatePoint(origin, pointColl.GetFloorNormal(), BLOCK(0.5f)).ToVector3(), Vector4(0, 1, 0, 1));
- g_Renderer.AddDebugLine(origin.ToVector3(), Geometry::TranslatePoint(origin, pointColl.GetCeilingNormal(), BLOCK(0.5f)).ToVector3(), Vector4(1, 0, 0, 1));
-
- g_Renderer.PrintDebugMessage("Floor bridge: %d", pointColl.GetFloorBridgeItemNumber());
- g_Renderer.PrintDebugMessage("Ceiling bridge: %d", pointColl.GetCeilingBridgeItemNumber());
-
//----------
// Alert nearby creatures.
From e84ddfa36dd8cd5acfa753346ea4164962015c60 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Tue, 5 Mar 2024 09:25:26 +0100
Subject: [PATCH 060/410] First experiment with 60 fps
---
Documentation/output.xml | 10806 ++++++++--------
TombEngine/Game/Lara/lara.cpp | 8 +
TombEngine/Game/Lara/lara.h | 1 +
TombEngine/Game/camera.cpp | 1 +
TombEngine/Game/camera.h | 1 +
TombEngine/Game/control/control.cpp | 64 +-
TombEngine/Game/control/control.h | 2 +-
TombEngine/Renderer/Renderer.cpp | 5 +-
TombEngine/Renderer/Renderer.h | 8 +-
TombEngine/Renderer/RendererDraw.cpp | 42 +-
TombEngine/Renderer/RendererFrame.cpp | 24 +-
TombEngine/Renderer/RendererHelper.cpp | 5 +-
TombEngine/Renderer/RendererLara.cpp | 4 +-
TombEngine/Renderer/Structures/RendererItem.h | 14 +
TombEngine/Specific/clock.cpp | 107 +-
TombEngine/Specific/clock.h | 50 +-
16 files changed, 5647 insertions(+), 5495 deletions(-)
diff --git a/Documentation/output.xml b/Documentation/output.xml
index 70dc8a903..2e3a40b3c 100644
--- a/Documentation/output.xml
+++ b/Documentation/output.xml
@@ -1,5403 +1,5403 @@
-
-
- Color
- Color
-
-
- R
- int
- red component
-
-
- G
- int
- green component
-
-
- B
- int
- blue component
-
-
-
-
- Color
- A new Color object.
-
-
-
-
-
- Color
- Color
-
-
- R
- int
- red component
-
-
- G
- int
- green component
-
-
- B
- int
- blue component
-
-
- A
- int
- alpha component (255 is opaque, 0 is invisible)
-
-
-
-
- Color
- A new Color object.
-
-
-
-
-
- Color
- tostring
-
-
- color
- Color
- this color
-
-
-
-
- string
- A string showing the r, g, b, and a values of the color
-
-
-
-
-
- View.DisplaySprite
- DisplaySprite
- Create a DisplaySprite object.
-
-
- ID
- Objects.ObjID
- of the sprite sequence object.
-
-
- int
- int
- spriteID ID of the sprite in the sequence.
-
-
- pos
- Vec2
- Display position in percent.
-
-
- rot
- float
- Rotation in degrees.
-
-
- scale
- Vec2
- Horizontal and vertical scale in percent. Scaling is interpreted by the DisplaySpriteEnum.ScaleMode passed to the Draw() function call.
-
-
- color
- Color
- Color. __Default: Color(255, 255, 255, 255)__
-
-
-
-
- DisplaySprite
- A new DisplaySprite object.
-
-
-
-
-
- View.DisplaySprite
- DisplaySprite
- GetObjectID
- Get the object ID of the sprite sequence object used by the display sprite.
- ()
-
-
- Objects.ObjID
- Sprite sequence object ID.
-
-
-
-
-
- View.DisplaySprite
- DisplaySprite
- GetSpriteID
- Get the sprite ID in the sprite sequence object used by the display sprite.
- ()
-
-
- int
- Sprite ID in the sprite sequence object.
-
-
-
-
-
- View.DisplaySprite
- DisplaySprite
- GetPosition
- Get the display position of the display sprite in percent.
- ()
-
-
- Vec2
- Display position in percent.
-
-
-
-
-
- View.DisplaySprite
- DisplaySprite
- GetRotation
- Get the rotation of the display sprite in degrees.
- ()
-
-
- float
- Rotation in degrees.
-
-
-
-
-
- View.DisplaySprite
- DisplaySprite
- GetScale
- Get the horizontal and vertical scale of the display sprite in percent.
- ()
-
-
- Vec2
- Horizontal and vertical scale in percent.
-
-
-
-
-
- View.DisplaySprite
- DisplaySprite
- GetColor
- Get the color of the display sprite.
- ()
-
-
- Color
- Color.
-
-
-
-
-
- View.DisplaySprite
- DisplaySprite
- SetObjectID
- Set the sprite sequence object ID used by the display sprite.
- (Objects.ObjID)
-
-
- New
- Objects.ObjID
- sprite sequence object ID.
-
-
-
-
-
- View.DisplaySprite
- DisplaySprite
- SetSpriteID
- Set the sprite ID in the sprite sequence object used by the display sprite.
- (int)
-
-
- New
- int
- sprite ID in the sprite sequence object.
-
-
-
-
-
- View.DisplaySprite
- DisplaySprite
- SetPosition
- Set the display position of the display sprite in percent.
- (Vec2)
-
-
- New
- Vec2
- display position in percent.
-
-
-
-
-
- View.DisplaySprite
- DisplaySprite
- SetRotation
- Set the rotation of the display sprite in degrees.
- (float)
-
-
- New
- float
- rotation in degrees.
-
-
-
-
-
- View.DisplaySprite
- DisplaySprite
- SetScale
- Set the horizontal and vertical scale of the display sprite in percent.
- (Vec2)
-
-
- New
- float
- horizontal and vertical scale in percent.
-
-
-
-
-
- View.DisplaySprite
- DisplaySprite
- SetColor
- Set the color of the display sprite.
- (Color)
-
-
- New
- float
- color.
-
-
-
-
-
- View.DisplaySprite
- DisplaySprite
- Draw
- Draw the display sprite in display space for the current frame.
-
-
- priority
- int
- Draw priority. Can be thought of as a layer, with higher values having precedence. __Default: 0__
-
-
- alignMode
- View.AlignMode
- Align mode interpreting an offset from the sprite's position. __Default: View.AlignMode.CENTER__
-
-
- scaleMode
- View.ScaleMode
- Scale mode interpreting the display sprite's horizontal and vertical scale. __Default: View.ScaleMode.FIT__
-
-
- blendMode
- Effects.BlendID
- Blend mode. __Default: Effects.BlendID.ALPHABLEND__
-
-
-
-
-
- Effects
- EmitLightningArc
- Emit a lightning arc.
-
-
- src
- Vec3
-
-
- dest
- Vec3
-
-
- color
- Color
- (default Color(255, 255, 255))
-
-
- lifetime
- float
- Lifetime in seconds. Clamped to [0, 4.233] for now because of strange internal maths. (default 1.0)
-
-
- amplitude
- int
- "strength" of the lightning - the higher the value, the "taller" the arcs. Clamped to [1, 255]. (default 20)
-
-
- beamWidth
- int
- Clamped to [1, 127]. (default 2)
-
-
- detail
- int
- Higher numbers equal more segments, but it's not a 1:1 correlation. Clamped to [1, 127]. (default 10)
-
-
- smooth
- bool
- If true, the arc will have large, smooth curves; if false, it will have small, jagged spikes. (default false)
-
-
- endDrift
- bool
- If true, the end of the arc will be able to gradually drift away from its destination in a random direction (default false)
-
-
-
-
-
- Effects
- EmitParticle
- Emit a particle.
- See the sprite editor in WadTool for DEFAULT_SPRITES to see a list of sprite indices.
-
-
- pos
- Vec3
-
-
- velocity
- Vec3
-
-
- spriteIndex
- int
- an index of a sprite in DEFAULT_SPRITES object.
-
-
- gravity
- int
- (default 0) Specifies whether particle will fall (positive values) or ascend (negative values) over time. Clamped to [-32768, 32767], but values between -1000 and 1000 are recommended; values too high or too low (e.g. under -2000 or above 2000) will cause the velocity of the particle to "wrap around" and switch directions.
-
-
- rot
- float
- (default 0) specifies a speed with which it will rotate (0 = no rotation, negative = anticlockwise rotation, positive = clockwise rotation).
-
-
- startColor
- Color
- (default Color(255, 255, 255)) color at start of life
-
-
- endColor
- Color
- (default Color(255, 255, 255)) color to fade to - at the time of writing this fade will finish long before the end of the particle's life due to internal maths
-
-
- blendMode
- Effects.BlendID
- (default TEN.Effects.BlendID.ALPHABLEND) How will we blend this with its surroundings?
-
-
- startSize
- int
- (default 10) Size on spawn. A value of 15 is approximately the size of Lara's head.
-
-
- endSize
- int
- (default 0) Size on death - the particle will linearly shrink or grow to this size during its lifespan
-
-
- lifetime
- float
- (default 2) Lifespan in seconds
-
-
- damage
- bool
- (default false) specifies whether particle can damage Lara (does a very small amount of damage, like the small lava emitters in TR1)
-
-
- poison
- bool
- (default false) specifies whether particle can poison Lara
-
-
-
-
-
- Effects
- EmitShockwave
- Emit a shockwave, similar to that seen when a harpy projectile hits something.
-
-
- pos
- Vec3
- Origin position
-
-
- innerRadius
- int
- (default 0) Initial inner radius of the shockwave circle - 128 will be approx a click, 512 approx a block
-
-
- outerRadius
- int
- (default 128) Initial outer radius of the shockwave circle
-
-
- color
- Color
- (default Color(255, 255, 255))
-
-
- lifetime
- float
- (default 1.0) Lifetime in seconds (max 8.5 because of inner maths weirdness)
-
-
- speed
- int
- (default 50) Initial speed of the shockwave's expansion (the shockwave will always slow as it goes)
-
-
- angle
- int
- (default 0) Angle about the X axis - a value of 90 will cause the shockwave to be entirely vertical
-
-
- hurtsLara
- bool
- (default false) If true, the shockwave will hurt Lara, with the damage being relative to the shockwave's current speed
-
-
-
-
-
- Effects
- EmitLight
- Emit dynamic light that lasts for a single frame.
- If you want a light that sticks around, you must call this each frame.
-
-
- pos
- Vec3
-
-
- color
- Color
- (default Color(255, 255, 255))
-
-
- radius
- int
- (default 20) corresponds loosely to both intensity and range
-
-
-
-
-
- Effects
- EmitBlood
- Emit blood.
-
-
- pos
- Vec3
-
-
- count
- int
- (default 1) "amount" of blood. Higher numbers won't add more blood but will make it more "flickery", with higher numbers turning it into a kind of red orb.
-
-
-
-
-
- Effects
- EmitFire
- Emit fire for one frame.
- Will not hurt Lara. Call this each frame if you want a continuous fire.
-
-
- pos
- Vec3
-
-
- size
- float
- (default 1.0)
-
-
-
-
-
- Effects
- MakeExplosion
- Make an explosion.
- Does not hurt Lara
-
-
- pos
- Vec3
-
-
- size
- float
- (default 512.0) this will not be the size of the sprites, but rather the distance between the origin and any additional sprites
-
-
- shockwave
- bool
- (default false) if true, create a very faint white shockwave which will not hurt Lara
-
-
-
-
-
- Effects
- MakeEarthquake
- Make an earthquake
-
-
- strength
- int
- (default 100) How strong should the earthquake be? Increasing this value also increases the lifespan of the earthquake.
-
-
-
-
-
- Flow
- AddLevel
- Add a level to the Flow.
-
-
- level
- Flow.Level
- a level object
-
-
-
-
-
- Flow
- SetIntroImagePath
- Image to show when loading the game.
- Must be a .jpg or .png image.
-
-
- path
- string
- the path to the image, relative to the TombEngine exe
-
-
-
-
-
- Flow
- SetTitleScreenImagePath
- Image to show in the background of the title screen.
- Must be a .jpg or .png image.
-__(not yet implemented)__
-
-
- path
- string
- the path to the image, relative to the TombEngine exe
-
-
-
-
-
- Flow
- EnableLaraInTitle
- Enable or disable Lara drawing in title flyby.
- Must be true or false
-
-
- enabled
- bool
- true or false
-
-
-
-
-
- Flow
- EnableLevelSelect
- Enable or disable level selection in title flyby.
- Must be true or false
-
-
- enabled
- bool
- true or false
-
-
-
-
-
- Flow
- EnableLoadSave
- Enable or disable saving and loading of savegames.
-
-
- enabled
- bool
- true or false.
-
-
-
-
-
- Flow
- EnableFlyCheat
- Enable or disable DOZY mode (fly cheat).
- Must be true or false
-
-
- enabled
- bool
- true or false
-
-
-
-
-
- Flow
- EnablePointFilter
- Enable or disable point texture filter.
- Must be true or false
-
-
- enabled
- bool
- true or false
-
-
-
-
-
- Flow
- EnableMassPickup
- Enable or disable mass pickup.
- Must be true or false
-
-
- enabled
- bool
- true or false
-
-
-
-
-
- Flow
- GetLevel
- Returns the level by index.
- Indices depend on the order in which AddLevel was called; the first added will
-have an ID of 0, the second an ID of 1, and so on.
-
-
- index
- int
- of the level
-
-
-
-
- Flow.Level
- the level indicated by the id
-
-
-
-
-
- Flow
- GetCurrentLevel
- Returns the level that the game control is running in that moment.
-
-
- Flow.Level
- the current level
-
-
-
-
-
- Flow
- EndLevel
- Finishes the current level, with optional level index and start position index provided.
- If level index is not provided or is zero, jumps to next level. If level index is more than
-level count, jumps to title. If LARA\_START\_POS objects are present in level, player will be
-teleported to such object with OCB similar to provided second argument.
-
-
- index
- int
- level index (default 0)
-
-
- startPos
- int
- player start position (default 0)
-
-
-
-
-
- Flow
- GetGameStatus
- Get current game status, such as normal game loop, exiting to title, etc.
-
-
- Flow.GameStatus
- the current game status
-
-
-
-
-
- Flow
- SaveGame
- Save the game to a savegame slot.
-
-
- slotID
- int
- ID of the savegame slot to save to.
-
-
-
-
-
- Flow
- LoadGame
- Load the game from a savegame slot.
-
-
- slotID
- int
- ID of the savegame slot to load from.
-
-
-
-
-
- Flow
- DeleteSaveGame
- Delete a savegame.
-
-
- slotID
- int
- ID of the savegame slot to clear.
-
-
-
-
-
- Flow
- DoesSaveGameExist
- Check if a savegame exists.
-
-
- slotID
- int
- ID of the savegame slot to check.
-
-
-
-
- bool
- true if the savegame exists, false if not.
-
-
-
-
-
- Flow
- GetSecretCount
- Returns the player's current per-game secret count.
-
-
- int
- Current game secret count.
-
-
-
-
-
- Flow
- SetSecretCount
- Sets the player's current per-game secret count.
-
-
- count
- int
- new secret count.
-
-
-
-
-
- Flow
- AddSecret
- Adds one secret to current level secret count and also plays secret music track.
- The index argument corresponds to the secret's unique ID, the same that would go in a secret trigger's Param.
-
-
- index
- int
- an index of current level's secret (must be from 0 to 31).
-
-
-
-
-
- Flow
- SetTotalSecretCount
- Total number of secrets in game.
- Must be an integer value (0 means no secrets).
-
-
- total
- int
- number of secrets
-
-
-
-
-
- Flow
- SetSettings
-
-
- settings
- Flow.Settings
- a settings object
-
-
-
-
-
- Flow
- SetAnimations
-
-
- animations
- Flow.Animations
- an animations object
-
-
-
-
-
- Flow
- SetStrings
- Set string variable keys and their translations.
-
-
- table
- tab
- array-style table with strings
-
-
-
-
-
- Flow
- GetString
- Get translated string.
-
-
- string
- key
- key for translated string
-
-
-
-
-
- Flow
- SetLanguageNames
- Set language names for translations.
- Specify which translations in the strings table correspond to which languages.
-
-
- table
- tab
- array-style table with language names
-
-
-
-
-
- Flow.Fog
- Fog
-
-
- color
- Color
- RGB color
-
-
- Min
- int
- Distance fog starts (in Sectors)
-
-
- Max
- int
- Distance fog ends (in Sectors)
-
-
-
-
- Fog
- A fog object.
-
-
-
-
-
- Flow.InventoryItem
- InventoryItem
- Create an InventoryItem.
-
-
- nameKey
- string
- key for the item's (localised) name.
-Corresponds to an entry in strings.lua.
-
-
- objectID
- Objects.ObjID
- object ID of the inventory object to change
-
-
- yOffset
- float
- y-axis offset (positive values move the item down).
-A value of about 100 will cause the item to display directly below its usual position.
-
-
- scale
- float
- item size (1 being standard size).
-A value of 0.5 will cause the item to render at half the size,
-and a value of 2 will cause the item to render at twice the size.
-
-
- rot
- Rotation
- rotation around x, y, and z axes
-
-
- axis
- RotationAxis
- Axis to rotate around when the item is observed at in the inventory.
-Note that this is entirely separate from the `rot` field described above.
-Must one of the following:
- X
- Y
- Z
-e.g. `myItem.rotAxisWhenCurrent = RotationAxis.X`
-
-
- meshBits
- int
- __Not currently implemented__ (will have no effect regardless of what you set it to)
-
-
- action
- ItemAction
- is this usable, equippable, combineable or examinable?
-Must be one of:
- EQUIP
- USE
- COMBINE
- EXAMINE
-e.g. `myItem.action = ItemAction.EXAMINE`
-
-
-
-
- InventoryItem
- an InventoryItem
-
-
-
-
-
- Flow.Level
- Level
- Make a new Level object.
-
-
- Level
- a Level object
-
-
-
-
-
- Flow.SkyLayer
- SkyLayer
-
-
- color
- Color
- RGB color
-
-
- speed
- int
- cloud speed
-
-
-
-
- SkyLayer
- A SkyLayer object.
-
-
-
-
-
- Input
- Vibrate
- Vibrate the game controller if the function is available and the setting is on.
-
-
- strength
- float
- Vibration strength.
-
-
- time
- float
- __(default 0.3)__ Vibration time in seconds.
-
-
-
-
-
- Input
- KeyIsHeld
- Check if an action key is being held.
-
-
- action
- Input.ActionID
- Action ID to check.
-
-
-
-
-
- Input
- KeyIsHit
- Check if an action key is being hit or clicked.
-
-
- action
- Input.ActionID
- Action ID to check.
-
-
-
-
-
- Input
- KeyPush
- Simulate an action key push.
-
-
- action
- Input.ActionID
- Action ID to push.
-
-
-
-
-
- Input
- KeyClear
- Clear an action key.
-
-
- action
- Input.ActionID
- Action ID to clear.
-
-
-
-
-
- Input
- GetMouseDisplayPosition
- Get the display position of the cursor in percent.
- ()
-
-
- Vec2
- Cursor display position in percent.
-
-
-
-
-
- Inventory
- GiveItem
- Add an item to the player's inventory.
-
-
- objectID
- Objects.ObjID
- Object ID of the item to add.
-
-
- count
- int
- The amount of items to add. Default is the yield from a single pickup, e.g. 1 from a medipack, 12 from a flare pack.
-
-
- addToPickupSummary
- bool
- If true, display the item in the pickup summary. Default is false.
-
-
-
-
-
- Inventory
- TakeItem
- Remove an item from the player's inventory.
-
-
- Object
- Objects.ObjID
- ID of the item to remove.
-
-
- count
- int
- The amount of items to remove. Default is the yield from a single pickup, e.g. 1 from a medipack, 12 from a flare pack.
-
-
-
-
-
- Inventory
- GetItemCount
- Get the amount of an item held in the player's inventory.
-
-
- objectID
- Objects.ObjID
- Object ID of the item to check.
-
-
-
-
- int
- The amount of items. -1 indicates infinity.
-
-
-
-
-
- Inventory
- SetItemCount
- Set the amount of an item in the player's inventory.
-
-
- objectID
- Objects.ObjID
- Object ID of the item amount to set.
-
-
- count
- int
- The amount of items to set. -1 indicates infinity.
-
-
-
-
-
- Logic
- AddCallback
- Register a function as a callback.
-
-
- point
- CallbackPoint
- When should the callback be called?
-
-
- func
- LevelFunc
- The function to be called (must be in the `LevelFuncs` hierarchy). Will receive, as an argument, the time in seconds since the last frame.
-
-
-
-
-
- Logic
- RemoveCallback
- Deregister a function as a callback.
- Will have no effect if the function was not registered as a callback
-
-
- point
- CallbackPoint
- The callback point the function was registered with. See @{AddCallback}
-
-
- func
- LevelFunc
- The function to remove; must be in the LevelFuncs hierarchy.
-
-
-
-
-
- Logic
- HandleEvent
- Attempt to find an event set and execute a particular event from it.
-
-
- name
- string
- Name of the event set to find.
-
-
- type
- EventType
- Event to execute.
-
-
- activator
- Objects.Moveable
- Optional activator. Default is the player object.
-
-
-
-
-
- Logic
- EnableEvent
- Attempt to find an event set and enable specified event in it.
-
-
- name
- string
- Name of the event set to find.
-
-
- type
- EventType
- Event to enable.
-
-
-
-
-
- Logic
- DisableEvent
- Attempt to find an event set and disable specified event in it.
-
-
- name
- string
- Name of the event set to find.
-
-
- type
- EventType
- Event to disable.
-
-
-
-
-
- Objects.AIObject
- AIObject
- GetPosition
- Get the object's position
-
-
- Vec3
- a copy of the object's position
-
-
-
-
-
- Objects.AIObject
- AIObject
- SetPosition
- Set the object's position
-
-
- position
- Vec3
- the new position of the object
-
-
-
-
-
- Objects.AIObject
- AIObject
- GetRotationY
- Get the object's Y-axis rotation.
- To the best of my knowledge, the rotation of an AIObject has no effect.
-
-
- number
- the object's Y-axis rotation
-
-
-
-
-
- Objects.AIObject
- AIObject
- SetRotationY
- Set the object's Y-axis rotation.
- To the best of my knowledge, the rotation of an AIObject has no effect.
-
-
- rotation
- number
- The object's new Y-axis rotation
-
-
-
-
-
- Objects.AIObject
- AIObject
- GetName
- Get the object's unique string identifier
-
-
- string
- the object's name
-
-
-
-
-
- Objects.AIObject
- AIObject
- SetName
- Set the object's name (its unique string identifier)
-
-
- name
- string
- The object's new name
-
-
-
-
-
- Objects.AIObject
- AIObject
- GetRoom
- Get the current room of the object
-
-
- Room
- current room of the object
-
-
-
-
-
- Objects.AIObject
- AIObject
- GetRoomNumber
- Get the current room number of the object
-
-
- int
- number representing the current room of the object
-
-
-
-
-
- Objects.AIObject
- AIObject
- SetRoomNumber
- Set room number of the object
- This is used in conjunction with SetPosition to teleport the object to a new room.
-
-
- ID
- int
- the ID of the new room
-
-
-
-
-
- Objects.AIObject
- AIObject
- GetObjectID
- Retrieve the object ID
-
-
- int
- a number representing the ID of the object
-
-
-
-
-
- Objects.AIObject
- AIObject
- SetObjectID
- Change the object's ID.
- This will change the type of AI object it is.
- Note that a baddy will gain the behaviour of the tile it's on _before_ said baddy is triggered.
- This means that changing the type of an AI object beneath a moveable will have no effect.
- Instead, this function can be used to change an object that the baddy isn't standing on.
- For example, you could have a pair of AI_GUARD objects, and change one or the other two
- AI_PATROL_1 based on whether the player has a certain item or not.
-
-
- ID
- Objects.ObjID
- the new ID
-
-
-
-
-
- Objects.Camera
- Camera
- GetPosition
- Get the camera's position
-
-
- Vec3
- a copy of the camera's position
-
-
-
-
-
- Objects.Camera
- Camera
- SetPosition
- Set the camera's position
-
-
- position
- Vec3
- the new position of the camera
-
-
-
-
-
- Objects.Camera
- Camera
- GetName
- Get the camera's unique string identifier
-
-
- string
- the camera's name
-
-
-
-
-
- Objects.Camera
- Camera
- SetName
- Set the camera's name (its unique string identifier)
-
-
- name
- string
- The camera's new name
-
-
-
-
-
- Objects.Camera
- Camera
- GetRoom
- Get the current room of the camera
-
-
- Room
- current room of the camera
-
-
-
-
-
- Objects.Camera
- Camera
- GetRoomNumber
- Get the current room number of the camera
-
-
- int
- number representing the current room of the camera
-
-
-
-
-
- Objects.Camera
- Camera
- SetRoomNumber
- Set room of camera
- This is used in conjunction with SetPosition to teleport the camera to a new room.
-
-
- ID
- int
- the ID of the new room
-
-
-
-
-
- Objects.Camera
- Camera
- PlayCamera
- Active the camera during that frame.
-
-
- Target
- Moveable
- If you put a moveable, the camera will look at it. Otherwise, it will look at Lara.
-
-
-
-
-
- Objects.LaraObject
- LaraObject
- SetPoison
- Set Lara poison
-
-
- Poison
- int
- ; maximum value is 128 (default 0)
-
-
-
-
-
- Objects.LaraObject
- LaraObject
- GetPoison
- Get poison potency of Lara
-
-
- int
- current poison potency
-
-
-
-
-
- Objects.LaraObject
- LaraObject
- SetAir
- Set air value of Lara
-
-
- Air
- int
- value to give Lara. Maximum value is 1800.
-
-
-
-
-
- Objects.LaraObject
- LaraObject
- GetAir
- Get air value of Lara
-
-
- int
- current air value
-
-
-
-
-
- Objects.LaraObject
- LaraObject
- SetWet
- Set wetness value of Lara (causes dripping)
-
-
- Wetness
- int
- value. Maximum 255
-
-
-
-
-
- Objects.LaraObject
- LaraObject
- GetWet
- Get wetness value of Lara
-
-
- int
- current wetness value
-
-
-
-
-
- Objects.LaraObject
- LaraObject
- SetStamina
- Set sprint energy value of Lara
-
-
- stamina
- int
- to give to Lara; maximum value is 120.
-
-
-
-
-
- Objects.LaraObject
- LaraObject
- GetStamina
- Get stamina value of Lara
-
-
- int
- current sprint value
-
-
-
-
-
- Objects.LaraObject
- Moveable
- GetAirborne
- Get the moveable's airborne status
-
-
- (bool)
- true if Lara state must react to aerial forces.
-
-
-
-
-
- Objects.LaraObject
- Moveable
- SetAirborne
- Set the moveable's airborne status
-
-
- New
- (bool)
- airborn status for Lara.
-
-
-
-
-
- Objects.LaraObject
- LaraObject
- UndrawWeapon
- Lara will undraw her weapon if it is drawn and throw away a flare if she is currently holding one.
-
-
-
- Objects.LaraObject
- LaraObject
- ThrowAwayTorch
- Lara will throw away the torch if she currently holds one in her hand.
-
-
-
- Objects.LaraObject
- LaraObject
- GetHandStatus
- Get actual hand status of Lara
-
-
- int
- hand status 0=HandsFree, 1=Busy(climbing,etc), 2=WeaponDraw, 3=WeaponUndraw, 4=WeaponInHand.
-
-
-
-
-
- Objects.LaraObject
- LaraObject
- GetWeaponType
- Get actual weapon type of Lara
-
-
- int
- weapon type 0=None, 1=Pistols, 2=Revolver, 3=Uzi, 4=Shotgun, 5=HK, 6=Crossbow, 7=Flare, 8=Torch, 9=GrenadeLauncher, 10=Harpoon, 11=RocketLauncher.
-
-
-
-
-
- Objects.LaraObject
- LaraObject
- SetWeaponType
- Set Lara weapon type
-
-
- weaponType
- LaraWeaponType
- Must be one of:
- NONE
- PISTOLS
- REVOLVER
- UZI
- SHOTGUN
- HK
- CROSSBOW
- FLARE
- TORCH
- GRENADELAUNCHER
- HARPOONGUN
- ROCKETLAUNCHER
-
-
- activate
- bool
- true = let her also draw the weapons, set torch lit. false = let Laras new weapons remain holstered until she draws them, set torch unlit.
-
-
-
-
-
- Objects.LaraObject
- LaraObject
- GetAmmoType
- Get player weapon ammo type.
-
-
- int
- player weapon ammo type
-
-
-
-
-
- Objects.LaraObject
- LaraObject
- GetAmmoCount
- Get current weapon's ammo count
-
-
- int
- current ammo count (-1 if infinite)
-
-
-
-
-
- Objects.LaraObject
- LaraObject
- GetVehicle
- Get current vehicle, if it exists
-
-
- Objects.Moveable
- current vehicle (nil if no vehicle present)
-
-
-
-
-
- Objects.LaraObject
- LaraObject
- GetTarget
- Get the player's current targeted moveable (if it exists).
-
-
- Objects.Moveable
- Target moveable (nil if the player is not currently targeting a moveable).
-
-
-
-
-
- Objects.LaraObject
- LaraObject
- GetInteractedMoveable
- Get the player's current interacted moveable (if it exists).
-
-
- Objects.Moveable
- Interacted moveable (nil if the player is not interacting with a moveable).
-
-
-
-
-
- Objects.LaraObject
- LaraObject
- TorchIsLit
- Get current light state of the torch, if it exists
-
-
- bool
- is torch currently lit or not? (false if no torch exists)
-
-
-
-
-
- Objects.Moveable
- Moveable
- For more information on each parameter, see the
-associated getters and setters.
- If you do not know what to set for these,
-most can just be ignored (see usage).
-
-
- object
- Objects.ObjID
- ID
-
-
- name
- string
- Lua name of the item
-
-
- position
- Vec3
- position in level
-
-
- rotation
- Rotation
- rotation about x, y, and z axes (default Rotation(0, 0, 0))
-
-
- roomID
- int
- room ID item is in (default: calculated automatically)
-
-
- animNumber
- int
- anim number
-
-
- frameNumber
- int
- frame number
-
-
- hp
- int
- HP of item
-
-
- OCB
- int
- ocb of item
-
-
- AIBits
- table
- table with AI bits (default { 0, 0, 0, 0, 0, 0 })
-
-
-
-
- Moveable
- A new Moveable object (a wrapper around the new object)
-
-
-
-
-
- Objects.Moveable
- Moveable
- Explode
- Explode item.
- This also kills and disables item.
-
-
-
- Objects.Moveable
- Moveable
- Shatter
- Shatter item.
- This also kills and disables item.
-
-
-
- Objects.Moveable
- Moveable
- SetEffect
- Set effect to moveable
-
-
- effect
- Effects.EffectID
- Type of effect to assign.
-
-
- timeout
- float
- time (in seconds) after which effect turns off (optional).
-
-
-
-
-
- Objects.Moveable
- Moveable
- SetCustomEffect
- Set custom colored burn effect to moveable
-
-
- Color1
- Color
- color the primary color of the effect (also used for lighting).
-
-
- Color2
- Color
- color the secondary color of the effect.
-
-
- timeout
- float
- time (in seconds) after which effect turns off (optional).
-
-
-
-
-
- Objects.Moveable
- Moveable
- GetEffect
- Get current moveable effect
-
-
- Effects.EffectID
- effect type currently assigned to moveable.
-
-
-
-
-
- Objects.Moveable
- Moveable
- GetStatus
- Get the moveable's status.
- ()
-
-
- Objects.MoveableStatus
- The moveable's status.
-
-
-
-
-
- Objects.Moveable
- Moveable
- SetStatus
- Set the moveable's status.
- ()
-
-
- status
- Objects.MoveableStatus
- The new status of the moveable.
-
-
-
-
-
- Objects.Moveable
- Moveable
- SetOnHit
- Set the name of the function to be called when the moveable is shot by Lara.
- Note that this will be triggered twice when shot with both pistols at once.
-
-
- callback
- function
- function in LevelFuncs hierarchy to call when moveable is shot
-
-
-
-
-
- Objects.Moveable
- Moveable
- SetOnKilled
- Set the name of the function to be called when the moveable is destroyed/killed
- Note that enemy death often occurs at the end of an animation, and not at the exact moment
- the enemy's HP becomes zero.
-
-
- callback
- function
- function in LevelFuncs hierarchy to call when enemy is killed
-
-
-
-
-
- Objects.Moveable
- Moveable
- GetObjectID
- Retrieve the object ID
-
-
- int
- a number representing the ID of the object
-
-
-
-
-
- Objects.Moveable
- Moveable
- SetObjectID
- Change the object's ID.
- This will literally change the object.
-
-
- ID
- Objects.ObjID
- the new ID
-
-
-
-
-
- Objects.Moveable
- Moveable
- GetState
- Retrieve the index of the current state.
- This corresponds to the number shown in the item's state ID field in WadTool.
-
-
- int
- the index of the active state
-
-
-
-
-
- Objects.Moveable
- Moveable
- SetState
- Set the object's state to the one specified by the given index.
- Performs no bounds checking. *Ensure the number given is correct, else
- object may end up in corrupted animation state.*
-
-
- index
- int
- the index of the desired state
-
-
-
-
-
- Objects.Moveable
- Moveable
- GetAnim
- Retrieve the index of the current animation.
- This corresponds to the number shown in the item's animation list in WadTool.
-
-
- int
- the index of the active animation
-
-
-
-
-
- Objects.Moveable
- Moveable
- SetAnim
- Set the object's animation to the one specified by the given index.
- Performs no bounds checking. *Ensure the number given is correct, else
- object may end up in corrupted animation state.*
-
-
- index
- int
- the index of the desired anim
-
-
-
-
-
- Objects.Moveable
- Moveable
- GetFrame
- Retrieve frame number.
- This is the current frame of the object's active animation.
-
-
- int
- the current frame of the active animation
-
-
-
-
-
- Objects.Moveable
- Moveable
- SetVelocity
- Set the object's velocity to specified value.
- In most cases, only Z and Y components are used as forward and vertical velocity.
- In some cases, primarily NPCs, X component is used as side velocity.
-
-
- velocity
- Vec3
- velocity represented as vector
-
-
-
-
-
- Objects.Moveable
- Moveable
- GetVelocity
- Get the object's velocity.
- In most cases, only Z and Y components are used as forward and vertical velocity.
- In some cases, primarily NPCs, X component is used as side velocity.
-
-
- Vec3
- current object velocity
-
-
-
-
-
- Objects.Moveable
- Moveable
- SetFrame
- Set frame number.
- This will move the animation to the given frame.
- The number of frames in an animation can be seen under the heading "End frame" in
- the WadTool animation editor. If the animation has no frames, the only valid argument
- is -1.
-
-
- frame
- int
- the new frame number
-
-
-
-
-
- Objects.Moveable
- Moveable
- GetSlotHP
- Get HP definded for that object type (hit points/health points) (Read Only).
-
-
- ID
- int
- of the moveable slot type.
-
-
-
-
-
- Objects.Moveable
- Moveable
- GetOCB
- Get OCB (object code bit) of the moveable
-
-
- int
- the moveable's current OCB value
-
-
-
-
-
- Objects.Moveable
- Moveable
- SetOCB
- Set OCB (object code bit) of the moveable
-
-
- OCB
- int
- the new value for the moveable's OCB
-
-
-
-
-
- Objects.Moveable
- Moveable
- GetItemFlags
- Get the value stored in ItemFlags[index]
-
-
- index
- int
- of the ItemFlags, can be between 0 and 7.
-
-
-
-
- int
- the value contained in the ItemFlags[index]
-
-
-
-
-
- Objects.Moveable
- Moveable
- SetItemFlags
- Stores a value in ItemFlags[index]
-
-
- value
- short
- to store in the moveable's ItemFlags[index]
-
-
- index
- int
- of the ItemFlags where store the value.
-
-
-
-
-
- Objects.Moveable
- Moveable
- GetColor
- Get the moveable's color
-
-
- Color
- a copy of the moveable's color
-
-
-
-
-
- Objects.Moveable
- Moveable
- SetColor
- Set the moveable's color
-
-
- color
- Color
- the new color of the moveable
-
-
-
-
-
- Objects.Moveable
- Moveable
- GetHitStatus
- Get the hit status of the object
-
-
- bool
- true if the moveable was hit by something in the last gameplay frame, false otherwise
-
-
-
-
-
- Objects.Moveable
- Moveable
- GetActive
- Determine whether the moveable is active or not
-
-
- bool
- true if the moveable is active
-
-
-
-
-
- Objects.Moveable
- Moveable
- GetJointPosition
- Get the object's joint position
-
-
- index
- int
- of a joint to get position
-
-
-
-
- Vec3
- a copy of the moveable's position
-
-
-
-
-
- Objects.Moveable
- Moveable
- GetRotation
- Get the moveable's rotation
-
-
- Rotation
- a copy of the moveable's rotation
-
-
-
-
-
- Objects.Moveable
- Moveable
- SetRotation
- Set the moveable's rotation
-
-
- rotation
- Rotation
- The moveable's new rotation
-
-
-
-
-
- Objects.Moveable
- Moveable
- GetName
- Get the moveable's name (its unique string identifier)
- e.g.
- "door\_back\_room" or "cracked\_greek\_statue"
- This corresponds with the "Lua Name" field in an object's properties in Tomb Editor.
-
-
- string
- the moveable's name
-
-
-
-
-
- Objects.Moveable
- Moveable
- SetName
- Set the moveable's name (its unique string identifier)
- e.g.
- "door\_back\_room" or "cracked\_greek\_statue"
- It cannot be blank and cannot share a name with any existing object.
-
-
- name
- string
- the new moveable's name
-
-
-
-
- bool
- true if we successfully set the name, false otherwise (e.g. if another object has the name already)
-
-
-
-
-
- Objects.Moveable
- Moveable
- GetValid
- Test if the object is in a valid state (i.e.
- has not been destroyed through Lua or killed by Lara).
-
-
- bool
- valid true if the object is still not destroyed
-
-
-
-
-
- Objects.Moveable
- Moveable
- Destroy
- Destroy the moveable.
- This will mean it can no longer be used, except to re-initialize it with another object.
-
-
-
- Objects.Moveable
- Moveable
- AttachObjCamera
- Attach camera to an object.
-
-
- mesh
- int
- of a target moveable to use as a camera target
-
-
- target
- Moveable
- moveable to attach camera to
-
-
- mesh
- int
- of a target moveable to use as a camera target
-
-
-
-
-
- Objects.Moveable
- Moveable
- AnimFromObject
- Borrow animation from an object
-
-
- ObjectID
- Objects.ObjID
- to take animation and stateID from,
-
-
- animNumber
- int
- animation from object
-
-
- stateID
- int
- state from object
-
-
-
-
-
- Objects.Moveable
- Moveable
- SetOnCollidedWithObject
- Set the function to be called when this moveable collides with another moveable
-
-
- func
- function
- callback function to be called (must be in LevelFuncs hierarchy). This function can take two arguments; these will store the two @{Moveable}s taking part in the collision.
-
-
-
-
-
- Objects.Moveable
- Moveable
- SetOnCollidedWithRoom
- Set the function called when this moveable collides with room geometry (e.g.
- a wall or floor). This function can take an argument that holds the @{Moveable} that collided with geometry.
-
-
- func
- function
- callback function to be called (must be in LevelFuncs hierarchy)
-
-
-
-
-
- Objects.Moveable
- Moveable
- GetPosition
- Get the object's position
-
-
- Vec3
- a copy of the moveable's position
-
-
-
-
-
- Objects.Moveable
- Moveable
- SetPosition
- Set the moveable's position
- If you are moving a moveable whose behaviour involves knowledge of room geometry,
- (e.g.
- a BADDY1, which uses it for pathfinding), then the second argument should
- be true (or omitted, as true is the default). Otherwise, said moveable will not behave correctly.
-
-
- position
- Vec3
- the new position of the moveable
-
-
- updateRoom
- bool
- Will room changes be automatically detected? Set to false if you are using overlapping rooms (default: true)
-
-
-
-
-
- Objects.Moveable
- Moveable
- GetHP
- Get current HP (hit points/health points)
-
-
- int
- the amount of HP the moveable currently has
-
-
-
-
-
- Objects.Moveable
- Moveable
- SetHP
- Set current HP (hit points/health points)
- Clamped to [0, 32767] for "intelligent" entities (i.e.
- anything with AI); clamped to [-32767, 32767] otherwise.
-
-
- HP
- int
- the amount of HP to give the moveable
-
-
-
-
-
- Objects.Moveable
- Moveable
- GetLocationAI
- Get the location value stored in the Enemy AI
-
-
- short
- the value contained in the LocationAI of the creature.
-
-
-
-
-
- Objects.Moveable
- Moveable
- SetLocationAI
- Updates the location in the enemy AI with the given value.
-
-
- value
- short
- to store.
-
-
-
-
-
- Objects.Moveable
- Moveable
- GetAIBits
- Get AIBits of object
- This will return a table with six values, each corresponding to
- an active behaviour.
- If the object is in a certain AI mode, the table will
- have a *1* in the corresponding cell. Otherwise, the cell will hold
- a *0*.
-
- 1 - guard
- 2 - ambush
- 3 - patrol 1
- 4 - modify
- 5 - follow
- 6 - patrol 2
-
-
- table
- a table of AI bits
-
-
-
-
-
- Objects.Moveable
- Moveable
- SetAIBits
- Set AIBits of object
- Use this to force a moveable into a certain AI mode or modes, as if a certain nullmesh
- (or more than one) had suddenly spawned beneath their feet.
-
-
- bits
- table
- the table of AI bits
-
-
-
-
-
- Objects.Moveable
- Moveable
- GetEndFrame
- Get the end frame number of the moveable's active animation.
- This is the "End Frame" set in WADTool for the animation.()
-
-
- int
- End frame number of the active animation.
-
-
-
-
-
- Objects.Moveable
- Moveable
- GetRoom
- Get the current room of the object
-
-
- Objects.Room
- current room of the object
-
-
-
-
-
- Objects.Moveable
- Moveable
- GetRoomNumber
- Get the current room number of the object
-
-
- int
- number representing the current room of the object
-
-
-
-
-
- Objects.Moveable
- Moveable
- SetRoomNumber
- Set the room ID of a moveable.
- Use this if not using SetPosition's automatic room update - for example, when dealing with overlapping rooms.
-
-
- roomID
- int
- New room's ID.
-
-
-
-
-
- Objects.Moveable
- Moveable
- GetMeshVisible
- Get state of specified mesh visibility of object
- Returns true if specified mesh is visible on an object, and false
- if it is not visible.
-
-
- index
- int
- index of a mesh
-
-
-
-
- bool
- visibility status
-
-
-
-
-
- Objects.Moveable
- Moveable
- SetMeshVisible
- Makes specified mesh visible or invisible
- Use this to show or hide a specified mesh of an object.
-
-
- index
- int
- index of a mesh
-
-
- isVisible
- bool
- true if you want the mesh to be visible, false otherwise
-
-
-
-
-
- Objects.Moveable
- Moveable
- ShatterMesh
- Shatters specified mesh and makes it invisible
- Note that you can re-enable mesh later by using SetMeshVisible().
-
-
- index
- int
- index of a mesh
-
-
-
-
-
- Objects.Moveable
- Moveable
- GetMeshSwapped
- Get state of specified mesh swap of object
- Returns true if specified mesh is swapped on an object, and false
- if it is not swapped.
-
-
- index
- int
- index of a mesh
-
-
-
-
- bool
- mesh swap status
-
-
-
-
-
- Objects.Moveable
- Moveable
- SwapMesh
- Set state of specified mesh swap of object
- Use this to swap specified mesh of an object.
-
-
- index
- int
- index of a mesh
-
-
- slotIndex
- int
- index of a slot to get meshswap from
-
-
- swapIndex
- int
- index of a mesh from meshswap slot to use
-
-
-
-
-
- Objects.Moveable
- Moveable
- UnswapMesh
- Set state of specified mesh swap of object
- Use this to bring back original unswapped mesh
-
-
- index
- int
- index of a mesh to unswap
-
-
-
-
-
- Objects.Moveable
- Moveable
- Enable
- Enable the item, as if a trigger for it had been stepped on.
-
-
-
- Objects.Moveable
- Moveable
- Disable
- Disable the item, as if an antitrigger for it had been stepped on (i.e.
- it will close an open door or extinguish a flame emitter).
- Note that this will not trigger an OnKilled callback.
-
-
-
- Objects.Moveable
- Moveable
- MakeInvisible
- Make the item invisible.
- Alias for `Moveable:SetVisible(false)`.
-
-
-
- Objects.Moveable
- Moveable
- SetVisible
- Set the item's visibility.
- __An invisible item will have collision turned off, as if it no longer exists in the game world__.
-
-
- visible
- bool
- true if the caller should become visible, false if it should become invisible
-
-
-
-
-
- Objects
- GetMoveableByName
- Get a moveable by its name.
-
-
- name
- string
- the unique name of the Moveable as set in, or generated by, Tomb Editor
-
-
-
-
- Moveable
- a non-owning Moveable referencing the item.
-
-
-
-
-
- Objects
- GetStaticByName
- Get a Static by its name.
-
-
- name
- string
- the unique name of the mesh as set in, or generated by, Tomb Editor
-
-
-
-
- Static
- a non-owning Static referencing the mesh.
-
-
-
-
-
- Objects
- GetMoveablesBySlot
- Get moveables by its slot.
-
-
- slot
- Objects.ObjID
- the unique slot of the Moveable, e.g. `Objects.ObjID.ANIMATING1`
-
-
-
-
- table
- table of Moveables referencing the given slot.
-
-
-
-
-
- Objects
- GetStaticsBySlot
- Get statics by its slot.
-
-
- slot
- int
- the unique slot of the mesh like 10
-
-
-
-
- table
- table of Statics referencing the given slot ID.
-
-
-
-
-
- Objects
- GetRoomsByTag
- Get rooms by tag.
-
-
- tag
- string
- to select rooms by
-
-
-
-
- table
- table of Rooms containing the given tag.
-
-
-
-
-
- Objects
- GetCameraByName
- Get a Camera by its name.
-
-
- name
- string
- the unique name of the camera as set in, or generated by, Tomb Editor
-
-
-
-
- Camera
- a non-owning Camera referencing the camera.
-
-
-
-
-
- Objects
- GetSinkByName
- Get a Sink by its name.
-
-
- name
- string
- the unique name of the sink as set in, or generated by, Tomb Editor
-
-
-
-
- Sink
- a non-owning Sink referencing the sink.
-
-
-
-
-
- Objects
- GetSoundSourceByName
- Get a SoundSource by its name.
-
-
- name
- string
- the unique name of the sound source as set in, or generated by, Tomb Editor
-
-
-
-
- SoundSource
- a non-owning SoundSource referencing the sound source.
-
-
-
-
-
- Objects
- GetAIObjectByName
- Get an AIObject by its name.
-
-
- name
- string
- the unique name of the AIObject as set in, or generated by, Tomb Editor
-
-
-
-
- AIObject
- a non-owning SoundSource referencing the AI moveable.
-
-
-
-
-
- Objects
- GetVolumeByName
- Get a Volume by its name.
-
-
- name
- string
- the unique name of the volume as set in, or generated by, Tomb Editor
-
-
-
-
- Volume
- a non-owning Volume referencing the room.
-
-
-
-
-
- Objects
- GetRoomByName
- Get a Room by its name.
-
-
- name
- string
- the unique name of the room as set in Tomb Editor
-
-
-
-
- Room
- a non-owning Room referencing the room.
-
-
-
-
-
- Objects.Room
- Room
- GetActive
- Determine whether the room is active or not
-
-
- bool
- true if the room is active
-
-
-
-
-
- Objects.Room
- Room
- GetColor
- Get the room's ambient light color.
-
-
- Color
- ambient light color of the room
-
-
-
-
-
- Objects.Room
- Room
- GetReverbType
- Get the room's reverb type.
-
-
- Objects.RoomReverb
- room's reverb type
-
-
-
-
-
- Objects.Room
- Room
- SetReverbType
- Set the room's reverb type.
-
-
- new
- Objects.RoomReverb
- reverb type of the room
-
-
-
-
-
- Objects.Room
- Room
- GetName
- Get the room's unique string identifier.
-
-
- string
- the room's name
-
-
-
-
-
- Objects.Room
- Room
- SetName
- Set the room's name (its unique string identifier).
-
-
- name
- string
- The room's new name
-
-
-
-
-
- Objects.Room
- Room
- GetFlag
- Get the room's specified flag value (true or false).
-
-
- flagID
- Objects.RoomFlagID
- The room's flag ID
-
-
-
-
- bool
- the room's specified flag value
-
-
-
-
-
- Objects.Room
- Room
- SetFlag
- Set the room's specified flag value.
-
-
- flagID
- Objects.RoomFlagID
- The room's flag ID
-
-
- the
- bool
- room's new flag value
-
-
-
-
-
- Objects.Room
- Room
- IsTagPresent
- Checks if specified tag is set for this room.
-
-
- tag
- string
- A text tag to check (case sensitive)
-
-
-
-
- bool
- true if tag is present, false if not
-
-
-
-
-
- Objects.Sink
- Sink
- GetPosition
- Get the sink's position
-
-
- Vec3
- a copy of the sink's position
-
-
-
-
-
- Objects.Sink
- Sink
- SetPosition
- Set the sink's position
-
-
- position
- Vec3
- the new position of the sink
-
-
-
-
-
- Objects.Sink
- Sink
- GetName
- Get the sink's unique string identifier
- e.g.
- "strong\_river\_current" or "propeller\_death\_sink"
-
-
- string
- the sink's name
-
-
-
-
-
- Objects.Sink
- Sink
- SetName
- Set the sink's name (its unique string identifier)
-
-
- name
- string
- The sink's new name
-
-
-
-
-
- Objects.Sink
- Sink
- GetStrength
- Get the sink's strength
-
-
- int
- the sink's current strength
-
-
-
-
-
- Objects.Sink
- Sink
- SetStrength
- Set the strength of the sink
- Higher numbers provide stronger currents.
- Will be clamped to [1, 32].
-
-
- strength
- int
- The sink's new strength
-
-
-
-
-
- Objects.SoundSource
- SoundSource
- GetPosition
- Get the sound source's position
-
-
- Vec3
- a copy of the sound source's position
-
-
-
-
-
- Objects.SoundSource
- SoundSource
- SetPosition
- Set the sound source's position
-
-
- position
- Vec3
- the new position of the sound source
-
-
-
-
-
- Objects.SoundSource
- SoundSource
- GetName
- Get the sound source's unique string identifier
-
-
- string
- the sound source's name
-
-
-
-
-
- Objects.SoundSource
- SoundSource
- SetName
- Set the sound source's name (its unique string identifier)
-
-
- name
- string
- The sound source's new name
-
-
-
-
-
- Objects.SoundSource
- SoundSource
- GetSoundID
- Get the sound source's unique int identifier
-
-
- int
- the ID of the sound
-
-
-
-
-
- Objects.SoundSource
- SoundSource
- SetSoundID
- Set the sound source's ID
- __TODO__ this and getSoundID should use enums
-
-
- name
- int
- The sound source's new name
-
-
-
-
-
- Objects.Static
- Static
- Enable
- Enable the static, for cases when it was shattered or manually disabled before.
-
-
-
- Objects.Static
- Static
- Disable
- Disable the static
-
-
-
- Objects.Static
- Static
- GetActive
- Get static mesh visibility
-
-
- bool
- visibility state
-
-
-
-
-
- Objects.Static
- Static
- GetSolid
- Get static mesh solid collision state
-
-
- bool
- solid collision state (true if solid, false if soft)
-
-
-
-
-
- Objects.Static
- Static
- SetSolid
- Set static mesh solid collision state
-
-
- solidState
- bool
- if set, collision will be solid, if not, will be soft
-
-
-
-
-
- Objects.Static
- Static
- GetPosition
- Get the static's position
-
-
- Vec3
- a copy of the static's position
-
-
-
-
-
- Objects.Static
- Static
- SetPosition
- Set the static's position
-
-
- position
- Vec3
- the new position of the static
-
-
-
-
-
- Objects.Static
- Static
- GetRotation
- Get the static's rotation
-
-
- Rotation
- a copy of the static's rotation
-
-
-
-
-
- Objects.Static
- Static
- SetRotation
- Set the static's rotation
-
-
- rotation
- Rotation
- the static's new rotation
-
-
-
-
-
- Objects.Static
- Static
- GetScale
- Get the static's scale
-
-
- float
- current static scale
-
-
-
-
-
- Objects.Static
- Static
- SetScale
- Set the static's scale
-
-
- scale
- Scale
- the static's new scale
-
-
-
-
-
- Objects.Static
- Static
- GetName
- Get the static's unique string identifier
-
-
- string
- the static's name
-
-
-
-
-
- Objects.Static
- Static
- SetName
- Set the static's name (its unique string identifier)
- e.g.
- "my\_vase" or "oldrubble"
-
-
- name
- string
- The static's new name
-
-
-
-
-
- Objects.Static
- Static
- GetSlot
- Get the static's slot number (as listed in Tomb Editor and WadTool)
-
-
- string
- the static's slot number
-
-
-
-
-
- Objects.Static
- Static
- SetSlot
- Set the static's slot number (as listed in Tomb Editor and WadTool)
-
-
- slot
- int
- The static's slot number
-
-
-
-
-
- Objects.Static
- Static
- GetColor
- Get the static's color
-
-
- Color
- a copy of the static's color
-
-
-
-
-
- Objects.Static
- Static
- SetColor
- Set the static's color
-
-
- color
- Color
- the new color of the static
-
-
-
-
-
- Objects.Static
- Static
- Shatter
- Shatter static mesh
-
-
-
- Objects.Volume
- Volume
- Enable
- Enable the volume.
-
-
-
- Objects.Volume
- Volume
- Disable
- Disable the volume.
-
-
-
- Objects.Volume
- Volume
- GetActive
- Determine whether the volume is active or not
-
-
- bool
- true if the volume is active
-
-
-
-
-
- Objects.Volume
- Volume
- GetPosition
- Get the volume's position.
-
-
- Vec3
- a copy of the volume's position
-
-
-
-
-
- Objects.Volume
- Volume
- SetPosition
- Set the volume's position.
-
-
- position
- Vec3
- the new position of the volume
-
-
-
-
-
- Objects.Volume
- Volume
- GetRotation
- Get the volume's rotation.
-
-
- Rotation
- a copy of the volume's rotation
-
-
-
-
-
- Objects.Volume
- Volume
- SetRotation
- Set the volume's rotation.
-
-
- rotation
- Rotation
- the volume's new rotation
-
-
-
-
-
- Objects.Volume
- Volume
- GetScale
- Get the volume's scale (separately on all 3 axes).
-
-
- Vec3
- current volume scale
-
-
-
-
-
- Objects.Volume
- Volume
- SetScale
- Set the volume's scale (separately on all 3 axes).
-
-
- scale
- Vec3
- the volume's new scale
-
-
-
-
-
- Objects.Volume
- Volume
- GetName
- Get the volume's unique string identifier.
-
-
- string
- the volume's name
-
-
-
-
-
- Objects.Volume
- Volume
- SetName
- Set the volume's name (its unique string identifier).
-
-
- name
- string
- The volume's new name
-
-
-
-
-
- Objects.Volume
- Volume
- ClearActivators
- Clear activator list for volumes (makes volume trigger everything again)
-
-
-
- Objects.Volume
- Volume
- IsMoveableInside
- Check if specified moveable is inside the volume
-
-
- Moveable
- Objects.Moveable
- which should be checked for containment
-
-
-
-
- bool
- state of the moveable, true if contained, false if not
-
-
-
-
-
- Rotation
- Rotation
-
-
- x
- float
- X angle component.
-
-
- y
- float
- Y angle component.
-
-
- z
- float
- Z angle component.
-
-
-
-
- Rotation
- A Rotation.
-
-
-
-
-
- Rotation
- tostring
-
-
- rotation
- Rotation
- this Rotation.
-
-
-
-
- string
- A string showing the X, Y, and Z angle components of the Rotation.
-
-
-
-
-
- Sound
- PlayAudioTrack
- Play an audio track
-
-
- name
- string
- of track (without file extension) to play
-
-
- type
- Sound.SoundTrackType
- of the audio track to play
-
-
-
-
-
- Sound
- SetAmbientTrack
- Set and play an ambient track
-
-
- name
- string
- of track (without file extension) to play
-
-
-
-
-
- Sound
- StopAudioTracks
- Stop any audio tracks currently playing
-
-
-
- Sound
- StopAudioTrack
- Stop audio track that is currently playing
-
-
- type
- Sound.SoundTrackType
- of the audio track
-
-
-
-
-
- Sound
- GetAudioTrackLoudness
- Get current loudness level for specified track type
-
-
- type
- Sound.SoundTrackType
- of the audio track
-
-
-
-
- float
- current loudness of a specified audio track
-
-
-
-
-
- Sound
- PlaySound
- Play sound effect
-
-
- sound
- int
- ID to play. Corresponds to the value in the sound XML file or Tomb Editor's "Sound Infos" window.
-
-
- position
- Vec3
- The 3D position of the sound, i.e. where the sound "comes from". If not given, the sound will not be positional.
-
-
-
-
-
- Sound
- StopSound
- Stop sound effect
-
-
- sound
- int
- ID to play. Corresponds to the value in the sound XML file or Tomb Editor's "Sound Infos" window.
-
-
-
-
-
- Sound
- IsSoundPlaying
- Check if the sound effect is playing
-
-
- Sound
- int
- ID to check. Corresponds to the value in the sound XML file or Tomb Editor's "Sound Infos" window.
-
-
-
-
-
- Sound
- IsAudioTrackPlaying
- Check if the audio track is playing
-
-
- Track
- string
- filename to check. Should be without extension and without full directory path.
-
-
-
-
-
- Sound
- GetCurrentSubtitle
- Get current subtitle string for a voice track currently playing.
- Subtitle file must be in .srt format, have same filename as voice track, and be placed in same directory as voice track.
-Returns nil if no voice track is playing or no subtitle present.
-
-
- string
- current subtitle string
-
-
-
-
-
- Strings.DisplayString
- DisplayString
- Create a DisplayString.
- For use in @{Strings.ShowString|ShowString} and @{Strings.HideString|HideString}.
-
-
- string
- string
- The string to display or key of the translated string.
-
-
- Position
- Vec2
- of the string in pixel coordinates.
-
-
- scale
- float
- size of the string, relative to the default size. __Default: 1.0__
-
-
- color
- Color
- the color of the text. __Default: white__
-
-
- translated
- bool
- If false or omitted, the input string argument will be displayed.
-If true, the string argument will be the key of a translated string specified in strings.lua. __Default: false__.
-
-
- flags
- table
- A table of string display options. Can be empty or omitted. The possible values and their effects are:
- TEN.Strings.DisplayStringOption.CENTER: set the horizontal origin point to the center of the string.
- TEN.Strings.DisplayStringOption.RIGHT: set the horizontal origin point to right of the string.
- TEN.Strings.DisplayStringOption.SHADOW: give the string a small shadow.
- TEN.Strings.DisplayStringOption.BLINK: blink the string.
-__Default: empty__
-
-
-
-
- DisplayString
- A new DisplayString object.
-
-
-
-
-
- Strings.DisplayString
- DisplayString
- GetColor
- Get the display string's color
-
-
- Color
- a copy of the display string's color
-
-
-
-
-
- Strings.DisplayString
- DisplayString
- SetColor
- Set the display string's color
-
-
- color
- Color
- the new color of the display string
-
-
-
-
-
- Strings.DisplayString
- DisplayString
- GetKey
- Get the string key to use.
- If `isTranslated` is true when @{DisplayString}
- is called, this will be the string key for the translation that will be displayed.
- If false or omitted, this will be the string that's displayed.()
-
-
- string
- the string to use
-
-
-
-
-
- Strings.DisplayString
- DisplayString
- SetKey
- Set the string key to use.
- If `isTranslated` is true when @{DisplayString}
- is called, this will be the string key for the translation that will be displayed.
- If false or omitted, this will be the string that's displayed.()
-
-
- string
- string
- the new key for the display string
-
-
-
-
-
- Strings.DisplayString
- DisplayString
- SetScale
- Set the scale of the string.
- ()
-
-
- scale
- float
- New scale of the string relative to the default size.
-
-
-
-
-
- Strings.DisplayString
- DisplayString
- GetScale
- Get the scale of the string.
- ()
-
-
- float
- Scale.
-
-
-
-
-
- Strings.DisplayString
- DisplayString
- SetPosition
- Set the position of the string.
- Screen-space coordinates are expected.()
-
-
- pos
- Vec2
- New position in pixel coordinates.
-
-
-
-
-
- Strings.DisplayString
- DisplayString
- GetPosition
- Get the position of the string.
- Screen-space coordinates are returned.()
-
-
- Vec2
- pos Position in pixel coordinates.
-
-
-
-
-
- Strings.DisplayString
- DisplayString
- SetFlags
- Set the display string's flags
- ()
-
-
- table
- table
- the new table with display flags options
-
-
-
-
-
- Strings.DisplayString
- DisplayString
- SetTranslated
- Set translated parameter of the string
-
-
- shouldTranslate
- bool
- if true, the string's key will be used as the key for the translation that will be displayed.
- If false, the key itself will be displayed
-
-
-
-
-
- Strings
- ShowString
- Show some text on-screen.
-
-
- str
- DisplayString
- the string object to draw
-
-
- time
- float
- the time in seconds for which to show the string.
-If not given, the string will have an "infinite" life, and will show
-until @{HideString} is called or until the level is finished.
-Default: nil (i.e. infinite)
-
-
-
-
-
- Strings
- HideString
- Hide some on-screen text.
-
-
- str
- DisplayString
- the string object to hide. Must previously have been shown
-with a call to @{ShowString}, or this function will have no effect.
-
-
-
-
-
- Strings
- IsStringDisplaying
- Checks if the string is shown
-
-
- str
- DisplayString
- the string object to be checked
-
-
-
-
- bool
- true if it is shown, false if it is hidden
-
-
-
-
-
- Util
- HasLineOfSight
- Determine if there is a clear line of sight between two positions.
- NOTE: Limited to room geometry. Objects are ignored.()
-
-
- roomID
- float
- Room ID of the first position's room.
-
-
- posA
- Vec3
- First position.
-
-
- posB
- Vec3
- Second position.
-
-
-
-
- bool
- __true__ if there is a line of sight, __false__ if not.
-
-
-
-
-
- Util
- CalculateDistance
- Calculate the distance between two positions.
-
-
- posA
- Vec3
- First position.
-
-
- posB
- Vec3
- Second position.
-
-
-
-
- float
- Distance between two positions.
-
-
-
-
-
- Util
- CalculateHorizontalDistance
- Calculate the horizontal distance between two positions.
-
-
- posA
- Vec3
- First position.
-
-
- posB
- Vec3
- Second position.
-
-
-
-
- float
- Horizontal distance between the two positions.
-
-
-
-
-
- Util
- GetDisplayPosition
- Get the projected display space position of a 3D world position.
- Returns nil if the world position is behind the camera view.
-
-
- worldPos
- Vec3
- 3D world position.
-
-
-
-
- Vec2
- Projected display space position in percent.
-
-
-
-
-
- Util
- PercentToScreen
- Translate a pair display position coordinates to pixel coordinates.
- To be used with @{Strings.DisplayString:SetPosition} and @{Strings.DisplayString}.
-
-
- x
- float
- X component of the display position.
-
-
- y
- float
- Y component of the display position.
-
-
-
-
- int
- x X coordinate in pixels.
-
-
- int
- y Y coordinate in pixels.
-
-
-
-
-
- Util
- ScreenToPercent
- Translate a pair of pixel coordinates to display position coordinates.
- To be used with @{Strings.DisplayString:GetPosition}.
-
-
- x
- int
- X pixel coordinate to translate to display position.
-
-
- y
- int
- Y pixel coordinate to translate to display position.
-
-
-
-
- float
- x X component of display position.
-
-
- float
- y Y component of display position.
-
-
-
-
-
- Util
- PickMoveableByDisplayPosition
- Pick a moveable by the given display position.
-
-
- Display
- Vec2
- space position in percent.
-
-
-
-
- Objects.Moveable
- Picked moveable (nil if no moveable was found under the cursor).
-
-
-
-
-
- Util
- PickStaticByDisplayPosition
- Pick a static mesh by the given display position.
-
-
- Display
- Vec2
- space position in percent.
-
-
-
-
- Objects.Static
- Picked static mesh (nil if no static mesh was found under the cursor).
-
-
-
-
-
- Util
- PrintLog
- Write messages within the Log file
-
-
- message
- string
- to be displayed within the Log
-
-
- logLevel
- Misc.LogLevel
- log level to be displayed
-
-
- allowSpam
- bool
- true allows spamming of the message
-
-
-
-
-
- Vec2
- Vec2
- Create a Vec2 object.
- (x, y)
-
-
- x
- float
- X component.
-
-
- y
- float
- Y component.
-
-
-
-
- Vec2
- A new Vec2 object.
-
-
-
-
-
- Vec2
- Vec
- Create a Vec2 object.
- (value)
-
-
- value
- float
- X and Z component.
-
-
-
-
- Vec2
- A new Vec2 object.
-
-
-
-
-
- Vec2
- tostring
- Metafunction.
- Use tostring(vector).
-
-
- This
- Vec2
- Vec2.
-
-
-
-
- string
- A string showing the X and Y components of the Vec2.
-
-
-
-
-
- Vec2
- Vec2
- Normalize
- Get a copy of this Vec2 normalized to length 1.
- ()
-
-
- Vec2
- Normalized vector.
-
-
-
-
-
- Vec2
- Vec2
- Rotate
- Get a copy of this Vec2 rotated by the input rotation in degrees.
- (rot)
-
-
- rot
- float
- Rotation in degrees.
-
-
-
-
- Vec2
- Rotated Vec2.
-
-
-
-
-
- Vec2
- Vec2
- Lerp
- Get the linearly interpolated Vec2 between this Vec2 and the input Vec2 according to the input interpolation alpha.
- (vector)
-
-
- vector
- Vec2
- Target interpolation vector.
-
-
- alpha
- float
- Interpolation alpha in the range [0, 1].
-
-
-
-
- Vec2
- Linearly interpolated vector
-
-
-
-
-
- Vec2
- Vec2
- Cross
- Get the cross product of this Vec2 and the input Vec2.
- (vector)
-
-
- vector
- Vec2
- Input vector.
-
-
-
-
- Vec2
- Cross product.
-
-
-
-
-
- Vec2
- Vec2
- Dot
- Get the dot product of this Vec2 and the input Vec2.
- (vector)
-
-
- vector
- Vec2
- Input vector.
-
-
-
-
- float
- Dot product.
-
-
-
-
-
- Vec2
- Vec2
- Distance
- Get the distance between this Vec2 and the input Vec2.
- (vector)
-
-
- vector
- Vec2
- Input vector.
-
-
-
-
- float
- Distance.
-
-
-
-
-
- Vec2
- Vec2
- Length
- Get the length of this Vec2.
- ()
-
-
- float
- Length.
-
-
-
-
-
- Vec3
- Vec3
- Create a Vec3 object.
- (x, y, z)
-
-
- x
- float
- X component.
-
-
- y
- float
- Y component.
-
-
- z
- float
- Z component.
-
-
-
-
- Vec3
- A new Vec3 object.
-
-
-
-
-
- Vec3
- Vec3
- Create a Vec3 object.
- (value)
-
-
- value
- float
- X, Y, and Z component.
-
-
-
-
- Vec3
- A new Vec3 object.
-
-
-
-
-
- Vec3
- Vec3
- Normalize
- Get a copy of this Vec3 normalized to length 1.
- ()
-
-
- Vec3
- Normalized vector.
-
-
-
-
-
- Vec3
- Vec3
- Rotate
- Get a copy of this Vec3 rotated by the input Rotation object.
- (rot)
-
-
- rot
- Rotation
- Rotation object.
-
-
-
-
- Vec3
- Rotated Vec3.
-
-
-
-
-
- Vec3
- Vec3
- Lerp
- Get the linearly interpolated Vec3 between this Vec3 and the input Vec3 according to the input interpolation alpha.
- (vector)
-
-
- vector
- Vec3
- Target interpolation vector.
-
-
- alpha
- float
- Interpolation alpha in the range [0, 1].
-
-
-
-
- Vec3
- Linearly interpolated vector
-
-
-
-
-
- Vec3
- Vec3
- Cross
- Get the cross product of this Vec3 and the input Vec3.
- (vector)
-
-
- vector
- Vec3
- Input vector.
-
-
-
-
- Vec3
- Cross product.
-
-
-
-
-
- Vec3
- Vec3
- Dot
- Get the dot product of this Vec3 and the input Vec3.
- (vector)
-
-
- vector
- Vec3
- Input vector.
-
-
-
-
- float
- Dot product.
-
-
-
-
-
- Vec3
- Vec3
- Distance
- Get the distance between this Vec3 and the input Vec3.
- (vector)
-
-
- vector
- Vec3
- Input vector.
-
-
-
-
- float
- Distance.
-
-
-
-
-
- Vec3
- Vec3
- Length
- Get the length of this Vec3.
- ()
-
-
- float
- Length.
-
-
-
-
-
- Vec3
- tostring
- Metafunction.
- Use tostring(vector).
-
-
- This
- Vec3
- Vec3.
-
-
-
-
- string
- A string showing the X, Y, and Z components of the Vec3.
-
-
-
-
-
- View
- FadeIn
- Do a full-screen fade-in from black.
-
-
- speed
- float
- (default 1.0). Speed in "amount" per second. A value of 1 will make the fade take one second.
-
-
-
-
-
- View
- FadeOut
- Do a full-screen fade-to-black.
- The screen will remain black until a call to FadeIn.
-
-
- speed
- float
- (default 1.0). Speed in "amount" per second. A value of 1 will make the fade take one second.
-
-
-
-
-
- View
- SetCineBars
- Move black cinematic bars in from the top and bottom of the game window.
-
-
- height
- float
- __(default 30)__ Percentage of the screen to be covered
-
-
- speed
- float
- __(default 30)__ Coverage percent per second
-
-
-
-
-
- View
- SetFOV
- Set field of view.
-
-
- angle
- float
- in degrees (clamped to [10, 170])
-
-
-
-
-
- View
- GetFOV
- Get field of view.
-
-
- float
- current FOV angle in degrees
-
-
-
-
-
- View
- GetCameraType
- Shows the mode of the game camera.
-
-
- View.CameraType
- value used by the Main Camera.
-
-
-
-
-
- View
- GetCameraRoom
- Gets current room where camera is positioned.
-
-
- Objects.Room
- current room of the camera
-
-
-
-
-
- View
- SetPostProcessMode
- Sets the post-process effect mode, like negative or monochrome.
-
-
- effect
- View.PostProcessMode
- type to set.
-
-
-
-
-
- View
- SetPostProcessStrength
- Sets the post-process effect strength.
-
-
- strength
- float
- (default 1.0). How strong the effect is.
-
-
-
-
-
- View
- SetPostProcessTint
- Sets the post-process tint.
-
-
- tint
- Color
- value to use.
-
-
-
-
-
- View
- GetCameraPosition
- Gets current camera position.
-
-
- Vec3
- current camera position
-
-
-
-
-
- View
- GetCameraTarget
- Gets current camera target.
-
-
- Vec3
- current camera target
-
-
-
-
-
- View
- PlayFlyBy
- Enable FlyBy with specific ID
-
-
- flyby
- short
- (ID of flyby)
-
-
-
-
-
- View
- ResetObjCamera
- Reset object camera back to Lara and deactivate object camera.
-
-
-
- View
- FlashScreen
- Flash screen.
-
-
- color
- Color
- (default Color(255, 255, 255))
-
-
- speed
- float
- (default 1.0). Speed in "amount" per second. Value of 1 will make flash take one second. Clamped to [0.005, 1.0].
-
-
-
-
-
- View
- GetAspectRatio
- Get the display resolution's aspect ratio.
-
-
- float
- Display resolution's aspect ratio.
-
-
-
-
-
- EventSequence
- Create
- Create (but do not start) a new event sequence.
-
-
- name
- string
- A label to give the sequence; used to retrieve the timer later as well as internally by TEN.
-
-
- loop
- bool
- if true, the sequence will start again from its first timer once its final function has been called
-
-
- timerFormat
- ?table|bool
- same as in Timer. This is mainly for debugging. __This will not work properly if another sequence or timer is showing a countdown.__
-
-
- ...
- ...
- a variable number of pairs of arguments - a time in seconds, followed by the function (must be defined in the LevelFuncs table) to call once the time has elapsed, followed by another duration in seconds, another function name, etc. You can specify a function either by its name as a string, or by a table with the function name as the first member, followed by its arguments (see above example).
-
-
-
-
- EventSequence
- The inactive sequence.
-
-
-
-
-
- EventSequence
- Get
- Get an event sequence by its name.
-
-
- name
- string
- The label that was given to the sequence when it was created
-
-
-
-
- EventSequence
- The sequence
-
-
-
-
-
- EventSequence
- mySequence
- SetPaused
- Pause or unpause the sequence.
- If showing the remaining time on-screen, its color will be set to yellow (paused) or white (unpaused).
-
-
- p
- bool
- if true, the sequence will be paused; if false, it will be unpaused
-
-
-
-
-
- EventSequence
- mySequence
- IsPaused
- Get whether or not the sequence is paused
-
-
- bool
- true if the timer is paused, false if otherwise
-
-
-
-
-
- EventSequence
- mySequence
- Start
- Begin or unpause a sequence.
- If showing the remaining time on-screen, its color will be set to white.
-
-
-
- EventSequence
- mySequence
- Stop
- Stop the sequence.
-
-
-
- EventSequence
- mySequence
- IsActive
- Get whether or not the sequence is active
-
-
- bool
- true if the sequence is active, false if otherwise
-
-
-
-
-
- Timer
- Create
- Create (but do not start) a new timer.
- You have the option of displaying the remaining time on the clock. Timer format details:
-
-
- name
- string
- A label to give this timer; used to retrieve the timer later. __Do not give your timers a name beginning with __TEN, as this is reserved for timers used by other internal libaries__.
-
-
- totalTime
- number
- The duration of the timer, in seconds
-
-
- loop
- bool
- if true, the timer will start again immediately after the time has elapsed
-
-
- timerFormat
- ?table|bool
- If a table is given, the remaining time will be shown as a string, formatted according to the values in the table. If true, the remaining seconds, rounded up, will show at the bottom of the screen. If false, the remaining time will not be shown on screen.
-
-
- func
- func
- The LevelFunc function to call when the time is up
-
-
- ...
- ...
- a variable number of arguments with which the above function will be called
-
-
-
-
- Timer
- The timer in its paused state
-
-
-
-
-
- Timer
- Get
- Get a timer by its name.
-
-
- name
- string
- The label that was given to the timer when it was created
-
-
-
-
- Timer
- The timer
-
-
-
-
-
- Timer
- myTimer
- SetFunction
- Give the timer a new function and args
-
-
- func
- function
- The LevelFunc member to call when the time is up
-
-
- ...
- ...
- a variable number of arguments with which the above function will be called
-
-
-
-
-
- Timer
- myTimer
- Start
- Begin or unpause a timer.
- If showing the remaining time on-screen, its color will be set to white.
-
-
-
- Timer
- myTimer
- Stop
- Stop the timer.
-
-
-
- Timer
- myTimer
- IsActive
- Get whether or not the timer is active
-
-
- bool
- true if the timer is active, false if otherwise
-
-
-
-
-
- Timer
- myTimer
- SetPaused
- Pause or unpause the timer.
- If showing the remaining time on-screen, its color will be set to yellow (paused) or white (unpaused).
-
-
- p
- bool
- if true, the timer will be paused; if false, it would be unpaused
-
-
-
-
-
- Timer
- myTimer
- IsPaused
- Get whether or not the timer is paused
-
-
- bool
- true if the timer is paused, false if otherwise
-
-
-
-
-
- Timer
- myTimer
- GetRemainingTime
- Get the remaining time for a timer.
-
-
- float
- the time in seconds remaining on the clock
-
-
-
-
-
- Timer
- myTimer
- SetRemainingTime
- Set the remaining time for a timer
-
-
- remainingTime
- number
- the new time remaining for the timer
-
-
-
-
-
- Timer
- myTimer
- GetTotalTime
- Get the total time for a timer.
- This is the amount of time the timer will start with, as well as when starting a new loop
-
-
- float
- the timer's total time
-
-
-
-
-
- Timer
- myTimer
- SetTotalTime
- Set the total time for a timer
-
-
- totalTime
- number
- timer's new total time
-
-
-
-
-
- Timer
- myTimer
- SetLooping
- Set whether or not the timer loops
-
-
- looping
- bool
- whether or not the timer loops
-
-
-
+
+
+ Color
+ Color
+
+
+ R
+ int
+ red component
+
+
+ G
+ int
+ green component
+
+
+ B
+ int
+ blue component
+
+
+
+
+ Color
+ A new Color object.
+
+
+
+
+
+ Color
+ Color
+
+
+ R
+ int
+ red component
+
+
+ G
+ int
+ green component
+
+
+ B
+ int
+ blue component
+
+
+ A
+ int
+ alpha component (255 is opaque, 0 is invisible)
+
+
+
+
+ Color
+ A new Color object.
+
+
+
+
+
+ Color
+ tostring
+
+
+ color
+ Color
+ this color
+
+
+
+
+ string
+ A string showing the r, g, b, and a values of the color
+
+
+
+
+
+ View.DisplaySprite
+ DisplaySprite
+ Create a DisplaySprite object.
+
+
+ ID
+ Objects.ObjID
+ of the sprite sequence object.
+
+
+ int
+ int
+ spriteID ID of the sprite in the sequence.
+
+
+ pos
+ Vec2
+ Display position in percent.
+
+
+ rot
+ float
+ Rotation in degrees.
+
+
+ scale
+ Vec2
+ Horizontal and vertical scale in percent. Scaling is interpreted by the DisplaySpriteEnum.ScaleMode passed to the Draw() function call.
+
+
+ color
+ Color
+ Color. __Default: Color(255, 255, 255, 255)__
+
+
+
+
+ DisplaySprite
+ A new DisplaySprite object.
+
+
+
+
+
+ View.DisplaySprite
+ DisplaySprite
+ GetObjectID
+ Get the object ID of the sprite sequence object used by the display sprite.
+ ()
+
+
+ Objects.ObjID
+ Sprite sequence object ID.
+
+
+
+
+
+ View.DisplaySprite
+ DisplaySprite
+ GetSpriteID
+ Get the sprite ID in the sprite sequence object used by the display sprite.
+ ()
+
+
+ int
+ Sprite ID in the sprite sequence object.
+
+
+
+
+
+ View.DisplaySprite
+ DisplaySprite
+ GetPosition
+ Get the display position of the display sprite in percent.
+ ()
+
+
+ Vec2
+ Display position in percent.
+
+
+
+
+
+ View.DisplaySprite
+ DisplaySprite
+ GetRotation
+ Get the rotation of the display sprite in degrees.
+ ()
+
+
+ float
+ Rotation in degrees.
+
+
+
+
+
+ View.DisplaySprite
+ DisplaySprite
+ GetScale
+ Get the horizontal and vertical scale of the display sprite in percent.
+ ()
+
+
+ Vec2
+ Horizontal and vertical scale in percent.
+
+
+
+
+
+ View.DisplaySprite
+ DisplaySprite
+ GetColor
+ Get the color of the display sprite.
+ ()
+
+
+ Color
+ Color.
+
+
+
+
+
+ View.DisplaySprite
+ DisplaySprite
+ SetObjectID
+ Set the sprite sequence object ID used by the display sprite.
+ (Objects.ObjID)
+
+
+ New
+ Objects.ObjID
+ sprite sequence object ID.
+
+
+
+
+
+ View.DisplaySprite
+ DisplaySprite
+ SetSpriteID
+ Set the sprite ID in the sprite sequence object used by the display sprite.
+ (int)
+
+
+ New
+ int
+ sprite ID in the sprite sequence object.
+
+
+
+
+
+ View.DisplaySprite
+ DisplaySprite
+ SetPosition
+ Set the display position of the display sprite in percent.
+ (Vec2)
+
+
+ New
+ Vec2
+ display position in percent.
+
+
+
+
+
+ View.DisplaySprite
+ DisplaySprite
+ SetRotation
+ Set the rotation of the display sprite in degrees.
+ (float)
+
+
+ New
+ float
+ rotation in degrees.
+
+
+
+
+
+ View.DisplaySprite
+ DisplaySprite
+ SetScale
+ Set the horizontal and vertical scale of the display sprite in percent.
+ (Vec2)
+
+
+ New
+ float
+ horizontal and vertical scale in percent.
+
+
+
+
+
+ View.DisplaySprite
+ DisplaySprite
+ SetColor
+ Set the color of the display sprite.
+ (Color)
+
+
+ New
+ float
+ color.
+
+
+
+
+
+ View.DisplaySprite
+ DisplaySprite
+ Draw
+ Draw the display sprite in display space for the current frame.
+
+
+ priority
+ int
+ Draw priority. Can be thought of as a layer, with higher values having precedence. __Default: 0__
+
+
+ alignMode
+ View.AlignMode
+ Align mode interpreting an offset from the sprite's position. __Default: View.AlignMode.CENTER__
+
+
+ scaleMode
+ View.ScaleMode
+ Scale mode interpreting the display sprite's horizontal and vertical scale. __Default: View.ScaleMode.FIT__
+
+
+ blendMode
+ Effects.BlendID
+ Blend mode. __Default: Effects.BlendID.ALPHABLEND__
+
+
+
+
+
+ Effects
+ EmitLightningArc
+ Emit a lightning arc.
+
+
+ src
+ Vec3
+
+
+ dest
+ Vec3
+
+
+ color
+ Color
+ (default Color(255, 255, 255))
+
+
+ lifetime
+ float
+ Lifetime in seconds. Clamped to [0, 4.233] for now because of strange internal maths. (default 1.0)
+
+
+ amplitude
+ int
+ "strength" of the lightning - the higher the value, the "taller" the arcs. Clamped to [1, 255]. (default 20)
+
+
+ beamWidth
+ int
+ Clamped to [1, 127]. (default 2)
+
+
+ detail
+ int
+ Higher numbers equal more segments, but it's not a 1:1 correlation. Clamped to [1, 127]. (default 10)
+
+
+ smooth
+ bool
+ If true, the arc will have large, smooth curves; if false, it will have small, jagged spikes. (default false)
+
+
+ endDrift
+ bool
+ If true, the end of the arc will be able to gradually drift away from its destination in a random direction (default false)
+
+
+
+
+
+ Effects
+ EmitParticle
+ Emit a particle.
+ See the sprite editor in WadTool for DEFAULT_SPRITES to see a list of sprite indices.
+
+
+ pos
+ Vec3
+
+
+ velocity
+ Vec3
+
+
+ spriteIndex
+ int
+ an index of a sprite in DEFAULT_SPRITES object.
+
+
+ gravity
+ int
+ (default 0) Specifies whether particle will fall (positive values) or ascend (negative values) over time. Clamped to [-32768, 32767], but values between -1000 and 1000 are recommended; values too high or too low (e.g. under -2000 or above 2000) will cause the velocity of the particle to "wrap around" and switch directions.
+
+
+ rot
+ float
+ (default 0) specifies a speed with which it will rotate (0 = no rotation, negative = anticlockwise rotation, positive = clockwise rotation).
+
+
+ startColor
+ Color
+ (default Color(255, 255, 255)) color at start of life
+
+
+ endColor
+ Color
+ (default Color(255, 255, 255)) color to fade to - at the time of writing this fade will finish long before the end of the particle's life due to internal maths
+
+
+ blendMode
+ Effects.BlendID
+ (default TEN.Effects.BlendID.ALPHABLEND) How will we blend this with its surroundings?
+
+
+ startSize
+ int
+ (default 10) Size on spawn. A value of 15 is approximately the size of Lara's head.
+
+
+ endSize
+ int
+ (default 0) Size on death - the particle will linearly shrink or grow to this size during its lifespan
+
+
+ lifetime
+ float
+ (default 2) Lifespan in seconds
+
+
+ damage
+ bool
+ (default false) specifies whether particle can damage Lara (does a very small amount of damage, like the small lava emitters in TR1)
+
+
+ poison
+ bool
+ (default false) specifies whether particle can poison Lara
+
+
+
+
+
+ Effects
+ EmitShockwave
+ Emit a shockwave, similar to that seen when a harpy projectile hits something.
+
+
+ pos
+ Vec3
+ Origin position
+
+
+ innerRadius
+ int
+ (default 0) Initial inner radius of the shockwave circle - 128 will be approx a click, 512 approx a block
+
+
+ outerRadius
+ int
+ (default 128) Initial outer radius of the shockwave circle
+
+
+ color
+ Color
+ (default Color(255, 255, 255))
+
+
+ lifetime
+ float
+ (default 1.0) Lifetime in seconds (max 8.5 because of inner maths weirdness)
+
+
+ speed
+ int
+ (default 50) Initial speed of the shockwave's expansion (the shockwave will always slow as it goes)
+
+
+ angle
+ int
+ (default 0) Angle about the X axis - a value of 90 will cause the shockwave to be entirely vertical
+
+
+ hurtsLara
+ bool
+ (default false) If true, the shockwave will hurt Lara, with the damage being relative to the shockwave's current speed
+
+
+
+
+
+ Effects
+ EmitLight
+ Emit dynamic light that lasts for a single frame.
+ If you want a light that sticks around, you must call this each frame.
+
+
+ pos
+ Vec3
+
+
+ color
+ Color
+ (default Color(255, 255, 255))
+
+
+ radius
+ int
+ (default 20) corresponds loosely to both intensity and range
+
+
+
+
+
+ Effects
+ EmitBlood
+ Emit blood.
+
+
+ pos
+ Vec3
+
+
+ count
+ int
+ (default 1) "amount" of blood. Higher numbers won't add more blood but will make it more "flickery", with higher numbers turning it into a kind of red orb.
+
+
+
+
+
+ Effects
+ EmitFire
+ Emit fire for one frame.
+ Will not hurt Lara. Call this each frame if you want a continuous fire.
+
+
+ pos
+ Vec3
+
+
+ size
+ float
+ (default 1.0)
+
+
+
+
+
+ Effects
+ MakeExplosion
+ Make an explosion.
+ Does not hurt Lara
+
+
+ pos
+ Vec3
+
+
+ size
+ float
+ (default 512.0) this will not be the size of the sprites, but rather the distance between the origin and any additional sprites
+
+
+ shockwave
+ bool
+ (default false) if true, create a very faint white shockwave which will not hurt Lara
+
+
+
+
+
+ Effects
+ MakeEarthquake
+ Make an earthquake
+
+
+ strength
+ int
+ (default 100) How strong should the earthquake be? Increasing this value also increases the lifespan of the earthquake.
+
+
+
+
+
+ Flow
+ AddLevel
+ Add a level to the Flow.
+
+
+ level
+ Flow.Level
+ a level object
+
+
+
+
+
+ Flow
+ SetIntroImagePath
+ Image to show when loading the game.
+ Must be a .jpg or .png image.
+
+
+ path
+ string
+ the path to the image, relative to the TombEngine exe
+
+
+
+
+
+ Flow
+ SetTitleScreenImagePath
+ Image to show in the background of the title screen.
+ Must be a .jpg or .png image.
+__(not yet implemented)__
+
+
+ path
+ string
+ the path to the image, relative to the TombEngine exe
+
+
+
+
+
+ Flow
+ EnableLaraInTitle
+ Enable or disable Lara drawing in title flyby.
+ Must be true or false
+
+
+ enabled
+ bool
+ true or false
+
+
+
+
+
+ Flow
+ EnableLevelSelect
+ Enable or disable level selection in title flyby.
+ Must be true or false
+
+
+ enabled
+ bool
+ true or false
+
+
+
+
+
+ Flow
+ EnableLoadSave
+ Enable or disable saving and loading of savegames.
+
+
+ enabled
+ bool
+ true or false.
+
+
+
+
+
+ Flow
+ EnableFlyCheat
+ Enable or disable DOZY mode (fly cheat).
+ Must be true or false
+
+
+ enabled
+ bool
+ true or false
+
+
+
+
+
+ Flow
+ EnablePointFilter
+ Enable or disable point texture filter.
+ Must be true or false
+
+
+ enabled
+ bool
+ true or false
+
+
+
+
+
+ Flow
+ EnableMassPickup
+ Enable or disable mass pickup.
+ Must be true or false
+
+
+ enabled
+ bool
+ true or false
+
+
+
+
+
+ Flow
+ GetLevel
+ Returns the level by index.
+ Indices depend on the order in which AddLevel was called; the first added will
+have an ID of 0, the second an ID of 1, and so on.
+
+
+ index
+ int
+ of the level
+
+
+
+
+ Flow.Level
+ the level indicated by the id
+
+
+
+
+
+ Flow
+ GetCurrentLevel
+ Returns the level that the game control is running in that moment.
+
+
+ Flow.Level
+ the current level
+
+
+
+
+
+ Flow
+ EndLevel
+ Finishes the current level, with optional level index and start position index provided.
+ If level index is not provided or is zero, jumps to next level. If level index is more than
+level count, jumps to title. If LARA\_START\_POS objects are present in level, player will be
+teleported to such object with OCB similar to provided second argument.
+
+
+ index
+ int
+ level index (default 0)
+
+
+ startPos
+ int
+ player start position (default 0)
+
+
+
+
+
+ Flow
+ GetGameStatus
+ Get current game status, such as normal game loop, exiting to title, etc.
+
+
+ Flow.GameStatus
+ the current game status
+
+
+
+
+
+ Flow
+ SaveGame
+ Save the game to a savegame slot.
+
+
+ slotID
+ int
+ ID of the savegame slot to save to.
+
+
+
+
+
+ Flow
+ LoadGame
+ Load the game from a savegame slot.
+
+
+ slotID
+ int
+ ID of the savegame slot to load from.
+
+
+
+
+
+ Flow
+ DeleteSaveGame
+ Delete a savegame.
+
+
+ slotID
+ int
+ ID of the savegame slot to clear.
+
+
+
+
+
+ Flow
+ DoesSaveGameExist
+ Check if a savegame exists.
+
+
+ slotID
+ int
+ ID of the savegame slot to check.
+
+
+
+
+ bool
+ true if the savegame exists, false if not.
+
+
+
+
+
+ Flow
+ GetSecretCount
+ Returns the player's current per-game secret count.
+
+
+ int
+ Current game secret count.
+
+
+
+
+
+ Flow
+ SetSecretCount
+ Sets the player's current per-game secret count.
+
+
+ count
+ int
+ new secret count.
+
+
+
+
+
+ Flow
+ AddSecret
+ Adds one secret to current level secret count and also plays secret music track.
+ The index argument corresponds to the secret's unique ID, the same that would go in a secret trigger's Param.
+
+
+ index
+ int
+ an index of current level's secret (must be from 0 to 31).
+
+
+
+
+
+ Flow
+ SetTotalSecretCount
+ Total number of secrets in game.
+ Must be an integer value (0 means no secrets).
+
+
+ total
+ int
+ number of secrets
+
+
+
+
+
+ Flow
+ SetSettings
+
+
+ settings
+ Flow.Settings
+ a settings object
+
+
+
+
+
+ Flow
+ SetAnimations
+
+
+ animations
+ Flow.Animations
+ an animations object
+
+
+
+
+
+ Flow
+ SetStrings
+ Set string variable keys and their translations.
+
+
+ table
+ tab
+ array-style table with strings
+
+
+
+
+
+ Flow
+ GetString
+ Get translated string.
+
+
+ string
+ key
+ key for translated string
+
+
+
+
+
+ Flow
+ SetLanguageNames
+ Set language names for translations.
+ Specify which translations in the strings table correspond to which languages.
+
+
+ table
+ tab
+ array-style table with language names
+
+
+
+
+
+ Flow.Fog
+ Fog
+
+
+ color
+ Color
+ RGB color
+
+
+ Min
+ int
+ Distance fog starts (in Sectors)
+
+
+ Max
+ int
+ Distance fog ends (in Sectors)
+
+
+
+
+ Fog
+ A fog object.
+
+
+
+
+
+ Flow.InventoryItem
+ InventoryItem
+ Create an InventoryItem.
+
+
+ nameKey
+ string
+ key for the item's (localised) name.
+Corresponds to an entry in strings.lua.
+
+
+ objectID
+ Objects.ObjID
+ object ID of the inventory object to change
+
+
+ yOffset
+ float
+ y-axis offset (positive values move the item down).
+A value of about 100 will cause the item to display directly below its usual position.
+
+
+ scale
+ float
+ item size (1 being standard size).
+A value of 0.5 will cause the item to render at half the size,
+and a value of 2 will cause the item to render at twice the size.
+
+
+ rot
+ Rotation
+ rotation around x, y, and z axes
+
+
+ axis
+ RotationAxis
+ Axis to rotate around when the item is observed at in the inventory.
+Note that this is entirely separate from the `rot` field described above.
+Must one of the following:
+ X
+ Y
+ Z
+e.g. `myItem.rotAxisWhenCurrent = RotationAxis.X`
+
+
+ meshBits
+ int
+ __Not currently implemented__ (will have no effect regardless of what you set it to)
+
+
+ action
+ ItemAction
+ is this usable, equippable, combineable or examinable?
+Must be one of:
+ EQUIP
+ USE
+ COMBINE
+ EXAMINE
+e.g. `myItem.action = ItemAction.EXAMINE`
+
+
+
+
+ InventoryItem
+ an InventoryItem
+
+
+
+
+
+ Flow.Level
+ Level
+ Make a new Level object.
+
+
+ Level
+ a Level object
+
+
+
+
+
+ Flow.SkyLayer
+ SkyLayer
+
+
+ color
+ Color
+ RGB color
+
+
+ speed
+ int
+ cloud speed
+
+
+
+
+ SkyLayer
+ A SkyLayer object.
+
+
+
+
+
+ Input
+ Vibrate
+ Vibrate the game controller if the function is available and the setting is on.
+
+
+ strength
+ float
+ Vibration strength.
+
+
+ time
+ float
+ __(default 0.3)__ Vibration time in seconds.
+
+
+
+
+
+ Input
+ KeyIsHeld
+ Check if an action key is being held.
+
+
+ action
+ Input.ActionID
+ Action ID to check.
+
+
+
+
+
+ Input
+ KeyIsHit
+ Check if an action key is being hit or clicked.
+
+
+ action
+ Input.ActionID
+ Action ID to check.
+
+
+
+
+
+ Input
+ KeyPush
+ Simulate an action key push.
+
+
+ action
+ Input.ActionID
+ Action ID to push.
+
+
+
+
+
+ Input
+ KeyClear
+ Clear an action key.
+
+
+ action
+ Input.ActionID
+ Action ID to clear.
+
+
+
+
+
+ Input
+ GetMouseDisplayPosition
+ Get the display position of the cursor in percent.
+ ()
+
+
+ Vec2
+ Cursor display position in percent.
+
+
+
+
+
+ Inventory
+ GiveItem
+ Add an item to the player's inventory.
+
+
+ objectID
+ Objects.ObjID
+ Object ID of the item to add.
+
+
+ count
+ int
+ The amount of items to add. Default is the yield from a single pickup, e.g. 1 from a medipack, 12 from a flare pack.
+
+
+ addToPickupSummary
+ bool
+ If true, display the item in the pickup summary. Default is false.
+
+
+
+
+
+ Inventory
+ TakeItem
+ Remove an item from the player's inventory.
+
+
+ Object
+ Objects.ObjID
+ ID of the item to remove.
+
+
+ count
+ int
+ The amount of items to remove. Default is the yield from a single pickup, e.g. 1 from a medipack, 12 from a flare pack.
+
+
+
+
+
+ Inventory
+ GetItemCount
+ Get the amount of an item held in the player's inventory.
+
+
+ objectID
+ Objects.ObjID
+ Object ID of the item to check.
+
+
+
+
+ int
+ The amount of items. -1 indicates infinity.
+
+
+
+
+
+ Inventory
+ SetItemCount
+ Set the amount of an item in the player's inventory.
+
+
+ objectID
+ Objects.ObjID
+ Object ID of the item amount to set.
+
+
+ count
+ int
+ The amount of items to set. -1 indicates infinity.
+
+
+
+
+
+ Logic
+ AddCallback
+ Register a function as a callback.
+
+
+ point
+ CallbackPoint
+ When should the callback be called?
+
+
+ func
+ LevelFunc
+ The function to be called (must be in the `LevelFuncs` hierarchy). Will receive, as an argument, the time in seconds since the last frame.
+
+
+
+
+
+ Logic
+ RemoveCallback
+ Deregister a function as a callback.
+ Will have no effect if the function was not registered as a callback
+
+
+ point
+ CallbackPoint
+ The callback point the function was registered with. See @{AddCallback}
+
+
+ func
+ LevelFunc
+ The function to remove; must be in the LevelFuncs hierarchy.
+
+
+
+
+
+ Logic
+ HandleEvent
+ Attempt to find an event set and execute a particular event from it.
+
+
+ name
+ string
+ Name of the event set to find.
+
+
+ type
+ EventType
+ Event to execute.
+
+
+ activator
+ Objects.Moveable
+ Optional activator. Default is the player object.
+
+
+
+
+
+ Logic
+ EnableEvent
+ Attempt to find an event set and enable specified event in it.
+
+
+ name
+ string
+ Name of the event set to find.
+
+
+ type
+ EventType
+ Event to enable.
+
+
+
+
+
+ Logic
+ DisableEvent
+ Attempt to find an event set and disable specified event in it.
+
+
+ name
+ string
+ Name of the event set to find.
+
+
+ type
+ EventType
+ Event to disable.
+
+
+
+
+
+ Objects.AIObject
+ AIObject
+ GetPosition
+ Get the object's position
+
+
+ Vec3
+ a copy of the object's position
+
+
+
+
+
+ Objects.AIObject
+ AIObject
+ SetPosition
+ Set the object's position
+
+
+ position
+ Vec3
+ the new position of the object
+
+
+
+
+
+ Objects.AIObject
+ AIObject
+ GetRotationY
+ Get the object's Y-axis rotation.
+ To the best of my knowledge, the rotation of an AIObject has no effect.
+
+
+ number
+ the object's Y-axis rotation
+
+
+
+
+
+ Objects.AIObject
+ AIObject
+ SetRotationY
+ Set the object's Y-axis rotation.
+ To the best of my knowledge, the rotation of an AIObject has no effect.
+
+
+ rotation
+ number
+ The object's new Y-axis rotation
+
+
+
+
+
+ Objects.AIObject
+ AIObject
+ GetName
+ Get the object's unique string identifier
+
+
+ string
+ the object's name
+
+
+
+
+
+ Objects.AIObject
+ AIObject
+ SetName
+ Set the object's name (its unique string identifier)
+
+
+ name
+ string
+ The object's new name
+
+
+
+
+
+ Objects.AIObject
+ AIObject
+ GetRoom
+ Get the current room of the object
+
+
+ Room
+ current room of the object
+
+
+
+
+
+ Objects.AIObject
+ AIObject
+ GetRoomNumber
+ Get the current room number of the object
+
+
+ int
+ number representing the current room of the object
+
+
+
+
+
+ Objects.AIObject
+ AIObject
+ SetRoomNumber
+ Set room number of the object
+ This is used in conjunction with SetPosition to teleport the object to a new room.
+
+
+ ID
+ int
+ the ID of the new room
+
+
+
+
+
+ Objects.AIObject
+ AIObject
+ GetObjectID
+ Retrieve the object ID
+
+
+ int
+ a number representing the ID of the object
+
+
+
+
+
+ Objects.AIObject
+ AIObject
+ SetObjectID
+ Change the object's ID.
+ This will change the type of AI object it is.
+ Note that a baddy will gain the behaviour of the tile it's on _before_ said baddy is triggered.
+ This means that changing the type of an AI object beneath a moveable will have no effect.
+ Instead, this function can be used to change an object that the baddy isn't standing on.
+ For example, you could have a pair of AI_GUARD objects, and change one or the other two
+ AI_PATROL_1 based on whether the player has a certain item or not.
+
+
+ ID
+ Objects.ObjID
+ the new ID
+
+
+
+
+
+ Objects.Camera
+ Camera
+ GetPosition
+ Get the camera's position
+
+
+ Vec3
+ a copy of the camera's position
+
+
+
+
+
+ Objects.Camera
+ Camera
+ SetPosition
+ Set the camera's position
+
+
+ position
+ Vec3
+ the new position of the camera
+
+
+
+
+
+ Objects.Camera
+ Camera
+ GetName
+ Get the camera's unique string identifier
+
+
+ string
+ the camera's name
+
+
+
+
+
+ Objects.Camera
+ Camera
+ SetName
+ Set the camera's name (its unique string identifier)
+
+
+ name
+ string
+ The camera's new name
+
+
+
+
+
+ Objects.Camera
+ Camera
+ GetRoom
+ Get the current room of the camera
+
+
+ Room
+ current room of the camera
+
+
+
+
+
+ Objects.Camera
+ Camera
+ GetRoomNumber
+ Get the current room number of the camera
+
+
+ int
+ number representing the current room of the camera
+
+
+
+
+
+ Objects.Camera
+ Camera
+ SetRoomNumber
+ Set room of camera
+ This is used in conjunction with SetPosition to teleport the camera to a new room.
+
+
+ ID
+ int
+ the ID of the new room
+
+
+
+
+
+ Objects.Camera
+ Camera
+ PlayCamera
+ Active the camera during that frame.
+
+
+ Target
+ Moveable
+ If you put a moveable, the camera will look at it. Otherwise, it will look at Lara.
+
+
+
+
+
+ Objects.LaraObject
+ LaraObject
+ SetPoison
+ Set Lara poison
+
+
+ Poison
+ int
+ ; maximum value is 128 (default 0)
+
+
+
+
+
+ Objects.LaraObject
+ LaraObject
+ GetPoison
+ Get poison potency of Lara
+
+
+ int
+ current poison potency
+
+
+
+
+
+ Objects.LaraObject
+ LaraObject
+ SetAir
+ Set air value of Lara
+
+
+ Air
+ int
+ value to give Lara. Maximum value is 1800.
+
+
+
+
+
+ Objects.LaraObject
+ LaraObject
+ GetAir
+ Get air value of Lara
+
+
+ int
+ current air value
+
+
+
+
+
+ Objects.LaraObject
+ LaraObject
+ SetWet
+ Set wetness value of Lara (causes dripping)
+
+
+ Wetness
+ int
+ value. Maximum 255
+
+
+
+
+
+ Objects.LaraObject
+ LaraObject
+ GetWet
+ Get wetness value of Lara
+
+
+ int
+ current wetness value
+
+
+
+
+
+ Objects.LaraObject
+ LaraObject
+ SetStamina
+ Set sprint energy value of Lara
+
+
+ stamina
+ int
+ to give to Lara; maximum value is 120.
+
+
+
+
+
+ Objects.LaraObject
+ LaraObject
+ GetStamina
+ Get stamina value of Lara
+
+
+ int
+ current sprint value
+
+
+
+
+
+ Objects.LaraObject
+ Moveable
+ GetAirborne
+ Get the moveable's airborne status
+
+
+ (bool)
+ true if Lara state must react to aerial forces.
+
+
+
+
+
+ Objects.LaraObject
+ Moveable
+ SetAirborne
+ Set the moveable's airborne status
+
+
+ New
+ (bool)
+ airborn status for Lara.
+
+
+
+
+
+ Objects.LaraObject
+ LaraObject
+ UndrawWeapon
+ Lara will undraw her weapon if it is drawn and throw away a flare if she is currently holding one.
+
+
+
+ Objects.LaraObject
+ LaraObject
+ ThrowAwayTorch
+ Lara will throw away the torch if she currently holds one in her hand.
+
+
+
+ Objects.LaraObject
+ LaraObject
+ GetHandStatus
+ Get actual hand status of Lara
+
+
+ int
+ hand status 0=HandsFree, 1=Busy(climbing,etc), 2=WeaponDraw, 3=WeaponUndraw, 4=WeaponInHand.
+
+
+
+
+
+ Objects.LaraObject
+ LaraObject
+ GetWeaponType
+ Get actual weapon type of Lara
+
+
+ int
+ weapon type 0=None, 1=Pistols, 2=Revolver, 3=Uzi, 4=Shotgun, 5=HK, 6=Crossbow, 7=Flare, 8=Torch, 9=GrenadeLauncher, 10=Harpoon, 11=RocketLauncher.
+
+
+
+
+
+ Objects.LaraObject
+ LaraObject
+ SetWeaponType
+ Set Lara weapon type
+
+
+ weaponType
+ LaraWeaponType
+ Must be one of:
+ NONE
+ PISTOLS
+ REVOLVER
+ UZI
+ SHOTGUN
+ HK
+ CROSSBOW
+ FLARE
+ TORCH
+ GRENADELAUNCHER
+ HARPOONGUN
+ ROCKETLAUNCHER
+
+
+ activate
+ bool
+ true = let her also draw the weapons, set torch lit. false = let Laras new weapons remain holstered until she draws them, set torch unlit.
+
+
+
+
+
+ Objects.LaraObject
+ LaraObject
+ GetAmmoType
+ Get player weapon ammo type.
+
+
+ int
+ player weapon ammo type
+
+
+
+
+
+ Objects.LaraObject
+ LaraObject
+ GetAmmoCount
+ Get current weapon's ammo count
+
+
+ int
+ current ammo count (-1 if infinite)
+
+
+
+
+
+ Objects.LaraObject
+ LaraObject
+ GetVehicle
+ Get current vehicle, if it exists
+
+
+ Objects.Moveable
+ current vehicle (nil if no vehicle present)
+
+
+
+
+
+ Objects.LaraObject
+ LaraObject
+ GetTarget
+ Get the player's current targeted moveable (if it exists).
+
+
+ Objects.Moveable
+ Target moveable (nil if the player is not currently targeting a moveable).
+
+
+
+
+
+ Objects.LaraObject
+ LaraObject
+ GetInteractedMoveable
+ Get the player's current interacted moveable (if it exists).
+
+
+ Objects.Moveable
+ Interacted moveable (nil if the player is not interacting with a moveable).
+
+
+
+
+
+ Objects.LaraObject
+ LaraObject
+ TorchIsLit
+ Get current light state of the torch, if it exists
+
+
+ bool
+ is torch currently lit or not? (false if no torch exists)
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ For more information on each parameter, see the
+associated getters and setters.
+ If you do not know what to set for these,
+most can just be ignored (see usage).
+
+
+ object
+ Objects.ObjID
+ ID
+
+
+ name
+ string
+ Lua name of the item
+
+
+ position
+ Vec3
+ position in level
+
+
+ rotation
+ Rotation
+ rotation about x, y, and z axes (default Rotation(0, 0, 0))
+
+
+ roomID
+ int
+ room ID item is in (default: calculated automatically)
+
+
+ animNumber
+ int
+ anim number
+
+
+ frameNumber
+ int
+ frame number
+
+
+ hp
+ int
+ HP of item
+
+
+ OCB
+ int
+ ocb of item
+
+
+ AIBits
+ table
+ table with AI bits (default { 0, 0, 0, 0, 0, 0 })
+
+
+
+
+ Moveable
+ A new Moveable object (a wrapper around the new object)
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ Explode
+ Explode item.
+ This also kills and disables item.
+
+
+
+ Objects.Moveable
+ Moveable
+ Shatter
+ Shatter item.
+ This also kills and disables item.
+
+
+
+ Objects.Moveable
+ Moveable
+ SetEffect
+ Set effect to moveable
+
+
+ effect
+ Effects.EffectID
+ Type of effect to assign.
+
+
+ timeout
+ float
+ time (in seconds) after which effect turns off (optional).
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ SetCustomEffect
+ Set custom colored burn effect to moveable
+
+
+ Color1
+ Color
+ color the primary color of the effect (also used for lighting).
+
+
+ Color2
+ Color
+ color the secondary color of the effect.
+
+
+ timeout
+ float
+ time (in seconds) after which effect turns off (optional).
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ GetEffect
+ Get current moveable effect
+
+
+ Effects.EffectID
+ effect type currently assigned to moveable.
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ GetStatus
+ Get the moveable's status.
+ ()
+
+
+ Objects.MoveableStatus
+ The moveable's status.
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ SetStatus
+ Set the moveable's status.
+ ()
+
+
+ status
+ Objects.MoveableStatus
+ The new status of the moveable.
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ SetOnHit
+ Set the name of the function to be called when the moveable is shot by Lara.
+ Note that this will be triggered twice when shot with both pistols at once.
+
+
+ callback
+ function
+ function in LevelFuncs hierarchy to call when moveable is shot
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ SetOnKilled
+ Set the name of the function to be called when the moveable is destroyed/killed
+ Note that enemy death often occurs at the end of an animation, and not at the exact moment
+ the enemy's HP becomes zero.
+
+
+ callback
+ function
+ function in LevelFuncs hierarchy to call when enemy is killed
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ GetObjectID
+ Retrieve the object ID
+
+
+ int
+ a number representing the ID of the object
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ SetObjectID
+ Change the object's ID.
+ This will literally change the object.
+
+
+ ID
+ Objects.ObjID
+ the new ID
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ GetState
+ Retrieve the index of the current state.
+ This corresponds to the number shown in the item's state ID field in WadTool.
+
+
+ int
+ the index of the active state
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ SetState
+ Set the object's state to the one specified by the given index.
+ Performs no bounds checking. *Ensure the number given is correct, else
+ object may end up in corrupted animation state.*
+
+
+ index
+ int
+ the index of the desired state
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ GetAnim
+ Retrieve the index of the current animation.
+ This corresponds to the number shown in the item's animation list in WadTool.
+
+
+ int
+ the index of the active animation
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ SetAnim
+ Set the object's animation to the one specified by the given index.
+ Performs no bounds checking. *Ensure the number given is correct, else
+ object may end up in corrupted animation state.*
+
+
+ index
+ int
+ the index of the desired anim
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ GetFrame
+ Retrieve frame number.
+ This is the current frame of the object's active animation.
+
+
+ int
+ the current frame of the active animation
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ SetVelocity
+ Set the object's velocity to specified value.
+ In most cases, only Z and Y components are used as forward and vertical velocity.
+ In some cases, primarily NPCs, X component is used as side velocity.
+
+
+ velocity
+ Vec3
+ velocity represented as vector
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ GetVelocity
+ Get the object's velocity.
+ In most cases, only Z and Y components are used as forward and vertical velocity.
+ In some cases, primarily NPCs, X component is used as side velocity.
+
+
+ Vec3
+ current object velocity
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ SetFrame
+ Set frame number.
+ This will move the animation to the given frame.
+ The number of frames in an animation can be seen under the heading "End frame" in
+ the WadTool animation editor. If the animation has no frames, the only valid argument
+ is -1.
+
+
+ frame
+ int
+ the new frame number
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ GetSlotHP
+ Get HP definded for that object type (hit points/health points) (Read Only).
+
+
+ ID
+ int
+ of the moveable slot type.
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ GetOCB
+ Get OCB (object code bit) of the moveable
+
+
+ int
+ the moveable's current OCB value
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ SetOCB
+ Set OCB (object code bit) of the moveable
+
+
+ OCB
+ int
+ the new value for the moveable's OCB
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ GetItemFlags
+ Get the value stored in ItemFlags[index]
+
+
+ index
+ int
+ of the ItemFlags, can be between 0 and 7.
+
+
+
+
+ int
+ the value contained in the ItemFlags[index]
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ SetItemFlags
+ Stores a value in ItemFlags[index]
+
+
+ value
+ short
+ to store in the moveable's ItemFlags[index]
+
+
+ index
+ int
+ of the ItemFlags where store the value.
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ GetColor
+ Get the moveable's color
+
+
+ Color
+ a copy of the moveable's color
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ SetColor
+ Set the moveable's color
+
+
+ color
+ Color
+ the new color of the moveable
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ GetHitStatus
+ Get the hit status of the object
+
+
+ bool
+ true if the moveable was hit by something in the last gameplay frame, false otherwise
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ GetActive
+ Determine whether the moveable is active or not
+
+
+ bool
+ true if the moveable is active
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ GetJointPosition
+ Get the object's joint position
+
+
+ index
+ int
+ of a joint to get position
+
+
+
+
+ Vec3
+ a copy of the moveable's position
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ GetRotation
+ Get the moveable's rotation
+
+
+ Rotation
+ a copy of the moveable's rotation
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ SetRotation
+ Set the moveable's rotation
+
+
+ rotation
+ Rotation
+ The moveable's new rotation
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ GetName
+ Get the moveable's name (its unique string identifier)
+ e.g.
+ "door\_back\_room" or "cracked\_greek\_statue"
+ This corresponds with the "Lua Name" field in an object's properties in Tomb Editor.
+
+
+ string
+ the moveable's name
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ SetName
+ Set the moveable's name (its unique string identifier)
+ e.g.
+ "door\_back\_room" or "cracked\_greek\_statue"
+ It cannot be blank and cannot share a name with any existing object.
+
+
+ name
+ string
+ the new moveable's name
+
+
+
+
+ bool
+ true if we successfully set the name, false otherwise (e.g. if another object has the name already)
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ GetValid
+ Test if the object is in a valid state (i.e.
+ has not been destroyed through Lua or killed by Lara).
+
+
+ bool
+ valid true if the object is still not destroyed
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ Destroy
+ Destroy the moveable.
+ This will mean it can no longer be used, except to re-initialize it with another object.
+
+
+
+ Objects.Moveable
+ Moveable
+ AttachObjCamera
+ Attach camera to an object.
+
+
+ mesh
+ int
+ of a target moveable to use as a camera target
+
+
+ target
+ Moveable
+ moveable to attach camera to
+
+
+ mesh
+ int
+ of a target moveable to use as a camera target
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ AnimFromObject
+ Borrow animation from an object
+
+
+ ObjectID
+ Objects.ObjID
+ to take animation and stateID from,
+
+
+ animNumber
+ int
+ animation from object
+
+
+ stateID
+ int
+ state from object
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ SetOnCollidedWithObject
+ Set the function to be called when this moveable collides with another moveable
+
+
+ func
+ function
+ callback function to be called (must be in LevelFuncs hierarchy). This function can take two arguments; these will store the two @{Moveable}s taking part in the collision.
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ SetOnCollidedWithRoom
+ Set the function called when this moveable collides with room geometry (e.g.
+ a wall or floor). This function can take an argument that holds the @{Moveable} that collided with geometry.
+
+
+ func
+ function
+ callback function to be called (must be in LevelFuncs hierarchy)
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ GetPosition
+ Get the object's position
+
+
+ Vec3
+ a copy of the moveable's position
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ SetPosition
+ Set the moveable's position
+ If you are moving a moveable whose behaviour involves knowledge of room geometry,
+ (e.g.
+ a BADDY1, which uses it for pathfinding), then the second argument should
+ be true (or omitted, as true is the default). Otherwise, said moveable will not behave correctly.
+
+
+ position
+ Vec3
+ the new position of the moveable
+
+
+ updateRoom
+ bool
+ Will room changes be automatically detected? Set to false if you are using overlapping rooms (default: true)
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ GetHP
+ Get current HP (hit points/health points)
+
+
+ int
+ the amount of HP the moveable currently has
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ SetHP
+ Set current HP (hit points/health points)
+ Clamped to [0, 32767] for "intelligent" entities (i.e.
+ anything with AI); clamped to [-32767, 32767] otherwise.
+
+
+ HP
+ int
+ the amount of HP to give the moveable
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ GetLocationAI
+ Get the location value stored in the Enemy AI
+
+
+ short
+ the value contained in the LocationAI of the creature.
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ SetLocationAI
+ Updates the location in the enemy AI with the given value.
+
+
+ value
+ short
+ to store.
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ GetAIBits
+ Get AIBits of object
+ This will return a table with six values, each corresponding to
+ an active behaviour.
+ If the object is in a certain AI mode, the table will
+ have a *1* in the corresponding cell. Otherwise, the cell will hold
+ a *0*.
+
+ 1 - guard
+ 2 - ambush
+ 3 - patrol 1
+ 4 - modify
+ 5 - follow
+ 6 - patrol 2
+
+
+ table
+ a table of AI bits
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ SetAIBits
+ Set AIBits of object
+ Use this to force a moveable into a certain AI mode or modes, as if a certain nullmesh
+ (or more than one) had suddenly spawned beneath their feet.
+
+
+ bits
+ table
+ the table of AI bits
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ GetEndFrame
+ Get the end frame number of the moveable's active animation.
+ This is the "End Frame" set in WADTool for the animation.()
+
+
+ int
+ End frame number of the active animation.
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ GetRoom
+ Get the current room of the object
+
+
+ Objects.Room
+ current room of the object
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ GetRoomNumber
+ Get the current room number of the object
+
+
+ int
+ number representing the current room of the object
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ SetRoomNumber
+ Set the room ID of a moveable.
+ Use this if not using SetPosition's automatic room update - for example, when dealing with overlapping rooms.
+
+
+ roomID
+ int
+ New room's ID.
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ GetMeshVisible
+ Get state of specified mesh visibility of object
+ Returns true if specified mesh is visible on an object, and false
+ if it is not visible.
+
+
+ index
+ int
+ index of a mesh
+
+
+
+
+ bool
+ visibility status
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ SetMeshVisible
+ Makes specified mesh visible or invisible
+ Use this to show or hide a specified mesh of an object.
+
+
+ index
+ int
+ index of a mesh
+
+
+ isVisible
+ bool
+ true if you want the mesh to be visible, false otherwise
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ ShatterMesh
+ Shatters specified mesh and makes it invisible
+ Note that you can re-enable mesh later by using SetMeshVisible().
+
+
+ index
+ int
+ index of a mesh
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ GetMeshSwapped
+ Get state of specified mesh swap of object
+ Returns true if specified mesh is swapped on an object, and false
+ if it is not swapped.
+
+
+ index
+ int
+ index of a mesh
+
+
+
+
+ bool
+ mesh swap status
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ SwapMesh
+ Set state of specified mesh swap of object
+ Use this to swap specified mesh of an object.
+
+
+ index
+ int
+ index of a mesh
+
+
+ slotIndex
+ int
+ index of a slot to get meshswap from
+
+
+ swapIndex
+ int
+ index of a mesh from meshswap slot to use
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ UnswapMesh
+ Set state of specified mesh swap of object
+ Use this to bring back original unswapped mesh
+
+
+ index
+ int
+ index of a mesh to unswap
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ Enable
+ Enable the item, as if a trigger for it had been stepped on.
+
+
+
+ Objects.Moveable
+ Moveable
+ Disable
+ Disable the item, as if an antitrigger for it had been stepped on (i.e.
+ it will close an open door or extinguish a flame emitter).
+ Note that this will not trigger an OnKilled callback.
+
+
+
+ Objects.Moveable
+ Moveable
+ MakeInvisible
+ Make the item invisible.
+ Alias for `Moveable:SetVisible(false)`.
+
+
+
+ Objects.Moveable
+ Moveable
+ SetVisible
+ Set the item's visibility.
+ __An invisible item will have collision turned off, as if it no longer exists in the game world__.
+
+
+ visible
+ bool
+ true if the caller should become visible, false if it should become invisible
+
+
+
+
+
+ Objects
+ GetMoveableByName
+ Get a moveable by its name.
+
+
+ name
+ string
+ the unique name of the Moveable as set in, or generated by, Tomb Editor
+
+
+
+
+ Moveable
+ a non-owning Moveable referencing the item.
+
+
+
+
+
+ Objects
+ GetStaticByName
+ Get a Static by its name.
+
+
+ name
+ string
+ the unique name of the mesh as set in, or generated by, Tomb Editor
+
+
+
+
+ Static
+ a non-owning Static referencing the mesh.
+
+
+
+
+
+ Objects
+ GetMoveablesBySlot
+ Get moveables by its slot.
+
+
+ slot
+ Objects.ObjID
+ the unique slot of the Moveable, e.g. `Objects.ObjID.ANIMATING1`
+
+
+
+
+ table
+ table of Moveables referencing the given slot.
+
+
+
+
+
+ Objects
+ GetStaticsBySlot
+ Get statics by its slot.
+
+
+ slot
+ int
+ the unique slot of the mesh like 10
+
+
+
+
+ table
+ table of Statics referencing the given slot ID.
+
+
+
+
+
+ Objects
+ GetRoomsByTag
+ Get rooms by tag.
+
+
+ tag
+ string
+ to select rooms by
+
+
+
+
+ table
+ table of Rooms containing the given tag.
+
+
+
+
+
+ Objects
+ GetCameraByName
+ Get a Camera by its name.
+
+
+ name
+ string
+ the unique name of the camera as set in, or generated by, Tomb Editor
+
+
+
+
+ Camera
+ a non-owning Camera referencing the camera.
+
+
+
+
+
+ Objects
+ GetSinkByName
+ Get a Sink by its name.
+
+
+ name
+ string
+ the unique name of the sink as set in, or generated by, Tomb Editor
+
+
+
+
+ Sink
+ a non-owning Sink referencing the sink.
+
+
+
+
+
+ Objects
+ GetSoundSourceByName
+ Get a SoundSource by its name.
+
+
+ name
+ string
+ the unique name of the sound source as set in, or generated by, Tomb Editor
+
+
+
+
+ SoundSource
+ a non-owning SoundSource referencing the sound source.
+
+
+
+
+
+ Objects
+ GetAIObjectByName
+ Get an AIObject by its name.
+
+
+ name
+ string
+ the unique name of the AIObject as set in, or generated by, Tomb Editor
+
+
+
+
+ AIObject
+ a non-owning SoundSource referencing the AI moveable.
+
+
+
+
+
+ Objects
+ GetVolumeByName
+ Get a Volume by its name.
+
+
+ name
+ string
+ the unique name of the volume as set in, or generated by, Tomb Editor
+
+
+
+
+ Volume
+ a non-owning Volume referencing the room.
+
+
+
+
+
+ Objects
+ GetRoomByName
+ Get a Room by its name.
+
+
+ name
+ string
+ the unique name of the room as set in Tomb Editor
+
+
+
+
+ Room
+ a non-owning Room referencing the room.
+
+
+
+
+
+ Objects.Room
+ Room
+ GetActive
+ Determine whether the room is active or not
+
+
+ bool
+ true if the room is active
+
+
+
+
+
+ Objects.Room
+ Room
+ GetColor
+ Get the room's ambient light color.
+
+
+ Color
+ ambient light color of the room
+
+
+
+
+
+ Objects.Room
+ Room
+ GetReverbType
+ Get the room's reverb type.
+
+
+ Objects.RoomReverb
+ room's reverb type
+
+
+
+
+
+ Objects.Room
+ Room
+ SetReverbType
+ Set the room's reverb type.
+
+
+ new
+ Objects.RoomReverb
+ reverb type of the room
+
+
+
+
+
+ Objects.Room
+ Room
+ GetName
+ Get the room's unique string identifier.
+
+
+ string
+ the room's name
+
+
+
+
+
+ Objects.Room
+ Room
+ SetName
+ Set the room's name (its unique string identifier).
+
+
+ name
+ string
+ The room's new name
+
+
+
+
+
+ Objects.Room
+ Room
+ GetFlag
+ Get the room's specified flag value (true or false).
+
+
+ flagID
+ Objects.RoomFlagID
+ The room's flag ID
+
+
+
+
+ bool
+ the room's specified flag value
+
+
+
+
+
+ Objects.Room
+ Room
+ SetFlag
+ Set the room's specified flag value.
+
+
+ flagID
+ Objects.RoomFlagID
+ The room's flag ID
+
+
+ the
+ bool
+ room's new flag value
+
+
+
+
+
+ Objects.Room
+ Room
+ IsTagPresent
+ Checks if specified tag is set for this room.
+
+
+ tag
+ string
+ A text tag to check (case sensitive)
+
+
+
+
+ bool
+ true if tag is present, false if not
+
+
+
+
+
+ Objects.Sink
+ Sink
+ GetPosition
+ Get the sink's position
+
+
+ Vec3
+ a copy of the sink's position
+
+
+
+
+
+ Objects.Sink
+ Sink
+ SetPosition
+ Set the sink's position
+
+
+ position
+ Vec3
+ the new position of the sink
+
+
+
+
+
+ Objects.Sink
+ Sink
+ GetName
+ Get the sink's unique string identifier
+ e.g.
+ "strong\_river\_current" or "propeller\_death\_sink"
+
+
+ string
+ the sink's name
+
+
+
+
+
+ Objects.Sink
+ Sink
+ SetName
+ Set the sink's name (its unique string identifier)
+
+
+ name
+ string
+ The sink's new name
+
+
+
+
+
+ Objects.Sink
+ Sink
+ GetStrength
+ Get the sink's strength
+
+
+ int
+ the sink's current strength
+
+
+
+
+
+ Objects.Sink
+ Sink
+ SetStrength
+ Set the strength of the sink
+ Higher numbers provide stronger currents.
+ Will be clamped to [1, 32].
+
+
+ strength
+ int
+ The sink's new strength
+
+
+
+
+
+ Objects.SoundSource
+ SoundSource
+ GetPosition
+ Get the sound source's position
+
+
+ Vec3
+ a copy of the sound source's position
+
+
+
+
+
+ Objects.SoundSource
+ SoundSource
+ SetPosition
+ Set the sound source's position
+
+
+ position
+ Vec3
+ the new position of the sound source
+
+
+
+
+
+ Objects.SoundSource
+ SoundSource
+ GetName
+ Get the sound source's unique string identifier
+
+
+ string
+ the sound source's name
+
+
+
+
+
+ Objects.SoundSource
+ SoundSource
+ SetName
+ Set the sound source's name (its unique string identifier)
+
+
+ name
+ string
+ The sound source's new name
+
+
+
+
+
+ Objects.SoundSource
+ SoundSource
+ GetSoundID
+ Get the sound source's unique int identifier
+
+
+ int
+ the ID of the sound
+
+
+
+
+
+ Objects.SoundSource
+ SoundSource
+ SetSoundID
+ Set the sound source's ID
+ __TODO__ this and getSoundID should use enums
+
+
+ name
+ int
+ The sound source's new name
+
+
+
+
+
+ Objects.Static
+ Static
+ Enable
+ Enable the static, for cases when it was shattered or manually disabled before.
+
+
+
+ Objects.Static
+ Static
+ Disable
+ Disable the static
+
+
+
+ Objects.Static
+ Static
+ GetActive
+ Get static mesh visibility
+
+
+ bool
+ visibility state
+
+
+
+
+
+ Objects.Static
+ Static
+ GetSolid
+ Get static mesh solid collision state
+
+
+ bool
+ solid collision state (true if solid, false if soft)
+
+
+
+
+
+ Objects.Static
+ Static
+ SetSolid
+ Set static mesh solid collision state
+
+
+ solidState
+ bool
+ if set, collision will be solid, if not, will be soft
+
+
+
+
+
+ Objects.Static
+ Static
+ GetPosition
+ Get the static's position
+
+
+ Vec3
+ a copy of the static's position
+
+
+
+
+
+ Objects.Static
+ Static
+ SetPosition
+ Set the static's position
+
+
+ position
+ Vec3
+ the new position of the static
+
+
+
+
+
+ Objects.Static
+ Static
+ GetRotation
+ Get the static's rotation
+
+
+ Rotation
+ a copy of the static's rotation
+
+
+
+
+
+ Objects.Static
+ Static
+ SetRotation
+ Set the static's rotation
+
+
+ rotation
+ Rotation
+ the static's new rotation
+
+
+
+
+
+ Objects.Static
+ Static
+ GetScale
+ Get the static's scale
+
+
+ float
+ current static scale
+
+
+
+
+
+ Objects.Static
+ Static
+ SetScale
+ Set the static's scale
+
+
+ scale
+ Scale
+ the static's new scale
+
+
+
+
+
+ Objects.Static
+ Static
+ GetName
+ Get the static's unique string identifier
+
+
+ string
+ the static's name
+
+
+
+
+
+ Objects.Static
+ Static
+ SetName
+ Set the static's name (its unique string identifier)
+ e.g.
+ "my\_vase" or "oldrubble"
+
+
+ name
+ string
+ The static's new name
+
+
+
+
+
+ Objects.Static
+ Static
+ GetSlot
+ Get the static's slot number (as listed in Tomb Editor and WadTool)
+
+
+ string
+ the static's slot number
+
+
+
+
+
+ Objects.Static
+ Static
+ SetSlot
+ Set the static's slot number (as listed in Tomb Editor and WadTool)
+
+
+ slot
+ int
+ The static's slot number
+
+
+
+
+
+ Objects.Static
+ Static
+ GetColor
+ Get the static's color
+
+
+ Color
+ a copy of the static's color
+
+
+
+
+
+ Objects.Static
+ Static
+ SetColor
+ Set the static's color
+
+
+ color
+ Color
+ the new color of the static
+
+
+
+
+
+ Objects.Static
+ Static
+ Shatter
+ Shatter static mesh
+
+
+
+ Objects.Volume
+ Volume
+ Enable
+ Enable the volume.
+
+
+
+ Objects.Volume
+ Volume
+ Disable
+ Disable the volume.
+
+
+
+ Objects.Volume
+ Volume
+ GetActive
+ Determine whether the volume is active or not
+
+
+ bool
+ true if the volume is active
+
+
+
+
+
+ Objects.Volume
+ Volume
+ GetPosition
+ Get the volume's position.
+
+
+ Vec3
+ a copy of the volume's position
+
+
+
+
+
+ Objects.Volume
+ Volume
+ SetPosition
+ Set the volume's position.
+
+
+ position
+ Vec3
+ the new position of the volume
+
+
+
+
+
+ Objects.Volume
+ Volume
+ GetRotation
+ Get the volume's rotation.
+
+
+ Rotation
+ a copy of the volume's rotation
+
+
+
+
+
+ Objects.Volume
+ Volume
+ SetRotation
+ Set the volume's rotation.
+
+
+ rotation
+ Rotation
+ the volume's new rotation
+
+
+
+
+
+ Objects.Volume
+ Volume
+ GetScale
+ Get the volume's scale (separately on all 3 axes).
+
+
+ Vec3
+ current volume scale
+
+
+
+
+
+ Objects.Volume
+ Volume
+ SetScale
+ Set the volume's scale (separately on all 3 axes).
+
+
+ scale
+ Vec3
+ the volume's new scale
+
+
+
+
+
+ Objects.Volume
+ Volume
+ GetName
+ Get the volume's unique string identifier.
+
+
+ string
+ the volume's name
+
+
+
+
+
+ Objects.Volume
+ Volume
+ SetName
+ Set the volume's name (its unique string identifier).
+
+
+ name
+ string
+ The volume's new name
+
+
+
+
+
+ Objects.Volume
+ Volume
+ ClearActivators
+ Clear activator list for volumes (makes volume trigger everything again)
+
+
+
+ Objects.Volume
+ Volume
+ IsMoveableInside
+ Check if specified moveable is inside the volume
+
+
+ Moveable
+ Objects.Moveable
+ which should be checked for containment
+
+
+
+
+ bool
+ state of the moveable, true if contained, false if not
+
+
+
+
+
+ Rotation
+ Rotation
+
+
+ x
+ float
+ X angle component.
+
+
+ y
+ float
+ Y angle component.
+
+
+ z
+ float
+ Z angle component.
+
+
+
+
+ Rotation
+ A Rotation.
+
+
+
+
+
+ Rotation
+ tostring
+
+
+ rotation
+ Rotation
+ this Rotation.
+
+
+
+
+ string
+ A string showing the X, Y, and Z angle components of the Rotation.
+
+
+
+
+
+ Sound
+ PlayAudioTrack
+ Play an audio track
+
+
+ name
+ string
+ of track (without file extension) to play
+
+
+ type
+ Sound.SoundTrackType
+ of the audio track to play
+
+
+
+
+
+ Sound
+ SetAmbientTrack
+ Set and play an ambient track
+
+
+ name
+ string
+ of track (without file extension) to play
+
+
+
+
+
+ Sound
+ StopAudioTracks
+ Stop any audio tracks currently playing
+
+
+
+ Sound
+ StopAudioTrack
+ Stop audio track that is currently playing
+
+
+ type
+ Sound.SoundTrackType
+ of the audio track
+
+
+
+
+
+ Sound
+ GetAudioTrackLoudness
+ Get current loudness level for specified track type
+
+
+ type
+ Sound.SoundTrackType
+ of the audio track
+
+
+
+
+ float
+ current loudness of a specified audio track
+
+
+
+
+
+ Sound
+ PlaySound
+ Play sound effect
+
+
+ sound
+ int
+ ID to play. Corresponds to the value in the sound XML file or Tomb Editor's "Sound Infos" window.
+
+
+ position
+ Vec3
+ The 3D position of the sound, i.e. where the sound "comes from". If not given, the sound will not be positional.
+
+
+
+
+
+ Sound
+ StopSound
+ Stop sound effect
+
+
+ sound
+ int
+ ID to play. Corresponds to the value in the sound XML file or Tomb Editor's "Sound Infos" window.
+
+
+
+
+
+ Sound
+ IsSoundPlaying
+ Check if the sound effect is playing
+
+
+ Sound
+ int
+ ID to check. Corresponds to the value in the sound XML file or Tomb Editor's "Sound Infos" window.
+
+
+
+
+
+ Sound
+ IsAudioTrackPlaying
+ Check if the audio track is playing
+
+
+ Track
+ string
+ filename to check. Should be without extension and without full directory path.
+
+
+
+
+
+ Sound
+ GetCurrentSubtitle
+ Get current subtitle string for a voice track currently playing.
+ Subtitle file must be in .srt format, have same filename as voice track, and be placed in same directory as voice track.
+Returns nil if no voice track is playing or no subtitle present.
+
+
+ string
+ current subtitle string
+
+
+
+
+
+ Strings.DisplayString
+ DisplayString
+ Create a DisplayString.
+ For use in @{Strings.ShowString|ShowString} and @{Strings.HideString|HideString}.
+
+
+ string
+ string
+ The string to display or key of the translated string.
+
+
+ Position
+ Vec2
+ of the string in pixel coordinates.
+
+
+ scale
+ float
+ size of the string, relative to the default size. __Default: 1.0__
+
+
+ color
+ Color
+ the color of the text. __Default: white__
+
+
+ translated
+ bool
+ If false or omitted, the input string argument will be displayed.
+If true, the string argument will be the key of a translated string specified in strings.lua. __Default: false__.
+
+
+ flags
+ table
+ A table of string display options. Can be empty or omitted. The possible values and their effects are:
+ TEN.Strings.DisplayStringOption.CENTER: set the horizontal origin point to the center of the string.
+ TEN.Strings.DisplayStringOption.RIGHT: set the horizontal origin point to right of the string.
+ TEN.Strings.DisplayStringOption.SHADOW: give the string a small shadow.
+ TEN.Strings.DisplayStringOption.BLINK: blink the string.
+__Default: empty__
+
+
+
+
+ DisplayString
+ A new DisplayString object.
+
+
+
+
+
+ Strings.DisplayString
+ DisplayString
+ GetColor
+ Get the display string's color
+
+
+ Color
+ a copy of the display string's color
+
+
+
+
+
+ Strings.DisplayString
+ DisplayString
+ SetColor
+ Set the display string's color
+
+
+ color
+ Color
+ the new color of the display string
+
+
+
+
+
+ Strings.DisplayString
+ DisplayString
+ GetKey
+ Get the string key to use.
+ If `isTranslated` is true when @{DisplayString}
+ is called, this will be the string key for the translation that will be displayed.
+ If false or omitted, this will be the string that's displayed.()
+
+
+ string
+ the string to use
+
+
+
+
+
+ Strings.DisplayString
+ DisplayString
+ SetKey
+ Set the string key to use.
+ If `isTranslated` is true when @{DisplayString}
+ is called, this will be the string key for the translation that will be displayed.
+ If false or omitted, this will be the string that's displayed.()
+
+
+ string
+ string
+ the new key for the display string
+
+
+
+
+
+ Strings.DisplayString
+ DisplayString
+ SetScale
+ Set the scale of the string.
+ ()
+
+
+ scale
+ float
+ New scale of the string relative to the default size.
+
+
+
+
+
+ Strings.DisplayString
+ DisplayString
+ GetScale
+ Get the scale of the string.
+ ()
+
+
+ float
+ Scale.
+
+
+
+
+
+ Strings.DisplayString
+ DisplayString
+ SetPosition
+ Set the position of the string.
+ Screen-space coordinates are expected.()
+
+
+ pos
+ Vec2
+ New position in pixel coordinates.
+
+
+
+
+
+ Strings.DisplayString
+ DisplayString
+ GetPosition
+ Get the position of the string.
+ Screen-space coordinates are returned.()
+
+
+ Vec2
+ pos Position in pixel coordinates.
+
+
+
+
+
+ Strings.DisplayString
+ DisplayString
+ SetFlags
+ Set the display string's flags
+ ()
+
+
+ table
+ table
+ the new table with display flags options
+
+
+
+
+
+ Strings.DisplayString
+ DisplayString
+ SetTranslated
+ Set translated parameter of the string
+
+
+ shouldTranslate
+ bool
+ if true, the string's key will be used as the key for the translation that will be displayed.
+ If false, the key itself will be displayed
+
+
+
+
+
+ Strings
+ ShowString
+ Show some text on-screen.
+
+
+ str
+ DisplayString
+ the string object to draw
+
+
+ time
+ float
+ the time in seconds for which to show the string.
+If not given, the string will have an "infinite" life, and will show
+until @{HideString} is called or until the level is finished.
+Default: nil (i.e. infinite)
+
+
+
+
+
+ Strings
+ HideString
+ Hide some on-screen text.
+
+
+ str
+ DisplayString
+ the string object to hide. Must previously have been shown
+with a call to @{ShowString}, or this function will have no effect.
+
+
+
+
+
+ Strings
+ IsStringDisplaying
+ Checks if the string is shown
+
+
+ str
+ DisplayString
+ the string object to be checked
+
+
+
+
+ bool
+ true if it is shown, false if it is hidden
+
+
+
+
+
+ Util
+ HasLineOfSight
+ Determine if there is a clear line of sight between two positions.
+ NOTE: Limited to room geometry. Objects are ignored.()
+
+
+ roomID
+ float
+ Room ID of the first position's room.
+
+
+ posA
+ Vec3
+ First position.
+
+
+ posB
+ Vec3
+ Second position.
+
+
+
+
+ bool
+ __true__ if there is a line of sight, __false__ if not.
+
+
+
+
+
+ Util
+ CalculateDistance
+ Calculate the distance between two positions.
+
+
+ posA
+ Vec3
+ First position.
+
+
+ posB
+ Vec3
+ Second position.
+
+
+
+
+ float
+ Distance between two positions.
+
+
+
+
+
+ Util
+ CalculateHorizontalDistance
+ Calculate the horizontal distance between two positions.
+
+
+ posA
+ Vec3
+ First position.
+
+
+ posB
+ Vec3
+ Second position.
+
+
+
+
+ float
+ Horizontal distance between the two positions.
+
+
+
+
+
+ Util
+ GetDisplayPosition
+ Get the projected display space position of a 3D world position.
+ Returns nil if the world position is behind the camera view.
+
+
+ worldPos
+ Vec3
+ 3D world position.
+
+
+
+
+ Vec2
+ Projected display space position in percent.
+
+
+
+
+
+ Util
+ PercentToScreen
+ Translate a pair display position coordinates to pixel coordinates.
+ To be used with @{Strings.DisplayString:SetPosition} and @{Strings.DisplayString}.
+
+
+ x
+ float
+ X component of the display position.
+
+
+ y
+ float
+ Y component of the display position.
+
+
+
+
+ int
+ x X coordinate in pixels.
+
+
+ int
+ y Y coordinate in pixels.
+
+
+
+
+
+ Util
+ ScreenToPercent
+ Translate a pair of pixel coordinates to display position coordinates.
+ To be used with @{Strings.DisplayString:GetPosition}.
+
+
+ x
+ int
+ X pixel coordinate to translate to display position.
+
+
+ y
+ int
+ Y pixel coordinate to translate to display position.
+
+
+
+
+ float
+ x X component of display position.
+
+
+ float
+ y Y component of display position.
+
+
+
+
+
+ Util
+ PickMoveableByDisplayPosition
+ Pick a moveable by the given display position.
+
+
+ Display
+ Vec2
+ space position in percent.
+
+
+
+
+ Objects.Moveable
+ Picked moveable (nil if no moveable was found under the cursor).
+
+
+
+
+
+ Util
+ PickStaticByDisplayPosition
+ Pick a static mesh by the given display position.
+
+
+ Display
+ Vec2
+ space position in percent.
+
+
+
+
+ Objects.Static
+ Picked static mesh (nil if no static mesh was found under the cursor).
+
+
+
+
+
+ Util
+ PrintLog
+ Write messages within the Log file
+
+
+ message
+ string
+ to be displayed within the Log
+
+
+ logLevel
+ Misc.LogLevel
+ log level to be displayed
+
+
+ allowSpam
+ bool
+ true allows spamming of the message
+
+
+
+
+
+ Vec2
+ Vec2
+ Create a Vec2 object.
+ (x, y)
+
+
+ x
+ float
+ X component.
+
+
+ y
+ float
+ Y component.
+
+
+
+
+ Vec2
+ A new Vec2 object.
+
+
+
+
+
+ Vec2
+ Vec
+ Create a Vec2 object.
+ (value)
+
+
+ value
+ float
+ X and Z component.
+
+
+
+
+ Vec2
+ A new Vec2 object.
+
+
+
+
+
+ Vec2
+ tostring
+ Metafunction.
+ Use tostring(vector).
+
+
+ This
+ Vec2
+ Vec2.
+
+
+
+
+ string
+ A string showing the X and Y components of the Vec2.
+
+
+
+
+
+ Vec2
+ Vec2
+ Normalize
+ Get a copy of this Vec2 normalized to length 1.
+ ()
+
+
+ Vec2
+ Normalized vector.
+
+
+
+
+
+ Vec2
+ Vec2
+ Rotate
+ Get a copy of this Vec2 rotated by the input rotation in degrees.
+ (rot)
+
+
+ rot
+ float
+ Rotation in degrees.
+
+
+
+
+ Vec2
+ Rotated Vec2.
+
+
+
+
+
+ Vec2
+ Vec2
+ Lerp
+ Get the linearly interpolated Vec2 between this Vec2 and the input Vec2 according to the input interpolation alpha.
+ (vector)
+
+
+ vector
+ Vec2
+ Target interpolation vector.
+
+
+ alpha
+ float
+ Interpolation alpha in the range [0, 1].
+
+
+
+
+ Vec2
+ Linearly interpolated vector
+
+
+
+
+
+ Vec2
+ Vec2
+ Cross
+ Get the cross product of this Vec2 and the input Vec2.
+ (vector)
+
+
+ vector
+ Vec2
+ Input vector.
+
+
+
+
+ Vec2
+ Cross product.
+
+
+
+
+
+ Vec2
+ Vec2
+ Dot
+ Get the dot product of this Vec2 and the input Vec2.
+ (vector)
+
+
+ vector
+ Vec2
+ Input vector.
+
+
+
+
+ float
+ Dot product.
+
+
+
+
+
+ Vec2
+ Vec2
+ Distance
+ Get the distance between this Vec2 and the input Vec2.
+ (vector)
+
+
+ vector
+ Vec2
+ Input vector.
+
+
+
+
+ float
+ Distance.
+
+
+
+
+
+ Vec2
+ Vec2
+ Length
+ Get the length of this Vec2.
+ ()
+
+
+ float
+ Length.
+
+
+
+
+
+ Vec3
+ Vec3
+ Create a Vec3 object.
+ (x, y, z)
+
+
+ x
+ float
+ X component.
+
+
+ y
+ float
+ Y component.
+
+
+ z
+ float
+ Z component.
+
+
+
+
+ Vec3
+ A new Vec3 object.
+
+
+
+
+
+ Vec3
+ Vec3
+ Create a Vec3 object.
+ (value)
+
+
+ value
+ float
+ X, Y, and Z component.
+
+
+
+
+ Vec3
+ A new Vec3 object.
+
+
+
+
+
+ Vec3
+ Vec3
+ Normalize
+ Get a copy of this Vec3 normalized to length 1.
+ ()
+
+
+ Vec3
+ Normalized vector.
+
+
+
+
+
+ Vec3
+ Vec3
+ Rotate
+ Get a copy of this Vec3 rotated by the input Rotation object.
+ (rot)
+
+
+ rot
+ Rotation
+ Rotation object.
+
+
+
+
+ Vec3
+ Rotated Vec3.
+
+
+
+
+
+ Vec3
+ Vec3
+ Lerp
+ Get the linearly interpolated Vec3 between this Vec3 and the input Vec3 according to the input interpolation alpha.
+ (vector)
+
+
+ vector
+ Vec3
+ Target interpolation vector.
+
+
+ alpha
+ float
+ Interpolation alpha in the range [0, 1].
+
+
+
+
+ Vec3
+ Linearly interpolated vector
+
+
+
+
+
+ Vec3
+ Vec3
+ Cross
+ Get the cross product of this Vec3 and the input Vec3.
+ (vector)
+
+
+ vector
+ Vec3
+ Input vector.
+
+
+
+
+ Vec3
+ Cross product.
+
+
+
+
+
+ Vec3
+ Vec3
+ Dot
+ Get the dot product of this Vec3 and the input Vec3.
+ (vector)
+
+
+ vector
+ Vec3
+ Input vector.
+
+
+
+
+ float
+ Dot product.
+
+
+
+
+
+ Vec3
+ Vec3
+ Distance
+ Get the distance between this Vec3 and the input Vec3.
+ (vector)
+
+
+ vector
+ Vec3
+ Input vector.
+
+
+
+
+ float
+ Distance.
+
+
+
+
+
+ Vec3
+ Vec3
+ Length
+ Get the length of this Vec3.
+ ()
+
+
+ float
+ Length.
+
+
+
+
+
+ Vec3
+ tostring
+ Metafunction.
+ Use tostring(vector).
+
+
+ This
+ Vec3
+ Vec3.
+
+
+
+
+ string
+ A string showing the X, Y, and Z components of the Vec3.
+
+
+
+
+
+ View
+ FadeIn
+ Do a full-screen fade-in from black.
+
+
+ speed
+ float
+ (default 1.0). Speed in "amount" per second. A value of 1 will make the fade take one second.
+
+
+
+
+
+ View
+ FadeOut
+ Do a full-screen fade-to-black.
+ The screen will remain black until a call to FadeIn.
+
+
+ speed
+ float
+ (default 1.0). Speed in "amount" per second. A value of 1 will make the fade take one second.
+
+
+
+
+
+ View
+ SetCineBars
+ Move black cinematic bars in from the top and bottom of the game window.
+
+
+ height
+ float
+ __(default 30)__ Percentage of the screen to be covered
+
+
+ speed
+ float
+ __(default 30)__ Coverage percent per second
+
+
+
+
+
+ View
+ SetFOV
+ Set field of view.
+
+
+ angle
+ float
+ in degrees (clamped to [10, 170])
+
+
+
+
+
+ View
+ GetFOV
+ Get field of view.
+
+
+ float
+ current FOV angle in degrees
+
+
+
+
+
+ View
+ GetCameraType
+ Shows the mode of the game camera.
+
+
+ View.CameraType
+ value used by the Main Camera.
+
+
+
+
+
+ View
+ GetCameraRoom
+ Gets current room where camera is positioned.
+
+
+ Objects.Room
+ current room of the camera
+
+
+
+
+
+ View
+ SetPostProcessMode
+ Sets the post-process effect mode, like negative or monochrome.
+
+
+ effect
+ View.PostProcessMode
+ type to set.
+
+
+
+
+
+ View
+ SetPostProcessStrength
+ Sets the post-process effect strength.
+
+
+ strength
+ float
+ (default 1.0). How strong the effect is.
+
+
+
+
+
+ View
+ SetPostProcessTint
+ Sets the post-process tint.
+
+
+ tint
+ Color
+ value to use.
+
+
+
+
+
+ View
+ GetCameraPosition
+ Gets current camera position.
+
+
+ Vec3
+ current camera position
+
+
+
+
+
+ View
+ GetCameraTarget
+ Gets current camera target.
+
+
+ Vec3
+ current camera target
+
+
+
+
+
+ View
+ PlayFlyBy
+ Enable FlyBy with specific ID
+
+
+ flyby
+ short
+ (ID of flyby)
+
+
+
+
+
+ View
+ ResetObjCamera
+ Reset object camera back to Lara and deactivate object camera.
+
+
+
+ View
+ FlashScreen
+ Flash screen.
+
+
+ color
+ Color
+ (default Color(255, 255, 255))
+
+
+ speed
+ float
+ (default 1.0). Speed in "amount" per second. Value of 1 will make flash take one second. Clamped to [0.005, 1.0].
+
+
+
+
+
+ View
+ GetAspectRatio
+ Get the display resolution's aspect ratio.
+
+
+ float
+ Display resolution's aspect ratio.
+
+
+
+
+
+ EventSequence
+ Create
+ Create (but do not start) a new event sequence.
+
+
+ name
+ string
+ A label to give the sequence; used to retrieve the timer later as well as internally by TEN.
+
+
+ loop
+ bool
+ if true, the sequence will start again from its first timer once its final function has been called
+
+
+ timerFormat
+ ?table|bool
+ same as in Timer. This is mainly for debugging. __This will not work properly if another sequence or timer is showing a countdown.__
+
+
+ ...
+ ...
+ a variable number of pairs of arguments - a time in seconds, followed by the function (must be defined in the LevelFuncs table) to call once the time has elapsed, followed by another duration in seconds, another function name, etc. You can specify a function either by its name as a string, or by a table with the function name as the first member, followed by its arguments (see above example).
+
+
+
+
+ EventSequence
+ The inactive sequence.
+
+
+
+
+
+ EventSequence
+ Get
+ Get an event sequence by its name.
+
+
+ name
+ string
+ The label that was given to the sequence when it was created
+
+
+
+
+ EventSequence
+ The sequence
+
+
+
+
+
+ EventSequence
+ mySequence
+ SetPaused
+ Pause or unpause the sequence.
+ If showing the remaining time on-screen, its color will be set to yellow (paused) or white (unpaused).
+
+
+ p
+ bool
+ if true, the sequence will be paused; if false, it will be unpaused
+
+
+
+
+
+ EventSequence
+ mySequence
+ IsPaused
+ Get whether or not the sequence is paused
+
+
+ bool
+ true if the timer is paused, false if otherwise
+
+
+
+
+
+ EventSequence
+ mySequence
+ Start
+ Begin or unpause a sequence.
+ If showing the remaining time on-screen, its color will be set to white.
+
+
+
+ EventSequence
+ mySequence
+ Stop
+ Stop the sequence.
+
+
+
+ EventSequence
+ mySequence
+ IsActive
+ Get whether or not the sequence is active
+
+
+ bool
+ true if the sequence is active, false if otherwise
+
+
+
+
+
+ Timer
+ Create
+ Create (but do not start) a new timer.
+ You have the option of displaying the remaining time on the clock. Timer format details:
+
+
+ name
+ string
+ A label to give this timer; used to retrieve the timer later. __Do not give your timers a name beginning with __TEN, as this is reserved for timers used by other internal libaries__.
+
+
+ totalTime
+ number
+ The duration of the timer, in seconds
+
+
+ loop
+ bool
+ if true, the timer will start again immediately after the time has elapsed
+
+
+ timerFormat
+ ?table|bool
+ If a table is given, the remaining time will be shown as a string, formatted according to the values in the table. If true, the remaining seconds, rounded up, will show at the bottom of the screen. If false, the remaining time will not be shown on screen.
+
+
+ func
+ func
+ The LevelFunc function to call when the time is up
+
+
+ ...
+ ...
+ a variable number of arguments with which the above function will be called
+
+
+
+
+ Timer
+ The timer in its paused state
+
+
+
+
+
+ Timer
+ Get
+ Get a timer by its name.
+
+
+ name
+ string
+ The label that was given to the timer when it was created
+
+
+
+
+ Timer
+ The timer
+
+
+
+
+
+ Timer
+ myTimer
+ SetFunction
+ Give the timer a new function and args
+
+
+ func
+ function
+ The LevelFunc member to call when the time is up
+
+
+ ...
+ ...
+ a variable number of arguments with which the above function will be called
+
+
+
+
+
+ Timer
+ myTimer
+ Start
+ Begin or unpause a timer.
+ If showing the remaining time on-screen, its color will be set to white.
+
+
+
+ Timer
+ myTimer
+ Stop
+ Stop the timer.
+
+
+
+ Timer
+ myTimer
+ IsActive
+ Get whether or not the timer is active
+
+
+ bool
+ true if the timer is active, false if otherwise
+
+
+
+
+
+ Timer
+ myTimer
+ SetPaused
+ Pause or unpause the timer.
+ If showing the remaining time on-screen, its color will be set to yellow (paused) or white (unpaused).
+
+
+ p
+ bool
+ if true, the timer will be paused; if false, it would be unpaused
+
+
+
+
+
+ Timer
+ myTimer
+ IsPaused
+ Get whether or not the timer is paused
+
+
+ bool
+ true if the timer is paused, false if otherwise
+
+
+
+
+
+ Timer
+ myTimer
+ GetRemainingTime
+ Get the remaining time for a timer.
+
+
+ float
+ the time in seconds remaining on the clock
+
+
+
+
+
+ Timer
+ myTimer
+ SetRemainingTime
+ Set the remaining time for a timer
+
+
+ remainingTime
+ number
+ the new time remaining for the timer
+
+
+
+
+
+ Timer
+ myTimer
+ GetTotalTime
+ Get the total time for a timer.
+ This is the amount of time the timer will start with, as well as when starting a new loop
+
+
+ float
+ the timer's total time
+
+
+
+
+
+ Timer
+ myTimer
+ SetTotalTime
+ Set the total time for a timer
+
+
+ totalTime
+ number
+ timer's new total time
+
+
+
+
+
+ Timer
+ myTimer
+ SetLooping
+ Set whether or not the timer loops
+
+
+ looping
+ bool
+ whether or not the timer loops
+
+
+
diff --git a/TombEngine/Game/Lara/lara.cpp b/TombEngine/Game/Lara/lara.cpp
index 5579a81da..41dd4d775 100644
--- a/TombEngine/Game/Lara/lara.cpp
+++ b/TombEngine/Game/Lara/lara.cpp
@@ -58,6 +58,7 @@ using namespace TEN::Gui;
using TEN::Renderer::g_Renderer;
LaraInfo Lara = {};
+LaraInfo OldLara = {};
ItemInfo* LaraItem;
CollisionInfo LaraCollision = {};
@@ -621,6 +622,13 @@ void UpdateLara(ItemInfo* item, bool isTitle)
// Control player.
InItemControlLoop = true;
+
+ // Copy current state to old state for interpolation
+ //memcpy(&item->OldPose, &item->Pose, sizeof(Pose));
+ //memcpy(&item->OldLocation, &item->Location, sizeof(Vector3i));
+ //memcpy(&item->OldAnimation, &item->Animation, sizeof(EntityAnimationData));
+ //memcpy(&OldLara, &Lara, sizeof(LaraInfo));
+
LaraControl(item, &LaraCollision);
HandlePlayerFlyCheat(*item);
InItemControlLoop = false;
diff --git a/TombEngine/Game/Lara/lara.h b/TombEngine/Game/Lara/lara.h
index 184a82cb3..b2562147b 100644
--- a/TombEngine/Game/Lara/lara.h
+++ b/TombEngine/Game/Lara/lara.h
@@ -94,6 +94,7 @@ constexpr auto SWIM_WATER_DEPTH = CLICK(2.75f);
constexpr auto SLOPE_DIFFERENCE = 60;
extern LaraInfo Lara;
+extern LaraInfo OldLara;
extern ItemInfo* LaraItem;
extern CollisionInfo LaraCollision;
diff --git a/TombEngine/Game/camera.cpp b/TombEngine/Game/camera.cpp
index 1fd9628d4..ee176e7d7 100644
--- a/TombEngine/Game/camera.cpp
+++ b/TombEngine/Game/camera.cpp
@@ -58,6 +58,7 @@ GameVector LookCamPosition;
GameVector LookCamTarget;
Vector3i CamOldPos;
CAMERA_INFO Camera;
+CAMERA_INFO PreviousCamera;
ObjectCameraInfo ItemCamera;
GameVector ForcedFixedCamera;
int UseForcedFixedCamera;
diff --git a/TombEngine/Game/camera.h b/TombEngine/Game/camera.h
index 504a59ed4..55453957b 100644
--- a/TombEngine/Game/camera.h
+++ b/TombEngine/Game/camera.h
@@ -66,6 +66,7 @@ constexpr auto FADE_SCREEN_SPEED = 16.0f / 255.0f;
constexpr auto DEFAULT_FOV = 80.0f;
extern CAMERA_INFO Camera;
+extern CAMERA_INFO PreviousCamera;
extern GameVector ForcedFixedCamera;
extern int UseForcedFixedCamera;
extern CameraType BinocularOldCamera;
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index 9977f8877..cd0ee8f09 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -110,7 +110,7 @@ short NextFxFree;
int ControlPhaseTime;
-int DrawPhase(bool isTitle)
+int DrawPhase(bool isTitle, float interpolateFactor)
{
if (isTitle)
{
@@ -118,13 +118,13 @@ int DrawPhase(bool isTitle)
}
else
{
- g_Renderer.Render();
+ g_Renderer.Render(interpolateFactor);
}
// Clear display sprites.
ClearDisplaySprites();
- Camera.numberFrames = g_Renderer.Synchronize();
+ //Camera.numberFrames = g_Renderer.Synchronize();
return Camera.numberFrames;
}
@@ -149,8 +149,10 @@ GameStatus ControlPhase(int numFrames)
bool isFirstTime = true;
static int framesCount = 0;
- for (framesCount += numFrames; framesCount > 0; framesCount -= LOOP_FRAME_COUNT)
+ //for (framesCount += numFrames; framesCount > 0; framesCount -= LOOP_FRAME_COUNT)
{
+ g_Renderer.SaveOldState();
+
// Controls are polled before OnLoop, so input data could be
// overwritten by script API methods.
HandleControls(isTitle);
@@ -548,12 +550,46 @@ GameStatus DoGameLoop(int levelIndex)
// Before entering actual game loop, ControlPhase must be
// called once to sort out various runtime shenanigangs (e.g. hair).
+
status = ControlPhase(numFrames);
+ LARGE_INTEGER lastTime;
+ LARGE_INTEGER currentTime;
+ LARGE_INTEGER lastDrawTime;
+ LARGE_INTEGER currentDrawTime;
+ double controlLag = 0;
+ double drawLag = 0;
+ double frameTime = 0;
+ constexpr auto controlFrameTime = 1000.0f / 30.0f;
+ constexpr auto drawFrameTime = 1000.0f / 60.0f;
+
+ LARGE_INTEGER frequency;
+ QueryPerformanceFrequency(&frequency);
+
+ QueryPerformanceCounter(&lastTime);
+ QueryPerformanceCounter(&lastDrawTime);
+
+ int controlCalls = 0;
+ int drawCalls = 0;
+
+ memcpy(&PreviousCamera , &Camera, sizeof(CAMERA_INFO));
+
while (DoTheGame)
{
- status = ControlPhase(numFrames);
+ QueryPerformanceCounter(¤tTime);
+ frameTime = (currentTime.QuadPart - lastTime.QuadPart) * 1000.0 / frequency.QuadPart;
+ lastTime = currentTime;
+ controlLag += frameTime;
+ //while (controlLag >= controlFrameTime)
+ if (controlLag >= controlFrameTime)
+ {
+ memcpy(&PreviousCamera, &Camera, sizeof(CAMERA_INFO));
+ status = ControlPhase(0);
+ controlLag -= controlFrameTime;
+ controlCalls++;
+ }
+
if (!levelIndex)
{
UpdateInputActions(LaraItem);
@@ -590,7 +626,23 @@ GameStatus DoGameLoop(int levelIndex)
}
}
- numFrames = DrawPhase(!levelIndex);
+ QueryPerformanceCounter(¤tDrawTime);
+ frameTime = (currentDrawTime.QuadPart - lastDrawTime.QuadPart) * 1000.0 / frequency.QuadPart;
+ lastDrawTime = currentDrawTime;
+ drawLag += frameTime;
+
+ //if (drawLag >= drawFrameTime)
+ {
+ float interpolateFactor = std::min((float)controlLag / (float)controlFrameTime, 1.0f);
+ //printf("%f\n", interpolateFactor);
+
+ numFrames = DrawPhase(!levelIndex, interpolateFactor);
+ drawLag -= drawFrameTime;
+ drawCalls++;
+ }
+
+
+
Sound_UpdateScene();
}
diff --git a/TombEngine/Game/control/control.h b/TombEngine/Game/control/control.h
index 805104c5a..be2af5736 100644
--- a/TombEngine/Game/control/control.h
+++ b/TombEngine/Game/control/control.h
@@ -74,7 +74,7 @@ extern int ControlPhaseTime;
extern std::vector OutsideRoomTable[OUTSIDE_SIZE][OUTSIDE_SIZE];
-int DrawPhase(bool isTitle);
+int DrawPhase(bool isTitle, float interpolateFactor);
GameStatus ControlPhase(int numFrames);
GameStatus DoLevel(int levelIndex, bool loadGame = false);
diff --git a/TombEngine/Renderer/Renderer.cpp b/TombEngine/Renderer/Renderer.cpp
index e7bfe0859..2092630a2 100644
--- a/TombEngine/Renderer/Renderer.cpp
+++ b/TombEngine/Renderer/Renderer.cpp
@@ -18,7 +18,10 @@ namespace TEN::Renderer
using namespace Utils;
Renderer g_Renderer;
- Renderer::Renderer() : _gameCamera({0, 0, 0}, {0, 0, 1}, {0, 1, 0}, 1, 1, 0, 1, 10, 90)
+ Renderer::Renderer() :
+ _gameCamera({0, 0, 0}, {0, 0, 1}, {0, 1, 0}, 1, 1, 0, 1, 10, 90),
+ _oldGameCamera({ 0, 0, 0 }, { 0, 0, 1 }, { 0, 1, 0 }, 1, 1, 0, 1, 10, 90),
+ _currentGameCamera({ 0, 0, 0 }, { 0, 0, 1 }, { 0, 1, 0 }, 1, 1, 0, 1, 10, 90)
{
}
diff --git a/TombEngine/Renderer/Renderer.h b/TombEngine/Renderer/Renderer.h
index d6f0442d7..efc25a7d2 100644
--- a/TombEngine/Renderer/Renderer.h
+++ b/TombEngine/Renderer/Renderer.h
@@ -160,6 +160,8 @@ namespace TEN::Renderer
// Constant buffers
RenderView _gameCamera;
+ RenderView _oldGameCamera;
+ RenderView _currentGameCamera;
ConstantBuffer _cbCameraMatrices;
CItemBuffer _stItem;
ConstantBuffer _cbItem;
@@ -373,6 +375,8 @@ namespace TEN::Renderer
VertexBuffer _sortedPolygonsVertexBuffer;
IndexBuffer _sortedPolygonsIndexBuffer;
+ float _interpolationFactor = 0.0f;
+
// Private functions
void ApplySMAA(RenderTarget2D* renderTarget, RenderView& view);
void ApplyFXAA(RenderTarget2D* renderTarget, RenderView& view);
@@ -580,7 +584,7 @@ namespace TEN::Renderer
void DrawBar(float percent, const RendererHudBar& bar, GAME_OBJECT_ID textureSlot, int frame, bool poison);
void Create();
void Initialize(int w, int h, bool windowed, HWND handle);
- void Render();
+ void Render(float interpolateFactor);
void RenderTitle();
void Lock();
bool PrepareDataForTheRenderer();
@@ -632,7 +636,7 @@ namespace TEN::Renderer
void SetLoadingScreen(std::wstring& fileName);
void SetTextureOrDefault(Texture2D& texture, std::wstring path);
std::string GetDefaultAdapterName();
-
+ void SaveOldState();
Vector2i GetScreenResolution() const;
std::optional Get2DPosition(const Vector3& pos) const;
Vector3 GetAbsEntityBonePosition(int itemNumber, int jointIndex, const Vector3& relOffset = Vector3::Zero);
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index 5ff0ba82b..4a9357491 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -2168,10 +2168,10 @@ namespace TEN::Renderer
RendererObject& moveableObj = *_moveableObjects[item->ObjectNumber];
// Bind item main properties
- _stItem.World = item->World;
+ _stItem.World = item->InterpolatedWorld; // item->World;
_stItem.Color = item->Color;
_stItem.AmbientLight = item->AmbientLight;
- memcpy(_stItem.BonesMatrices, item->AnimationTransforms, sizeof(Matrix) * MAX_BONES);
+ memcpy(_stItem.BonesMatrices, item->InterpolatedAnimationTransforms, sizeof(Matrix) * MAX_BONES);
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
_stItem.BoneLightModes[k] = (int)moveableObj.ObjectMeshes[k]->LightMode;
@@ -2720,9 +2720,45 @@ namespace TEN::Renderer
_context->ClearDepthStencilView(depthTarget, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
}
- void Renderer::Render()
+ void Renderer::Render(float interpolateFactor)
{
//RenderToCubemap(reflectionCubemap, Vector3(LaraItem->pos.xPos, LaraItem->pos.yPos - 1024, LaraItem->pos.zPos), LaraItem->roomNumber);
+
+ /*RenderView oldCamera = RenderView(
+ &PreviousCamera,
+ 0,
+ TO_RAD(CurrentFOV / 1.333333f) ,
+ 32, 100*1024, g_Configuration.ScreenWidth, g_Configuration.ScreenHeight);
+
+ RenderView newCamera = RenderView(
+ &Camera,
+ 0,
+ TO_RAD(CurrentFOV / 1.333333f),
+ 32, 100 * 1024, g_Configuration.ScreenWidth, g_Configuration.ScreenHeight);
+
+ _gameCamera.Camera = oldCamera.Camera;
+ _gameCamera.Camera.WorldPosition = Vector3::Lerp(oldCamera.Camera.WorldPosition, newCamera.Camera.WorldPosition, interpolateFactor);
+ _gameCamera.Camera.WorldDirection = Vector3::Lerp(oldCamera.Camera.WorldDirection, newCamera.Camera.WorldDirection, interpolateFactor);
+ _gameCamera.Camera.View = Matrix::Lerp(oldCamera.Camera.View, newCamera.Camera.View, interpolateFactor);
+ _gameCamera.Camera.Projection = Matrix::Lerp(oldCamera.Camera.Projection, newCamera.Camera.Projection, interpolateFactor);
+ _gameCamera.Camera.View = _gameCamera.Camera.View * _gameCamera.Camera.Projection;
+*/
+
+ _gameCamera.Camera.WorldPosition = Vector3::Lerp(_oldGameCamera.Camera.WorldPosition, _currentGameCamera.Camera.WorldPosition, interpolateFactor);
+ _gameCamera.Camera.WorldDirection = Vector3::Lerp(_oldGameCamera.Camera.WorldDirection, _currentGameCamera.Camera.WorldDirection, interpolateFactor);
+ _gameCamera.Camera.View = Matrix::Lerp(_oldGameCamera.Camera.View, _currentGameCamera.Camera.View, interpolateFactor);
+ _gameCamera.Camera.Projection = Matrix::Lerp(_oldGameCamera.Camera.Projection, _currentGameCamera.Camera.Projection, interpolateFactor);
+ _gameCamera.Camera.ViewProjection = _gameCamera.Camera.View * _gameCamera.Camera.Projection;
+ _gameCamera.Camera.FOV = _currentGameCamera.Camera.FOV;
+ _gameCamera.Camera.Frustum=_currentGameCamera.Camera.Frustum;
+ _gameCamera.Camera.ViewSize = _currentGameCamera.Camera.ViewSize;
+ _gameCamera.Camera.InvViewSize = _currentGameCamera.Camera.InvViewSize;
+ _gameCamera.Camera.NearPlane = _currentGameCamera.Camera.NearPlane;
+ _gameCamera.Camera.FarPlane = _currentGameCamera.Camera.FarPlane;
+
+ _interpolationFactor = interpolateFactor;
+
+ //_gameCamera = _currentGameCamera;
RenderScene(&_backBuffer, true, _gameCamera);
_context->ClearState();
_swapChain->Present(1, 0);
diff --git a/TombEngine/Renderer/RendererFrame.cpp b/TombEngine/Renderer/RendererFrame.cpp
index f56578d0a..06e39d24d 100644
--- a/TombEngine/Renderer/RendererFrame.cpp
+++ b/TombEngine/Renderer/RendererFrame.cpp
@@ -380,11 +380,18 @@ namespace TEN::Renderer
newItem->ObjectNumber = item->ObjectNumber;
newItem->Color = item->Model.Color;
newItem->Position = item->Pose.Position.ToVector3();
- newItem->Translation = Matrix::CreateTranslation(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z);
+ newItem->Translation = Matrix::CreateTranslation(newItem->Position.x, newItem->Position.y, newItem->Position.z);
newItem->Rotation = item->Pose.Orientation.ToRotationMatrix();
newItem->Scale = Matrix::CreateScale(1.0f);
newItem->World = newItem->Rotation * newItem->Translation;
+ newItem->InterpolatedPosition = Vector3::Lerp(newItem->OldPosition, newItem->Position, _interpolationFactor);
+ newItem->InterpolatedTranslation = Matrix::Lerp(newItem->OldTranslation, newItem->Translation, _interpolationFactor);
+ newItem->InterpolatedRotation = Matrix::Lerp(newItem->InterpolatedRotation, newItem->Rotation, _interpolationFactor);
+ newItem->InterpolatedWorld = Matrix::Lerp(newItem->OldWorld, newItem->World, _interpolationFactor);
+ for (int j = 0; j < MAX_BONES; j++)
+ newItem->InterpolatedAnimationTransforms[j] = Matrix::Lerp(newItem->OldAnimationTransforms[j], newItem->AnimationTransforms[j], _interpolationFactor);
+
CalculateLightFades(newItem);
CollectLightsForItem(newItem);
@@ -832,5 +839,20 @@ namespace TEN::Renderer
_items[i].DoneAnimations = false;
}
+
+ void Renderer::SaveOldState()
+ {
+ for (int i = 0; i < NUM_ITEMS; i++)
+ {
+ _items[i].OldPosition = _items[i].Position;
+ _items[i].OldWorld = _items[i].World;
+ _items[i].OldTranslation = _items[i].Translation;
+ _items[i].OldRotation = _items[i].Rotation;
+ _items[i].OldScale = _items[i].Scale;
+ for (int j = 0; j < MAX_BONES; j++)
+ _items[i].OldAnimationTransforms[j] = _items[i].AnimationTransforms[j];
+ }
+ }
+
} // namespace TEN::Renderer
diff --git a/TombEngine/Renderer/RendererHelper.cpp b/TombEngine/Renderer/RendererHelper.cpp
index 490a0b48d..4ef1310fc 100644
--- a/TombEngine/Renderer/RendererHelper.cpp
+++ b/TombEngine/Renderer/RendererHelper.cpp
@@ -79,7 +79,7 @@ namespace TEN::Renderer
{
auto offset0 = frameData.FramePtr0->Offset;
auto rotMatrix = Matrix::CreateFromQuaternion(frameData.FramePtr0->BoneOrientations[bonePtr->Index]);
-
+
if (frameData.Alpha != 0.0f)
{
auto offset1 = frameData.FramePtr1->Offset;
@@ -362,6 +362,9 @@ namespace TEN::Renderer
farView = DEFAULT_FAR_VIEW;
farView = farView;
+
+ _oldGameCamera = _currentGameCamera;
+ _currentGameCamera = RenderView(cam, roll, fov, 32, farView, g_Configuration.ScreenWidth, g_Configuration.ScreenHeight);
_gameCamera = RenderView(cam, roll, fov, 32, farView, g_Configuration.ScreenWidth, g_Configuration.ScreenHeight);
}
diff --git a/TombEngine/Renderer/RendererLara.cpp b/TombEngine/Renderer/RendererLara.cpp
index bccc49e04..4539999d8 100644
--- a/TombEngine/Renderer/RendererLara.cpp
+++ b/TombEngine/Renderer/RendererLara.cpp
@@ -302,10 +302,10 @@ void TEN::Renderer::Renderer::DrawLara(RenderView& view, RendererPass rendererPa
RendererRoom* room = &_rooms[LaraItem->RoomNumber];
- _stItem.World = _laraWorldMatrix;
+ _stItem.World = item->InterpolatedWorld; // _laraWorldMatrix;
_stItem.Color = item->Color;
_stItem.AmbientLight = item->AmbientLight;
- memcpy(_stItem.BonesMatrices, laraObj.AnimationTransforms.data(), laraObj.AnimationTransforms.size() * sizeof(Matrix));
+ memcpy(_stItem.BonesMatrices, item->InterpolatedAnimationTransforms, laraObj.AnimationTransforms.size() * sizeof(Matrix));
for (int k = 0; k < laraSkin.ObjectMeshes.size(); k++)
{
_stItem.BoneLightModes[k] = (int)GetMesh(nativeItem->Model.MeshIndex[k])->LightMode;
diff --git a/TombEngine/Renderer/Structures/RendererItem.h b/TombEngine/Renderer/Structures/RendererItem.h
index 078b6177b..d4840a0e8 100644
--- a/TombEngine/Renderer/Structures/RendererItem.h
+++ b/TombEngine/Renderer/Structures/RendererItem.h
@@ -20,6 +20,20 @@ namespace TEN::Renderer::Structures
Matrix Scale;
Matrix AnimationTransforms[MAX_BONES];
+ Vector3 OldPosition;
+ Matrix OldWorld;
+ Matrix OldTranslation;
+ Matrix OldRotation;
+ Matrix OldScale;
+ Matrix OldAnimationTransforms[MAX_BONES];
+
+ Vector3 InterpolatedPosition;
+ Matrix InterpolatedWorld;
+ Matrix InterpolatedTranslation;
+ Matrix InterpolatedRotation;
+ Matrix InterpolatedScale;
+ Matrix InterpolatedAnimationTransforms[MAX_BONES];
+
int RoomNumber = NO_ROOM;
int PrevRoomNumber = NO_ROOM;
Vector4 Color;
diff --git a/TombEngine/Specific/clock.cpp b/TombEngine/Specific/clock.cpp
index 4812b9511..e1a04f259 100644
--- a/TombEngine/Specific/clock.cpp
+++ b/TombEngine/Specific/clock.cpp
@@ -1,52 +1,57 @@
-#include "framework.h"
-#include "Specific/clock.h"
-
-LARGE_INTEGER PerformanceCount;
-double LdFreq;
-double LdSync;
-
-bool TimeReset()
-{
- LARGE_INTEGER fq;
- QueryPerformanceCounter(&fq);
- LdSync = (double)fq.LowPart + (double)fq.HighPart * (double)0xffffffff;
- LdSync /= LdFreq;
- return true;
-}
-
-bool TimeInit()
-{
- LARGE_INTEGER fq;
- if (!QueryPerformanceFrequency(&fq))
- return false;
- LdFreq = (double)fq.LowPart + (double)fq.HighPart * (double)0xFFFFFFFF;
- LdFreq /= 60.0;
- TimeReset();
- return true;
-}
-
-int Sync()
-{
- LARGE_INTEGER ct;
- double dCounter;
- QueryPerformanceCounter(&ct);
- dCounter = (double)ct.LowPart + (double)ct.HighPart * (double)0xFFFFFFFF;
- dCounter /= LdFreq;
- long nFrames = long(dCounter) - long(LdSync);
- LdSync = dCounter;
- return nFrames;
-}
-
-GameTime GetGameTime(int frameCount)
-{
- GameTime result = {};
-
- auto seconds = GameTimer / FPS;
-
- result.Days = (seconds / (DAY_UNIT * TIME_UNIT * TIME_UNIT));
- result.Hours = (seconds % (DAY_UNIT * TIME_UNIT * TIME_UNIT)) / (TIME_UNIT * TIME_UNIT);
- result.Minutes = (seconds / TIME_UNIT) % TIME_UNIT;
- result.Seconds = (seconds % TIME_UNIT);
-
- return result;
+#include "framework.h"
+#include "Specific/clock.h"
+
+LARGE_INTEGER PerformanceCount;
+double LdFreq;
+double LdSync;
+
+bool TimeReset()
+{
+ LARGE_INTEGER fq;
+ QueryPerformanceCounter(&fq);
+ LdSync = (double)fq.LowPart + (double)fq.HighPart * (double)0xffffffff;
+ LdSync /= LdFreq;
+ return true;
+}
+
+bool TimeInit()
+{
+ LARGE_INTEGER fq;
+ if (!QueryPerformanceFrequency(&fq))
+ return false;
+ LdFreq = (double)fq.LowPart + (double)fq.HighPart * (double)0xFFFFFFFF;
+ LdFreq /= 60.0;
+ TimeReset();
+ return true;
+}
+
+int Sync()
+{
+ LARGE_INTEGER ct;
+ double dCounter;
+ QueryPerformanceCounter(&ct);
+ dCounter = (double)ct.LowPart + (double)ct.HighPart * (double)0xFFFFFFFF;
+ dCounter /= LdFreq;
+ long nFrames = long(dCounter) - long(LdSync);
+ LdSync = dCounter;
+ return nFrames;
+}
+
+double Clock_GetCurrent()
+{
+ return 0;
+}
+
+GameTime GetGameTime(int frameCount)
+{
+ GameTime result = {};
+
+ auto seconds = GameTimer / FPS;
+
+ result.Days = (seconds / (DAY_UNIT * TIME_UNIT * TIME_UNIT));
+ result.Hours = (seconds % (DAY_UNIT * TIME_UNIT * TIME_UNIT)) / (TIME_UNIT * TIME_UNIT);
+ result.Minutes = (seconds / TIME_UNIT) % TIME_UNIT;
+ result.Seconds = (seconds % TIME_UNIT);
+
+ return result;
}
\ No newline at end of file
diff --git a/TombEngine/Specific/clock.h b/TombEngine/Specific/clock.h
index 2fd36373b..9b0a1a9ad 100644
--- a/TombEngine/Specific/clock.h
+++ b/TombEngine/Specific/clock.h
@@ -1,24 +1,26 @@
-#pragma once
-#include "Game/control/control.h"
-
-// This might not be the exact amount of time that has passed, but giving it a
-// value of 1/30 keeps it in lock-step with the rest of the game logic,
-// which assumes 30 iterations per second.
-constexpr auto FPS = 30;
-constexpr auto DELTA_TIME = 1.0f / FPS;
-constexpr auto TIME_UNIT = 60;
-constexpr auto DAY_UNIT = 24;
-
-struct GameTime
-{
- int Days;
- int Hours;
- int Minutes;
- int Seconds;
-};
-
-int Sync();
-bool TimeInit();
-bool TimeReset();
-
-GameTime GetGameTime(int frameCount);
+#pragma once
+#include "Game/control/control.h"
+
+// This might not be the exact amount of time that has passed, but giving it a
+// value of 1/30 keeps it in lock-step with the rest of the game logic,
+// which assumes 30 iterations per second.
+constexpr auto FPS = 30;
+constexpr auto DELTA_TIME = 1.0f / FPS;
+constexpr auto TIME_UNIT = 60;
+constexpr auto DAY_UNIT = 24;
+
+struct GameTime
+{
+ int Days;
+ int Hours;
+ int Minutes;
+ int Seconds;
+};
+
+int Sync();
+bool TimeInit();
+bool TimeReset();
+
+double Clock_GetCurrent();
+
+GameTime GetGameTime(int frameCount);
From f9589155d589c698a36211029e7bf29ca44fea97 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Tue, 5 Mar 2024 09:53:12 +0100
Subject: [PATCH 061/410] Fixed horizon flickering
---
TombEngine/Renderer/RendererDraw.cpp | 8 +++++---
TombEngine/Renderer/RendererLara.cpp | 2 +-
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index 4a9357491..f054d28ec 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -2660,8 +2660,10 @@ namespace TEN::Renderer
{
auto weather = TEN::Effects::Environment::Weather;
- auto translation = Matrix::CreateTranslation(Camera.pos.x + weather.SkyPosition(s) - i * SKY_SIZE,
- Camera.pos.y - 1536.0f, Camera.pos.z);
+ auto translation = Matrix::CreateTranslation(
+ renderView.Camera.WorldPosition.x + weather.SkyPosition(s) - i * SKY_SIZE,
+ renderView.Camera.WorldPosition.y - 1536.0f,
+ renderView.Camera.WorldPosition.z);
auto world = rotation * translation;
_stStatic.World = (rotation * translation);
@@ -2685,7 +2687,7 @@ namespace TEN::Renderer
auto& moveableObj = *_moveableObjects[ID_HORIZON];
- _stStatic.World = Matrix::CreateTranslation(Camera.pos.x, Camera.pos.y, Camera.pos.z);
+ _stStatic.World = Matrix::CreateTranslation(renderView.Camera.WorldPosition);
_stStatic.Color = Vector4::One;
_stStatic.ApplyFogBulbs = 1;
_cbStatic.UpdateData(_stStatic, _context.Get());
diff --git a/TombEngine/Renderer/RendererLara.cpp b/TombEngine/Renderer/RendererLara.cpp
index 4539999d8..b294e5735 100644
--- a/TombEngine/Renderer/RendererLara.cpp
+++ b/TombEngine/Renderer/RendererLara.cpp
@@ -345,7 +345,7 @@ void Renderer::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, Render
// First matrix is Lara's head matrix, then all hair unit segment matrices.
// Bones are adjusted at load time to account for this.
_stItem.World = Matrix::Identity;
- _stItem.BonesMatrices[0] = itemToDraw->AnimationTransforms[LM_HEAD] * _laraWorldMatrix;
+ _stItem.BonesMatrices[0] = itemToDraw->InterpolatedAnimationTransforms[LM_HEAD] * _laraWorldMatrix;
for (int i = 0; i < unit.Segments.size(); i++)
{
From 96d08f41e79c8eff4ebc0d46cfed297af77ee79d Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Wed, 6 Mar 2024 14:50:16 +0100
Subject: [PATCH 062/410] Fixed lag logic
---
TombEngine/Game/control/control.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index cd0ee8f09..27a5dd646 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -581,8 +581,8 @@ GameStatus DoGameLoop(int levelIndex)
lastTime = currentTime;
controlLag += frameTime;
- //while (controlLag >= controlFrameTime)
- if (controlLag >= controlFrameTime)
+ while (controlLag >= controlFrameTime)
+ //if (controlLag >= controlFrameTime)
{
memcpy(&PreviousCamera, &Camera, sizeof(CAMERA_INFO));
status = ControlPhase(0);
From c44e4d40be15abd474d0cfa6f66718dea4400515 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Thu, 7 Mar 2024 06:16:12 +0100
Subject: [PATCH 063/410] Clock reset on window focus change, inventory and
pause menu
---
TombEngine/Game/control/control.cpp | 258 ++++++++++++++--------------
TombEngine/Game/control/control.h | 2 +
TombEngine/Game/gui.cpp | 11 ++
TombEngine/Specific/winmain.cpp | 6 +
TombEngine/Specific/winmain.h | 80 ++++-----
5 files changed, 187 insertions(+), 170 deletions(-)
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index 27a5dd646..2972de79b 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -145,124 +145,123 @@ GameStatus ControlPhase(int numFrames)
}
g_GameStringsHandler->ProcessDisplayStrings(DELTA_TIME);
-
+
bool isFirstTime = true;
static int framesCount = 0;
- //for (framesCount += numFrames; framesCount > 0; framesCount -= LOOP_FRAME_COUNT)
+ // Save current state to old variables for interpolation
+ SaveOldState();
+ g_Renderer.SaveOldState();
+
+ // Controls are polled before OnLoop, so input data could be
+ // overwritten by script API methods.
+ HandleControls(isTitle);
+
+ // Pre-loop script and event handling.
+ g_GameScript->OnLoop(DELTA_TIME, false); // TODO: Don't use DELTA_TIME constant with variable framerate
+ HandleAllGlobalEvents(EventType::Loop, (Activator)LaraItem->Index);
+
+ // Control lock is processed after handling scripts, because builder may want to
+ // process input externally, while still locking Lara from input.
+ if (!isTitle && Lara.Control.IsLocked)
+ ClearAllActions();
+
+ // Handle inventory / pause / load / save screens.
+ auto result = HandleMenuCalls(isTitle);
+ if (result != GameStatus::Normal)
+ return result;
+
+ // Handle global input events.
+ result = HandleGlobalInputEvents(isTitle);
+ if (result != GameStatus::Normal)
+ return result;
+
+ // Queued input actions are read again and cleared after UI
+ // interrupts are processed, so first frame after exiting UI
+ // will still register it.
+ ApplyActionQueue();
+ ClearActionQueue();
+
+ UpdateAllItems();
+ UpdateAllEffects();
+ UpdateLara(LaraItem, isTitle);
+
+ g_GameScriptEntities->TestCollidingObjects();
+
+ if (UseSpotCam)
{
- g_Renderer.SaveOldState();
+ // Draw flyby cameras.
+ CalculateSpotCameras();
+ }
+ else
+ {
+ // Do the standard camera.
+ TrackCameraInit = false;
+ CalculateCamera(LaraCollision);
+ }
- // Controls are polled before OnLoop, so input data could be
- // overwritten by script API methods.
- HandleControls(isTitle);
+ // Update oscillator seed.
+ Wibble = (Wibble + WIBBLE_SPEED) & WIBBLE_MAX;
- // Pre-loop script and event handling.
- g_GameScript->OnLoop(DELTA_TIME, false); // TODO: Don't use DELTA_TIME constant with variable framerate
- HandleAllGlobalEvents(EventType::Loop, (Activator)LaraItem->Index);
+ // Smash shatters and clear stopper flags under them.
+ UpdateShatters();
- // Control lock is processed after handling scripts, because builder may want to
- // process input externally, while still locking Lara from input.
- if (!isTitle && Lara.Control.IsLocked)
- ClearAllActions();
+ // Update weather.
+ Weather.Update();
- // Handle inventory / pause / load / save screens.
- auto result = HandleMenuCalls(isTitle);
- if (result != GameStatus::Normal)
- return result;
+ // Update effects.
+ StreamerEffect.Update();
+ UpdateSparks();
+ UpdateFireSparks();
+ UpdateSmoke();
+ UpdateBlood();
+ UpdateBubbles();
+ UpdateDebris();
+ UpdateGunShells();
+ UpdateFootprints();
+ UpdateSplashes();
+ UpdateElectricityArcs();
+ UpdateHelicalLasers();
+ UpdateDrips();
+ UpdateRats();
+ UpdateRipples();
+ UpdateBats();
+ UpdateSpiders();
+ UpdateSparkParticles();
+ UpdateSmokeParticles();
+ UpdateSimpleParticles();
+ UpdateExplosionParticles();
+ UpdateShockwaves();
+ UpdateBeetleSwarm();
+ UpdateLocusts();
+ UpdateUnderwaterBloodParticles();
- // Handle global input events.
- result = HandleGlobalInputEvents(isTitle);
- if (result != GameStatus::Normal)
- return result;
+ // Update HUD.
+ g_Hud.Update(*LaraItem);
+ UpdateFadeScreenAndCinematicBars();
- // Queued input actions are read again and cleared after UI
- // interrupts are processed, so first frame after exiting UI
- // will still register it.
- ApplyActionQueue();
- ClearActionQueue();
+ // Rumble screen (like in submarine level of TRC).
+ if (g_GameFlow->GetLevel(CurrentLevel)->Rumble)
+ RumbleScreen();
- UpdateAllItems();
- UpdateAllEffects();
- UpdateLara(LaraItem, isTitle);
+ PlaySoundSources();
+ DoFlipEffect(FlipEffect, LaraItem);
- g_GameScriptEntities->TestCollidingObjects();
+ // Post-loop script and event handling.
+ g_GameScript->OnLoop(DELTA_TIME, true);
- if (UseSpotCam)
- {
- // Draw flyby cameras.
- CalculateSpotCameras();
- }
- else
- {
- // Do the standard camera.
- TrackCameraInit = false;
- CalculateCamera(LaraCollision);
- }
+ // Clear savegame loaded flag.
+ JustLoaded = false;
- // Update oscillator seed.
- Wibble = (Wibble + WIBBLE_SPEED) & WIBBLE_MAX;
+ // Update timers.
+ GameTimer++;
+ GlobalCounter++;
- // Smash shatters and clear stopper flags under them.
- UpdateShatters();
-
- // Update weather.
- Weather.Update();
-
- // Update effects.
- StreamerEffect.Update();
- UpdateSparks();
- UpdateFireSparks();
- UpdateSmoke();
- UpdateBlood();
- UpdateBubbles();
- UpdateDebris();
- UpdateGunShells();
- UpdateFootprints();
- UpdateSplashes();
- UpdateElectricityArcs();
- UpdateHelicalLasers();
- UpdateDrips();
- UpdateRats();
- UpdateRipples();
- UpdateBats();
- UpdateSpiders();
- UpdateSparkParticles();
- UpdateSmokeParticles();
- UpdateSimpleParticles();
- UpdateExplosionParticles();
- UpdateShockwaves();
- UpdateBeetleSwarm();
- UpdateLocusts();
- UpdateUnderwaterBloodParticles();
-
- // Update HUD.
- g_Hud.Update(*LaraItem);
- UpdateFadeScreenAndCinematicBars();
-
- // Rumble screen (like in submarine level of TRC).
- if (g_GameFlow->GetLevel(CurrentLevel)->Rumble)
- RumbleScreen();
-
- PlaySoundSources();
- DoFlipEffect(FlipEffect, LaraItem);
-
- // Post-loop script and event handling.
- g_GameScript->OnLoop(DELTA_TIME, true);
-
- // Clear savegame loaded flag.
- JustLoaded = false;
-
- // Update timers.
- GameTimer++;
- GlobalCounter++;
-
- // Add renderer objects on the first processed frame.
- if (isFirstTime)
- {
- g_Renderer.Lock();
- isFirstTime = false;
- }
+ // Add renderer objects on the first processed frame.
+ if (isFirstTime)
+ {
+ g_Renderer.Lock();
+ isFirstTime = false;
}
using ns = std::chrono::nanoseconds;
@@ -555,19 +554,13 @@ GameStatus DoGameLoop(int levelIndex)
LARGE_INTEGER lastTime;
LARGE_INTEGER currentTime;
- LARGE_INTEGER lastDrawTime;
- LARGE_INTEGER currentDrawTime;
double controlLag = 0;
- double drawLag = 0;
double frameTime = 0;
constexpr auto controlFrameTime = 1000.0f / 30.0f;
- constexpr auto drawFrameTime = 1000.0f / 60.0f;
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
-
QueryPerformanceCounter(&lastTime);
- QueryPerformanceCounter(&lastDrawTime);
int controlCalls = 0;
int drawCalls = 0;
@@ -576,20 +569,30 @@ GameStatus DoGameLoop(int levelIndex)
while (DoTheGame)
{
- QueryPerformanceCounter(¤tTime);
- frameTime = (currentTime.QuadPart - lastTime.QuadPart) * 1000.0 / frequency.QuadPart;
- lastTime = currentTime;
- controlLag += frameTime;
+ if (App.ResetClock)
+ {
+ App.ResetClock = false;
+ QueryPerformanceCounter(&lastTime);
+ currentTime = lastTime;
+ controlLag = 0;
+ frameTime = 0;
+ }
+ else
+ {
+ QueryPerformanceCounter(¤tTime);
+ frameTime = (currentTime.QuadPart - lastTime.QuadPart) * 1000.0 / frequency.QuadPart;
+ lastTime = currentTime;
+ controlLag += frameTime;
+ }
while (controlLag >= controlFrameTime)
- //if (controlLag >= controlFrameTime)
{
memcpy(&PreviousCamera, &Camera, sizeof(CAMERA_INFO));
status = ControlPhase(0);
controlLag -= controlFrameTime;
controlCalls++;
}
-
+
if (!levelIndex)
{
UpdateInputActions(LaraItem);
@@ -626,27 +629,15 @@ GameStatus DoGameLoop(int levelIndex)
}
}
- QueryPerformanceCounter(¤tDrawTime);
- frameTime = (currentDrawTime.QuadPart - lastDrawTime.QuadPart) * 1000.0 / frequency.QuadPart;
- lastDrawTime = currentDrawTime;
- drawLag += frameTime;
-
- //if (drawLag >= drawFrameTime)
- {
- float interpolateFactor = std::min((float)controlLag / (float)controlFrameTime, 1.0f);
- //printf("%f\n", interpolateFactor);
-
- numFrames = DrawPhase(!levelIndex, interpolateFactor);
- drawLag -= drawFrameTime;
- drawCalls++;
- }
-
-
+ float interpolateFactor = std::min((float)controlLag / (float)controlFrameTime, 1.0f);
+ DrawPhase(!levelIndex, interpolateFactor);
+ drawCalls++;
Sound_UpdateScene();
}
EndGameLoop(levelIndex, status);
+
return status;
}
@@ -659,6 +650,11 @@ void EndGameLoop(int levelIndex, GameStatus reason)
StopRumble();
}
+void SaveOldState()
+{
+
+}
+
void HandleControls(bool isTitle)
{
// Poll input devices and update input variables.
diff --git a/TombEngine/Game/control/control.h b/TombEngine/Game/control/control.h
index be2af5736..0f88acb1d 100644
--- a/TombEngine/Game/control/control.h
+++ b/TombEngine/Game/control/control.h
@@ -98,4 +98,6 @@ void InitializeOrLoadGame(bool loadGame);
void InitializeScripting(int levelIndex, bool loadGame);
void DeInitializeScripting(int levelIndex);
+void SaveOldState();
+
unsigned CALLBACK GameMain(void*);
diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp
index bc1b82c6e..745254ae6 100644
--- a/TombEngine/Game/gui.cpp
+++ b/TombEngine/Game/gui.cpp
@@ -25,6 +25,7 @@
#include "Specific/configuration.h"
#include "Specific/level.h"
#include "Specific/trutils.h"
+#include "Specific/winmain.h"
using namespace TEN::Input;
using namespace TEN::Renderer;
@@ -1166,6 +1167,7 @@ namespace TEN::Gui
case Menu::Display:
HandleDisplaySettingsInput(true);
+ App.ResetClock = true;
return InventoryResult::None;
case Menu::GeneralActions:
@@ -1173,10 +1175,12 @@ namespace TEN::Gui
case Menu::QuickActions:
case Menu::MenuActions:
HandleControlSettingsInput(item, true);
+ App.ResetClock = true;
return InventoryResult::None;
case Menu::OtherSettings:
HandleOtherSettingsInput(true);
+ App.ResetClock = true;
return InventoryResult::None;
}
@@ -1242,6 +1246,7 @@ namespace TEN::Gui
case PauseMenuOption::ExitToTitle:
SetInventoryMode(InventoryMode::None);
+ App.ResetClock = true;
return InventoryResult::ExitToTitle;
break;
}
@@ -1259,6 +1264,7 @@ namespace TEN::Gui
}
}
+ App.ResetClock = true;
return InventoryResult::None;
}
@@ -3315,7 +3321,10 @@ namespace TEN::Gui
while (!exitLoop)
{
if (ThreadEnded)
+ {
+ App.ResetClock = true;
return false;
+ }
TimeInMenu++;
GameTimer++;
@@ -3402,6 +3411,8 @@ namespace TEN::Gui
lara->Inventory.IsBusy = lara->Inventory.OldBusy;
SetInventoryMode(InventoryMode::None);
+ App.ResetClock = true;
+
return doLoad;
}
diff --git a/TombEngine/Specific/winmain.cpp b/TombEngine/Specific/winmain.cpp
index fe1cd8bc3..3a3d7438b 100644
--- a/TombEngine/Specific/winmain.cpp
+++ b/TombEngine/Specific/winmain.cpp
@@ -165,6 +165,12 @@ LRESULT CALLBACK WinAppProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
return 0;
}
+ if (msg == WM_ACTIVATEAPP)
+ {
+ App.ResetClock = true;
+ return DefWindowProcA(hWnd, msg, wParam, (LPARAM)lParam);
+ }
+
if (msg > WM_CLOSE)
{
if (msg == WM_COMMAND)
diff --git a/TombEngine/Specific/winmain.h b/TombEngine/Specific/winmain.h
index 5162e48c9..80427898b 100644
--- a/TombEngine/Specific/winmain.h
+++ b/TombEngine/Specific/winmain.h
@@ -1,40 +1,42 @@
-#pragma once
-#pragma comment(linker,"/manifestdependency:\"" \
- "type='win32' " \
- "name='Microsoft.Windows.Common-Controls' " \
- "version='6.0.0.0' " \
- "processorArchitecture='*' " \
- "publicKeyToken='6595b64144ccf1df' " \
- "language='*'\"")
-
-#include
-#include
-
-#include "Math/Math.h"
-
-using namespace TEN::Math;
-
-struct WINAPP
-{
- HINSTANCE hInstance;
- int nFillMode;
- WNDCLASS WindowClass;
- HWND WindowHandle;
- bool bNoFocus;
- bool isInScene;
-};
-
-extern bool DebugMode;
-extern HWND WindowsHandle;
-
-// return handle
-#define BeginThread(function, threadid) _beginthreadex(0, 0, &function, 0, 0, &threadid)
-#define EndThread() _endthreadex(1)
-
-void WinProcMsg();
-int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd);
-void WinClose();
-LRESULT CALLBACK WinAppProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
-void CALLBACK HandleWmCommand(unsigned short wParam);
-Vector2i GetScreenResolution();
+#pragma once
+#pragma comment(linker,"/manifestdependency:\"" \
+ "type='win32' " \
+ "name='Microsoft.Windows.Common-Controls' " \
+ "version='6.0.0.0' " \
+ "processorArchitecture='*' " \
+ "publicKeyToken='6595b64144ccf1df' " \
+ "language='*'\"")
+
+#include
+#include
+
+#include "Math/Math.h"
+
+using namespace TEN::Math;
+
+struct WINAPP
+{
+ HINSTANCE hInstance;
+ int nFillMode;
+ WNDCLASS WindowClass;
+ HWND WindowHandle;
+ bool bNoFocus;
+ bool isInScene;
+ bool ResetClock;
+};
+
+extern bool DebugMode;
+extern HWND WindowsHandle;
+extern WINAPP App;
+
+// return handle
+#define BeginThread(function, threadid) _beginthreadex(0, 0, &function, 0, 0, &threadid)
+#define EndThread() _endthreadex(1)
+
+void WinProcMsg();
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd);
+void WinClose();
+LRESULT CALLBACK WinAppProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
+void CALLBACK HandleWmCommand(unsigned short wParam);
+Vector2i GetScreenResolution();
std::vector GetAllSupportedScreenResolutions();
\ No newline at end of file
From 118c6d6105842861723e13ff256835be1c2ad0f5 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sun, 10 Mar 2024 15:05:02 +1100
Subject: [PATCH 064/410] Fix final bug; remove debug code
---
TombEngine/Game/Lara/lara.cpp | 60 --------------------
TombEngine/Game/Lara/lara_collide.cpp | 25 ++++----
TombEngine/Game/Lara/lara_collide.h | 5 --
TombEngine/Game/collision/PointCollision.cpp | 13 ++---
TombEngine/Game/collision/collide_room.h | 14 +++--
5 files changed, 29 insertions(+), 88 deletions(-)
diff --git a/TombEngine/Game/Lara/lara.cpp b/TombEngine/Game/Lara/lara.cpp
index c8715618a..efff5745f 100644
--- a/TombEngine/Game/Lara/lara.cpp
+++ b/TombEngine/Game/Lara/lara.cpp
@@ -63,70 +63,10 @@ LaraInfo Lara = {};
ItemInfo* LaraItem;
CollisionInfo LaraCollision = {};
-//---------debug
-#include
-#include "Specific/Input/Input.h"
-//----------
-
void LaraControl(ItemInfo* item, CollisionInfo* coll)
{
auto& player = GetLaraInfo(*item);
- //---------debug
-
- static int bridgeItemNumber = NO_ITEM;
- if (coll->LastBridgeItemNumber != NO_ITEM)
- bridgeItemNumber = coll->LastBridgeItemNumber;
-
- if (bridgeItemNumber != NO_ITEM)
- {
- constexpr auto TRANSLATE_STEP = BLOCK(0.1f);
-
- auto& bridgeItem = g_Level.Items[bridgeItemNumber];
-
- // Move bridge.
- if (KeyMap[OIS::KeyCode::KC_K])
- {
- auto rotMatrix = EulerAngles(0, Camera.actualAngle, 0).ToRotationMatrix();
- auto offset = Vector3(AxisMap[(int)InputAxis::Mouse].x, 0.0f, -AxisMap[(int)InputAxis::Mouse].y) * 1000;
- bridgeItem.Pose.Position += Vector3::Transform(offset, rotMatrix);
-
- UpdateItemRoom(bridgeItem.Index);
- UpdateBridgeItem(bridgeItem);
- }
- else if (KeyMap[OIS::KeyCode::KC_L])
- {
- auto offset = Vector3(0.0f, AxisMap[(int)InputAxis::Mouse].y, 0.0f) * 1000;
- bridgeItem.Pose.Position += offset;
-
- UpdateItemRoom(bridgeItem.Index);
- UpdateBridgeItem(bridgeItem);
- }
- // Rotate bridge.
- else if (KeyMap[OIS::KeyCode::KC_H])
- {
- auto rotMatrix = EulerAngles(0, Camera.actualAngle, 0).ToRotationMatrix();
- auto offset = Vector3(AxisMap[(int)InputAxis::Mouse].x, 0.0f, -AxisMap[(int)InputAxis::Mouse].y) * 10000;
- offset = Vector3::Transform(offset, rotMatrix);
-
- auto rot = EulerAngles(-AxisMap[(int)InputAxis::Mouse].x * 10000, 0.0f, -AxisMap[(int)InputAxis::Mouse].y * 10000);
- bridgeItem.Pose.Orientation += rot;
-
- UpdateItemRoom(bridgeItem.Index);
- UpdateBridgeItem(bridgeItem);
- }
- else if (KeyMap[OIS::KeyCode::KC_J])
- {
- auto rot = EulerAngles(0.0f, AxisMap[(int)InputAxis::Mouse].y * 10000, 0.0f);
- bridgeItem.Pose.Orientation += rot;
-
- UpdateItemRoom(bridgeItem.Index);
- UpdateBridgeItem(bridgeItem);
- }
- }
-
- //----------
-
// Alert nearby creatures.
if (player.Control.Weapon.HasFired)
{
diff --git a/TombEngine/Game/Lara/lara_collide.cpp b/TombEngine/Game/Lara/lara_collide.cpp
index 358dc2c1d..1d60e2795 100644
--- a/TombEngine/Game/Lara/lara_collide.cpp
+++ b/TombEngine/Game/Lara/lara_collide.cpp
@@ -24,6 +24,11 @@ using namespace TEN::Collision::PointCollision;
using namespace TEN::Entities::Player;
using namespace TEN::Input;
+constexpr auto DEFLECT_STRAIGHT_ANGLE = ANGLE(5.0f);
+constexpr auto DEFLECT_DIAGONAL_ANGLE = ANGLE(12.0f);
+constexpr auto DEFLECT_STRAIGHT_ANGLE_CRAWL = ANGLE(2.0f);
+constexpr auto DEFLECT_DIAGONAL_ANGLE_CRAWL = ANGLE(5.0f);
+
// -----------------------------
// COLLISION TEST FUNCTIONS
// For State Control & Collision
@@ -45,12 +50,12 @@ bool LaraDeflectEdge(ItemInfo* item, CollisionInfo* coll)
if (coll->CollisionType == CT_LEFT)
{
ShiftItem(item, coll);
- item->Pose.Orientation.y += ANGLE(coll->DiagonalStepAtLeft() ? DEFLECT_DIAGONAL_ANGLE : DEFLECT_STRAIGHT_ANGLE);
+ item->Pose.Orientation.y += coll->DiagonalStepAtLeft() ? DEFLECT_DIAGONAL_ANGLE : DEFLECT_STRAIGHT_ANGLE;
}
else if (coll->CollisionType == CT_RIGHT)
{
ShiftItem(item, coll);
- item->Pose.Orientation.y -= ANGLE(coll->DiagonalStepAtRight() ? DEFLECT_DIAGONAL_ANGLE : DEFLECT_STRAIGHT_ANGLE);
+ item->Pose.Orientation.y -= coll->DiagonalStepAtRight() ? DEFLECT_DIAGONAL_ANGLE : DEFLECT_STRAIGHT_ANGLE;
}
else if (coll->LastBridgeItemNumber != NO_ITEM)
{
@@ -120,11 +125,11 @@ bool LaraDeflectEdgeJump(ItemInfo* item, CollisionInfo* coll)
switch (coll->CollisionType)
{
case CT_LEFT:
- item->Pose.Orientation.y += ANGLE(DEFLECT_STRAIGHT_ANGLE);
+ item->Pose.Orientation.y += DEFLECT_STRAIGHT_ANGLE;
break;
case CT_RIGHT:
- item->Pose.Orientation.y -= ANGLE(DEFLECT_STRAIGHT_ANGLE);
+ item->Pose.Orientation.y -= DEFLECT_STRAIGHT_ANGLE;
break;
case CT_TOP:
@@ -156,11 +161,11 @@ void LaraSlideEdgeJump(ItemInfo* item, CollisionInfo* coll)
switch (coll->CollisionType)
{
case CT_LEFT:
- item->Pose.Orientation.y += ANGLE(DEFLECT_STRAIGHT_ANGLE);
+ item->Pose.Orientation.y += DEFLECT_STRAIGHT_ANGLE;
break;
case CT_RIGHT:
- item->Pose.Orientation.y -= ANGLE(DEFLECT_STRAIGHT_ANGLE);
+ item->Pose.Orientation.y -= DEFLECT_STRAIGHT_ANGLE;
break;
case CT_TOP:
@@ -198,12 +203,12 @@ bool LaraDeflectEdgeCrawl(ItemInfo* item, CollisionInfo* coll)
if (coll->CollisionType == CT_LEFT)
{
ShiftItem(item, coll);
- item->Pose.Orientation.y += ANGLE(coll->DiagonalStepAtLeft() ? DEFLECT_DIAGONAL_ANGLE_CRAWL : DEFLECT_STRAIGHT_ANGLE_CRAWL);
+ item->Pose.Orientation.y += coll->DiagonalStepAtLeft() ? DEFLECT_DIAGONAL_ANGLE_CRAWL : DEFLECT_STRAIGHT_ANGLE_CRAWL;
}
else if (coll->CollisionType == CT_RIGHT)
{
ShiftItem(item, coll);
- item->Pose.Orientation.y -= ANGLE(coll->DiagonalStepAtRight() ? DEFLECT_DIAGONAL_ANGLE_CRAWL : DEFLECT_STRAIGHT_ANGLE_CRAWL);
+ item->Pose.Orientation.y -= coll->DiagonalStepAtRight() ? DEFLECT_DIAGONAL_ANGLE_CRAWL : DEFLECT_STRAIGHT_ANGLE_CRAWL;
}
return false;
@@ -229,12 +234,12 @@ bool LaraDeflectEdgeMonkey(ItemInfo* item, CollisionInfo* coll)
if (coll->CollisionType == CT_LEFT)
{
ShiftItem(item, coll);
- item->Pose.Orientation.y += ANGLE(coll->DiagonalStepAtLeft() ? DEFLECT_DIAGONAL_ANGLE : DEFLECT_STRAIGHT_ANGLE);
+ item->Pose.Orientation.y += coll->DiagonalStepAtLeft() ? DEFLECT_DIAGONAL_ANGLE : DEFLECT_STRAIGHT_ANGLE;
}
else if (coll->CollisionType == CT_RIGHT)
{
ShiftItem(item, coll);
- item->Pose.Orientation.y -= ANGLE(coll->DiagonalStepAtRight() ? DEFLECT_DIAGONAL_ANGLE : DEFLECT_STRAIGHT_ANGLE);
+ item->Pose.Orientation.y -= coll->DiagonalStepAtRight() ? DEFLECT_DIAGONAL_ANGLE : DEFLECT_STRAIGHT_ANGLE;
}
return false;
diff --git a/TombEngine/Game/Lara/lara_collide.h b/TombEngine/Game/Lara/lara_collide.h
index 79a25d9ad..41a6bf3b1 100644
--- a/TombEngine/Game/Lara/lara_collide.h
+++ b/TombEngine/Game/Lara/lara_collide.h
@@ -3,11 +3,6 @@
struct ItemInfo;
struct CollisionInfo;
-constexpr auto DEFLECT_STRAIGHT_ANGLE = 5.0f;
-constexpr auto DEFLECT_DIAGONAL_ANGLE = 12.0f;
-constexpr auto DEFLECT_STRAIGHT_ANGLE_CRAWL = 2.0f;
-constexpr auto DEFLECT_DIAGONAL_ANGLE_CRAWL = 5.0f;
-
// -----------------------------
// COLLISION TEST FUNCTIONS
// For State Control & Collision
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 42e34c183..7c596723f 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -14,9 +14,6 @@ using namespace TEN::Collision::Floordata;
using namespace TEN::Collision::Room;
using namespace TEN::Math;
-// TODO
-// BUG: Grabbing diagonal ledges stopped working. Lara deflects. Minor error somewhere.
-
namespace TEN::Collision::PointCollision
{
PointCollisionData::PointCollisionData(const Vector3i& pos, int roomNumber)
@@ -57,9 +54,10 @@ namespace TEN::Collision::PointCollision
auto roomNumberBelow = bottomSectorPtr->GetNextRoomNumber(_position, true);
while (roomNumberBelow.has_value())
{
- auto& room = g_Level.Rooms[roomNumberBelow.value_or(bottomSectorPtr->RoomNumber)];
- bottomSectorPtr = Room::GetSector(&room, _position.x - room.x, _position.z - room.z);
+ int roomNumber = roomNumberBelow.value_or(bottomSectorPtr->RoomNumber);
+ auto& room = g_Level.Rooms[roomNumber];
+ bottomSectorPtr = Room::GetSector(&room, _position.x - room.x, _position.z - room.z);
roomNumberBelow = bottomSectorPtr->GetNextRoomNumber(_position, true);
}
_bottomSectorPtr = bottomSectorPtr;
@@ -77,9 +75,10 @@ namespace TEN::Collision::PointCollision
auto roomNumberAbove = topSectorPtr->GetNextRoomNumber(_position, false);
while (roomNumberAbove.has_value())
{
- auto& room = g_Level.Rooms[roomNumberAbove.value_or(topSectorPtr->RoomNumber)];
- topSectorPtr = Room::GetSector(&room, _position.x - room.x, _position.z - room.z);
+ int roomNumber = roomNumberAbove.value_or(topSectorPtr->RoomNumber);
+ auto& room = g_Level.Rooms[roomNumber];
+ topSectorPtr = Room::GetSector(&room, _position.x - room.x, _position.z - room.z);
roomNumberAbove = topSectorPtr->GetNextRoomNumber(_position, false);
}
_topSectorPtr = topSectorPtr;
diff --git a/TombEngine/Game/collision/collide_room.h b/TombEngine/Game/collision/collide_room.h
index 363545bc5..06c8b71cc 100644
--- a/TombEngine/Game/collision/collide_room.h
+++ b/TombEngine/Game/collision/collide_room.h
@@ -1,4 +1,5 @@
#pragma once
+#include "Game/collision/floordata.h"
#include "Math/Math.h"
#include "Objects/game_object_ids.h"
@@ -8,13 +9,14 @@ struct ItemInfo;
struct MESH_INFO;
struct ROOM_INFO;
+using namespace TEN::Collision::Floordata;
using namespace TEN::Math;
constexpr auto NO_LOWER_BOUND = -NO_HEIGHT; // Used by coll->Setup.LowerFloorBound.
constexpr auto NO_UPPER_BOUND = NO_HEIGHT; // Used by coll->Setup.UpperFloorBound.
constexpr auto COLLISION_CHECK_DISTANCE = BLOCK(8);
-constexpr auto DEFAULT_ILLEGAL_FLOOR_SLOPE_ANGLE = ANGLE(45.0f * 0.75f);
+constexpr auto DEFAULT_ILLEGAL_FLOOR_SLOPE_ANGLE = ANGLE(36.0f);
constexpr auto DEFAULT_ILLEGAL_CEILING_SLOPE_ANGLE = ANGLE(45.0f);
enum CollisionType
@@ -47,13 +49,13 @@ struct CollisionPositionData
int Floor = 0;
int Ceiling = 0;
int Bridge = 0;
- float SplitAngle = 0.0f;
+ short SplitAngle = 0;
bool FloorSlope = false;
bool CeilingSlope = false;
bool DiagonalStep = false;
- bool HasDiagonalSplit() { return ((SplitAngle == (45.0f * RADIAN)) || (SplitAngle == (135.0f * RADIAN))); }
- bool HasFlippedDiagonalSplit() { return (HasDiagonalSplit() && (SplitAngle != (45.0f * RADIAN))); }
+ bool HasDiagonalSplit() { return ((SplitAngle == SectorSurfaceData::SPLIT_ANGLE_0) || (SplitAngle == SectorSurfaceData::SPLIT_ANGLE_1)); }
+ bool HasFlippedDiagonalSplit() { return (HasDiagonalSplit() && (SplitAngle != SectorSurfaceData::SPLIT_ANGLE_0)); }
};
struct CollisionSetupData
@@ -112,8 +114,8 @@ struct CollisionInfo
bool HitStatic = false;
bool HitTallObject = false;
- bool TriangleAtRight() { return ((MiddleRight.SplitAngle != 0.0f) && (MiddleRight.SplitAngle == Middle.SplitAngle)); }
- bool TriangleAtLeft() { return ((MiddleLeft.SplitAngle != 0.0f) && (MiddleLeft.SplitAngle == Middle.SplitAngle)); }
+ bool TriangleAtRight() { return ((MiddleRight.SplitAngle != 0) && (MiddleRight.SplitAngle == Middle.SplitAngle)); }
+ bool TriangleAtLeft() { return ((MiddleLeft.SplitAngle != 0) && (MiddleLeft.SplitAngle == Middle.SplitAngle)); }
bool DiagonalStepAtRight() { return (MiddleRight.DiagonalStep && TriangleAtRight() && (NearestLedgeAngle % ANGLE(90.0f))); }
bool DiagonalStepAtLeft() { return (MiddleLeft.DiagonalStep && TriangleAtLeft() && (NearestLedgeAngle % ANGLE(90.0f))); }
};
From 2366bcbd1d8bdaf3c7983cefa419aa242a21ad01 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sun, 10 Mar 2024 15:49:42 +1100
Subject: [PATCH 065/410] Update comment; rename methods
---
TombEngine/Game/collision/PointCollision.cpp | 20 ++++++++------------
TombEngine/Game/collision/PointCollision.h | 8 ++++----
2 files changed, 12 insertions(+), 16 deletions(-)
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/PointCollision.cpp
index 7c596723f..9bdb931cc 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/PointCollision.cpp
@@ -241,25 +241,25 @@ namespace TEN::Collision::PointCollision
return GetTopSector().IsSurfaceDiagonalStep(false);
}
- bool PointCollisionData::IsFloorDiagonalSplit()
+ bool PointCollisionData::IsDiagonalFloorSplit()
{
float splitAngle = GetBottomSector().FloorSurface.SplitAngle;
return (splitAngle == SectorSurfaceData::SPLIT_ANGLE_0 || splitAngle == SectorSurfaceData::SPLIT_ANGLE_1);
}
- bool PointCollisionData::IsCeilingDiagonalSplit()
+ bool PointCollisionData::IsDiagonalCeilingSplit()
{
float splitAngle = GetTopSector().CeilingSurface.SplitAngle;
return (splitAngle == SectorSurfaceData::SPLIT_ANGLE_0 || splitAngle == SectorSurfaceData::SPLIT_ANGLE_1);
}
- bool PointCollisionData::IsFloorFlippedDiagonalSplit()
+ bool PointCollisionData::IsFlippedDiagonalFloorSplit()
{
float splitAngle = GetBottomSector().FloorSurface.SplitAngle;
return (IsDiagonalFloorStep() && splitAngle == SectorSurfaceData::SPLIT_ANGLE_1);
}
- bool PointCollisionData::IsCeilingFlippedDiagonalSplit()
+ bool PointCollisionData::IsFlippedDiagonalCeilingSplit()
{
float splitAngle = GetTopSector().CeilingSurface.SplitAngle;
return (IsDiagonalCeilingStep() && splitAngle == SectorSurfaceData::SPLIT_ANGLE_1);
@@ -339,15 +339,11 @@ namespace TEN::Collision::PointCollision
PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber)
{
- // TEMP HACK
- // GetPointCollision() takes arguments for a *current* position and room number.
- // However, since some calls to the old GetPointCollision() function had *projected*
- // positions passed to it, the room number had be corrected to account for such cases.
- // These are primarily found in camera.cpp.
- short correctedRoomNumber = roomNumber;
- GetFloor(pos.x, pos.y, pos.z, &correctedRoomNumber);
+ // HACK: Ensure room number is correct if position extends to another room.
+ // Accounts for some calls to this function which directly pass offset position instead of using dedicated overloads to probe.
+ GetFloor(pos.x, pos.y, pos.z, (short*)&roomNumber);
- return PointCollisionData(pos, correctedRoomNumber);
+ return PointCollisionData(pos, roomNumber);
}
PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber, const Vector3& dir, float dist)
diff --git a/TombEngine/Game/collision/PointCollision.h b/TombEngine/Game/collision/PointCollision.h
index cc031d4ab..b5717cec0 100644
--- a/TombEngine/Game/collision/PointCollision.h
+++ b/TombEngine/Game/collision/PointCollision.h
@@ -61,10 +61,10 @@ namespace TEN::Collision::PointCollision
bool IsIllegalCeiling();
bool IsDiagonalFloorStep();
bool IsDiagonalCeilingStep();
- bool IsFloorDiagonalSplit();
- bool IsCeilingDiagonalSplit();
- bool IsFloorFlippedDiagonalSplit();
- bool IsCeilingFlippedDiagonalSplit();
+ bool IsDiagonalFloorSplit();
+ bool IsDiagonalCeilingSplit();
+ bool IsFlippedDiagonalFloorSplit();
+ bool IsFlippedDiagonalCeilingSplit();
bool TestEnvironmentFlag(RoomEnvFlags envFlag);
From e17543c49736b7d9039c351ec15cd68a7e8fbecf Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 27 Mar 2024 16:38:55 +1100
Subject: [PATCH 066/410] Update comments
---
TombEngine/Game/collision/collide_room.h | 35 +++++++++++++-----------
1 file changed, 19 insertions(+), 16 deletions(-)
diff --git a/TombEngine/Game/collision/collide_room.h b/TombEngine/Game/collision/collide_room.h
index 3a83e31d5..c2c018073 100644
--- a/TombEngine/Game/collision/collide_room.h
+++ b/TombEngine/Game/collision/collide_room.h
@@ -60,26 +60,29 @@ struct CollisionPositionData
struct CollisionSetupData
{
- CollisionProbeMode Mode = CollisionProbeMode::Quadrants; // Probe rotation mode
- int Radius = 0; // Collision bounds horizontal size
- int Height = 0; // Collision bounds vertical size
- short ForwardAngle = 0; // Forward angle direction
+ // Collider parameters.
+ CollisionProbeMode Mode = CollisionProbeMode::Quadrants;
+ int Radius = 0;
+ int Height = 0;
+ short ForwardAngle = 0;
- int LowerFloorBound = 0; // Borderline floor step-up height
- int UpperFloorBound = 0; // Borderline floor step-down height
- int LowerCeilingBound = 0; // Borderline ceiling step-up height
- int UpperCeilingBound = 0; // Borderline ceiling step-down height
+ // Borderline step heights.
+ int LowerFloorBound = 0;
+ int UpperFloorBound = 0;
+ int LowerCeilingBound = 0;
+ int UpperCeilingBound = 0;
- bool BlockFloorSlopeUp = false; // Treat steep slopes as walls
- bool BlockFloorSlopeDown = false; // Treat steep slopes as pits
- bool BlockCeilingSlope = false; // Treat steep slopes on ceilings as walls
- bool BlockDeathFloorDown = false; // Treat death sectors as pits
- bool BlockMonkeySwingEdge = false; // Treat non-monkey sectors as walls
+ // Blocker flags.
+ bool BlockFloorSlopeUp = false;
+ bool BlockFloorSlopeDown = false;
+ bool BlockCeilingSlope = false;
+ bool BlockDeathFloorDown = false;
+ bool BlockMonkeySwingEdge = false;
- bool EnableObjectPush = false; // Can be pushed by objects
- bool EnableSpasm = false; // Convulse when pushed
+ bool EnableObjectPush = false;
+ bool EnableSpasm = false;
- // Preserve previous parameters to restore later.
+ // Previous parameters.
Vector3i PrevPosition = Vector3i::Zero;
GAME_OBJECT_ID PrevAnimObjectID = ID_NO_OBJECT;
int PrevAnimNumber = 0;
From d9d89b4139cbdde0f3fe9964cba2e56c93fadaaa Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 27 Mar 2024 16:40:37 +1100
Subject: [PATCH 067/410] Add comment
---
TombEngine/Game/collision/collide_room.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/TombEngine/Game/collision/collide_room.h b/TombEngine/Game/collision/collide_room.h
index c2c018073..a748ef8c2 100644
--- a/TombEngine/Game/collision/collide_room.h
+++ b/TombEngine/Game/collision/collide_room.h
@@ -79,6 +79,7 @@ struct CollisionSetupData
bool BlockDeathFloorDown = false;
bool BlockMonkeySwingEdge = false;
+ // Object collision inquirers.
bool EnableObjectPush = false;
bool EnableSpasm = false;
From 8e55fe316e2bd30e249de7bacc01257ba46e3aeb Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 27 Mar 2024 16:42:43 +1100
Subject: [PATCH 068/410] Update comments
---
TombEngine/Game/collision/collide_room.h | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/TombEngine/Game/collision/collide_room.h b/TombEngine/Game/collision/collide_room.h
index a748ef8c2..52a215687 100644
--- a/TombEngine/Game/collision/collide_room.h
+++ b/TombEngine/Game/collision/collide_room.h
@@ -60,30 +60,30 @@ struct CollisionPositionData
struct CollisionSetupData
{
- // Collider parameters.
+ // Collider parameters
CollisionProbeMode Mode = CollisionProbeMode::Quadrants;
int Radius = 0;
int Height = 0;
short ForwardAngle = 0;
- // Borderline step heights.
+ // Borderline step heights
int LowerFloorBound = 0;
int UpperFloorBound = 0;
int LowerCeilingBound = 0;
int UpperCeilingBound = 0;
- // Blocker flags.
+ // Blocker flags
bool BlockFloorSlopeUp = false;
bool BlockFloorSlopeDown = false;
bool BlockCeilingSlope = false;
bool BlockDeathFloorDown = false;
bool BlockMonkeySwingEdge = false;
- // Object collision inquirers.
+ // Inquirers
bool EnableObjectPush = false;
bool EnableSpasm = false;
- // Previous parameters.
+ // Previous parameters
Vector3i PrevPosition = Vector3i::Zero;
GAME_OBJECT_ID PrevAnimObjectID = ID_NO_OBJECT;
int PrevAnimNumber = 0;
@@ -93,7 +93,7 @@ struct CollisionSetupData
struct CollisionInfo
{
- CollisionSetupData Setup = {}; // In parameters
+ CollisionSetupData Setup = {};
CollisionPositionData Middle = {};
CollisionPositionData MiddleLeft = {};
@@ -118,6 +118,7 @@ struct CollisionInfo
bool HitStatic = false;
bool HitTallObject = false;
+ // Inquirers.
bool TriangleAtRight() { return ((MiddleRight.SplitAngle != 0) && (MiddleRight.SplitAngle == Middle.SplitAngle)); }
bool TriangleAtLeft() { return ((MiddleLeft.SplitAngle != 0) && (MiddleLeft.SplitAngle == Middle.SplitAngle)); }
bool DiagonalStepAtRight() { return (MiddleRight.DiagonalStep && TriangleAtRight() && (NearestLedgeAngle % ANGLE(90.0f))); }
From bab278f9df6ccaa232a40600eba788a040bee907 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Thu, 28 Mar 2024 19:27:02 +1100
Subject: [PATCH 069/410] Rename file and namespace
---
TombEngine/Game/Lara/PlayerContext.cpp | 4 ++--
TombEngine/Game/Lara/lara.cpp | 4 ++--
TombEngine/Game/Lara/lara_climb.cpp | 4 ++--
TombEngine/Game/Lara/lara_collide.cpp | 4 ++--
TombEngine/Game/Lara/lara_flare.cpp | 4 ++--
TombEngine/Game/Lara/lara_helpers.cpp | 4 ++--
TombEngine/Game/Lara/lara_one_gun.cpp | 4 ++--
TombEngine/Game/Lara/lara_overhang.cpp | 4 ++--
TombEngine/Game/Lara/lara_tests.cpp | 4 ++--
TombEngine/Game/camera.cpp | 4 ++--
TombEngine/Game/collision/{PointCollision.cpp => Point.cpp} | 4 ++--
TombEngine/Game/collision/{PointCollision.h => Point.h} | 2 +-
TombEngine/Game/collision/collide_item.cpp | 4 ++--
TombEngine/Game/collision/collide_item.h | 4 ++--
TombEngine/Game/collision/collide_room.cpp | 4 ++--
TombEngine/Game/collision/floordata.cpp | 4 ++--
TombEngine/Game/control/box.cpp | 4 ++--
TombEngine/Game/control/trigger.cpp | 4 ++--
TombEngine/Game/effects/drip.cpp | 4 ++--
TombEngine/Game/effects/effects.cpp | 4 ++--
TombEngine/Game/effects/footprint.cpp | 4 ++--
TombEngine/Game/effects/hair.cpp | 4 ++--
TombEngine/Game/effects/item_fx.cpp | 4 ++--
TombEngine/Game/effects/weather.cpp | 4 ++--
TombEngine/Game/items.cpp | 4 ++--
TombEngine/Game/missile.cpp | 4 ++--
TombEngine/Game/pickup/pickup.cpp | 4 ++--
TombEngine/Game/room.cpp | 4 ++--
TombEngine/Objects/Effects/enemy_missile.cpp | 4 ++--
TombEngine/Objects/Effects/flame_emitters.cpp | 4 ++--
TombEngine/Objects/Effects/tr5_electricity.cpp | 4 ++--
.../Objects/Generic/Object/Pushable/PushableCollision.cpp | 4 ++--
TombEngine/Objects/Generic/Object/Pushable/PushableObject.cpp | 4 ++--
TombEngine/Objects/Generic/Object/Pushable/PushableSound.cpp | 4 ++--
TombEngine/Objects/Generic/Object/Pushable/PushableStack.cpp | 4 ++--
TombEngine/Objects/Generic/Traps/crumblingPlatform.cpp | 4 ++--
TombEngine/Objects/TR1/Entity/tr1_bear.cpp | 4 ++--
TombEngine/Objects/TR1/Entity/tr1_doppelganger.cpp | 4 ++--
TombEngine/Objects/TR1/Trap/DamoclesSword.cpp | 4 ++--
TombEngine/Objects/TR2/Entity/Dragon.cpp | 4 ++--
TombEngine/Objects/TR2/Trap/tr2_spinningblade.cpp | 4 ++--
TombEngine/Objects/TR2/Vehicles/skidoo.cpp | 4 ++--
TombEngine/Objects/TR2/Vehicles/speedboat.cpp | 4 ++--
TombEngine/Objects/TR3/Entity/Shiva.cpp | 4 ++--
TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp | 4 ++--
TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp | 4 ++--
TombEngine/Objects/TR3/Entity/tr3_tony.cpp | 4 ++--
TombEngine/Objects/TR3/Object/corpse.cpp | 4 ++--
TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp | 4 ++--
TombEngine/Objects/TR3/Trap/train.cpp | 4 ++--
TombEngine/Objects/TR3/Vehicles/big_gun.cpp | 4 ++--
TombEngine/Objects/TR3/Vehicles/kayak.cpp | 4 ++--
TombEngine/Objects/TR3/Vehicles/minecart.cpp | 4 ++--
TombEngine/Objects/TR3/Vehicles/quad_bike.cpp | 4 ++--
TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp | 4 ++--
TombEngine/Objects/TR3/Vehicles/upv.cpp | 4 ++--
TombEngine/Objects/TR4/Entity/Wraith.cpp | 4 ++--
TombEngine/Objects/TR4/Entity/tr4_baboon.cpp | 4 ++--
TombEngine/Objects/TR4/Entity/tr4_baddy.cpp | 4 ++--
TombEngine/Objects/TR4/Entity/tr4_enemy_jeep.cpp | 4 ++--
TombEngine/Objects/TR4/Entity/tr4_horseman.cpp | 4 ++--
TombEngine/Objects/TR4/Entity/tr4_sas.cpp | 4 ++--
TombEngine/Objects/TR4/Entity/tr4_setha.cpp | 4 ++--
TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp | 4 ++--
TombEngine/Objects/TR4/Entity/tr4_sphinx.cpp | 4 ++--
TombEngine/Objects/TR4/Entity/tr4_von_croy.cpp | 4 ++--
TombEngine/Objects/TR4/Object/tr4_clockwork_beetle.cpp | 4 ++--
TombEngine/Objects/TR4/Object/tr4_mapper.cpp | 4 ++--
TombEngine/Objects/TR4/Object/tr4_senet.cpp | 4 ++--
TombEngine/Objects/TR4/Trap/SpikyCeiling.cpp | 4 ++--
TombEngine/Objects/TR4/Trap/SpikyWall.cpp | 4 ++--
TombEngine/Objects/TR4/Trap/tr4_joby_spikes.cpp | 4 ++--
TombEngine/Objects/TR4/Trap/tr4_slicerdicer.cpp | 4 ++--
TombEngine/Objects/TR4/Trap/tr4_teethspike.cpp | 4 ++--
TombEngine/Objects/TR4/Vehicles/jeep.cpp | 4 ++--
TombEngine/Objects/TR4/Vehicles/motorbike.cpp | 4 ++--
TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp | 4 ++--
TombEngine/Objects/TR5/Entity/tr5_guard.cpp | 4 ++--
TombEngine/Objects/TR5/Entity/tr5_submarine.cpp | 4 ++--
TombEngine/Objects/TR5/Object/tr5_bodypart.cpp | 4 ++--
TombEngine/Objects/TR5/Object/tr5_missile.cpp | 4 ++--
TombEngine/Objects/TR5/Object/tr5_rollingball.cpp | 4 ++--
TombEngine/Objects/TR5/Object/tr5_twoblockplatform.cpp | 4 ++--
TombEngine/Objects/TR5/Trap/LaserBarrier.cpp | 4 ++--
TombEngine/Objects/TR5/Trap/ZipLine.cpp | 4 ++--
TombEngine/Objects/TR5/Trap/tr5_fallingceiling.cpp | 4 ++--
TombEngine/Objects/Utils/VehicleHelpers.cpp | 4 ++--
TombEngine/TombEngine.vcxproj | 4 ++--
88 files changed, 175 insertions(+), 175 deletions(-)
rename TombEngine/Game/collision/{PointCollision.cpp => Point.cpp} (99%)
rename TombEngine/Game/collision/{PointCollision.h => Point.h} (98%)
diff --git a/TombEngine/Game/Lara/PlayerContext.cpp b/TombEngine/Game/Lara/PlayerContext.cpp
index 63f30f3f2..6e6d4d721 100644
--- a/TombEngine/Game/Lara/PlayerContext.cpp
+++ b/TombEngine/Game/Lara/PlayerContext.cpp
@@ -3,7 +3,7 @@
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/collision/floordata.h"
#include "Game/control/los.h"
#include "Game/items.h"
@@ -15,7 +15,7 @@
#include "Specific/Input/Input.h"
using namespace TEN::Collision::Floordata;
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Input;
namespace TEN::Entities::Player
diff --git a/TombEngine/Game/Lara/lara.cpp b/TombEngine/Game/Lara/lara.cpp
index d74594b3e..6823a03f6 100644
--- a/TombEngine/Game/Lara/lara.cpp
+++ b/TombEngine/Game/Lara/lara.cpp
@@ -24,7 +24,7 @@
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/floordata.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/flipeffect.h"
#include "Game/control/volume.h"
#include "Game/effects/Hair.h"
@@ -48,7 +48,7 @@
#include "Specific/winmain.h"
using namespace TEN::Collision::Floordata;
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Control::Volumes;
using namespace TEN::Effects::Hair;
using namespace TEN::Effects::Items;
diff --git a/TombEngine/Game/Lara/lara_climb.cpp b/TombEngine/Game/Lara/lara_climb.cpp
index f944dde5c..68917f419 100644
--- a/TombEngine/Game/Lara/lara_climb.cpp
+++ b/TombEngine/Game/Lara/lara_climb.cpp
@@ -3,7 +3,7 @@
#include "Game/animation.h"
#include "Game/camera.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/collision/sphere.h"
#include "Game/control/control.h"
#include "Game/items.h"
@@ -15,7 +15,7 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Input;
constexpr auto LADDER_TEST_MARGIN = 8;
diff --git a/TombEngine/Game/Lara/lara_collide.cpp b/TombEngine/Game/Lara/lara_collide.cpp
index 546c3b25d..d0527f388 100644
--- a/TombEngine/Game/Lara/lara_collide.cpp
+++ b/TombEngine/Game/Lara/lara_collide.cpp
@@ -4,7 +4,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
#include "Game/collision/collide_item.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/control.h"
#include "Game/effects/effects.h"
#include "Game/items.h"
@@ -20,7 +20,7 @@
#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
#include "Scripting/Include/ScriptInterfaceLevel.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Entities::Player;
using namespace TEN::Input;
diff --git a/TombEngine/Game/Lara/lara_flare.cpp b/TombEngine/Game/Lara/lara_flare.cpp
index 3e8402ec2..375562969 100644
--- a/TombEngine/Game/Lara/lara_flare.cpp
+++ b/TombEngine/Game/Lara/lara_flare.cpp
@@ -4,7 +4,7 @@
#include "Game/animation.h"
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/control.h"
#include "Game/effects/effects.h"
#include "Game/effects/chaffFX.h"
@@ -19,7 +19,7 @@
#include "Specific/clock.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Math;
constexpr auto FLARE_LIFE_MAX = 60.0f * FPS;
diff --git a/TombEngine/Game/Lara/lara_helpers.cpp b/TombEngine/Game/Lara/lara_helpers.cpp
index 0ab9aa44f..a84f0e5f9 100644
--- a/TombEngine/Game/Lara/lara_helpers.cpp
+++ b/TombEngine/Game/Lara/lara_helpers.cpp
@@ -7,7 +7,7 @@
#include "Game/camera.h"
#include "Game/collision/collide_room.h"
#include "Game/collision/floordata.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/control.h"
#include "Game/control/volume.h"
#include "Game/items.h"
@@ -38,7 +38,7 @@
#include "Objects/TR4/Vehicles/motorbike.h"
using namespace TEN::Collision::Floordata;
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Control::Volumes;
using namespace TEN::Effects::Bubble;
using namespace TEN::Effects::Drip;
diff --git a/TombEngine/Game/Lara/lara_one_gun.cpp b/TombEngine/Game/Lara/lara_one_gun.cpp
index 898a001f8..708cac335 100644
--- a/TombEngine/Game/Lara/lara_one_gun.cpp
+++ b/TombEngine/Game/Lara/lara_one_gun.cpp
@@ -4,7 +4,7 @@
#include "Game/animation.h"
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/box.h"
#include "Game/control/control.h"
#include "Game/control/los.h"
@@ -32,7 +32,7 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Effects::Bubble;
using namespace TEN::Effects::Drip;
using namespace TEN::Effects::Environment;
diff --git a/TombEngine/Game/Lara/lara_overhang.cpp b/TombEngine/Game/Lara/lara_overhang.cpp
index a9b81c427..9915346a5 100644
--- a/TombEngine/Game/Lara/lara_overhang.cpp
+++ b/TombEngine/Game/Lara/lara_overhang.cpp
@@ -4,7 +4,7 @@
#include "Game/camera.h"
#include "Game/collision/collide_room.h"
#include "Game/collision/floordata.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/control.h"
#include "Game/Lara/lara.h"
#include "Game/Lara/lara_climb.h"
@@ -18,7 +18,7 @@
#include "Specific/level.h"
using namespace TEN::Collision::Floordata;
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Entities::Generic;
using namespace TEN::Input;
diff --git a/TombEngine/Game/Lara/lara_tests.cpp b/TombEngine/Game/Lara/lara_tests.cpp
index 342a69075..d8412059b 100644
--- a/TombEngine/Game/Lara/lara_tests.cpp
+++ b/TombEngine/Game/Lara/lara_tests.cpp
@@ -5,7 +5,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/control.h"
#include "Game/control/los.h"
#include "Game/items.h"
@@ -23,7 +23,7 @@
#include "Specific/trutils.h"
using namespace TEN::Collision::Floordata;
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Entities::Player;
using namespace TEN::Input;
using namespace TEN::Math;
diff --git a/TombEngine/Game/camera.cpp b/TombEngine/Game/camera.cpp
index 11dd4720c..e0863e650 100644
--- a/TombEngine/Game/camera.cpp
+++ b/TombEngine/Game/camera.cpp
@@ -3,7 +3,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/los.h"
#include "Game/effects/debris.h"
#include "Game/effects/effects.h"
@@ -23,7 +23,7 @@
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Effects::Environment;
using namespace TEN::Entities::Generic;
using namespace TEN::Input;
diff --git a/TombEngine/Game/collision/PointCollision.cpp b/TombEngine/Game/collision/Point.cpp
similarity index 99%
rename from TombEngine/Game/collision/PointCollision.cpp
rename to TombEngine/Game/collision/Point.cpp
index 9bdb931cc..db80021a7 100644
--- a/TombEngine/Game/collision/PointCollision.cpp
+++ b/TombEngine/Game/collision/Point.cpp
@@ -1,5 +1,5 @@
#include "framework.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/collision/collide_room.h"
#include "Game/collision/floordata.h"
@@ -14,7 +14,7 @@ using namespace TEN::Collision::Floordata;
using namespace TEN::Collision::Room;
using namespace TEN::Math;
-namespace TEN::Collision::PointCollision
+namespace TEN::Collision::Point
{
PointCollisionData::PointCollisionData(const Vector3i& pos, int roomNumber)
{
diff --git a/TombEngine/Game/collision/PointCollision.h b/TombEngine/Game/collision/Point.h
similarity index 98%
rename from TombEngine/Game/collision/PointCollision.h
rename to TombEngine/Game/collision/Point.h
index b5717cec0..318082c42 100644
--- a/TombEngine/Game/collision/PointCollision.h
+++ b/TombEngine/Game/collision/Point.h
@@ -8,7 +8,7 @@ struct ItemInfo;
using namespace TEN::Math;
-namespace TEN::Collision::PointCollision
+namespace TEN::Collision::Point
{
class PointCollisionData
{
diff --git a/TombEngine/Game/collision/collide_item.cpp b/TombEngine/Game/collision/collide_item.cpp
index de15f6b82..b212b96a8 100644
--- a/TombEngine/Game/collision/collide_item.cpp
+++ b/TombEngine/Game/collision/collide_item.cpp
@@ -5,7 +5,7 @@
#include "Game/control/los.h"
#include "Game/collision/collide_room.h"
#include "Game/collision/floordata.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/collision/sphere.h"
#include "Game/effects/debris.h"
#include "Game/effects/effects.h"
@@ -23,7 +23,7 @@
#include "Sound/sound.h"
using namespace TEN::Collision::Floordata;
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Math;
using namespace TEN::Renderer;
diff --git a/TombEngine/Game/collision/collide_item.h b/TombEngine/Game/collision/collide_item.h
index 9f10dc584..ee9d6a8b6 100644
--- a/TombEngine/Game/collision/collide_item.h
+++ b/TombEngine/Game/collision/collide_item.h
@@ -1,14 +1,14 @@
#pragma once
#include "Math/Math.h"
-namespace TEN::Collision::PointCollision { class PointCollisionData; };
+namespace TEN::Collision::Point { class PointCollisionData; };
class FloorInfo;
struct CollisionInfo;
struct CollisionResult;
struct ItemInfo;
struct MESH_INFO;
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
constexpr auto MAX_COLLIDED_OBJECTS = 1024;
constexpr auto ITEM_RADIUS_YMAX = BLOCK(3);
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index abc632d39..ce25ae013 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -4,7 +4,7 @@
#include "Game/control/box.h"
#include "Game/control/los.h"
#include "Game/collision/collide_item.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/animation.h"
#include "Game/Lara/lara.h"
#include "Game/items.h"
@@ -14,7 +14,7 @@
#include "Renderer/Renderer.h"
using namespace TEN::Collision::Floordata;
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Collision::Room;
using namespace TEN::Math;
using namespace TEN::Renderer;
diff --git a/TombEngine/Game/collision/floordata.cpp b/TombEngine/Game/collision/floordata.cpp
index 2724d156f..8d02233e0 100644
--- a/TombEngine/Game/collision/floordata.cpp
+++ b/TombEngine/Game/collision/floordata.cpp
@@ -2,7 +2,7 @@
#include "Game/collision/floordata.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/items.h"
#include "Game/room.h"
#include "Game/Setup.h"
@@ -13,7 +13,7 @@
#include "Specific/trutils.h"
using namespace TEN::Collision::Floordata;
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Entities::Generic;
using namespace TEN::Math;
using namespace TEN::Utils;
diff --git a/TombEngine/Game/control/box.cpp b/TombEngine/Game/control/box.cpp
index 6db0d80c7..90778ecf5 100644
--- a/TombEngine/Game/control/box.cpp
+++ b/TombEngine/Game/control/box.cpp
@@ -5,7 +5,7 @@
#include "Game/camera.h"
#include "Game/collision/sphere.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/control.h"
#include "Game/control/lot.h"
#include "Game/effects/smoke.h"
@@ -23,7 +23,7 @@
#include "Objects/Generic/Object/Pushable/PushableObject.h"
#include "Renderer/Renderer.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Collision::Room;
using namespace TEN::Effects::Smoke;
diff --git a/TombEngine/Game/control/trigger.cpp b/TombEngine/Game/control/trigger.cpp
index bf323e985..0fc94666b 100644
--- a/TombEngine/Game/control/trigger.cpp
+++ b/TombEngine/Game/control/trigger.cpp
@@ -3,7 +3,7 @@
#include "Game/camera.h"
#include "Game/collision/floordata.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/flipeffect.h"
#include "Game/control/box.h"
#include "Game/control/lot.h"
@@ -25,7 +25,7 @@
#include "Sound/sound.h"
#include "Specific/clock.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Effects::Items;
using namespace TEN::Entities::Switches;
diff --git a/TombEngine/Game/effects/drip.cpp b/TombEngine/Game/effects/drip.cpp
index ad6ee12e2..08336ecfc 100644
--- a/TombEngine/Game/effects/drip.cpp
+++ b/TombEngine/Game/effects/drip.cpp
@@ -3,7 +3,7 @@
#include "Game/collision/collide_room.h"
#include "Game/collision/floordata.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/effects/effects.h"
#include "Game/effects/Ripple.h"
#include "Game/effects/weather.h"
@@ -13,7 +13,7 @@
#include "Specific/clock.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Effects::Environment;
using namespace TEN::Effects::Ripple;
using namespace TEN::Collision::Floordata;
diff --git a/TombEngine/Game/effects/effects.cpp b/TombEngine/Game/effects/effects.cpp
index 33a36982e..737b536a9 100644
--- a/TombEngine/Game/effects/effects.cpp
+++ b/TombEngine/Game/effects/effects.cpp
@@ -4,7 +4,7 @@
#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/effects/Blood.h"
#include "Game/effects/Bubble.h"
#include "Game/effects/Drip.h"
@@ -26,7 +26,7 @@
#include "Specific/clock.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Effects::Blood;
using namespace TEN::Effects::Bubble;
using namespace TEN::Effects::Drip;
diff --git a/TombEngine/Game/effects/footprint.cpp b/TombEngine/Game/effects/footprint.cpp
index d990792d9..33c50c03c 100644
--- a/TombEngine/Game/effects/footprint.cpp
+++ b/TombEngine/Game/effects/footprint.cpp
@@ -4,7 +4,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
#include "Game/collision/floordata.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/control.h"
#include "Game/effects/effects.h"
#include "Game/items.h"
@@ -17,7 +17,7 @@
#include "Specific/level.h"
using namespace TEN::Collision::Floordata;
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Math;
namespace TEN::Effects::Footprint
diff --git a/TombEngine/Game/effects/hair.cpp b/TombEngine/Game/effects/hair.cpp
index cb9a0514f..70e3278c7 100644
--- a/TombEngine/Game/effects/hair.cpp
+++ b/TombEngine/Game/effects/hair.cpp
@@ -3,7 +3,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/collision/sphere.h"
#include "Game/control/control.h"
#include "Game/effects/weather.h"
@@ -15,7 +15,7 @@
#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Effects::Environment;
using TEN::Renderer::g_Renderer;
diff --git a/TombEngine/Game/effects/item_fx.cpp b/TombEngine/Game/effects/item_fx.cpp
index 09a127024..5261e6734 100644
--- a/TombEngine/Game/effects/item_fx.cpp
+++ b/TombEngine/Game/effects/item_fx.cpp
@@ -3,7 +3,7 @@
#include "Game/collision/collide_room.h"
#include "Game/collision/floordata.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/control.h"
#include "Game/effects/effects.h"
#include "Game/effects/smoke.h"
@@ -14,7 +14,7 @@
#include "Specific/clock.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Effects::Smoke;
namespace TEN::Effects::Items
diff --git a/TombEngine/Game/effects/weather.cpp b/TombEngine/Game/effects/weather.cpp
index 2ba7c761b..25ab784e2 100644
--- a/TombEngine/Game/effects/weather.cpp
+++ b/TombEngine/Game/effects/weather.cpp
@@ -3,7 +3,7 @@
#include "Game/camera.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/effects/effects.h"
#include "Game/effects/Ripple.h"
#include "Game/effects/tomb4fx.h"
@@ -14,7 +14,7 @@
#include "Specific/level.h"
#include "Scripting/Include/ScriptInterfaceLevel.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Effects::Ripple;
using namespace TEN::Math::Random;
diff --git a/TombEngine/Game/items.cpp b/TombEngine/Game/items.cpp
index b88cf120d..267a4fbb7 100644
--- a/TombEngine/Game/items.cpp
+++ b/TombEngine/Game/items.cpp
@@ -3,7 +3,7 @@
#include "Game/collision/floordata.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/control.h"
#include "Game/control/volume.h"
#include "Game/effects/effects.h"
@@ -27,7 +27,7 @@
#include "Specific/trutils.h"
using namespace TEN::Collision::Floordata;
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Collision::Room;
using namespace TEN::Control::Volumes;
using namespace TEN::Effects::Items;
diff --git a/TombEngine/Game/missile.cpp b/TombEngine/Game/missile.cpp
index d8891afa0..bf171f0be 100644
--- a/TombEngine/Game/missile.cpp
+++ b/TombEngine/Game/missile.cpp
@@ -4,7 +4,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/effects/tomb4fx.h"
#include "Game/effects/effects.h"
#include "Game/effects/explosion.h"
@@ -16,7 +16,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;;
+using namespace TEN::Collision::Point;;
using namespace TEN::Effects::Bubble;
using namespace TEN::Effects::Explosion;
using namespace TEN::Math;
diff --git a/TombEngine/Game/pickup/pickup.cpp b/TombEngine/Game/pickup/pickup.cpp
index 9618c1a5b..c20a0a2e3 100644
--- a/TombEngine/Game/pickup/pickup.cpp
+++ b/TombEngine/Game/pickup/pickup.cpp
@@ -5,7 +5,7 @@
#include "Game/animation.h"
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/effects/debris.h"
#include "Game/Gui.h"
#include "Game/Hud/Hud.h"
@@ -31,7 +31,7 @@
#include "Specific/level.h"
#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Entities::Generic;
using namespace TEN::Hud;
using namespace TEN::Input;
diff --git a/TombEngine/Game/room.cpp b/TombEngine/Game/room.cpp
index 85da187fc..3d2d36ac9 100644
--- a/TombEngine/Game/room.cpp
+++ b/TombEngine/Game/room.cpp
@@ -2,7 +2,7 @@
#include "Game/room.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/control.h"
#include "Game/control/lot.h"
#include "Game/control/volume.h"
@@ -14,7 +14,7 @@
using namespace TEN::Math;
using namespace TEN::Collision::Floordata;
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Renderer;
using namespace TEN::Utils;
diff --git a/TombEngine/Objects/Effects/enemy_missile.cpp b/TombEngine/Objects/Effects/enemy_missile.cpp
index f11fdeddf..286b3b43b 100644
--- a/TombEngine/Objects/Effects/enemy_missile.cpp
+++ b/TombEngine/Objects/Effects/enemy_missile.cpp
@@ -3,7 +3,7 @@
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/control.h"
#include "Game/effects/debris.h"
#include "Game/effects/effects.h"
@@ -18,7 +18,7 @@
#include "Renderer/RendererEnums.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Effects::Items;
using namespace TEN::Entities::Creatures::TR3;
using namespace TEN::Entities::TR4;
diff --git a/TombEngine/Objects/Effects/flame_emitters.cpp b/TombEngine/Objects/Effects/flame_emitters.cpp
index 37ccc5465..d790a652f 100644
--- a/TombEngine/Objects/Effects/flame_emitters.cpp
+++ b/TombEngine/Objects/Effects/flame_emitters.cpp
@@ -4,7 +4,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/collision/sphere.h"
#include "Game/effects/effects.h"
#include "Game/effects/Electricity.h"
@@ -21,7 +21,7 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Effects::Electricity;
using namespace TEN::Effects::Environment;
using namespace TEN::Effects::Items;
diff --git a/TombEngine/Objects/Effects/tr5_electricity.cpp b/TombEngine/Objects/Effects/tr5_electricity.cpp
index 973a41402..3bd02ec50 100644
--- a/TombEngine/Objects/Effects/tr5_electricity.cpp
+++ b/TombEngine/Objects/Effects/tr5_electricity.cpp
@@ -4,7 +4,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/collision/sphere.h"
#include "Game/control/control.h"
#include "Game/effects/effects.h"
@@ -18,7 +18,7 @@
#include "Specific/clock.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Effects::Items;
using namespace TEN::Effects::Ripple;
diff --git a/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp b/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
index d9a06eb94..1c5b33210 100644
--- a/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
+++ b/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
@@ -3,7 +3,7 @@
#include "Game/collision/collide_item.h"
#include "Game/collision/floordata.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/Lara/lara.h"
#include "Game/Setup.h"
#include "Objects/Generic/Object/BridgeObject.h"
@@ -13,7 +13,7 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Collision::Floordata;
using namespace TEN::Entities::Generic;
using namespace TEN::Input;
diff --git a/TombEngine/Objects/Generic/Object/Pushable/PushableObject.cpp b/TombEngine/Objects/Generic/Object/Pushable/PushableObject.cpp
index 57d9658fe..491caea4f 100644
--- a/TombEngine/Objects/Generic/Object/Pushable/PushableObject.cpp
+++ b/TombEngine/Objects/Generic/Object/Pushable/PushableObject.cpp
@@ -4,7 +4,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/collision/floordata.h"
#include "Game/control/box.h"
#include "Game/control/flipeffect.h"
@@ -23,7 +23,7 @@
#include "Specific/level.h"
using namespace TEN::Collision::Floordata;
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Input;
namespace TEN::Entities::Generic
diff --git a/TombEngine/Objects/Generic/Object/Pushable/PushableSound.cpp b/TombEngine/Objects/Generic/Object/Pushable/PushableSound.cpp
index b28869af2..f5d3592fc 100644
--- a/TombEngine/Objects/Generic/Object/Pushable/PushableSound.cpp
+++ b/TombEngine/Objects/Generic/Object/Pushable/PushableSound.cpp
@@ -1,12 +1,12 @@
#include "framework.h"
#include "Objects/Generic/Object/Pushable/PushableSound.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Objects/Generic/Object/Pushable/PushableObject.h"
#include "Sound/sound.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
namespace TEN::Entities::Generic
{
diff --git a/TombEngine/Objects/Generic/Object/Pushable/PushableStack.cpp b/TombEngine/Objects/Generic/Object/Pushable/PushableStack.cpp
index 833efe10d..9f56c8b8f 100644
--- a/TombEngine/Objects/Generic/Object/Pushable/PushableStack.cpp
+++ b/TombEngine/Objects/Generic/Object/Pushable/PushableStack.cpp
@@ -2,14 +2,14 @@
#include "Objects/Generic/Object/Pushable/PushableStack.h"
#include "Game/collision/floordata.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/Setup.h"
#include "Objects/Generic/Object/Pushable/PushableBridge.h"
#include "Objects/Generic/Object/Pushable/PushableObject.h"
#include "Specific/level.h"
using namespace TEN::Collision::Floordata;
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
namespace TEN::Entities::Generic
{
diff --git a/TombEngine/Objects/Generic/Traps/crumblingPlatform.cpp b/TombEngine/Objects/Generic/Traps/crumblingPlatform.cpp
index 406262f9f..9a1a87e89 100644
--- a/TombEngine/Objects/Generic/Traps/crumblingPlatform.cpp
+++ b/TombEngine/Objects/Generic/Traps/crumblingPlatform.cpp
@@ -3,7 +3,7 @@
#include "Game/collision/collide_item.h"
#include "Game/collision/floordata.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/Lara/lara.h"
#include "Game/Lara/lara_helpers.h"
#include "Game/setup.h"
@@ -12,7 +12,7 @@
#include "Specific/level.h"
using namespace TEN::Collision::Floordata;
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Entities::Generic;
// NOTES:
diff --git a/TombEngine/Objects/TR1/Entity/tr1_bear.cpp b/TombEngine/Objects/TR1/Entity/tr1_bear.cpp
index fce60b3eb..8d219f369 100644
--- a/TombEngine/Objects/TR1/Entity/tr1_bear.cpp
+++ b/TombEngine/Objects/TR1/Entity/tr1_bear.cpp
@@ -2,7 +2,7 @@
#include "Objects/TR1/Entity/tr1_bear.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/box.h"
#include "Game/control/control.h"
#include "Game/effects/effects.h"
@@ -14,7 +14,7 @@
#include "Math/Math.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Math;
namespace TEN::Entities::Creatures::TR1
diff --git a/TombEngine/Objects/TR1/Entity/tr1_doppelganger.cpp b/TombEngine/Objects/TR1/Entity/tr1_doppelganger.cpp
index d91999010..d9e981c69 100644
--- a/TombEngine/Objects/TR1/Entity/tr1_doppelganger.cpp
+++ b/TombEngine/Objects/TR1/Entity/tr1_doppelganger.cpp
@@ -3,7 +3,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/control.h"
#include "Game/control/lot.h"
#include "Game/items.h"
@@ -12,7 +12,7 @@
#include "Game/misc.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
namespace TEN::Entities::Creatures::TR1
{
diff --git a/TombEngine/Objects/TR1/Trap/DamoclesSword.cpp b/TombEngine/Objects/TR1/Trap/DamoclesSword.cpp
index 50b1cccec..348827f7e 100644
--- a/TombEngine/Objects/TR1/Trap/DamoclesSword.cpp
+++ b/TombEngine/Objects/TR1/Trap/DamoclesSword.cpp
@@ -4,14 +4,14 @@
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/effects/effects.h"
#include "Game/Lara/lara.h"
#include "Game/Setup.h"
#include "Math/Math.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Math;
namespace TEN::Entities::Traps::TR1
diff --git a/TombEngine/Objects/TR2/Entity/Dragon.cpp b/TombEngine/Objects/TR2/Entity/Dragon.cpp
index 7613ed5fb..6cab05dbf 100644
--- a/TombEngine/Objects/TR2/Entity/Dragon.cpp
+++ b/TombEngine/Objects/TR2/Entity/Dragon.cpp
@@ -3,7 +3,7 @@
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/collision/sphere.h"
#include "Game/control/lot.h"
#include "Game/effects/effects.h"
@@ -17,7 +17,7 @@
#include "Specific/clock.h"
#include "Specific/Input/Input.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Input;
using namespace TEN::Math;
diff --git a/TombEngine/Objects/TR2/Trap/tr2_spinningblade.cpp b/TombEngine/Objects/TR2/Trap/tr2_spinningblade.cpp
index 50a2800e4..dc027a558 100644
--- a/TombEngine/Objects/TR2/Trap/tr2_spinningblade.cpp
+++ b/TombEngine/Objects/TR2/Trap/tr2_spinningblade.cpp
@@ -3,7 +3,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/control.h"
#include "Game/effects/effects.h"
#include "Game/items.h"
@@ -12,7 +12,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
void InitializeSpinningBlade(short itemNumber)
{
diff --git a/TombEngine/Objects/TR2/Vehicles/skidoo.cpp b/TombEngine/Objects/TR2/Vehicles/skidoo.cpp
index c72777c44..cff60fb15 100644
--- a/TombEngine/Objects/TR2/Vehicles/skidoo.cpp
+++ b/TombEngine/Objects/TR2/Vehicles/skidoo.cpp
@@ -4,7 +4,7 @@
#include "Game/animation.h"
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/collision/sphere.h"
#include "Game/effects/effects.h"
#include "Game/effects/simple_particle.h"
@@ -22,7 +22,7 @@
#include "Math/Math.h"
#include "Sound/sound.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Input;
using namespace TEN::Math;
diff --git a/TombEngine/Objects/TR2/Vehicles/speedboat.cpp b/TombEngine/Objects/TR2/Vehicles/speedboat.cpp
index 162d6df91..5f85dba8e 100644
--- a/TombEngine/Objects/TR2/Vehicles/speedboat.cpp
+++ b/TombEngine/Objects/TR2/Vehicles/speedboat.cpp
@@ -4,7 +4,7 @@
#include "Game/animation.h"
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/collision/sphere.h"
#include "Game/effects/effects.h"
#include "Game/effects/simple_particle.h"
@@ -18,7 +18,7 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Input;
namespace TEN::Entities::Vehicles
diff --git a/TombEngine/Objects/TR3/Entity/Shiva.cpp b/TombEngine/Objects/TR3/Entity/Shiva.cpp
index 1b07d640a..3d74ab035 100644
--- a/TombEngine/Objects/TR3/Entity/Shiva.cpp
+++ b/TombEngine/Objects/TR3/Entity/Shiva.cpp
@@ -4,7 +4,7 @@
#include "Game/animation.h"
#include "Game/camera.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/box.h"
#include "Game/effects/effects.h"
#include "Game/itemdata/creature_info.h"
@@ -18,7 +18,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Math;
namespace TEN::Entities::Creatures::TR3
diff --git a/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp b/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp
index 12bdf11a7..96f4b2a76 100644
--- a/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp
+++ b/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp
@@ -3,7 +3,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/box.h"
#include "Game/control/lot.h"
#include "Game/collision/sphere.h"
@@ -18,7 +18,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Math;
namespace TEN::Entities::Creatures::TR3
diff --git a/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp b/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp
index 802578b2d..2b7f9bf0d 100644
--- a/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp
+++ b/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp
@@ -2,7 +2,7 @@
#include "Objects/TR3/Entity/tr3_scuba_diver.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/box.h"
#include "Game/control/control.h"
#include "Game/control/los.h"
@@ -14,7 +14,7 @@
#include "Game/Setup.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
namespace TEN::Entities::Creatures::TR3
{
diff --git a/TombEngine/Objects/TR3/Entity/tr3_tony.cpp b/TombEngine/Objects/TR3/Entity/tr3_tony.cpp
index efc5feef8..27728f2a3 100644
--- a/TombEngine/Objects/TR3/Entity/tr3_tony.cpp
+++ b/TombEngine/Objects/TR3/Entity/tr3_tony.cpp
@@ -4,7 +4,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/box.h"
#include "Game/control/lot.h"
#include "Game/effects/effects.h"
@@ -19,7 +19,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Effects::Items;
using namespace TEN::Effects::Boss;
diff --git a/TombEngine/Objects/TR3/Object/corpse.cpp b/TombEngine/Objects/TR3/Object/corpse.cpp
index 987c695f7..54df7cbfa 100644
--- a/TombEngine/Objects/TR3/Object/corpse.cpp
+++ b/TombEngine/Objects/TR3/Object/corpse.cpp
@@ -7,7 +7,7 @@
#include "Game/control/control.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/collision/floordata.h"
#include "Game/collision/sphere.h"
#include "Game/effects/effects.h"
@@ -19,7 +19,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Effects::Ripple;
using namespace TEN::Math::Random;
diff --git a/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp b/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp
index b823d479a..13404cbae 100644
--- a/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp
+++ b/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp
@@ -3,7 +3,7 @@
#include "Game/collision/collide_item.h"
#include "Game/collision/floordata.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/box.h"
#include "Game/effects/item_fx.h"
#include "Game/effects/spark.h"
@@ -11,7 +11,7 @@
#include "Game/Lara/lara_helpers.h"
#include "Game/Setup.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Collision::Floordata;
using namespace TEN::Effects::Items;
using namespace TEN::Effects::Spark;
diff --git a/TombEngine/Objects/TR3/Trap/train.cpp b/TombEngine/Objects/TR3/Trap/train.cpp
index aab505f7a..0bd209b1d 100644
--- a/TombEngine/Objects/TR3/Trap/train.cpp
+++ b/TombEngine/Objects/TR3/Trap/train.cpp
@@ -6,7 +6,7 @@
#include "Game/control/control.h"
#include "Game/collision/collide_room.h"
#include "Game/collision/collide_item.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/collision/floordata.h"
#include "Game/collision/sphere.h"
#include "Game/effects/effects.h"
@@ -17,7 +17,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
constexpr auto TRAIN_VEL = 260;
diff --git a/TombEngine/Objects/TR3/Vehicles/big_gun.cpp b/TombEngine/Objects/TR3/Vehicles/big_gun.cpp
index b27904790..2e49fb8b9 100644
--- a/TombEngine/Objects/TR3/Vehicles/big_gun.cpp
+++ b/TombEngine/Objects/TR3/Vehicles/big_gun.cpp
@@ -6,7 +6,7 @@
#include "Game/control/box.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/effects/effects.h"
#include "Game/effects/tomb4fx.h"
#include "Game/items.h"
@@ -21,7 +21,7 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Input;
namespace TEN::Entities::Vehicles
diff --git a/TombEngine/Objects/TR3/Vehicles/kayak.cpp b/TombEngine/Objects/TR3/Vehicles/kayak.cpp
index 5b26186bf..e3ae3d7a8 100644
--- a/TombEngine/Objects/TR3/Vehicles/kayak.cpp
+++ b/TombEngine/Objects/TR3/Vehicles/kayak.cpp
@@ -5,7 +5,7 @@
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/control.h"
#include "Game/effects/effects.h"
#include "Game/items.h"
@@ -19,7 +19,7 @@
#include "Specific/level.h"
#include "Specific/Input/Input.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Input;
namespace TEN::Entities::Vehicles
diff --git a/TombEngine/Objects/TR3/Vehicles/minecart.cpp b/TombEngine/Objects/TR3/Vehicles/minecart.cpp
index b3ac6e8de..888cc1ab6 100644
--- a/TombEngine/Objects/TR3/Vehicles/minecart.cpp
+++ b/TombEngine/Objects/TR3/Vehicles/minecart.cpp
@@ -5,7 +5,7 @@
#include "Game/camera.h"
#include "Game/collision/sphere.h"
#include "Game/collision/collide_item.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/effects/effects.h"
#include "Game/effects/spark.h"
#include "Game/effects/tomb4fx.h"
@@ -21,7 +21,7 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Effects::Spark;
using namespace TEN::Input;
using namespace TEN::Math;
diff --git a/TombEngine/Objects/TR3/Vehicles/quad_bike.cpp b/TombEngine/Objects/TR3/Vehicles/quad_bike.cpp
index 15b4ce4f4..8711384ef 100644
--- a/TombEngine/Objects/TR3/Vehicles/quad_bike.cpp
+++ b/TombEngine/Objects/TR3/Vehicles/quad_bike.cpp
@@ -5,7 +5,7 @@
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/effects/effects.h"
#include "Game/effects/simple_particle.h"
#include "Game/effects/tomb4fx.h"
@@ -23,7 +23,7 @@
#include "Specific/level.h"
#include "Specific/Input/Input.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Input;
using namespace TEN::Math;
diff --git a/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp b/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp
index c73754806..78f938ab2 100644
--- a/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp
+++ b/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp
@@ -4,7 +4,7 @@
#include "Game/animation.h"
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/collision/sphere.h"
#include "Game/effects/Bubble.h"
#include "Game/effects/effects.h"
@@ -20,7 +20,7 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Effects::Bubble;
using namespace TEN::Input;
diff --git a/TombEngine/Objects/TR3/Vehicles/upv.cpp b/TombEngine/Objects/TR3/Vehicles/upv.cpp
index 5c5939548..bbd37ad60 100644
--- a/TombEngine/Objects/TR3/Vehicles/upv.cpp
+++ b/TombEngine/Objects/TR3/Vehicles/upv.cpp
@@ -6,7 +6,7 @@
#include "Game/collision/sphere.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/box.h"
#include "Game/control/los.h"
#include "Game/effects/Bubble.h"
@@ -27,7 +27,7 @@
#include "Specific/level.h"
#include "Specific/Input/Input.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Effects::Bubble;
using namespace TEN::Effects::Streamer;
using namespace TEN::Input;
diff --git a/TombEngine/Objects/TR4/Entity/Wraith.cpp b/TombEngine/Objects/TR4/Entity/Wraith.cpp
index 790f0ed8c..e3e536366 100644
--- a/TombEngine/Objects/TR4/Entity/Wraith.cpp
+++ b/TombEngine/Objects/TR4/Entity/Wraith.cpp
@@ -2,7 +2,7 @@
#include "Objects/TR4/Entity/Wraith.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/flipeffect.h"
#include "Game/effects/effects.h"
#include "Game/effects/Electricity.h"
@@ -19,7 +19,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Effects::Items;
using namespace TEN::Effects::Electricity;
using namespace TEN::Effects::Streamer;
diff --git a/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp b/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp
index b201ba54a..262a36d62 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp
@@ -2,7 +2,7 @@
#include "Objects/TR4/Entity/tr4_baboon.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/box.h"
#include "Game/control/lot.h"
#include "Game/control/control.h"
@@ -16,7 +16,7 @@
#include "Game/Setup.h"
#include "Math/Math.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Effects::Environment;
using namespace TEN::Math;
diff --git a/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp b/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp
index f1f808d8b..4490c0f0a 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp
@@ -3,7 +3,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/box.h"
#include "Game/control/control.h"
#include "Game/control/lot.h"
@@ -19,7 +19,7 @@
#include "Math/Math.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Math;
/*
diff --git a/TombEngine/Objects/TR4/Entity/tr4_enemy_jeep.cpp b/TombEngine/Objects/TR4/Entity/tr4_enemy_jeep.cpp
index ead8f8949..c540afd27 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_enemy_jeep.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_enemy_jeep.cpp
@@ -3,7 +3,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/box.h"
#include "Game/control/lot.h"
#include "Game/control/trigger.h"
@@ -18,7 +18,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Math;
namespace TEN::Entities::TR4
diff --git a/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp b/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp
index 2b48d98b3..ef35f9efb 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp
@@ -3,7 +3,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/collision/sphere.h"
#include "Game/control/box.h"
#include "Game/control/control.h"
@@ -17,7 +17,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Math;
namespace TEN::Entities::TR4
diff --git a/TombEngine/Objects/TR4/Entity/tr4_sas.cpp b/TombEngine/Objects/TR4/Entity/tr4_sas.cpp
index 65633f6a2..7c94d44d5 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_sas.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_sas.cpp
@@ -4,7 +4,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/box.h"
#include "Game/control/control.h"
#include "Game/control/volume.h"
@@ -24,7 +24,7 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Control::Volumes;
using namespace TEN::Input;
using namespace TEN::Math;
diff --git a/TombEngine/Objects/TR4/Entity/tr4_setha.cpp b/TombEngine/Objects/TR4/Entity/tr4_setha.cpp
index ef0742ccc..03c5963c4 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_setha.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_setha.cpp
@@ -5,7 +5,7 @@
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/control.h"
#include "Game/effects/effects.h"
#include "Game/effects/spark.h"
@@ -21,7 +21,7 @@
#include "Specific/clock.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Effects::Items;
using namespace TEN::Effects::Spark;
using namespace TEN::Math;
diff --git a/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp b/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp
index 6f346fabb..b2ddd7053 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp
@@ -3,7 +3,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/collision/floordata.h"
#include "Game/control/box.h"
#include "Game/control/lot.h"
@@ -21,7 +21,7 @@
#include "Math/Math.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Math;
namespace TEN::Entities::TR4
diff --git a/TombEngine/Objects/TR4/Entity/tr4_sphinx.cpp b/TombEngine/Objects/TR4/Entity/tr4_sphinx.cpp
index 5fd89bdb2..e6d194981 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_sphinx.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_sphinx.cpp
@@ -2,7 +2,7 @@
#include "Objects/TR4/Entity/tr4_sphinx.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/box.h"
#include "Game/effects/debris.h"
#include "Game/effects/effects.h"
@@ -14,7 +14,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
namespace TEN::Entities::TR4
{
diff --git a/TombEngine/Objects/TR4/Entity/tr4_von_croy.cpp b/TombEngine/Objects/TR4/Entity/tr4_von_croy.cpp
index 96b7d8ed6..6b4c44690 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_von_croy.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_von_croy.cpp
@@ -3,7 +3,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/box.h"
#include "Game/control/lot.h"
#include "Game/effects/effects.h"
@@ -17,7 +17,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Math;
namespace TEN::Entities::TR4
diff --git a/TombEngine/Objects/TR4/Object/tr4_clockwork_beetle.cpp b/TombEngine/Objects/TR4/Object/tr4_clockwork_beetle.cpp
index b48269f15..0535ae8d2 100644
--- a/TombEngine/Objects/TR4/Object/tr4_clockwork_beetle.cpp
+++ b/TombEngine/Objects/TR4/Object/tr4_clockwork_beetle.cpp
@@ -6,10 +6,10 @@
#include "Game/animation.h"
#include "Sound/sound.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/effects/debris.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
void ClockworkBeetleControl(short itemNumber)
{
diff --git a/TombEngine/Objects/TR4/Object/tr4_mapper.cpp b/TombEngine/Objects/TR4/Object/tr4_mapper.cpp
index e12847de8..faf2fe1f0 100644
--- a/TombEngine/Objects/TR4/Object/tr4_mapper.cpp
+++ b/TombEngine/Objects/TR4/Object/tr4_mapper.cpp
@@ -2,7 +2,7 @@
#include "Objects/TR4/Object/tr4_mapper.h"
#include "Specific/level.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/control.h"
#include "Sound/sound.h"
#include "Game/animation.h"
@@ -12,7 +12,7 @@
#include "Game/items.h"
#include "Renderer/RendererEnums.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
namespace TEN::Entities::TR4
{
diff --git a/TombEngine/Objects/TR4/Object/tr4_senet.cpp b/TombEngine/Objects/TR4/Object/tr4_senet.cpp
index f923e964c..0568a42c6 100644
--- a/TombEngine/Objects/TR4/Object/tr4_senet.cpp
+++ b/TombEngine/Objects/TR4/Object/tr4_senet.cpp
@@ -12,9 +12,9 @@
#include "Specific/level.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Input;
int SenetPiecesNumber[6];
diff --git a/TombEngine/Objects/TR4/Trap/SpikyCeiling.cpp b/TombEngine/Objects/TR4/Trap/SpikyCeiling.cpp
index 52bebb8fa..ac0bc9a2d 100644
--- a/TombEngine/Objects/TR4/Trap/SpikyCeiling.cpp
+++ b/TombEngine/Objects/TR4/Trap/SpikyCeiling.cpp
@@ -4,7 +4,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/collision/sphere.h"
#include "Game/control/control.h"
#include "Game/effects/effects.h"
@@ -13,7 +13,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
namespace TEN::Entities::Traps
{
diff --git a/TombEngine/Objects/TR4/Trap/SpikyWall.cpp b/TombEngine/Objects/TR4/Trap/SpikyWall.cpp
index 5049c604c..0554f13c5 100644
--- a/TombEngine/Objects/TR4/Trap/SpikyWall.cpp
+++ b/TombEngine/Objects/TR4/Trap/SpikyWall.cpp
@@ -3,7 +3,7 @@
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/collision/sphere.h"
#include "Game/control/control.h"
#include "Game/effects/debris.h"
@@ -15,7 +15,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Math;
// NOTES:
diff --git a/TombEngine/Objects/TR4/Trap/tr4_joby_spikes.cpp b/TombEngine/Objects/TR4/Trap/tr4_joby_spikes.cpp
index 27a6b96e5..ea72a171b 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_joby_spikes.cpp
+++ b/TombEngine/Objects/TR4/Trap/tr4_joby_spikes.cpp
@@ -2,7 +2,7 @@
#include "tr4_joby_spikes.h"
#include "Specific/level.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/control.h"
#include "Game/animation.h"
#include "Sound/sound.h"
@@ -10,7 +10,7 @@
#include "Game/effects/effects.h"
#include "Game/items.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
namespace TEN::Entities::TR4
{
diff --git a/TombEngine/Objects/TR4/Trap/tr4_slicerdicer.cpp b/TombEngine/Objects/TR4/Trap/tr4_slicerdicer.cpp
index 74fc1e265..d24178af5 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_slicerdicer.cpp
+++ b/TombEngine/Objects/TR4/Trap/tr4_slicerdicer.cpp
@@ -3,12 +3,12 @@
#include "Specific/level.h"
#include "Sound/sound.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/items.h"
#include "Game/animation.h"
#include "Math/Math.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
namespace TEN::Entities::TR4
{
diff --git a/TombEngine/Objects/TR4/Trap/tr4_teethspike.cpp b/TombEngine/Objects/TR4/Trap/tr4_teethspike.cpp
index 87dcbb8eb..28f043852 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_teethspike.cpp
+++ b/TombEngine/Objects/TR4/Trap/tr4_teethspike.cpp
@@ -3,7 +3,7 @@
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/effects/tomb4fx.h"
#include "Game/items.h"
#include "Game/Lara/lara.h"
@@ -12,7 +12,7 @@
#include "Specific/level.h"
#include "Math/Math.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
namespace TEN::Entities::TR4
{
diff --git a/TombEngine/Objects/TR4/Vehicles/jeep.cpp b/TombEngine/Objects/TR4/Vehicles/jeep.cpp
index 1a70f3fbe..d06cdbd3d 100644
--- a/TombEngine/Objects/TR4/Vehicles/jeep.cpp
+++ b/TombEngine/Objects/TR4/Vehicles/jeep.cpp
@@ -4,7 +4,7 @@
#include "Game/animation.h"
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/effects/effects.h"
#include "Game/effects/simple_particle.h"
#include "Game/effects/tomb4fx.h"
@@ -23,7 +23,7 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Input;
namespace TEN::Entities::Vehicles
diff --git a/TombEngine/Objects/TR4/Vehicles/motorbike.cpp b/TombEngine/Objects/TR4/Vehicles/motorbike.cpp
index d364c8368..358878548 100644
--- a/TombEngine/Objects/TR4/Vehicles/motorbike.cpp
+++ b/TombEngine/Objects/TR4/Vehicles/motorbike.cpp
@@ -5,7 +5,7 @@
#include "Game/animation.h"
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/control.h"
#include "Game/effects/effects.h"
#include "Game/effects/simple_particle.h"
@@ -24,7 +24,7 @@
#include "Specific/level.h"
using std::vector;
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Input;
using namespace TEN::Math::Random;
diff --git a/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp b/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp
index 1d4a94fd2..f618f3145 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp
@@ -3,7 +3,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/box.h"
#include "Game/effects/effects.h"
#include "Game/effects/Electricity.h"
@@ -21,7 +21,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Effects::Electricity;
using namespace TEN::Effects::Items;
using namespace TEN::Effects::Spark;
diff --git a/TombEngine/Objects/TR5/Entity/tr5_guard.cpp b/TombEngine/Objects/TR5/Entity/tr5_guard.cpp
index ce1cc5591..b4867f799 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_guard.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_guard.cpp
@@ -3,7 +3,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/box.h"
#include "Game/control/los.h"
#include "Game/effects/effects.h"
@@ -18,7 +18,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Math;
namespace TEN::Entities::Creatures::TR5
diff --git a/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp b/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp
index 3739b4108..ee7bb7b9e 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp
@@ -4,7 +4,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/box.h"
#include "Game/control/los.h"
#include "Game/effects/effects.h"
@@ -20,7 +20,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Math;
diff --git a/TombEngine/Objects/TR5/Object/tr5_bodypart.cpp b/TombEngine/Objects/TR5/Object/tr5_bodypart.cpp
index 33baf715d..dcb5e844d 100644
--- a/TombEngine/Objects/TR5/Object/tr5_bodypart.cpp
+++ b/TombEngine/Objects/TR5/Object/tr5_bodypart.cpp
@@ -8,12 +8,12 @@
#include "Game/Lara/lara.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/items.h"
#include "Game/effects/tomb4fx.h"
#include "Math/Random.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Math::Random;
constexpr int BODY_PART_LIFE = 64;
diff --git a/TombEngine/Objects/TR5/Object/tr5_missile.cpp b/TombEngine/Objects/TR5/Object/tr5_missile.cpp
index 4ee9a44af..838dd04fd 100644
--- a/TombEngine/Objects/TR5/Object/tr5_missile.cpp
+++ b/TombEngine/Objects/TR5/Object/tr5_missile.cpp
@@ -2,7 +2,7 @@
#include "tr5_missile.h"
#include "Game/items.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/collision/sphere.h"
#include "Game/effects/tomb4fx.h"
#include "Game/effects/effects.h"
@@ -16,7 +16,7 @@
#include "Game/effects/item_fx.h"
#include "Math/Math.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Effects::Items;
using namespace TEN::Math;
diff --git a/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp b/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp
index da785bfd8..4c92f76e1 100644
--- a/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp
+++ b/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp
@@ -4,7 +4,7 @@
#include "Game/animation.h"
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/collision/sphere.h"
#include "Game/control/control.h"
#include "Game/effects/effects.h"
@@ -16,7 +16,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
constexpr auto ROLLING_BALL_MAX_VELOCITY = BLOCK(3);
diff --git a/TombEngine/Objects/TR5/Object/tr5_twoblockplatform.cpp b/TombEngine/Objects/TR5/Object/tr5_twoblockplatform.cpp
index 220ac21c6..52cb85e20 100644
--- a/TombEngine/Objects/TR5/Object/tr5_twoblockplatform.cpp
+++ b/TombEngine/Objects/TR5/Object/tr5_twoblockplatform.cpp
@@ -3,7 +3,7 @@
#include "Game/collision/collide_room.h"
#include "Game/collision/floordata.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/control.h"
#include "Game/items.h"
#include "Game/Lara/lara.h"
@@ -13,7 +13,7 @@
#include "Sound/sound.h"
using namespace TEN::Collision::Floordata;
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Math;
using namespace TEN::Renderer;
diff --git a/TombEngine/Objects/TR5/Trap/LaserBarrier.cpp b/TombEngine/Objects/TR5/Trap/LaserBarrier.cpp
index bb716d60d..cf44a2b01 100644
--- a/TombEngine/Objects/TR5/Trap/LaserBarrier.cpp
+++ b/TombEngine/Objects/TR5/Trap/LaserBarrier.cpp
@@ -3,14 +3,14 @@
#include "Game/collision/collide_room.h"
#include "Game/collision/floordata.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/effects/effects.h"
#include "Game/effects/item_fx.h"
#include "Game/items.h"
#include "Game/Lara/lara.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Effects::Items;
namespace TEN::Traps::TR5
diff --git a/TombEngine/Objects/TR5/Trap/ZipLine.cpp b/TombEngine/Objects/TR5/Trap/ZipLine.cpp
index d18a4dcd4..e53c5bcae 100644
--- a/TombEngine/Objects/TR5/Trap/ZipLine.cpp
+++ b/TombEngine/Objects/TR5/Trap/ZipLine.cpp
@@ -3,7 +3,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_item.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/box.h"
#include "Game/items.h"
#include "Game/Lara/lara.h"
@@ -13,7 +13,7 @@
#include "Sound/sound.h"
#include "Specific/Input/Input.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Input;
using namespace TEN::Math;
diff --git a/TombEngine/Objects/TR5/Trap/tr5_fallingceiling.cpp b/TombEngine/Objects/TR5/Trap/tr5_fallingceiling.cpp
index ddb99803a..a086231d5 100644
--- a/TombEngine/Objects/TR5/Trap/tr5_fallingceiling.cpp
+++ b/TombEngine/Objects/TR5/Trap/tr5_fallingceiling.cpp
@@ -3,13 +3,13 @@
#include "Game/animation.h"
#include "Game/collision/collide_room.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/control/control.h"
#include "Game/items.h"
#include "Game/Lara/lara.h"
#include "Specific/level.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
void FallingCeilingControl(short itemNumber)
{
diff --git a/TombEngine/Objects/Utils/VehicleHelpers.cpp b/TombEngine/Objects/Utils/VehicleHelpers.cpp
index d1c2a8081..ae9a5b137 100644
--- a/TombEngine/Objects/Utils/VehicleHelpers.cpp
+++ b/TombEngine/Objects/Utils/VehicleHelpers.cpp
@@ -2,7 +2,7 @@
#include "Objects/Utils/VehicleHelpers.h"
#include "Game/collision/collide_item.h"
-#include "Game/collision/PointCollision.h"
+#include "Game/collision/Point.h"
#include "Game/collision/sphere.h"
#include "Game/effects/simple_particle.h"
#include "Game/effects/Streamer.h"
@@ -16,7 +16,7 @@
#include "Sound/sound.h"
#include "Specific/Input/Input.h"
-using namespace TEN::Collision::PointCollision;
+using namespace TEN::Collision::Point;
using namespace TEN::Effects::Streamer;
using namespace TEN::Hud;
using namespace TEN::Input;
diff --git a/TombEngine/TombEngine.vcxproj b/TombEngine/TombEngine.vcxproj
index 496f8c5d6..e4612b226 100644
--- a/TombEngine/TombEngine.vcxproj
+++ b/TombEngine/TombEngine.vcxproj
@@ -337,7 +337,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
-
+
@@ -858,7 +858,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
-
+
From d10423c0e048dc64405cb8e2aa1bdec7891c6d89 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Thu, 11 Apr 2024 10:47:03 +0200
Subject: [PATCH 070/410] Smokes particles interpolation
---
TombEngine/Game/effects/smoke.cpp | 36 ++++++++++++++++++++++
TombEngine/Game/effects/smoke.h | 4 +++
TombEngine/Renderer/RendererDrawEffect.cpp | 13 ++++++--
3 files changed, 51 insertions(+), 2 deletions(-)
diff --git a/TombEngine/Game/effects/smoke.cpp b/TombEngine/Game/effects/smoke.cpp
index d9f6727a2..a428f893f 100644
--- a/TombEngine/Game/effects/smoke.cpp
+++ b/TombEngine/Game/effects/smoke.cpp
@@ -52,6 +52,12 @@ namespace TEN::Effects::Smoke
continue;
}
+ // Interpolation
+ s.oldPosition = s.position;
+ s.oldColor = s.color;
+ s.oldRotation = s.rotation;
+ s.oldSize = s.size;
+
s.velocity.y += s.gravity;
if (s.terminalVelocity != 0)
@@ -108,6 +114,11 @@ namespace TEN::Effects::Smoke
s.affectedByWind = true;
s.active = true;
s.room = room;
+
+ s.oldPosition = s.position;
+ s.oldColor = s.color;
+ s.oldRotation = s.rotation;
+ s.oldSize = s.size;
}
//TODO: add additional "Weapon Special" param or something. Currently initial == 2 means Rocket Launcher backwards smoke.
@@ -194,6 +205,11 @@ namespace TEN::Effects::Smoke
s.angularVelocity = Random::GenerateFloat(-PI_DIV_4, PI_DIV_4);
s.angularDrag = 0.95f;
s.room = roomNumber;
+
+ s.oldPosition = s.position;
+ s.oldColor = s.color;
+ s.oldRotation = s.rotation;
+ s.oldSize = s.size;
}
void TriggerQuadExhaustSmoke(int x, int y, int z, short angle, int velocity, int moving)
@@ -217,6 +233,11 @@ namespace TEN::Effects::Smoke
s.destinationSize = Random::GenerateFloat(128, 160);
s.angularVelocity = Random::GenerateFloat(-1, 1);
s.angularDrag = Random::GenerateFloat(0.97f, 0.999f);
+
+ s.oldPosition = s.position;
+ s.oldColor = s.color;
+ s.oldRotation = s.rotation;
+ s.oldSize = s.size;
}
void TriggerRocketSmoke(int x, int y, int z)
@@ -236,6 +257,11 @@ namespace TEN::Effects::Smoke
s.destinationSize = Random::GenerateFloat(1024, 1152);
s.angularVelocity = Random::GenerateFloat(-0.6f, 0.6f);
s.angularDrag = Random::GenerateFloat(0.87f, 0.99f);
+
+ s.oldPosition = s.position;
+ s.oldColor = s.color;
+ s.oldRotation = s.rotation;
+ s.oldSize = s.size;
}
void SpawnCorpseEffect(const Vector3& pos)
@@ -259,6 +285,11 @@ namespace TEN::Effects::Smoke
smoke.destinationSize = Random::GenerateFloat(BLOCK(1), BLOCK(1.1f));
smoke.angularVelocity = Random::GenerateFloat(-0.1f, 0.1f);
smoke.angularDrag = Random::GenerateFloat(0.8f, 0.9f);
+
+ smoke.oldPosition = smoke.position;
+ smoke.oldColor = smoke.color;
+ smoke.oldRotation = smoke.rotation;
+ smoke.oldSize = smoke.size;
}
void TriggerBreathSmoke(long x, long y, long z, short angle)
@@ -282,5 +313,10 @@ namespace TEN::Effects::Smoke
s.destinationSize = Random::GenerateFloat(128, 160);
s.angularVelocity = Random::GenerateFloat(-0.5f, 0.5f);
s.angularDrag = Random::GenerateFloat(0.95f, 0.95f);
+
+ s.oldPosition = s.position;
+ s.oldColor = s.color;
+ s.oldRotation = s.rotation;
+ s.oldSize = s.size;
}
}
diff --git a/TombEngine/Game/effects/smoke.h b/TombEngine/Game/effects/smoke.h
index 33e146fd8..41fef8a8f 100644
--- a/TombEngine/Game/effects/smoke.h
+++ b/TombEngine/Game/effects/smoke.h
@@ -27,6 +27,10 @@ namespace TEN::Effects::Smoke
float terminalVelocity;
bool affectedByWind;
bool active;
+ Vector4 oldColor;
+ Vector3 oldPosition;
+ float oldRotation;
+ float oldSize;
};
extern std::array SmokeParticles;
diff --git a/TombEngine/Renderer/RendererDrawEffect.cpp b/TombEngine/Renderer/RendererDrawEffect.cpp
index b819670a5..1106e151f 100644
--- a/TombEngine/Renderer/RendererDrawEffect.cpp
+++ b/TombEngine/Renderer/RendererDrawEffect.cpp
@@ -1295,8 +1295,17 @@ namespace TEN::Renderer
AddSpriteBillboard(
&_sprites[Objects[ID_SMOKE_SPRITES].meshIndex + smoke.sprite],
- smoke.position,
- smoke.color, smoke.rotation, 1.0f, { smoke.size, smoke.size }, BlendMode::AlphaBlend, true, view);
+ Vector3::Lerp(smoke.oldPosition, smoke.position, _interpolationFactor),
+ Vector4::Lerp(smoke.oldColor, smoke.color, _interpolationFactor),
+ Lerp(smoke.oldRotation, smoke.rotation, _interpolationFactor),
+ 1.0f,
+ {
+ Lerp(smoke.oldSize, smoke.size, _interpolationFactor),
+ Lerp(smoke.oldSize, smoke.size, _interpolationFactor)
+ },
+ BlendMode::AlphaBlend,
+ true,
+ view);
}
}
From 72b3aa9b7ea47740aa703c88bc97bfde7193f668 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Thu, 11 Apr 2024 12:08:22 +0200
Subject: [PATCH 071/410] Blood interpolation
---
TombEngine/Game/effects/Blood.h | 5 +++++
TombEngine/Game/effects/tomb4fx.cpp | 14 ++++++++++++
TombEngine/Game/effects/tomb4fx.h | 7 ++++++
TombEngine/Renderer/RendererDrawEffect.cpp | 26 +++++++++++++++++-----
4 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/TombEngine/Game/effects/Blood.h b/TombEngine/Game/effects/Blood.h
index 8b1e41650..820f269d0 100644
--- a/TombEngine/Game/effects/Blood.h
+++ b/TombEngine/Game/effects/Blood.h
@@ -14,6 +14,11 @@ namespace TEN::Effects::Blood
float Init = 0.0f;
float Size = 0.0f;
float Opacity = 0.0f;
+
+ Vector3 OldPosition = Vector3::Zero;
+ Vector4 OldColor = Vector4::Zero;
+ float OldSize = 0.0f;
+ float OldOpacity = 0.0f;
};
extern std::vector UnderwaterBloodParticles;
diff --git a/TombEngine/Game/effects/tomb4fx.cpp b/TombEngine/Game/effects/tomb4fx.cpp
index 2d128dc87..105662c2c 100644
--- a/TombEngine/Game/effects/tomb4fx.cpp
+++ b/TombEngine/Game/effects/tomb4fx.cpp
@@ -748,6 +748,13 @@ void TriggerBlood(int x, int y, int z, int unk, int num)
int size = (GetRandomControl() & 7) + 8;
blood->sSize = blood->size = size;
blood->dSize = size >> 2;
+
+ blood->oldX = blood->x;
+ blood->oldY = blood->y;
+ blood->oldZ = blood->z;
+ blood->oldRotAng = blood->rotAng;
+ blood->oldSize = blood->size;
+ blood->oldShade = blood->shade;
}
}
@@ -767,6 +774,13 @@ void UpdateBlood()
continue;
}
+ blood->oldX = blood->x;
+ blood->oldY = blood->y;
+ blood->oldZ = blood->z;
+ blood->oldRotAng = blood->rotAng;
+ blood->oldSize = blood->size;
+ blood->oldShade = blood->shade;
+
if (blood->sLife - blood->life >= blood->colFadeSpeed)
{
if (blood->life >= blood->fadeToBlack)
diff --git a/TombEngine/Game/effects/tomb4fx.h b/TombEngine/Game/effects/tomb4fx.h
index ae58bd055..d1a089034 100644
--- a/TombEngine/Game/effects/tomb4fx.h
+++ b/TombEngine/Game/effects/tomb4fx.h
@@ -183,6 +183,13 @@ struct BLOOD_STRUCT
byte sLife;
byte life;
byte pad;
+
+ int oldX;
+ int oldY;
+ int oldZ;
+ short oldRotAng;
+ unsigned char oldShade;
+ unsigned char oldSize;
};
enum class ShockwaveStyle
diff --git a/TombEngine/Renderer/RendererDrawEffect.cpp b/TombEngine/Renderer/RendererDrawEffect.cpp
index 1106e151f..32bc398cd 100644
--- a/TombEngine/Renderer/RendererDrawEffect.cpp
+++ b/TombEngine/Renderer/RendererDrawEffect.cpp
@@ -767,16 +767,30 @@ namespace TEN::Renderer
{
BLOOD_STRUCT* blood = &Blood[i];
- if (blood->on)
+ if (blood->on)
{
if (!CheckIfSlotExists(ID_DEFAULT_SPRITES, "Blood rendering"))
return;
- AddSpriteBillboard(&_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_BLOOD],
- Vector3(blood->x, blood->y, blood->z),
- Vector4(blood->shade / 255.0f, blood->shade * 0, blood->shade * 0, 1.0f),
- TO_RAD(blood->rotAng << 4), 1.0f, { blood->size * 8.0f, blood->size * 8.0f },
- BlendMode::Additive, true, view);
+ AddSpriteBillboard(
+ &_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_BLOOD],
+ Vector3::Lerp(
+ Vector3(blood->oldX, blood->oldY, blood->oldZ),
+ Vector3(blood->x, blood->y, blood->z),
+ _interpolationFactor),
+ Vector4::Lerp(
+ Vector4(blood->oldShade / 255.0f, blood->oldShade * 0, blood->oldShade * 0, 1.0f),
+ Vector4(blood->shade / 255.0f, blood->shade * 0, blood->shade * 0, 1.0f),
+ _interpolationFactor
+ ),
+ TO_RAD(Lerp(blood->oldRotAng << 4, blood->rotAng << 4, _interpolationFactor)),
+ 1.0f,
+ {
+ Lerp(blood->oldSize, blood->size, _interpolationFactor) * 8.0f,
+ Lerp(blood->oldSize, blood->size, _interpolationFactor) * 8.0f },
+ BlendMode::Additive,
+ true,
+ view);
}
}
}
From 44c52201d022914b007e858bdc76d853b2b05a8d Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Thu, 11 Apr 2024 14:27:53 +0200
Subject: [PATCH 072/410] Added partial support to fire and smoke interpolation
---
TombEngine/Game/effects/tomb4fx.cpp | 60 ++++++++++++++++++++++
TombEngine/Game/effects/tomb4fx.h | 23 +++++++++
TombEngine/Renderer/RendererDrawEffect.cpp | 42 +++++++++++++--
3 files changed, 120 insertions(+), 5 deletions(-)
diff --git a/TombEngine/Game/effects/tomb4fx.cpp b/TombEngine/Game/effects/tomb4fx.cpp
index 105662c2c..ba9e84347 100644
--- a/TombEngine/Game/effects/tomb4fx.cpp
+++ b/TombEngine/Game/effects/tomb4fx.cpp
@@ -120,6 +120,16 @@ void TriggerGlobalStaticFlame()
spark->zVel = 0;
spark->flags = SP_NONE;
spark->dSize = spark->sSize = spark->size = (GetRandomControl() & 0x1F) + -128;
+
+ spark->oldX = spark->x;
+ spark->oldY = spark->y;
+ spark->oldZ = spark->z;
+ spark->oldSize = spark->size;
+ spark->oldRotAng = spark->rotAng;
+ spark->oldR = spark->r;
+ spark->oldG = spark->g;
+ spark->oldB = spark->b;
+ spark->oldScalar = spark->scalar;
}
void TriggerGlobalFireSmoke()
@@ -161,6 +171,16 @@ void TriggerGlobalFireSmoke()
spark->gravity = -16 - (GetRandomControl() & 0xF);
spark->maxYvel = -8 - (GetRandomControl() & 7);
spark->dSize = spark->sSize = spark->size = (GetRandomControl() & 0x7F) + 128;
+
+ spark->oldX = spark->x;
+ spark->oldY = spark->y;
+ spark->oldZ = spark->z;
+ spark->oldSize = spark->size;
+ spark->oldRotAng = spark->rotAng;
+ spark->oldR = spark->r;
+ spark->oldG = spark->g;
+ spark->oldB = spark->b;
+ spark->oldScalar = spark->scalar;
}
void TriggerGlobalFireFlame()
@@ -203,6 +223,16 @@ void TriggerGlobalFireFlame()
spark->sSize = spark->size = (GetRandomControl() & 0x1F) + 128;
spark->dSize = spark->size;
+
+ spark->oldX = spark->x;
+ spark->oldY = spark->y;
+ spark->oldZ = spark->z;
+ spark->oldSize = spark->size;
+ spark->oldRotAng = spark->rotAng;
+ spark->oldR = spark->r;
+ spark->oldG = spark->g;
+ spark->oldB = spark->b;
+ spark->oldScalar = spark->scalar;
}
void TriggerPilotFlame(int itemNumber, int nodeIndex)
@@ -394,6 +424,11 @@ void AddFire(int x, int y, int z, short roomNum, float size, short fade)
fptr->z = z;
fptr->roomNumber = roomNum;
fptr->size = size;
+
+ fptr->oldX = fptr->x;
+ fptr->oldY = fptr->y;
+ fptr->oldZ = fptr->z;
+ fptr->oldSize = fptr->size;
}
void ClearFires()
@@ -420,6 +455,16 @@ void UpdateFireSparks()
continue;
}
+ spark->oldX = spark->x;
+ spark->oldY = spark->y;
+ spark->oldZ = spark->z;
+ spark->oldSize = spark->size;
+ spark->oldRotAng = spark->rotAng;
+ spark->oldR = spark->r;
+ spark->oldG = spark->g;
+ spark->oldB = spark->b;
+ spark->oldScalar = spark->scalar;
+
if (spark->sLife - spark->life < spark->colFadeSpeed)
{
int dl = ((spark->sLife - spark->life) << 16) / spark->colFadeSpeed;
@@ -534,6 +579,14 @@ void UpdateSmoke()
continue;
}
+ spark->oldX = spark->x;
+ spark->oldY = spark->y;
+ spark->oldZ = spark->z;
+ spark->oldSize = spark->size;
+ spark->oldRotAng = spark->rotAng;
+ spark->oldScalar = spark->scalar;
+ spark->oldScalar = spark->scalar;
+
if (spark->sLife - spark->life >= spark->colFadeSpeed)
{
if (spark->life >= spark->fadeToBlack)
@@ -680,6 +733,13 @@ void TriggerShatterSmoke(int x, int y, int z)
spark->dSize = (GetRandomControl() & 0x3F) + 64;
spark->sSize = spark->dSize >> 3;
spark->size = spark->dSize >> 3;
+
+ spark->oldX = spark->x;
+ spark->oldY = spark->y;
+ spark->oldZ = spark->z;
+ spark->oldSize = spark->size;
+ spark->oldRotAng = spark->rotAng;
+ spark->oldScalar = spark->scalar;
}
int GetFreeBlood()
diff --git a/TombEngine/Game/effects/tomb4fx.h b/TombEngine/Game/effects/tomb4fx.h
index d1a089034..f04296afe 100644
--- a/TombEngine/Game/effects/tomb4fx.h
+++ b/TombEngine/Game/effects/tomb4fx.h
@@ -56,6 +56,14 @@ struct SMOKE_SPARKS
byte fxObj;
byte nodeNumber;
byte mirror;
+
+ int oldX;
+ int oldY;
+ int oldZ;
+ unsigned char oldShade;
+ short oldRotAng;
+ unsigned char oldSize;
+ unsigned char oldScalar;
};
struct SHOCKWAVE_STRUCT
@@ -122,6 +130,11 @@ struct FIRE_LIST
byte on;
float size;
short roomNumber;
+
+ int oldX;
+ int oldY;
+ int oldZ;
+ int oldSize;
};
struct FIRE_SPARKS
@@ -157,6 +170,16 @@ struct FIRE_SPARKS
unsigned char fadeToBlack;
unsigned char sLife;
unsigned char life;
+
+ int oldX;
+ int oldY;
+ int oldZ;
+ int oldR;
+ int oldG;
+ int oldB;
+ unsigned char oldScalar;
+ unsigned char oldSize;
+ short oldRotAng;
};
struct BLOOD_STRUCT
diff --git a/TombEngine/Renderer/RendererDrawEffect.cpp b/TombEngine/Renderer/RendererDrawEffect.cpp
index 32bc398cd..5b4010033 100644
--- a/TombEngine/Renderer/RendererDrawEffect.cpp
+++ b/TombEngine/Renderer/RendererDrawEffect.cpp
@@ -286,6 +286,26 @@ namespace TEN::Renderer
Vector4(spark->shade / 255.0f, spark->shade / 255.0f, spark->shade / 255.0f, 1.0f),
TO_RAD(spark->rotAng << 4), spark->scalar, { spark->size * 4.0f, spark->size * 4.0f },
BlendMode::Additive, true, view);
+
+ AddSpriteBillboard(
+ &_sprites[spark->def],
+ Vector3::Lerp(
+ Vector3(spark->oldX, spark->oldY, spark->oldZ),
+ Vector3(spark->x, spark->y, spark->z),
+ _interpolationFactor),
+ Vector4::Lerp(
+ Vector4(spark->oldShade / 255.0f, spark->oldShade / 255.0f, spark->oldShade / 255.0f, 1.0f),
+ Vector4(spark->shade / 255.0f, spark->shade / 255.0f, spark->shade / 255.0f, 1.0f),
+ _interpolationFactor),
+ TO_RAD(Lerp(spark->oldRotAng << 4, spark->rotAng << 4, _interpolationFactor)),
+ Lerp(spark->oldScalar, spark->scalar, _interpolationFactor),
+ {
+ Lerp(spark->oldSize, spark->size, _interpolationFactor) * 4.0f,
+ Lerp(spark->oldSize, spark->size, _interpolationFactor) * 4.0f
+ },
+ BlendMode::Additive,
+ true,
+ view);
}
}
}
@@ -307,11 +327,23 @@ namespace TEN::Renderer
{
AddSpriteBillboard(
&_sprites[spark->def],
- Vector3(fire->x + spark->x * fire->size / 2, fire->y + spark->y * fire->size / 2, fire->z + spark->z * fire->size / 2),
- Vector4(spark->r / 255.0f * fade, spark->g / 255.0f * fade, spark->b / 255.0f * fade, 1.0f),
- TO_RAD(spark->rotAng << 4),
- spark->scalar,
- Vector2(spark->size * fire->size, spark->size * fire->size), BlendMode::Additive, true, view);
+ Vector3::Lerp(
+ Vector3(fire->oldX + spark->oldX * fire->oldSize / 2, fire->oldY + spark->oldY * fire->oldSize / 2, fire->oldZ + spark->oldZ * fire->oldSize / 2),
+ Vector3(fire->x + spark->x * fire->size / 2, fire->y + spark->y * fire->size / 2, fire->z + spark->z * fire->size / 2),
+ _interpolationFactor),
+ Vector4::Lerp(
+ Vector4(spark->oldR / 255.0f * fade, spark->oldG / 255.0f * fade, spark->oldB / 255.0f * fade, 1.0f),
+ Vector4(spark->r / 255.0f * fade, spark->g / 255.0f * fade, spark->b / 255.0f * fade, 1.0f),
+ _interpolationFactor),
+ TO_RAD((short)Lerp(spark->oldRotAng, spark->rotAng, _interpolationFactor) << 4),
+ Lerp(spark->oldScalar, spark->scalar, _interpolationFactor),
+ Vector2::Lerp(
+ Vector2(spark->oldSize * fire->oldSize, spark->oldSize * fire->oldSize),
+ Vector2(spark->size * fire->size, spark->size * fire->size),
+ _interpolationFactor),
+ BlendMode::Additive,
+ true,
+ view);
}
}
}
From 98c8f6df913ae0234c81298db92c3da0df46443d Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Sat, 13 Apr 2024 06:02:58 +0200
Subject: [PATCH 073/410] Cleaning smoke sparks code
---
TombEngine/Game/Setup.cpp | 2 +-
TombEngine/Game/effects/chaffFX.cpp | 14 ++---
TombEngine/Game/effects/effects.cpp | 16 ++---
TombEngine/Game/effects/tomb4fx.cpp | 63 ++++++++-----------
TombEngine/Game/effects/tomb4fx.h | 31 ++++-----
TombEngine/Objects/TR4/Entity/tr4_demigod.cpp | 12 ++--
TombEngine/Objects/TR5/Entity/AutoGun.cpp | 10 ++-
.../Objects/TR5/Entity/tr5_roman_statue.cpp | 16 +++--
TombEngine/Renderer/RendererDrawEffect.cpp | 16 ++---
9 files changed, 83 insertions(+), 97 deletions(-)
diff --git a/TombEngine/Game/Setup.cpp b/TombEngine/Game/Setup.cpp
index a427dfe71..a0b27bb4a 100644
--- a/TombEngine/Game/Setup.cpp
+++ b/TombEngine/Game/Setup.cpp
@@ -135,7 +135,7 @@ void InitializeGameFlags()
void InitializeSpecialEffects()
{
memset(&FireSparks, 0, MAX_SPARKS_FIRE * sizeof(FIRE_SPARKS));
- memset(&SmokeSparks, 0, MAX_SPARKS_SMOKE * sizeof(SMOKE_SPARKS));
+ memset(&SmokeSparks, 0, MAX_SPARKS_SMOKE * sizeof(SmokeSpark));
memset(&Gunshells, 0, MAX_GUNSHELL * sizeof(GUNSHELL_STRUCT));
memset(&Blood, 0, MAX_SPARKS_BLOOD * sizeof(BLOOD_STRUCT));
memset(&Splashes, 0, MAX_SPLASHES * sizeof(SPLASH_STRUCT));
diff --git a/TombEngine/Game/effects/chaffFX.cpp b/TombEngine/Game/effects/chaffFX.cpp
index ed2468ce9..092cebade 100644
--- a/TombEngine/Game/effects/chaffFX.cpp
+++ b/TombEngine/Game/effects/chaffFX.cpp
@@ -98,7 +98,7 @@ void TriggerChaffSparkles(const Vector3i& pos, const Vector3i& vel, const Color&
void TriggerChaffSmoke(const Vector3i& pos, const Vector3i& vel, int speed, bool isMoving, bool wind)
{
- SMOKE_SPARKS* smoke;
+ SmokeSpark* smoke;
int rnd = 0;
BYTE trans, size;
@@ -133,12 +133,12 @@ void TriggerChaffSmoke(const Vector3i& pos, const Vector3i& vel, int speed, bool
smoke->blendMode = BlendMode::Additive;
- smoke->x = pos.x + (GetRandomControl() & 7) - 3;
- smoke->y = pos.y + (GetRandomControl() & 7) - 3;
- smoke->z = pos.z + (GetRandomControl() & 7) - 3;
- smoke->xVel = vel.x + ((GetRandomDraw() & 63) - 32);
- smoke->yVel = vel.y;
- smoke->zVel = vel.z + ((GetRandomDraw() & 63) - 32);
+ smoke->position.x = pos.x + (GetRandomControl() & 7) - 3;
+ smoke->position.y = pos.y + (GetRandomControl() & 7) - 3;
+ smoke->position.z = pos.z + (GetRandomControl() & 7) - 3;
+ smoke->velocity.x = vel.x + ((GetRandomDraw() & 63) - 32);
+ smoke->velocity.y = vel.y;
+ smoke->velocity.z = vel.z + ((GetRandomDraw() & 63) - 32);
smoke->friction = 4;
if (GetRandomControl() & 1)
diff --git a/TombEngine/Game/effects/effects.cpp b/TombEngine/Game/effects/effects.cpp
index 9913a9486..e1e04d1ab 100644
--- a/TombEngine/Game/effects/effects.cpp
+++ b/TombEngine/Game/effects/effects.cpp
@@ -1455,21 +1455,21 @@ void TriggerFlashSmoke(int x, int y, int z, short roomNumber)
spark->fadeToBlack = 16;
spark->blendMode = BlendMode::Additive;
spark->life = spark->sLife = (GetRandomControl() & 0xF) + 64;
- spark->x = (GetRandomControl() & 0x1F) + x - 16;
- spark->y = (GetRandomControl() & 0x1F) + y - 16;
- spark->z = (GetRandomControl() & 0x1F) + z - 16;
+ spark->position.x = (GetRandomControl() & 0x1F) + x - 16;
+ spark->position.y = (GetRandomControl() & 0x1F) + y - 16;
+ spark->position.z = (GetRandomControl() & 0x1F) + z - 16;
if (water)
{
- spark->xVel = spark->yVel = GetRandomControl() & 0x3FF - 512;
- spark->zVel = (GetRandomControl() & 0x3FF) - 512;
+ spark->velocity.x = spark->velocity.y = GetRandomControl() & 0x3FF - 512;
+ spark->velocity.z = (GetRandomControl() & 0x3FF) - 512;
spark->friction = 68;
}
else
{
- spark->xVel = 2 * (GetRandomControl() & 0x3FF) - 1024;
- spark->yVel = -512 - (GetRandomControl() & 0x3FF);
- spark->zVel = 2 * (GetRandomControl() & 0x3FF) - 1024;
+ spark->velocity.x = 2 * (GetRandomControl() & 0x3FF) - 1024;
+ spark->velocity.y = -512 - (GetRandomControl() & 0x3FF);
+ spark->velocity.z = 2 * (GetRandomControl() & 0x3FF) - 1024;
spark->friction = 85;
}
diff --git a/TombEngine/Game/effects/tomb4fx.cpp b/TombEngine/Game/effects/tomb4fx.cpp
index ba9e84347..236559d4a 100644
--- a/TombEngine/Game/effects/tomb4fx.cpp
+++ b/TombEngine/Game/effects/tomb4fx.cpp
@@ -47,7 +47,7 @@ int NextBlood = 0;
int NextGunShell = 0;
FIRE_SPARKS FireSparks[MAX_SPARKS_FIRE];
-SMOKE_SPARKS SmokeSparks[MAX_SPARKS_SMOKE];
+SmokeSpark SmokeSparks[MAX_SPARKS_SMOKE];
GUNSHELL_STRUCT Gunshells[MAX_GUNSHELL];
BLOOD_STRUCT Blood[MAX_SPARKS_BLOOD];
SHOCKWAVE_STRUCT ShockWaves[MAX_SHOCKWAVE];
@@ -527,7 +527,7 @@ void UpdateFireSparks()
int GetFreeSmokeSpark()
{
- SMOKE_SPARKS* spark = &SmokeSparks[NextSmokeSpark];
+ SmokeSpark* spark = &SmokeSparks[NextSmokeSpark];
int sparkNum = NextSmokeSpark;
short minLife = 4095;
short minIndex = 0;
@@ -567,7 +567,7 @@ void UpdateSmoke()
{
for (int i = 0; i < MAX_SPARKS_SMOKE; i++)
{
- SMOKE_SPARKS* spark = &SmokeSparks[i];
+ SmokeSpark* spark = &SmokeSparks[i];
if (spark->on)
{
@@ -579,13 +579,7 @@ void UpdateSmoke()
continue;
}
- spark->oldX = spark->x;
- spark->oldY = spark->y;
- spark->oldZ = spark->z;
- spark->oldSize = spark->size;
- spark->oldRotAng = spark->rotAng;
- spark->oldScalar = spark->scalar;
- spark->oldScalar = spark->scalar;
+ spark->StoreInterpolationData();
if (spark->sLife - spark->life >= spark->colFadeSpeed)
{
@@ -625,45 +619,45 @@ void UpdateSmoke()
int dl = ((spark->sLife - spark->life) << 16) / spark->sLife;
- spark->yVel += spark->gravity;
+ spark->velocity.y += spark->gravity;
if (spark->maxYvel != 0)
{
- if (spark->yVel < 0)
+ if (spark->velocity.y < 0)
{
- if (spark->yVel < spark->maxYvel)
+ if (spark->velocity.y < spark->maxYvel)
{
- spark->yVel = spark->maxYvel;
+ spark->velocity.y = spark->maxYvel;
}
}
else
{
- if (spark->yVel > spark->maxYvel)
+ if (spark->velocity.y > spark->maxYvel)
{
- spark->yVel = spark->maxYvel;
+ spark->velocity.y = spark->maxYvel;
}
}
}
if (spark->friction & 0xF)
{
- spark->xVel -= spark->xVel >> (spark->friction & 0xF);
- spark->zVel -= spark->zVel >> (spark->friction & 0xF);
+ spark->velocity.x -= spark->velocity.x >> (spark->friction & 0xF);
+ spark->velocity.z -= spark->velocity.z >> (spark->friction & 0xF);
}
if (spark->friction & 0xF0)
{
- spark->yVel -= spark->yVel >> (spark->friction >> 4);
+ spark->velocity.y -= spark->velocity.y >> (spark->friction >> 4);
}
- spark->x += spark->xVel >> 5;
- spark->y += spark->yVel >> 5;
- spark->z += spark->zVel >> 5;
+ spark->position.x += spark->velocity.x >> 5;
+ spark->position.y += spark->velocity.y >> 5;
+ spark->position.z += spark->velocity.z >> 5;
if (spark->flags & SP_WIND)
{
- spark->x += Weather.Wind().x;
- spark->z += Weather.Wind().z;
+ spark->position.x += Weather.Wind().x;
+ spark->position.z += Weather.Wind().z;
}
spark->size = spark->sSize + (dl * (spark->dSize - spark->sSize) >> 16);
@@ -693,7 +687,7 @@ void TriggerGunSmoke(int x, int y, int z, short xv, short yv, short zv, byte ini
void TriggerShatterSmoke(int x, int y, int z)
{
- SMOKE_SPARKS* spark = &SmokeSparks[GetFreeSmokeSpark()];
+ SmokeSpark* spark = &SmokeSparks[GetFreeSmokeSpark()];
spark->on = true;
spark->sShade = 0;
@@ -702,12 +696,12 @@ void TriggerShatterSmoke(int x, int y, int z)
spark->fadeToBlack = 24 - (GetRandomControl() & 7);
spark->blendMode = BlendMode::Additive;
spark->life = spark->sLife = (GetRandomControl() & 7) + 48;
- spark->x = (GetRandomControl() & 0x1F) + x - 16;
- spark->y = (GetRandomControl() & 0x1F) + y - 16;
- spark->z = (GetRandomControl() & 0x1F) + z - 16;
- spark->xVel = 2 * (GetRandomControl() & 0x1FF) - 512;
- spark->yVel = 2 * (GetRandomControl() & 0x1FF) - 512;
- spark->zVel = 2 * (GetRandomControl() & 0x1FF) - 512;
+ spark->position.x = (GetRandomControl() & 0x1F) + x - 16;
+ spark->position.y = (GetRandomControl() & 0x1F) + y - 16;
+ spark->position.z = (GetRandomControl() & 0x1F) + z - 16;
+ spark->velocity.x = 2 * (GetRandomControl() & 0x1FF) - 512;
+ spark->velocity.y = 2 * (GetRandomControl() & 0x1FF) - 512;
+ spark->velocity.z = 2 * (GetRandomControl() & 0x1FF) - 512;
spark->friction = 7;
if (GetRandomControl() & 1)
@@ -733,13 +727,6 @@ void TriggerShatterSmoke(int x, int y, int z)
spark->dSize = (GetRandomControl() & 0x3F) + 64;
spark->sSize = spark->dSize >> 3;
spark->size = spark->dSize >> 3;
-
- spark->oldX = spark->x;
- spark->oldY = spark->y;
- spark->oldZ = spark->z;
- spark->oldSize = spark->size;
- spark->oldRotAng = spark->rotAng;
- spark->oldScalar = spark->scalar;
}
int GetFreeBlood()
diff --git a/TombEngine/Game/effects/tomb4fx.h b/TombEngine/Game/effects/tomb4fx.h
index f04296afe..2d84e0dbc 100644
--- a/TombEngine/Game/effects/tomb4fx.h
+++ b/TombEngine/Game/effects/tomb4fx.h
@@ -25,14 +25,10 @@ enum BodyPartFlags
BODY_NO_SHATTER_EFFECT = (1 << 13), // Remove shatter effect upon despawn.
};
-struct SMOKE_SPARKS
+struct SmokeSpark
{
- int x;
- int y;
- int z;
- int xVel;
- int yVel;
- int zVel;
+ Vector3i position;
+ Vector3i velocity;
int gravity;
short rotAng;
short flags;
@@ -57,13 +53,20 @@ struct SMOKE_SPARKS
byte nodeNumber;
byte mirror;
- int oldX;
- int oldY;
- int oldZ;
- unsigned char oldShade;
+ Vector3i oldPosition;
+ byte oldShade;
+ byte oldSize;
+ byte oldScalar;
short oldRotAng;
- unsigned char oldSize;
- unsigned char oldScalar;
+
+ void StoreInterpolationData()
+ {
+ oldPosition = position;
+ oldShade = shade;
+ oldSize = size;
+ oldScalar = scalar;
+ oldRotAng = rotAng;
+ }
};
struct SHOCKWAVE_STRUCT
@@ -247,7 +250,7 @@ constexpr auto MAX_GUNSHELL = 24;
constexpr auto MAX_SHOCKWAVE = 16;
extern FIRE_SPARKS FireSparks[MAX_SPARKS_FIRE];
-extern SMOKE_SPARKS SmokeSparks[MAX_SPARKS_SMOKE];
+extern SmokeSpark SmokeSparks[MAX_SPARKS_SMOKE];
extern GUNSHELL_STRUCT Gunshells[MAX_GUNSHELL];
extern BLOOD_STRUCT Blood[MAX_SPARKS_BLOOD];
extern SHOCKWAVE_STRUCT ShockWaves[MAX_SHOCKWAVE];
diff --git a/TombEngine/Objects/TR4/Entity/tr4_demigod.cpp b/TombEngine/Objects/TR4/Entity/tr4_demigod.cpp
index 17c14ea39..4b4e1fe91 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_demigod.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_demigod.cpp
@@ -290,12 +290,12 @@ namespace TEN::Entities::TR4
spark->fadeToBlack = 24 - (GetRandomControl() & 7);
spark->blendMode = BlendMode::Additive;
spark->life = spark->sLife = (GetRandomControl() & 7) + 48;
- spark->x = (GetRandomControl() & 0x1F) + x - 16;
- spark->y = (GetRandomControl() & 0x1F) + y - 16;
- spark->z = (GetRandomControl() & 0x1F) + z - 16;
- spark->xVel = (byte)(GetRandomControl() + 256) * phd_sin(angle);
- spark->yVel = -32 - (GetRandomControl() & 0x3F);
- spark->zVel = (byte)(GetRandomControl() + 256) * phd_cos(angle);
+ spark->position.x = (GetRandomControl() & 0x1F) + x - 16;
+ spark->position.y = (GetRandomControl() & 0x1F) + y - 16;
+ spark->position.z = (GetRandomControl() & 0x1F) + z - 16;
+ spark->velocity.x = (byte)(GetRandomControl() + 256) * phd_sin(angle);
+ spark->velocity.y = -32 - (GetRandomControl() & 0x3F);
+ spark->velocity.z = (byte)(GetRandomControl() + 256) * phd_cos(angle);
spark->friction = 9;
if (Random::TestProbability(1 / 2.0f))
diff --git a/TombEngine/Objects/TR5/Entity/AutoGun.cpp b/TombEngine/Objects/TR5/Entity/AutoGun.cpp
index 6ed1cb87c..5246f727f 100644
--- a/TombEngine/Objects/TR5/Entity/AutoGun.cpp
+++ b/TombEngine/Objects/TR5/Entity/AutoGun.cpp
@@ -62,12 +62,10 @@ namespace TEN::Entities::Creatures::TR5
smoke.fadeToBlack = 32;
smoke.blendMode = BlendMode::Additive;
smoke.life = smoke.sLife = Random::GenerateInt(40, 44);
- smoke.x = smokePos.x;
- smoke.y = smokePos.y;
- smoke.z = smokePos.z;
- smoke.xVel = 0;
- smoke.yVel = 0;
- smoke.zVel = 0;
+ smoke.position.x = smokePos.x;
+ smoke.position.y = smokePos.y;
+ smoke.position.z = smokePos.z;
+ smoke.velocity = Vector3i::Zero;
smoke.friction = 4;
smoke.flags = SP_ROTATE;
smoke.rotAng = Random::GenerateInt(0, 4096);
diff --git a/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp b/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp
index 72a8d3aa8..d78e551b2 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp
@@ -112,12 +112,16 @@ namespace TEN::Entities::Creatures::TR5
spark->dShade = (GetRandomControl() & 0xF) + 64;
spark->blendMode = BlendMode::Additive;
spark->life = spark->sLife = (GetRandomControl() & 3) + 64;
- spark->x = (GetRandomControl() & 0x1F) + pos->x - 16;
- spark->y = (GetRandomControl() & 0x1F) + pos->y - 16;
- spark->z = (GetRandomControl() & 0x1F) + pos->z - 16;
- spark->xVel = (GetRandomControl() & 0x7F) - 64;
- spark->yVel = 0;
- spark->zVel = (GetRandomControl() & 0x7F) - 64;
+ spark->position = Vector3i(
+ (GetRandomControl() & 0x1F) + pos->x - 16,
+ (GetRandomControl() & 0x1F) + pos->y - 16,
+ (GetRandomControl() & 0x1F) + pos->z - 16
+ );
+ spark->velocity = Vector3i(
+ (GetRandomControl() & 0x7F) - 64,
+ 0,
+ (GetRandomControl() & 0x7F) - 64
+ );
spark->friction = 4;
spark->flags = SP_ROTATE;
spark->rotAng = GetRandomControl() & 0xFFF;
diff --git a/TombEngine/Renderer/RendererDrawEffect.cpp b/TombEngine/Renderer/RendererDrawEffect.cpp
index 5b4010033..7d390adeb 100644
--- a/TombEngine/Renderer/RendererDrawEffect.cpp
+++ b/TombEngine/Renderer/RendererDrawEffect.cpp
@@ -48,7 +48,7 @@ using namespace TEN::Traps::TR5;
extern BLOOD_STRUCT Blood[MAX_SPARKS_BLOOD];
extern FIRE_SPARKS FireSparks[MAX_SPARKS_FIRE];
-extern SMOKE_SPARKS SmokeSparks[MAX_SPARKS_SMOKE];
+extern SmokeSpark SmokeSparks[MAX_SPARKS_SMOKE];
extern SHOCKWAVE_STRUCT ShockWaves[MAX_SHOCKWAVE];
extern FIRE_LIST Fires[MAX_FIRE_LIST];
extern Particle Particles[MAX_PARTICLES];
@@ -277,21 +277,15 @@ namespace TEN::Renderer
{
for (int i = 0; i < 32; i++)
{
- SMOKE_SPARKS* spark = &SmokeSparks[i];
+ SmokeSpark* spark = &SmokeSparks[i];
if (spark->on)
{
- AddSpriteBillboard(&_sprites[spark->def],
- Vector3(spark->x, spark->y, spark->z),
- Vector4(spark->shade / 255.0f, spark->shade / 255.0f, spark->shade / 255.0f, 1.0f),
- TO_RAD(spark->rotAng << 4), spark->scalar, { spark->size * 4.0f, spark->size * 4.0f },
- BlendMode::Additive, true, view);
-
AddSpriteBillboard(
&_sprites[spark->def],
Vector3::Lerp(
- Vector3(spark->oldX, spark->oldY, spark->oldZ),
- Vector3(spark->x, spark->y, spark->z),
+ Vector3(spark->oldPosition.x, spark->oldPosition.y, spark->oldPosition.z),
+ Vector3(spark->position.x, spark->position.y, spark->position.z),
_interpolationFactor),
Vector4::Lerp(
Vector4(spark->oldShade / 255.0f, spark->oldShade / 255.0f, spark->oldShade / 255.0f, 1.0f),
@@ -335,7 +329,7 @@ namespace TEN::Renderer
Vector4(spark->oldR / 255.0f * fade, spark->oldG / 255.0f * fade, spark->oldB / 255.0f * fade, 1.0f),
Vector4(spark->r / 255.0f * fade, spark->g / 255.0f * fade, spark->b / 255.0f * fade, 1.0f),
_interpolationFactor),
- TO_RAD((short)Lerp(spark->oldRotAng, spark->rotAng, _interpolationFactor) << 4),
+ TO_RAD(Lerp(spark->oldRotAng << 4, spark->rotAng << 4, _interpolationFactor)),
Lerp(spark->oldScalar, spark->scalar, _interpolationFactor),
Vector2::Lerp(
Vector2(spark->oldSize * fire->oldSize, spark->oldSize * fire->oldSize),
From f4a5644dc0afb0e0731e36c97f9500570ceaa08b Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Mon, 15 Apr 2024 08:33:10 +0200
Subject: [PATCH 074/410] Gunshells interpolation
---
TombEngine/Game/Setup.cpp | 4 ++--
TombEngine/Game/effects/chaffFX.cpp | 2 +-
TombEngine/Game/effects/tomb4fx.cpp | 14 ++++++++------
TombEngine/Game/effects/tomb4fx.h | 15 +++++++++++----
TombEngine/Renderer/RendererDraw.cpp | 12 +++++++++++-
TombEngine/Renderer/RendererDrawEffect.cpp | 4 ++--
6 files changed, 35 insertions(+), 16 deletions(-)
diff --git a/TombEngine/Game/Setup.cpp b/TombEngine/Game/Setup.cpp
index a0b27bb4a..20eaa6b14 100644
--- a/TombEngine/Game/Setup.cpp
+++ b/TombEngine/Game/Setup.cpp
@@ -135,8 +135,8 @@ void InitializeGameFlags()
void InitializeSpecialEffects()
{
memset(&FireSparks, 0, MAX_SPARKS_FIRE * sizeof(FIRE_SPARKS));
- memset(&SmokeSparks, 0, MAX_SPARKS_SMOKE * sizeof(SmokeSpark));
- memset(&Gunshells, 0, MAX_GUNSHELL * sizeof(GUNSHELL_STRUCT));
+ memset(&SmokeSparks, 0, MAX_SPARKS_SMOKE * sizeof(SmokeSparkInfo));
+ memset(&Gunshells, 0, MAX_GUNSHELL * sizeof(GunshellInfo));
memset(&Blood, 0, MAX_SPARKS_BLOOD * sizeof(BLOOD_STRUCT));
memset(&Splashes, 0, MAX_SPLASHES * sizeof(SPLASH_STRUCT));
memset(&ShockWaves, 0, MAX_SHOCKWAVE * sizeof(SHOCKWAVE_STRUCT));
diff --git a/TombEngine/Game/effects/chaffFX.cpp b/TombEngine/Game/effects/chaffFX.cpp
index 092cebade..4b4674204 100644
--- a/TombEngine/Game/effects/chaffFX.cpp
+++ b/TombEngine/Game/effects/chaffFX.cpp
@@ -98,7 +98,7 @@ void TriggerChaffSparkles(const Vector3i& pos, const Vector3i& vel, const Color&
void TriggerChaffSmoke(const Vector3i& pos, const Vector3i& vel, int speed, bool isMoving, bool wind)
{
- SmokeSpark* smoke;
+ SmokeSparkInfo* smoke;
int rnd = 0;
BYTE trans, size;
diff --git a/TombEngine/Game/effects/tomb4fx.cpp b/TombEngine/Game/effects/tomb4fx.cpp
index 236559d4a..d1191322c 100644
--- a/TombEngine/Game/effects/tomb4fx.cpp
+++ b/TombEngine/Game/effects/tomb4fx.cpp
@@ -47,8 +47,8 @@ int NextBlood = 0;
int NextGunShell = 0;
FIRE_SPARKS FireSparks[MAX_SPARKS_FIRE];
-SmokeSpark SmokeSparks[MAX_SPARKS_SMOKE];
-GUNSHELL_STRUCT Gunshells[MAX_GUNSHELL];
+SmokeSparkInfo SmokeSparks[MAX_SPARKS_SMOKE];
+GunshellInfo Gunshells[MAX_GUNSHELL];
BLOOD_STRUCT Blood[MAX_SPARKS_BLOOD];
SHOCKWAVE_STRUCT ShockWaves[MAX_SHOCKWAVE];
FIRE_LIST Fires[MAX_FIRE_LIST];
@@ -527,7 +527,7 @@ void UpdateFireSparks()
int GetFreeSmokeSpark()
{
- SmokeSpark* spark = &SmokeSparks[NextSmokeSpark];
+ SmokeSparkInfo* spark = &SmokeSparks[NextSmokeSpark];
int sparkNum = NextSmokeSpark;
short minLife = 4095;
short minIndex = 0;
@@ -567,7 +567,7 @@ void UpdateSmoke()
{
for (int i = 0; i < MAX_SPARKS_SMOKE; i++)
{
- SmokeSpark* spark = &SmokeSparks[i];
+ SmokeSparkInfo* spark = &SmokeSparks[i];
if (spark->on)
{
@@ -687,7 +687,7 @@ void TriggerGunSmoke(int x, int y, int z, short xv, short yv, short zv, byte ini
void TriggerShatterSmoke(int x, int y, int z)
{
- SmokeSpark* spark = &SmokeSparks[GetFreeSmokeSpark()];
+ SmokeSparkInfo* spark = &SmokeSparks[GetFreeSmokeSpark()];
spark->on = true;
spark->sShade = 0;
@@ -878,7 +878,7 @@ int GetFreeGunshell()
while (true)
{
- GUNSHELL_STRUCT* gs = &Gunshells[NextGunShell];
+ GunshellInfo* gs = &Gunshells[NextGunShell];
if (!gs->counter)
break;
@@ -1018,6 +1018,8 @@ void UpdateGunShells()
if (gunshell->counter)
{
+ gunshell->StoreInterpolationData();
+
auto prevPos = gunshell->pos.Position;
gunshell->counter--;
diff --git a/TombEngine/Game/effects/tomb4fx.h b/TombEngine/Game/effects/tomb4fx.h
index 2d84e0dbc..cada0ccfa 100644
--- a/TombEngine/Game/effects/tomb4fx.h
+++ b/TombEngine/Game/effects/tomb4fx.h
@@ -25,7 +25,7 @@ enum BodyPartFlags
BODY_NO_SHATTER_EFFECT = (1 << 13), // Remove shatter effect upon despawn.
};
-struct SmokeSpark
+struct SmokeSparkInfo
{
Vector3i position;
Vector3i velocity;
@@ -97,7 +97,7 @@ struct SHOCKWAVE_STRUCT
bool HasLight = false;
};
-struct GUNSHELL_STRUCT
+struct GunshellInfo
{
Pose pos;
short fallspeed;
@@ -106,6 +106,13 @@ struct GUNSHELL_STRUCT
short counter;
short dirXrot;
short objectNumber;
+
+ Pose oldPos;
+
+ void StoreInterpolationData()
+ {
+ oldPos = pos;
+ }
};
struct DRIP_STRUCT
@@ -250,8 +257,8 @@ constexpr auto MAX_GUNSHELL = 24;
constexpr auto MAX_SHOCKWAVE = 16;
extern FIRE_SPARKS FireSparks[MAX_SPARKS_FIRE];
-extern SmokeSpark SmokeSparks[MAX_SPARKS_SMOKE];
-extern GUNSHELL_STRUCT Gunshells[MAX_GUNSHELL];
+extern SmokeSparkInfo SmokeSparks[MAX_SPARKS_SMOKE];
+extern GunshellInfo Gunshells[MAX_GUNSHELL];
extern BLOOD_STRUCT Blood[MAX_SPARKS_BLOOD];
extern SHOCKWAVE_STRUCT ShockWaves[MAX_SHOCKWAVE];
extern FIRE_LIST Fires[MAX_FIRE_LIST];
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index 404dca789..fd7969397 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -39,7 +39,7 @@ using namespace TEN::Entities::Generic;
using namespace TEN::Hud;
using namespace TEN::Renderer::Structures;
-extern GUNSHELL_STRUCT Gunshells[MAX_GUNSHELL];
+extern GunshellInfo Gunshells[MAX_GUNSHELL];
namespace TEN::Renderer
{
@@ -276,6 +276,16 @@ namespace TEN::Renderer
Matrix rotation = gunshell->pos.Orientation.ToRotationMatrix();
Matrix world = rotation * translation;
+ Matrix oldTranslation = Matrix::CreateTranslation(
+ gunshell->oldPos.Position.x,
+ gunshell->oldPos.Position.y,
+ gunshell->oldPos.Position.z
+ );
+ Matrix oldRotation = gunshell->oldPos.Orientation.ToRotationMatrix();
+ Matrix oldWorld = oldRotation * oldTranslation;
+
+ world = Matrix::Lerp(oldWorld, world, _interpolationFactor);
+
_stInstancedStaticMeshBuffer.StaticMeshes[gunShellsCount].World = world;
_stInstancedStaticMeshBuffer.StaticMeshes[gunShellsCount].Ambient = room.AmbientLight;
_stInstancedStaticMeshBuffer.StaticMeshes[gunShellsCount].Color = room.AmbientLight;
diff --git a/TombEngine/Renderer/RendererDrawEffect.cpp b/TombEngine/Renderer/RendererDrawEffect.cpp
index 7d390adeb..a165679ba 100644
--- a/TombEngine/Renderer/RendererDrawEffect.cpp
+++ b/TombEngine/Renderer/RendererDrawEffect.cpp
@@ -48,7 +48,7 @@ using namespace TEN::Traps::TR5;
extern BLOOD_STRUCT Blood[MAX_SPARKS_BLOOD];
extern FIRE_SPARKS FireSparks[MAX_SPARKS_FIRE];
-extern SmokeSpark SmokeSparks[MAX_SPARKS_SMOKE];
+extern SmokeSparkInfo SmokeSparks[MAX_SPARKS_SMOKE];
extern SHOCKWAVE_STRUCT ShockWaves[MAX_SHOCKWAVE];
extern FIRE_LIST Fires[MAX_FIRE_LIST];
extern Particle Particles[MAX_PARTICLES];
@@ -277,7 +277,7 @@ namespace TEN::Renderer
{
for (int i = 0; i < 32; i++)
{
- SmokeSpark* spark = &SmokeSparks[i];
+ SmokeSparkInfo* spark = &SmokeSparks[i];
if (spark->on)
{
From d5526be20852dbae7a9f90f161856e45298cf756 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Mon, 15 Apr 2024 11:08:41 +0200
Subject: [PATCH 075/410] Improved fires and flares interpolation; Fixed fast
blinking of dynamic lights;
---
Documentation/output.xml | 130 ++++++++++----------
TombEngine/Game/control/control.cpp | 2 +
TombEngine/Game/effects/tomb4fx.cpp | 131 ++++++++-------------
TombEngine/Game/effects/tomb4fx.h | 47 ++++----
TombEngine/Renderer/Renderer.h | 2 +-
TombEngine/Renderer/RendererDraw.cpp | 2 -
TombEngine/Renderer/RendererDrawEffect.cpp | 25 +++-
7 files changed, 162 insertions(+), 177 deletions(-)
diff --git a/Documentation/output.xml b/Documentation/output.xml
index 96faf84ae..deacfcb96 100644
--- a/Documentation/output.xml
+++ b/Documentation/output.xml
@@ -1931,9 +1931,9 @@ e.g. `myItem.action = ItemAction.EXAMINE`
Objects.Moveable
Moveable
- For more information on each parameter, see the
-associated getters and setters.
- If you do not know what to set for these,
+ Used to generate a new moveable dynamically at runtime.
+ For more information on each parameter, see the
+associated getters and setters. If you do not know what to set for these,
most can just be ignored (see usage).
@@ -1954,7 +1954,7 @@ most can just be ignored (see usage).
rotation
Rotation
- rotation about x, y, and z axes (default Rotation(0, 0, 0))
+ rotation rotation about x, y, and z axes (default Rotation(0, 0, 0))
roomID
@@ -1964,7 +1964,7 @@ most can just be ignored (see usage).
animNumber
int
- anim number
+ animation number
frameNumber
@@ -2096,66 +2096,6 @@ most can just be ignored (see usage).
-
- Objects.Moveable
- Moveable
- SetOnHit
- Set the name of the function to be called when the moveable is shot by Lara.
- Note that this will be triggered twice when shot with both pistols at once.
-
-
- callback
- function
- function in LevelFuncs hierarchy to call when moveable is shot
-
-
-
-
-
- Objects.Moveable
- Moveable
- SetOnCollidedWithObject
- Set the function to be called when this moveable collides with another moveable
-
-
- func
- function
- callback function to be called (must be in LevelFuncs hierarchy). This function can take two arguments; these will store the two @{Moveable}s taking part in the collision.
-
-
-
-
-
- Objects.Moveable
- Moveable
- SetOnCollidedWithRoom
- Set the function called when this moveable collides with room geometry (e.g.
- a wall or floor). This function can take an argument that holds the @{Moveable} that collided with geometry.
-
-
- func
- function
- callback function to be called (must be in LevelFuncs hierarchy)
-
-
-
-
-
- Objects.Moveable
- Moveable
- SetOnKilled
- Set the name of the function to be called when the moveable is destroyed/killed
- Note that enemy death often occurs at the end of an animation, and not at the exact moment
- the enemy's HP becomes zero.
-
-
- callback
- function
- function in LevelFuncs hierarchy to call when enemy is killed
-
-
-
-
Objects.Moveable
Moveable
@@ -2624,6 +2564,66 @@ most can just be ignored (see usage).
+
+ Objects.Moveable
+ Moveable
+ SetOnHit
+ Set the name of the function to be called when the moveable is shot by Lara.
+ Note that this will be triggered twice when shot with both pistols at once.
+
+
+ callback
+ function
+ function in LevelFuncs hierarchy to call when moveable is shot
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ SetOnCollidedWithObject
+ Set the function to be called when this moveable collides with another moveable
+
+
+ func
+ function
+ callback function to be called (must be in LevelFuncs hierarchy). This function can take two arguments; these will store the two @{Moveable}s taking part in the collision.
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ SetOnCollidedWithRoom
+ Set the function called when this moveable collides with room geometry (e.g.
+ a wall or floor). This function can take an argument that holds the @{Moveable} that collided with geometry.
+
+
+ func
+ function
+ callback function to be called (must be in LevelFuncs hierarchy)
+
+
+
+
+
+ Objects.Moveable
+ Moveable
+ SetOnKilled
+ Set the name of the function to be called when the moveable is destroyed/killed
+ Note that enemy death often occurs at the end of an animation, and not at the exact moment
+ the enemy's HP becomes zero.
+
+
+ callback
+ function
+ function in LevelFuncs hierarchy to call when enemy is killed
+
+
+
+
Objects.Moveable
Moveable
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index a8ce63314..f904d35cb 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -137,6 +137,8 @@ GameStatus ControlPhase(int numFrames)
bool isTitle = (CurrentLevel == 0);
+ ClearFires();
+ g_Renderer.ClearDynamicLights();
RegeneratePickups();
numFrames = std::clamp(numFrames, 0, 10);
diff --git a/TombEngine/Game/effects/tomb4fx.cpp b/TombEngine/Game/effects/tomb4fx.cpp
index d1191322c..886a240c4 100644
--- a/TombEngine/Game/effects/tomb4fx.cpp
+++ b/TombEngine/Game/effects/tomb4fx.cpp
@@ -109,27 +109,17 @@ void TriggerGlobalStaticFlame()
spark->fadeToBlack = 0;
spark->life = 8;
spark->sLife = 8;
- spark->y = 0;
- spark->x = (GetRandomControl() & 7) - 4;
+ spark->position = Vector3i(
+ (GetRandomControl() & 7) - 4,
+ 0,
+ (GetRandomControl() & 7) - 4
+ );
spark->maxYvel = 0;
spark->gravity = 0;
- spark->z = (GetRandomControl() & 7) - 4;
spark->friction = 0;
- spark->xVel = 0;
- spark->yVel = 0;
- spark->zVel = 0;
+ spark->velocity = Vector3i::Zero;
spark->flags = SP_NONE;
spark->dSize = spark->sSize = spark->size = (GetRandomControl() & 0x1F) + -128;
-
- spark->oldX = spark->x;
- spark->oldY = spark->y;
- spark->oldZ = spark->z;
- spark->oldSize = spark->size;
- spark->oldRotAng = spark->rotAng;
- spark->oldR = spark->r;
- spark->oldG = spark->g;
- spark->oldB = spark->b;
- spark->oldScalar = spark->scalar;
}
void TriggerGlobalFireSmoke()
@@ -146,12 +136,16 @@ void TriggerGlobalFireSmoke()
spark->fadeToBlack = 16;
spark->colFadeSpeed = (GetRandomControl() & 7) + 32;
spark->life = spark->sLife = (GetRandomControl() & 0xF) + 57;
- spark->x = (GetRandomControl() & 0xF) - 8;
- spark->y = -256 - (GetRandomControl() & 0x7F);
- spark->z = (GetRandomControl() & 0xF) - 8;
- spark->xVel = (GetRandomControl() & 0xFF) - 128;
- spark->yVel = -16 - (GetRandomControl() & 0xF);
- spark->zVel = (GetRandomControl() & 0xFF) - 128;
+ spark->position = Vector3i(
+ (GetRandomControl() & 0xF) - 8,
+ -256 - (GetRandomControl() & 0x7F),
+ (GetRandomControl() & 0xF) - 8
+ );
+ spark->velocity = Vector3i(
+ (GetRandomControl() & 0xFF) - 128,
+ -16 - (GetRandomControl() & 0xF),
+ (GetRandomControl() & 0xFF) - 128
+ );
spark->friction = 4;
if (GetRandomControl() & 1)
@@ -171,16 +165,6 @@ void TriggerGlobalFireSmoke()
spark->gravity = -16 - (GetRandomControl() & 0xF);
spark->maxYvel = -8 - (GetRandomControl() & 7);
spark->dSize = spark->sSize = spark->size = (GetRandomControl() & 0x7F) + 128;
-
- spark->oldX = spark->x;
- spark->oldY = spark->y;
- spark->oldZ = spark->z;
- spark->oldSize = spark->size;
- spark->oldRotAng = spark->rotAng;
- spark->oldR = spark->r;
- spark->oldG = spark->g;
- spark->oldB = spark->b;
- spark->oldScalar = spark->scalar;
}
void TriggerGlobalFireFlame()
@@ -197,12 +181,16 @@ void TriggerGlobalFireFlame()
spark->fadeToBlack = 8;
spark->colFadeSpeed = (GetRandomControl() & 3) + 8;
spark->life = spark->sLife = (GetRandomControl() & 7) + 32;
- spark->y = 0;
- spark->x = 4 * (GetRandomControl() & 0x1F) - 64;
- spark->z = 4 * (GetRandomControl() & 0x1F) - 64;
- spark->xVel = 2 * (GetRandomControl() & 0xFF) - 256;
- spark->yVel = -16 - (GetRandomControl() & 0xF);
- spark->zVel = 2 * (GetRandomControl() & 0xFF) - 256;
+ spark->position = Vector3i(
+ 4 * (GetRandomControl() & 0x1F) - 64,
+ 0,
+ 4 * (GetRandomControl() & 0x1F) - 64
+ );
+ spark->velocity = Vector3i(
+ 2 * (GetRandomControl() & 0xFF) - 256,
+ -16 - (GetRandomControl() & 0xF),
+ 2 * (GetRandomControl() & 0xFF) - 256
+ );
spark->friction = 5;
spark->gravity = -32 - (GetRandomControl() & 0x1F);
spark->maxYvel = -16 - (GetRandomControl() & 7);
@@ -223,16 +211,6 @@ void TriggerGlobalFireFlame()
spark->sSize = spark->size = (GetRandomControl() & 0x1F) + 128;
spark->dSize = spark->size;
-
- spark->oldX = spark->x;
- spark->oldY = spark->y;
- spark->oldZ = spark->z;
- spark->oldSize = spark->size;
- spark->oldRotAng = spark->rotAng;
- spark->oldR = spark->r;
- spark->oldG = spark->g;
- spark->oldB = spark->b;
- spark->oldScalar = spark->scalar;
}
void TriggerPilotFlame(int itemNumber, int nodeIndex)
@@ -419,16 +397,11 @@ void AddFire(int x, int y, int z, short roomNum, float size, short fade)
else
fptr->on = 1;
- fptr->x = x;
- fptr->y = y;
- fptr->z = z;
+ fptr->position = Vector3i(x, y, z);
fptr->roomNumber = roomNum;
fptr->size = size;
- fptr->oldX = fptr->x;
- fptr->oldY = fptr->y;
- fptr->oldZ = fptr->z;
- fptr->oldSize = fptr->size;
+ fptr->StoreInterpolationData();
}
void ClearFires()
@@ -455,39 +428,33 @@ void UpdateFireSparks()
continue;
}
- spark->oldX = spark->x;
- spark->oldY = spark->y;
- spark->oldZ = spark->z;
- spark->oldSize = spark->size;
- spark->oldRotAng = spark->rotAng;
- spark->oldR = spark->r;
- spark->oldG = spark->g;
- spark->oldB = spark->b;
- spark->oldScalar = spark->scalar;
+ spark->StoreInterpolationData();
if (spark->sLife - spark->life < spark->colFadeSpeed)
{
int dl = ((spark->sLife - spark->life) << 16) / spark->colFadeSpeed;
- spark->r = spark->sR + (dl * (spark->dR - spark->sR) >> 16);
- spark->g = spark->sG + (dl * (spark->dG - spark->sG) >> 16);
- spark->b = spark->sB + (dl * (spark->dB - spark->sB) >> 16);
+ spark->color = Vector3i(
+ spark->sR + (dl * (spark->dR - spark->sR) >> 16),
+ spark->sG + (dl * (spark->dG - spark->sG) >> 16),
+ spark->sB + (dl * (spark->dB - spark->sB) >> 16)
+ );
}
else if (spark->life >= spark->fadeToBlack)
{
- spark->r = spark->dR;
- spark->g = spark->dG;
- spark->b = spark->dB;
+ spark->color = Vector3i(spark->dR, spark->dG, spark->dB);
}
else
{
int dl = ((spark->life - spark->fadeToBlack) << 16) / spark->fadeToBlack + 0x10000;
- spark->r = dl * spark->dR >> 16;
- spark->g = dl * spark->dG >> 16;
- spark->b = dl * spark->dB >> 16;
+ spark->color = Vector3i(
+ dl * spark->dR >> 16,
+ dl * spark->dG >> 16,
+ dl * spark->dB >> 16
+ );
- if (spark->r < 8 && spark->g < 8 && spark->b < 8)
+ if (spark->color.x < 8 && spark->color.y < 8 && spark->color.z < 8)
{
spark->on = false;
continue;
@@ -502,23 +469,21 @@ void UpdateFireSparks()
spark->def = sprite;
int dl = ((spark->sLife - spark->life) << 16) / spark->sLife;
- spark->yVel += spark->gravity;
+ spark->velocity.y += spark->gravity;
if (spark->maxYvel)
{
- if ((spark->yVel < 0 && spark->yVel < (spark->maxYvel << 5)) ||
- (spark->yVel > 0 && spark->yVel > (spark->maxYvel << 5)))
- spark->yVel = spark->maxYvel << 5;
+ if ((spark->velocity.y < 0 && spark->velocity.y < (spark->maxYvel << 5)) ||
+ (spark->velocity.y > 0 && spark->velocity.y > (spark->maxYvel << 5)))
+ spark->velocity.y = spark->maxYvel << 5;
}
if (spark->friction)
{
- spark->xVel -= spark->xVel >> spark->friction;
- spark->zVel -= spark->zVel >> spark->friction;
+ spark->velocity.x -= spark->velocity.x >> spark->friction;
+ spark->velocity.z -= spark->velocity.z >> spark->friction;
}
- spark->x += spark->xVel / 48;
- spark->y += spark->yVel / 48;
- spark->z += spark->zVel / 48;
+ spark->position += spark->velocity / 48;
spark->size = spark->sSize + ((dl * (spark->dSize - spark->sSize)) / 65536);
}
diff --git a/TombEngine/Game/effects/tomb4fx.h b/TombEngine/Game/effects/tomb4fx.h
index cada0ccfa..da63cb1cc 100644
--- a/TombEngine/Game/effects/tomb4fx.h
+++ b/TombEngine/Game/effects/tomb4fx.h
@@ -134,27 +134,28 @@ struct DRIP_STRUCT
struct FIRE_LIST
{
- int x;
- int y;
- int z;
+ Vector3i position;
byte on;
float size;
short roomNumber;
- int oldX;
- int oldY;
- int oldZ;
- int oldSize;
+ Vector3i oldPosition;
+ float oldSize;
+ byte oldOn;
+
+ void StoreInterpolationData()
+ {
+ oldPosition = position;
+ oldSize = size;
+ oldOn = on;
+ }
};
struct FIRE_SPARKS
{
- short x;
- short y;
- short z;
- short xVel;
- short yVel;
- short zVel;
+ Vector3i position;
+ Vector3i velocity;
+ Vector3i color;
short gravity;
short rotAng;
short flags;
@@ -173,23 +174,25 @@ struct FIRE_SPARKS
unsigned char dR;
unsigned char dG;
unsigned char dB;
- unsigned char r;
- unsigned char g;
- unsigned char b;
unsigned char colFadeSpeed;
unsigned char fadeToBlack;
unsigned char sLife;
unsigned char life;
- int oldX;
- int oldY;
- int oldZ;
- int oldR;
- int oldG;
- int oldB;
+ Vector3i oldPosition;
+ Vector3i oldColor;
unsigned char oldScalar;
unsigned char oldSize;
short oldRotAng;
+
+ void StoreInterpolationData()
+ {
+ oldPosition = position;
+ oldColor = color;
+ oldScalar = scalar;
+ oldSize = size;
+ oldRotAng = rotAng;
+ }
};
struct BLOOD_STRUCT
diff --git a/TombEngine/Renderer/Renderer.h b/TombEngine/Renderer/Renderer.h
index ab4f9977c..30c1386b0 100644
--- a/TombEngine/Renderer/Renderer.h
+++ b/TombEngine/Renderer/Renderer.h
@@ -404,7 +404,6 @@ namespace TEN::Renderer
void CalculateLightFades(RendererItem* item);
void CollectEffects(short roomNumber);
void ClearSceneItems();
- void ClearDynamicLights();
void ClearShadowMap();
void CalculateSSAO(RenderView& view);
void UpdateItemAnimations(RenderView& view);
@@ -613,6 +612,7 @@ namespace TEN::Renderer
void SetFullScreen();
bool IsFullsScreen();
void RenderTitleImage();
+ void ClearDynamicLights();
void AddLine2D(const Vector2& origin, const Vector2& target, const Color& color, RendererDebugPage page = RendererDebugPage::None);
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index fd7969397..b5f99e81c 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -1634,8 +1634,6 @@ namespace TEN::Renderer
{
ResetAnimations();
- ClearFires();
- ClearDynamicLights();
ClearSceneItems();
ClearShadowMap();
diff --git a/TombEngine/Renderer/RendererDrawEffect.cpp b/TombEngine/Renderer/RendererDrawEffect.cpp
index a165679ba..2e353c16d 100644
--- a/TombEngine/Renderer/RendererDrawEffect.cpp
+++ b/TombEngine/Renderer/RendererDrawEffect.cpp
@@ -312,22 +312,39 @@ namespace TEN::Renderer
auto* fire = &Fires[k];
if (fire->on)
{
+ auto oldFade = fire->oldOn == 1 ? 1.0f : (float)(255 - fire->oldOn) / 255.0f;
auto fade = fire->on == 1 ? 1.0f : (float)(255 - fire->on) / 255.0f;
+ fade = Lerp(oldFade, fade, _interpolationFactor);
for (int i = 0; i < MAX_SPARKS_FIRE; i++)
{
auto* spark = &FireSparks[i];
+
if (spark->on)
{
AddSpriteBillboard(
&_sprites[spark->def],
Vector3::Lerp(
- Vector3(fire->oldX + spark->oldX * fire->oldSize / 2, fire->oldY + spark->oldY * fire->oldSize / 2, fire->oldZ + spark->oldZ * fire->oldSize / 2),
- Vector3(fire->x + spark->x * fire->size / 2, fire->y + spark->y * fire->size / 2, fire->z + spark->z * fire->size / 2),
+ Vector3(
+ fire->oldPosition.x + spark->oldPosition.x * fire->oldSize / 2,
+ fire->oldPosition.y + spark->oldPosition.y * fire->oldSize / 2,
+ fire->oldPosition.z + spark->oldPosition.z * fire->oldSize / 2),
+ Vector3(
+ fire->position.x + spark->position.x * fire->size / 2,
+ fire->position.y + spark->position.y * fire->size / 2,
+ fire->position.z + spark->position.z * fire->size / 2),
_interpolationFactor),
Vector4::Lerp(
- Vector4(spark->oldR / 255.0f * fade, spark->oldG / 255.0f * fade, spark->oldB / 255.0f * fade, 1.0f),
- Vector4(spark->r / 255.0f * fade, spark->g / 255.0f * fade, spark->b / 255.0f * fade, 1.0f),
+ Vector4(
+ spark->oldColor.x / 255.0f * fade,
+ spark->oldColor.y / 255.0f * fade,
+ spark->oldColor.z / 255.0f * fade,
+ 1.0f),
+ Vector4(
+ spark->color.x / 255.0f * fade,
+ spark->color.y / 255.0f * fade,
+ spark->color.z / 255.0f * fade,
+ 1.0f),
_interpolationFactor),
TO_RAD(Lerp(spark->oldRotAng << 4, spark->rotAng << 4, _interpolationFactor)),
Lerp(spark->oldScalar, spark->scalar, _interpolationFactor),
From c455fc6a39ff22d1c7a8398e2afd49652e89b96d Mon Sep 17 00:00:00 2001
From: Sezz
Date: Tue, 16 Apr 2024 16:50:49 +1000
Subject: [PATCH 076/410] Merge
---
Documentation/Changes.txt | 9 +-
Documentation/doc/1 modules/Flow.html | 59 ++
.../doc/2 classes/Objects.Moveable.html | 149 +++--
.../doc/2 classes/Objects.Volume.html | 516 +++++++++---------
Documentation/doc/4 enums/Objects.ObjID.html | 4 +-
Documentation/doc/index.html | 2 +-
Documentation/output.xml | 289 +++++-----
Scripts/Engine/Timer.lua | 10 +-
TombEngine/Game/Hud/StatusBars.cpp | 2 +-
TombEngine/Game/Hud/TargetHighlighter.cpp | 6 +-
TombEngine/Game/Lara/PlayerContext.cpp | 2 +-
TombEngine/Game/Lara/lara.cpp | 22 +-
TombEngine/Game/Lara/lara_collide.cpp | 8 +-
TombEngine/Game/Lara/lara_fire.cpp | 10 +-
TombEngine/Game/Lara/lara_fire.h | 2 +-
TombEngine/Game/Lara/lara_flare.cpp | 8 +-
TombEngine/Game/Lara/lara_helpers.cpp | 18 +-
TombEngine/Game/Lara/lara_initialise.cpp | 42 +-
TombEngine/Game/Lara/lara_one_gun.cpp | 56 +-
TombEngine/Game/Lara/lara_overhang.cpp | 2 +-
TombEngine/Game/Lara/lara_struct.h | 2 +-
TombEngine/Game/Lara/lara_tests.cpp | 20 +-
TombEngine/Game/Setup.cpp | 4 +-
TombEngine/Game/animation.cpp | 12 +-
TombEngine/Game/animation.h | 19 +-
TombEngine/Game/collision/Point.cpp | 8 +-
TombEngine/Game/collision/collide_item.cpp | 280 +++++-----
TombEngine/Game/collision/collide_item.h | 29 +-
TombEngine/Game/collision/collide_room.cpp | 14 +-
TombEngine/Game/collision/floordata.cpp | 8 +-
TombEngine/Game/control/box.cpp | 102 ++--
TombEngine/Game/control/box.h | 2 -
TombEngine/Game/control/control.cpp | 9 +-
TombEngine/Game/control/flipeffect.cpp | 8 +-
TombEngine/Game/control/los.cpp | 8 +-
TombEngine/Game/control/lot.cpp | 20 +-
TombEngine/Game/control/trigger.cpp | 53 +-
TombEngine/Game/effects/tomb4fx.cpp | 2 +-
TombEngine/Game/gui.cpp | 16 +-
TombEngine/Game/items.cpp | 88 +--
TombEngine/Game/items.h | 194 +++----
TombEngine/Game/misc.cpp | 91 ++-
TombEngine/Game/misc.h | 1 +
TombEngine/Game/missile.cpp | 6 +-
TombEngine/Game/pickup/pickup.cpp | 94 ++--
TombEngine/Game/room.cpp | 16 +-
TombEngine/Game/savegame.cpp | 56 +-
TombEngine/Game/spotcam.cpp | 317 +++++++----
TombEngine/Game/spotcam.h | 25 +-
TombEngine/Math/Geometry.cpp | 5 +
TombEngine/Math/Geometry.h | 3 +
TombEngine/Math/Math.cpp | 2 +
TombEngine/Math/Random.cpp | 29 +-
TombEngine/Math/Random.h | 3 +
TombEngine/Objects/Effects/Boss.cpp | 4 +-
TombEngine/Objects/Effects/flame_emitters.cpp | 17 +-
TombEngine/Objects/Effects/tr4_locusts.cpp | 4 +-
.../Objects/Effects/tr5_electricity.cpp | 49 +-
.../Objects/Generic/Doors/generic_doors.cpp | 22 +-
.../Object/Pushable/PushableBridge.cpp | 2 +-
.../Object/Pushable/PushableCollision.cpp | 40 +-
.../Generic/Object/Pushable/PushableInfo.cpp | 4 +-
.../Generic/Object/Pushable/PushableStack.cpp | 32 +-
.../Object/Pushable/PushableStates.cpp | 32 +-
.../Objects/Generic/Object/burning_torch.cpp | 28 +-
.../Generic/Switches/crowbar_switch.cpp | 4 +-
.../Objects/Generic/Traps/dart_emitter.cpp | 2 +-
TombEngine/Objects/Generic/puzzles_keys.cpp | 20 +-
TombEngine/Objects/TR1/Entity/Cowboy.cpp | 4 +-
TombEngine/Objects/TR1/Entity/Kold.cpp | 4 +-
.../Objects/TR1/Entity/SkateboardKid.cpp | 13 +-
TombEngine/Objects/TR1/Entity/tr1_ape.cpp | 4 +-
TombEngine/Objects/TR1/Entity/tr1_bear.cpp | 10 +-
TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp | 8 +-
TombEngine/Objects/TR1/Entity/tr1_centaur.cpp | 8 +-
TombEngine/Objects/TR1/Entity/tr1_natla.cpp | 4 +-
.../Objects/TR1/Entity/tr1_winged_mutant.cpp | 6 +-
TombEngine/Objects/TR1/Entity/tr1_wolf.cpp | 12 +-
TombEngine/Objects/TR2/Entity/Dragon.cpp | 8 +-
.../Objects/TR2/Entity/tr2_eagle_or_crow.cpp | 2 +-
.../Objects/TR2/Entity/tr2_knife_thrower.cpp | 2 +-
TombEngine/Objects/TR2/Entity/tr2_rat.cpp | 6 +-
.../Objects/TR2/Entity/tr2_silencer.cpp | 4 +-
TombEngine/Objects/TR2/Entity/tr2_skidman.cpp | 6 +-
TombEngine/Objects/TR2/Entity/tr2_yeti.cpp | 2 +-
TombEngine/Objects/TR2/Vehicles/skidoo.cpp | 4 +-
TombEngine/Objects/TR2/Vehicles/speedboat.cpp | 6 +-
.../Objects/TR3/Entity/Compsognathus.cpp | 25 +-
TombEngine/Objects/TR3/Entity/FishSwarm.cpp | 427 +++++++++++++++
TombEngine/Objects/TR3/Entity/FishSwarm.h | 37 ++
TombEngine/Objects/TR3/Entity/Lizard.cpp | 4 +-
TombEngine/Objects/TR3/Entity/PunaBoss.cpp | 22 +-
TombEngine/Objects/TR3/Entity/Shiva.cpp | 2 +-
TombEngine/Objects/TR3/Entity/SophiaLeigh.cpp | 2 +-
TombEngine/Objects/TR3/Entity/WaspMutant.cpp | 4 +-
TombEngine/Objects/TR3/Entity/Winston.cpp | 6 +-
TombEngine/Objects/TR3/Entity/tr3_civvy.cpp | 4 +-
.../Objects/TR3/Entity/tr3_claw_mutant.cpp | 4 +-
.../Objects/TR3/Entity/tr3_fish_emitter.cpp | 424 --------------
.../Objects/TR3/Entity/tr3_fish_emitter.h | 9 -
.../Objects/TR3/Entity/tr3_flamethrower.cpp | 2 +-
TombEngine/Objects/TR3/Entity/tr3_monkey.cpp | 22 +-
TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp | 4 +-
.../Objects/TR3/Entity/tr3_mp_stick.cpp | 6 +-
TombEngine/Objects/TR3/Entity/tr3_raptor.cpp | 4 +-
.../Objects/TR3/Entity/tr3_scuba_diver.cpp | 2 +-
TombEngine/Objects/TR3/Entity/tr3_tiger.cpp | 2 +-
TombEngine/Objects/TR3/Entity/tr3_tony.cpp | 2 +-
TombEngine/Objects/TR3/Entity/tr3_trex.cpp | 2 +-
.../Objects/TR3/Entity/tr3_tribesman.cpp | 2 +-
TombEngine/Objects/TR3/Object/corpse.cpp | 77 +--
TombEngine/Objects/TR3/Object/corpse.h | 14 +-
.../Objects/TR3/Trap/ElectricCleaner.cpp | 112 +---
TombEngine/Objects/TR3/Vehicles/big_gun.cpp | 4 +-
TombEngine/Objects/TR3/Vehicles/kayak.cpp | 12 +-
TombEngine/Objects/TR3/Vehicles/minecart.cpp | 18 +-
TombEngine/Objects/TR3/Vehicles/quad_bike.cpp | 4 +-
.../Objects/TR3/Vehicles/rubber_boat.cpp | 6 +-
TombEngine/Objects/TR3/Vehicles/upv.cpp | 6 +-
TombEngine/Objects/TR3/fish.h | 24 -
TombEngine/Objects/TR3/tr3_objects.cpp | 15 +-
TombEngine/Objects/TR4/Entity/Wraith.cpp | 8 +-
TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp | 2 +-
TombEngine/Objects/TR4/Entity/tr4_baboon.cpp | 10 +-
TombEngine/Objects/TR4/Entity/tr4_baddy.cpp | 8 +-
.../Objects/TR4/Entity/tr4_beetle_swarm.cpp | 4 +-
.../Objects/TR4/Entity/tr4_big_beetle.cpp | 4 +-
.../Objects/TR4/Entity/tr4_big_scorpion.cpp | 6 +-
.../Objects/TR4/Entity/tr4_crocodile.cpp | 14 +-
TombEngine/Objects/TR4/Entity/tr4_dog.cpp | 2 +-
.../Objects/TR4/Entity/tr4_enemy_jeep.cpp | 6 +-
TombEngine/Objects/TR4/Entity/tr4_guide.cpp | 6 +-
TombEngine/Objects/TR4/Entity/tr4_harpy.cpp | 4 +-
.../Objects/TR4/Entity/tr4_horseman.cpp | 12 +-
TombEngine/Objects/TR4/Entity/tr4_mutant.cpp | 4 +-
TombEngine/Objects/TR4/Entity/tr4_sas.cpp | 16 +-
TombEngine/Objects/TR4/Entity/tr4_setha.cpp | 2 +-
.../Objects/TR4/Entity/tr4_skeleton.cpp | 6 +-
TombEngine/Objects/TR4/Entity/tr4_troops.cpp | 4 +-
.../Objects/TR4/Entity/tr4_von_croy.cpp | 2 +-
.../Objects/TR4/Entity/tr4_wild_boar.cpp | 2 +-
.../TR4/Object/tr4_clockwork_beetle.cpp | 10 +-
.../Objects/TR4/Object/tr4_element_puzzle.cpp | 4 +-
TombEngine/Objects/TR4/Object/tr4_obelisk.cpp | 4 +-
TombEngine/Objects/TR4/Object/tr4_senet.cpp | 2 +-
TombEngine/Objects/TR4/Trap/SpikyWall.cpp | 18 +-
TombEngine/Objects/TR4/Trap/SquishyBlock.cpp | 221 ++++++++
TombEngine/Objects/TR4/Trap/SquishyBlock.h | 13 +
TombEngine/Objects/TR4/Trap/tr4_hammer.cpp | 12 +-
TombEngine/Objects/TR4/Trap/tr4_mine.cpp | 2 +-
.../Objects/TR4/Trap/tr4_teethspike.cpp | 2 +-
TombEngine/Objects/TR4/Vehicles/jeep.cpp | 4 +-
TombEngine/Objects/TR4/Vehicles/motorbike.cpp | 8 +-
TombEngine/Objects/TR4/tr4_objects.cpp | 18 +
.../Objects/TR5/Emitter/tr5_bats_emitter.cpp | 4 +-
.../Objects/TR5/Emitter/tr5_rats_emitter.cpp | 2 +-
.../TR5/Emitter/tr5_spider_emitter.cpp | 4 +-
TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp | 2 +-
.../Objects/TR5/Entity/tr5_doberman.cpp | 2 +-
.../Objects/TR5/Entity/tr5_gladiator.cpp | 2 +-
TombEngine/Objects/TR5/Entity/tr5_guard.cpp | 14 +-
TombEngine/Objects/TR5/Entity/tr5_hydra.cpp | 2 +-
TombEngine/Objects/TR5/Entity/tr5_imp.cpp | 4 +-
TombEngine/Objects/TR5/Entity/tr5_larson.cpp | 2 +-
TombEngine/Objects/TR5/Entity/tr5_lion.cpp | 2 +-
.../Objects/TR5/Entity/tr5_roman_statue.cpp | 4 +-
.../Objects/TR5/Entity/tr5_submarine.cpp | 6 +-
.../Objects/TR5/Object/tr5_raisingblock.cpp | 2 +-
.../Objects/TR5/Object/tr5_rollingball.cpp | 2 +-
.../Objects/TR5/Shatter/tr5_smashobject.cpp | 6 +-
TombEngine/Objects/TR5/Trap/LaserBeam.cpp | 15 +-
TombEngine/Objects/TR5/Trap/tr5_explosion.cpp | 52 +-
TombEngine/Objects/game_object_ids.h | 4 +-
.../ConstantBuffers/InstancedStaticBuffer.h | 2 +-
TombEngine/Renderer/Renderer.cpp | 2 +-
TombEngine/Renderer/Renderer.h | 5 +-
TombEngine/Renderer/RendererDraw.cpp | 289 +++++++---
TombEngine/Renderer/RendererFrame.cpp | 10 +-
TombEngine/Renderer/RendererInit.cpp | 2 +-
TombEngine/Renderer/RendererSprites.cpp | 3 +-
TombEngine/Resources.rc | 8 +-
.../Scripting/Internal/ReservedScriptNames.h | 1 +
.../Internal/TEN/Effects/EffectsFunctions.cpp | 2 +-
.../Internal/TEN/Flow/FlowHandler.cpp | 39 +-
.../Scripting/Internal/TEN/Flow/FlowHandler.h | 3 +-
.../TEN/Objects/AIObject/AIObject.cpp | 8 +-
.../TEN/Objects/Camera/CameraObject.cpp | 8 +-
.../Internal/TEN/Objects/Lara/LaraObject.cpp | 4 +-
.../TEN/Objects/Moveable/MoveableObject.cpp | 167 +++---
.../Internal/TEN/Objects/ObjectIDs.h | 8 +-
.../Internal/TEN/Objects/ObjectsHandler.cpp | 35 +-
.../Internal/TEN/Objects/Room/RoomObject.cpp | 8 +-
.../Internal/TEN/Objects/Sink/SinkObject.cpp | 8 +-
.../Objects/SoundSource/SoundSourceObject.cpp | 8 +-
.../TEN/Objects/Static/StaticObject.cpp | 8 +-
.../TEN/Objects/Volume/VolumeObject.cpp | 221 ++++----
.../TEN/Objects/Volume/VolumeObject.h | 45 +-
TombEngine/Specific/clock.cpp | 68 ++-
TombEngine/Specific/clock.h | 14 +-
TombEngine/Specific/level.cpp | 15 +-
.../flatbuffers/ten_savegame_generated.h | 345 ++++++++++--
.../Specific/savegame/schema/ten_savegame.fbs | 16 +
TombEngine/TombEngine.vcxproj | 7 +-
203 files changed, 3690 insertions(+), 2685 deletions(-)
create mode 100644 TombEngine/Objects/TR3/Entity/FishSwarm.cpp
create mode 100644 TombEngine/Objects/TR3/Entity/FishSwarm.h
delete mode 100644 TombEngine/Objects/TR3/Entity/tr3_fish_emitter.cpp
delete mode 100644 TombEngine/Objects/TR3/Entity/tr3_fish_emitter.h
delete mode 100644 TombEngine/Objects/TR3/fish.h
create mode 100644 TombEngine/Objects/TR4/Trap/SquishyBlock.cpp
create mode 100644 TombEngine/Objects/TR4/Trap/SquishyBlock.h
diff --git a/Documentation/Changes.txt b/Documentation/Changes.txt
index cbbb93f4b..796c56194 100644
--- a/Documentation/Changes.txt
+++ b/Documentation/Changes.txt
@@ -2,6 +2,7 @@ Version 1.4
===========
* Fixed drawing of display sprites in title level.
+* Fixed drawing of smoke sprites and various other sprites.
* Fixed player holster state and current vehicle not preserved correctly on level jump.
* Fixed fade-in and fade-out effects not canceling correctly when next level is loaded.
* Fixed shadows still being visible after shattering a moveable.
@@ -15,15 +16,19 @@ Version 1.4
- Wall spikes will shatter any shatter in its path.
- Wall spikes can be stopped by normal antitrigger or with a volume.
* Added hub system to preserve level state on level jumps.
-* Added ember emitter object.
+* Added ember emitter.
+* Added fish emitter.
* Added laser beam object.
* Added TR2 dragon.
-* Added TR3 Winston (requires updated TEN Winston .wad2).
+* Added TR3 Winston (requires updated TEN .wad2 on TombEngine.com).
+* Added TR4 squishy blocks (requires updated TEN .wad2 on TombEngine.com).
Lua API changes:
* Added resetHub flag to Flow.Level, which allows to reset hub data.
+* Added Flow.GetFlipMapStatus() function to get current flipmap status.
* Added Moveable:GetMeshCount() function to get number of moveable meshes.
* Added Static:GetHP() and Static:SetHP() functions to change shatterable static mesh hit points.
+* Fixed Moveable:SetOnCollidedWithObject() callback.
Version 1.3
===========
diff --git a/Documentation/doc/1 modules/Flow.html b/Documentation/doc/1 modules/Flow.html
index df72adc0c..47dd024fe 100644
--- a/Documentation/doc/1 modules/Flow.html
+++ b/Documentation/doc/1 modules/Flow.html
@@ -195,6 +195,14 @@ scripts too.
SetTotalSecretCount(total)
Total number of secrets in game.
+
+ FlipMap(flipmap)
+ Do FlipMap with specific group ID.
+
+
+ GetFlipMapStatus([index])
+ Get current FlipMap status for specific group ID.
+
@@ -734,6 +742,57 @@ Must be an integer value (0 means no secrets).
+
+
+
+ FlipMap(flipmap)
+
+
+ Do FlipMap with specific group ID.
+
+
+
+ Parameters:
+
+ flipmap
+ int
+ (ID of flipmap group to actuvate / deactivate)
+
+
+
+
+
+
+
+
+
+
+ GetFlipMapStatus([index])
+
+
+ Get current FlipMap status for specific group ID.
+
+
+
+ Parameters:
+
+ index
+ int
+ Flipmap group ID to check. If no group specified or group is -1, function returns overall flipmap status (on or off).
+ (optional )
+
+
+
+ Returns:
+
+
+ int
+ Status of the flipmap group (true means on, false means off).
+
+
+
+
+
diff --git a/Documentation/doc/2 classes/Objects.Moveable.html b/Documentation/doc/2 classes/Objects.Moveable.html
index 2aa6c0cbd..5eb0c2962 100644
--- a/Documentation/doc/2 classes/Objects.Moveable.html
+++ b/Documentation/doc/2 classes/Objects.Moveable.html
@@ -108,9 +108,8 @@ pickups, and Lara herself (see also Functions
- Moveable(object, name, position[, rotation][, roomID][, animNumber=0][, frameNumber=0][, hp=10][, OCB=0][, AIBits])
- For more information on each parameter, see the
-associated getters and setters.
+ Moveable(object, name, position, rotation, roomID, animNumber, frameNumber, hp, OCB, AIBits)
+ Used to generate a new moveable dynamically at runtime.
Moveable:Explode()
@@ -139,16 +138,6 @@ associated getters and setters.
Moveable:SetStatus(status)
Set the moveable's status.
-
-
- Moveable:SetOnHit(callback)
- Set the name of the function to be called when the moveable is shot by Lara.
-
-
- Moveable:SetOnKilled(callback)
- Set the name of the function to be called when the moveable is destroyed/killed
- Note that enemy death often occurs at the end of an animation, and not at the exact moment
- the enemy's HP becomes zero.
Moveable:GetObjectID()
@@ -274,12 +263,22 @@ associated getters and setters.
Borrow animation from an object
+ Moveable:SetOnHit(callback)
+ Set the name of the function to be called when the moveable is shot by Lara.
+
+
Moveable:SetOnCollidedWithObject(func)
Set the function to be called when this moveable collides with another moveable
Moveable:SetOnCollidedWithRoom(func)
Set the function called when this moveable collides with room geometry (e.g.
+
+
+ Moveable:SetOnKilled(callback)
+ Set the name of the function to be called when the moveable is destroyed/killed
+ Note that enemy death often occurs at the end of an animation, and not at the exact moment
+ the enemy's HP becomes zero.
Moveable:GetPosition()
@@ -391,11 +390,12 @@ associated getters and setters.
- Moveable(object, name, position[, rotation][, roomID][, animNumber=0][, frameNumber=0][, hp=10][, OCB=0][, AIBits])
+ Moveable(object, name, position, rotation, roomID, animNumber, frameNumber, hp, OCB, AIBits)
- For more information on each parameter, see the
-associated getters and setters. If you do not know what to set for these,
+ Used to generate a new moveable dynamically at runtime.
+For more information on each parameter, see the
+associated getters and setters. If you do not know what to set for these,
most can just be ignored (see usage).
@@ -416,38 +416,31 @@ most can just be ignored (see usage).
rotation
Rotation
- rotation about x, y, and z axes (default Rotation(0, 0, 0))
- (optional )
+ rotation rotation about x, y, and z axes (default Rotation(0, 0, 0))
roomID
int
room ID item is in (default: calculated automatically)
- (optional )
animNumber
int
- anim number
- (default 0)
+ animation number
frameNumber
int
frame number
- (default 0)
hp
int
HP of item
- (default 10)
OCB
int
ocb of item
- (default 0)
AIBits
table
table with AI bits (default { 0, 0, 0, 0, 0, 0 })
- (optional )
@@ -465,7 +458,7 @@ most can just be ignored (see usage).
local item = Moveable(
TEN.Objects.ObjID.PISTOLS_ITEM, "test" , Vec3(18907 , 0 , 21201 ))
+ Vec3(18907 , 0 , 21201 ))
@@ -618,58 +611,6 @@ most can just be ignored (see usage).
-
-
-
- Moveable:SetOnHit(callback)
-
-
- Set the name of the function to be called when the moveable is shot by Lara.
- Note that this will be triggered twice when shot with both pistols at once.
-
-
-
- Parameters:
-
- callback
- function
- function in LevelFuncs hierarchy to call when moveable is shot
-
-
-
-
-
-
-
-
-
-
- Moveable:SetOnKilled(callback)
-
-
- Set the name of the function to be called when the moveable is destroyed/killed
- Note that enemy death often occurs at the end of an animation, and not at the exact moment
- the enemy's HP becomes zero.
-
-
-
- Parameters:
-
- callback
- function
- function in LevelFuncs hierarchy to call when enemy is killed
-
-
-
-
-
-
- Usage:
- LevelFuncs.baddyKilled = function (theBaddy) print ("You killed a baddy!" ) end
-baddy:SetOnKilled(LevelFuncs.baddyKilled)
-
-
@@ -1372,6 +1313,29 @@ shiva:SetObjectID(TEN.Objects.ObjID.BIGMEDI_ITEM)
+
+
+
+ Moveable:SetOnHit(callback)
+
+
+ Set the name of the function to be called when the moveable is shot by Lara.
+ Note that this will be triggered twice when shot with both pistols at once.
+
+
+
+ Parameters:
+
+ callback
+ function
+ function in LevelFuncs hierarchy to call when moveable is shot
+
+
+
+
+
+
+
@@ -1430,6 +1394,35 @@ baddy:SetOnCollidedWithObject(LevelFuncs.objCollided)
baddy:SetOnCollidedWithRoom(LevelFuncs.roomCollided)
+
+
+
+ Moveable:SetOnKilled(callback)
+
+
+ Set the name of the function to be called when the moveable is destroyed/killed
+ Note that enemy death often occurs at the end of an animation, and not at the exact moment
+ the enemy's HP becomes zero.
+
+
+
+ Parameters:
+
+ callback
+ function
+ function in LevelFuncs hierarchy to call when enemy is killed
+
+
+
+
+
+
+ Usage:
+ LevelFuncs.baddyKilled = function (theBaddy) print ("You killed a baddy!" ) end
+baddy:SetOnKilled(LevelFuncs.baddyKilled)
+
+
diff --git a/Documentation/doc/2 classes/Objects.Volume.html b/Documentation/doc/2 classes/Objects.Volume.html
index f7ff425f2..9f5fa9fb2 100644
--- a/Documentation/doc/2 classes/Objects.Volume.html
+++ b/Documentation/doc/2 classes/Objects.Volume.html
@@ -100,7 +100,7 @@
Class Objects.Volume
-
Volumes
+
Activator volume.
@@ -109,56 +109,56 @@
@@ -169,12 +169,233 @@
+
+
+ Volume:GetName()
+
+
+ Get the unique string identifier of this volume. ()
+
+
+
+
+ Returns:
+
+
+ string
+ Name.
+
+
+
+
+
+
+
+
+ Volume:GetPosition()
+
+
+ Get the position of this volume. ()
+
+
+
+
+ Returns:
+
+
+ Vec3
+ Position.
+
+
+
+
+
+
+
+
+ Volume:GetRotation()
+
+
+ Get the rotation of this volume. ()
+
+
+
+
+ Returns:
+
+
+ Rotation
+ Rotation.
+
+
+
+
+
+
+
+
+ Volume:GetScale()
+
+
+ Get this scale of this volume. ()
+
+
+
+
+ Returns:
+
+
+ Vec3
+ Scale.
+
+
+
+
+
+
+
+
+ Volume:SetName(name)
+
+
+ Set the unique string identifier of this volume. ()
+
+
+
+ Parameters:
+
+ name
+ string
+ New name.
+
+
+
+
+
+
+
+
+
+
+ Volume:SetPosition(pos)
+
+
+ Set the position of this volume. ()
+
+
+
+ Parameters:
+
+ pos
+ Vec3
+ New position.
+
+
+
+
+
+
+
+
+
+
+ Volume:SetRotation(rot)
+
+
+ Set the rotation of this volume. ()
+
+
+
+ Parameters:
+
+
+
+
+
+
+
+
+
+ Volume:SetScale(scale)
+
+
+ Set the scale of the volume. ()
+
+
+
+ Parameters:
+
+ scale
+ Vec3
+ New scale.
+
+
+
+
+
+
+
+
+
+
+ Volume:GetActive()
+
+
+ Determine if this volume is active. ()
+
+
+
+
+ Returns:
+
+
+ bool
+ Boolean representing active status.
+
+
+
+
+
+
+
+
+ Volume:IsMoveableInside(Moveable)
+
+
+ Determine if a moveable is inside this volume. ()
+
+
+
+ Parameters:
+
+ Moveable
+ Moveable
+ to be checked for containment.
+
+
+
+ Returns:
+
+
+ bool
+ Boolean representing containment status.
+
+
+
+
+
+
Volume:Enable()
- Enable the volume.
+ Enable this volume. ()
@@ -189,7 +410,7 @@
Volume:Disable()
- Disable the volume.
+ Disable this volume. ()
@@ -198,206 +419,13 @@
-
-
-
- Volume:GetActive()
-
-
- Determine whether the volume is active or not
-
-
-
-
- Returns:
-
-
- bool
- true if the volume is active
-
-
-
-
-
-
-
-
- Volume:GetPosition()
-
-
- Get the volume's position.
-
-
-
-
- Returns:
-
-
- Vec3
- a copy of the volume's position
-
-
-
-
-
-
-
-
- Volume:SetPosition(position)
-
-
- Set the volume's position.
-
-
-
- Parameters:
-
- position
- Vec3
- the new position of the volume
-
-
-
-
-
-
-
-
-
-
- Volume:GetRotation()
-
-
- Get the volume's rotation.
-
-
-
-
- Returns:
-
-
- Rotation
- a copy of the volume's rotation
-
-
-
-
-
-
-
-
- Volume:SetRotation(rotation)
-
-
- Set the volume's rotation.
-
-
-
- Parameters:
-
- rotation
- Rotation
- the volume's new rotation
-
-
-
-
-
-
-
-
-
-
- Volume:GetScale()
-
-
- Get the volume's scale (separately on all 3 axes).
-
-
-
-
- Returns:
-
-
- Vec3
- current volume scale
-
-
-
-
-
-
-
-
- Volume:SetScale(scale)
-
-
- Set the volume's scale (separately on all 3 axes).
-
-
-
- Parameters:
-
- scale
- Vec3
- the volume's new scale
-
-
-
-
-
-
-
-
-
-
- Volume:GetName()
-
-
- Get the volume's unique string identifier.
-
-
-
-
- Returns:
-
-
- string
- the volume's name
-
-
-
-
-
-
-
-
- Volume:SetName(name)
-
-
- Set the volume's name (its unique string identifier).
-
-
-
- Parameters:
-
- name
- string
- The volume's new name
-
-
-
-
-
-
-
Volume:ClearActivators()
- Clear activator list for volumes (makes volume trigger everything again)
+ Clear the activators for this volume, allowing it to trigger again. ()
@@ -406,34 +434,6 @@
-
-
-
- Volume:IsMoveableInside(Moveable)
-
-
- Check if specified moveable is inside the volume
-
-
-
- Parameters:
-
- Moveable
- Moveable
- which should be checked for containment
-
-
-
- Returns:
-
-
- bool
- state of the moveable, true if contained, false if not
-
-
-
-
-
diff --git a/Documentation/doc/4 enums/Objects.ObjID.html b/Documentation/doc/4 enums/Objects.ObjID.html
index db14eef45..a4e71b10a 100644
--- a/Documentation/doc/4 enums/Objects.ObjID.html
+++ b/Documentation/doc/4 enums/Objects.ObjID.html
@@ -462,8 +462,8 @@ SEARCH_OBJECT4
SARCOPHAGUS
ENEMY_PIECE
EXPANDING_PLATFORM
-SQUISHY_BLOCK1
-SQUISHY_BLOCK2
+SQUISHY_BLOCK_HORIZONTAL
+SQUISHY_BLOCK_VERTICAL
LASER_BEAM
MINE_DETECTOR
MAP
diff --git a/Documentation/doc/index.html b/Documentation/doc/index.html
index 75857d49e..28889444d 100644
--- a/Documentation/doc/index.html
+++ b/Documentation/doc/index.html
@@ -233,7 +233,7 @@ local door = GetMoveableByName("door_type4_14")
Objects.Volume
- Volumes
+ Activator volume.
Strings.DisplayString
diff --git a/Documentation/output.xml b/Documentation/output.xml
index d2c1f4a79..7f960b6df 100644
--- a/Documentation/output.xml
+++ b/Documentation/output.xml
@@ -892,6 +892,38 @@ teleported to such object with OCB similar to provided second argument.
+
+ Flow
+ FlipMap
+ Do FlipMap with specific group ID.
+
+
+ flipmap
+ int
+ (ID of flipmap group to actuvate / deactivate)
+
+
+
+
+
+ Flow
+ GetFlipMapStatus
+ Get current FlipMap status for specific group ID.
+
+
+ index
+ int
+ Flipmap group ID to check. If no group specified or group is -1, function returns overall flipmap status (on or off).
+
+
+
+
+ int
+ Status of the flipmap group (true means on, false means off).
+
+
+
+
Flow
SetSettings
@@ -1899,9 +1931,9 @@ e.g. `myItem.action = ItemAction.EXAMINE`
Objects.Moveable
Moveable
- For more information on each parameter, see the
-associated getters and setters.
- If you do not know what to set for these,
+ Used to generate a new moveable dynamically at runtime.
+ For more information on each parameter, see the
+associated getters and setters. If you do not know what to set for these,
most can just be ignored (see usage).
@@ -1922,7 +1954,7 @@ most can just be ignored (see usage).
rotation
Rotation
- rotation about x, y, and z axes (default Rotation(0, 0, 0))
+ rotation rotation about x, y, and z axes (default Rotation(0, 0, 0))
roomID
@@ -1932,7 +1964,7 @@ most can just be ignored (see usage).
animNumber
int
- anim number
+ animation number
frameNumber
@@ -2064,37 +2096,6 @@ most can just be ignored (see usage).
-
- Objects.Moveable
- Moveable
- SetOnHit
- Set the name of the function to be called when the moveable is shot by Lara.
- Note that this will be triggered twice when shot with both pistols at once.
-
-
- callback
- function
- function in LevelFuncs hierarchy to call when moveable is shot
-
-
-
-
-
- Objects.Moveable
- Moveable
- SetOnKilled
- Set the name of the function to be called when the moveable is destroyed/killed
- Note that enemy death often occurs at the end of an animation, and not at the exact moment
- the enemy's HP becomes zero.
-
-
- callback
- function
- function in LevelFuncs hierarchy to call when enemy is killed
-
-
-
-
Objects.Moveable
Moveable
@@ -2563,6 +2564,21 @@ most can just be ignored (see usage).
+
+ Objects.Moveable
+ Moveable
+ SetOnHit
+ Set the name of the function to be called when the moveable is shot by Lara.
+ Note that this will be triggered twice when shot with both pistols at once.
+
+
+ callback
+ function
+ function in LevelFuncs hierarchy to call when moveable is shot
+
+
+
+
Objects.Moveable
Moveable
@@ -2592,6 +2608,22 @@ most can just be ignored (see usage).
+
+ Objects.Moveable
+ Moveable
+ SetOnKilled
+ Set the name of the function to be called when the moveable is destroyed/killed
+ Note that enemy death often occurs at the end of an animation, and not at the exact moment
+ the enemy's HP becomes zero.
+
+
+ callback
+ function
+ function in LevelFuncs hierarchy to call when enemy is killed
+
+
+
+
Objects.Moveable
Moveable
@@ -3695,26 +3727,13 @@ most can just be ignored (see usage).
Objects.Volume
Volume
- Enable
- Enable the volume.
-
-
-
- Objects.Volume
- Volume
- Disable
- Disable the volume.
-
-
-
- Objects.Volume
- Volume
- GetActive
- Determine whether the volume is active or not
+ GetName
+ Get the unique string identifier of this volume.
+ ()
- bool
- true if the volume is active
+ string
+ Name.
@@ -3723,92 +3742,40 @@ most can just be ignored (see usage).
Objects.Volume
Volume
GetPosition
- Get the volume's position.
+ Get the position of this volume.
+ ()
Vec3
- a copy of the volume's position
+ Position.
-
- Objects.Volume
- Volume
- SetPosition
- Set the volume's position.
-
-
- position
- Vec3
- the new position of the volume
-
-
-
-
Objects.Volume
Volume
GetRotation
- Get the volume's rotation.
+ Get the rotation of this volume.
+ ()
Rotation
- a copy of the volume's rotation
+ Rotation.
-
- Objects.Volume
- Volume
- SetRotation
- Set the volume's rotation.
-
-
- rotation
- Rotation
- the volume's new rotation
-
-
-
-
Objects.Volume
Volume
GetScale
- Get the volume's scale (separately on all 3 axes).
+ Get this scale of this volume.
+ ()
Vec3
- current volume scale
-
-
-
-
-
- Objects.Volume
- Volume
- SetScale
- Set the volume's scale (separately on all 3 axes).
-
-
- scale
- Vec3
- the volume's new scale
-
-
-
-
-
- Objects.Volume
- Volume
- GetName
- Get the volume's unique string identifier.
-
-
- string
- the volume's name
+ Scale.
@@ -3817,12 +3784,13 @@ most can just be ignored (see usage).
Objects.Volume
Volume
SetName
- Set the volume's name (its unique string identifier).
+ Set the unique string identifier of this volume.
+ ()
name
string
- The volume's new name
+ New name.
@@ -3830,30 +3798,107 @@ most can just be ignored (see usage).
Objects.Volume
Volume
- ClearActivators
- Clear activator list for volumes (makes volume trigger everything again)
+ SetPosition
+ Set the position of this volume.
+ ()
+
+
+ pos
+ Vec3
+ New position.
+
+
+
+
+
+ Objects.Volume
+ Volume
+ SetRotation
+ Set the rotation of this volume.
+ ()
+
+
+ rot
+ Rotation
+ New rotation.
+
+
+
+
+
+ Objects.Volume
+ Volume
+ SetScale
+ Set the scale of the volume.
+ ()
+
+
+ scale
+ Vec3
+ New scale.
+
+
+
+
+
+ Objects.Volume
+ Volume
+ GetActive
+ Determine if this volume is active.
+ ()
+
+
+ bool
+ Boolean representing active status.
+
+
Objects.Volume
Volume
IsMoveableInside
- Check if specified moveable is inside the volume
+ Determine if a moveable is inside this volume.
+ ()
Moveable
Objects.Moveable
- which should be checked for containment
+ to be checked for containment.
bool
- state of the moveable, true if contained, false if not
+ Boolean representing containment status.
+
+ Objects.Volume
+ Volume
+ Enable
+ Enable this volume.
+ ()
+
+
+
+ Objects.Volume
+ Volume
+ Disable
+ Disable this volume.
+ ()
+
+
+
+ Objects.Volume
+ Volume
+ ClearActivators
+ Clear the activators for this volume, allowing it to trigger again.
+ ()
+
+
Rotation
Rotation
diff --git a/Scripts/Engine/Timer.lua b/Scripts/Engine/Timer.lua
index 72ffef812..59ce2f3a3 100644
--- a/Scripts/Engine/Timer.lua
+++ b/Scripts/Engine/Timer.lua
@@ -81,7 +81,7 @@ Timer = {
print("Warning: a timer with name " .. name .. " already exists; overwriting it with a new one...")
end
- LevelVars.Engine.Timer.timers[name] ={}
+ LevelVars.Engine.Timer.timers[name] = {}
local thisTimer = LevelVars.Engine.Timer.timers[name]
thisTimer.name = name
thisTimer.totalTime = totalTime
@@ -98,6 +98,14 @@ Timer = {
end
return obj
end;
+
+ Delete = function(name)
+ if LevelVars.Engine.Timer.timers[name] then
+ LevelVars.Engine.Timer.timers[name] = nil
+ else
+ print("Warning: a timer with name " .. name .. " does not exist and can't be deleted.")
+ end
+ end;
--- Get a timer by its name.
-- @string name The label that was given to the timer when it was created
diff --git a/TombEngine/Game/Hud/StatusBars.cpp b/TombEngine/Game/Hud/StatusBars.cpp
index 46f6b0ce5..b9ab5a415 100644
--- a/TombEngine/Game/Hud/StatusBars.cpp
+++ b/TombEngine/Game/Hud/StatusBars.cpp
@@ -109,7 +109,7 @@ namespace TEN::Hud
}
// HACK: Special case for UPV as it sets player.Control.WaterStatus to WaterStatus::Dry.
- if (player.Context.Vehicle != NO_ITEM)
+ if (player.Context.Vehicle != NO_VALUE)
{
const auto& vehicleItem = g_Level.Items[player.Context.Vehicle];
if (vehicleItem.ObjectNumber == ID_UPV)
diff --git a/TombEngine/Game/Hud/TargetHighlighter.cpp b/TombEngine/Game/Hud/TargetHighlighter.cpp
index 2957dc5be..34638f991 100644
--- a/TombEngine/Game/Hud/TargetHighlighter.cpp
+++ b/TombEngine/Game/Hud/TargetHighlighter.cpp
@@ -181,7 +181,8 @@ namespace TEN::Hud
continue;
// Collect item number.
- itemNumbers.push_back(itemPtr->Index);
+ if (itemPtr->HitPoints != NOT_TARGETABLE)
+ itemNumbers.push_back(itemPtr->Index);
// Find crosshair at item number key.
auto it = _crosshairs.find(itemPtr->Index);
@@ -190,8 +191,7 @@ namespace TEN::Hud
// Set crosshair as primary or peripheral.
auto& crosshair = it->second;
- if (player.TargetEntity != nullptr &&
- itemPtr->Index == player.TargetEntity->Index)
+ if (player.TargetEntity != nullptr && itemPtr->Index == player.TargetEntity->Index)
{
crosshair.SetPrimary();
}
diff --git a/TombEngine/Game/Lara/PlayerContext.cpp b/TombEngine/Game/Lara/PlayerContext.cpp
index 6e6d4d721..5832264dc 100644
--- a/TombEngine/Game/Lara/PlayerContext.cpp
+++ b/TombEngine/Game/Lara/PlayerContext.cpp
@@ -109,7 +109,7 @@ namespace TEN::Entities::Player
if (!(IsHeld(In::Flare) || IsHeld(In::Draw)) && // Avoid unsightly concurrent actions.
(player.Control.Weapon.GunType != LaraWeaponType::Flare || // Not handling flare.
player.Flare.Life) && // OR flare is still active.
- player.Context.Vehicle == NO_ITEM) // Not in a vehicle.
+ player.Context.Vehicle == NO_VALUE) // Not in a vehicle.
{
return true;
}
diff --git a/TombEngine/Game/Lara/lara.cpp b/TombEngine/Game/Lara/lara.cpp
index fe9d8d088..05d0c9567 100644
--- a/TombEngine/Game/Lara/lara.cpp
+++ b/TombEngine/Game/Lara/lara.cpp
@@ -91,7 +91,7 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
}
if (!player.Control.IsLocked)
- player.LocationPad = -1;
+ player.LocationPad = NO_VALUE;
// FAILSAFE: Force hand status reset.
if (item->Animation.AnimNumber == LA_STAND_IDLE &&
@@ -109,14 +109,14 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
auto water = GetPlayerWaterData(*item);
player.Context.WaterSurfaceDist = -water.HeightFromWater;
- if (player.Context.Vehicle == NO_ITEM)
+ if (player.Context.Vehicle == NO_VALUE)
SpawnPlayerWaterSurfaceEffects(*item, water.WaterHeight, water.WaterDepth);
bool isWaterOnHeadspace = false;
// TODO: Move unrelated handling elsewhere.
// Handle environment state transition.
- if (player.Context.Vehicle == NO_ITEM && player.ExtraAnim == NO_ITEM)
+ if (player.Context.Vehicle == NO_VALUE && player.ExtraAnim == NO_VALUE)
{
switch (player.Control.WaterStatus)
{
@@ -367,7 +367,7 @@ void LaraAboveWater(ItemInfo* item, CollisionInfo* coll)
// Handle look-around.
if (((IsHeld(In::Look) && CanPlayerLookAround(*item)) ||
(player.Control.Look.IsUsingBinoculars || player.Control.Look.IsUsingLasersight)) &&
- player.ExtraAnim == NO_ITEM)
+ player.ExtraAnim == NO_VALUE)
{
HandlePlayerLookAround(*item);
}
@@ -382,19 +382,17 @@ void LaraAboveWater(ItemInfo* item, CollisionInfo* coll)
if (HandleLaraVehicle(item, coll))
return;
- // Handle player behavior state control.
HandlePlayerBehaviorState(*item, *coll, PlayerBehaviorStateRoutineType::Control);
-
HandleLaraMovementParameters(item, coll);
AnimateItem(item);
- if (player.ExtraAnim == NO_ITEM)
+ if (player.ExtraAnim == NO_VALUE)
{
// Check for collision with items.
DoObjectCollision(item, coll);
// Handle player behavior state collision.
- if (player.Context.Vehicle == NO_ITEM)
+ if (player.Context.Vehicle == NO_VALUE)
HandlePlayerBehaviorState(*item, *coll, PlayerBehaviorStateRoutineType::Collision);
}
@@ -468,7 +466,7 @@ void LaraWaterSurface(ItemInfo* item, CollisionInfo* coll)
DoObjectCollision(item, coll);
- if (player.Context.Vehicle == NO_ITEM)
+ if (player.Context.Vehicle == NO_VALUE)
HandlePlayerBehaviorState(*item, *coll, PlayerBehaviorStateRoutineType::Collision);
UpdateLaraRoom(item, LARA_RADIUS);
@@ -571,7 +569,7 @@ void LaraUnderwater(ItemInfo* item, CollisionInfo* coll)
DoObjectCollision(item, coll);
- if (player.Context.Vehicle == NO_ITEM)
+ if (player.Context.Vehicle == NO_VALUE)
HandlePlayerBehaviorState(*item, *coll, PlayerBehaviorStateRoutineType::Collision);
UpdateLaraRoom(item, 0);
@@ -638,9 +636,9 @@ void UpdateLara(ItemInfo* item, bool isTitle)
if (isTitle)
ActionMap = actionMap;
- if (g_Gui.GetInventoryItemChosen() != NO_ITEM)
+ if (g_Gui.GetInventoryItemChosen() != NO_VALUE)
{
- g_Gui.SetInventoryItemChosen(NO_ITEM);
+ g_Gui.SetInventoryItemChosen(NO_VALUE);
SayNo();
}
diff --git a/TombEngine/Game/Lara/lara_collide.cpp b/TombEngine/Game/Lara/lara_collide.cpp
index d0527f388..1ffd4202d 100644
--- a/TombEngine/Game/Lara/lara_collide.cpp
+++ b/TombEngine/Game/Lara/lara_collide.cpp
@@ -57,7 +57,7 @@ bool LaraDeflectEdge(ItemInfo* item, CollisionInfo* coll)
ShiftItem(item, coll);
item->Pose.Orientation.y -= coll->DiagonalStepAtRight() ? DEFLECT_DIAGONAL_ANGLE : DEFLECT_STRAIGHT_ANGLE;
}
- else if (coll->LastBridgeItemNumber != NO_ITEM)
+ else if (coll->LastBridgeItemNumber != NO_VALUE)
{
ShiftItem(item, coll);
}
@@ -652,7 +652,7 @@ void LaraSwimCollision(ItemInfo* item, CollisionInfo* coll)
return;
}
- if (lara->ExtraAnim == NO_ITEM)
+ if (lara->ExtraAnim == NO_VALUE)
TestLaraWaterDepth(item, coll);
}
@@ -760,8 +760,8 @@ bool TestLaraObjectCollision(ItemInfo* item, short headingAngle, int forward, in
item->Pose.Position.y += down;
item->Pose.Position.z += phd_cos(item->Pose.Orientation.y + headingAngle) * forward + phd_sin(headingAngle + ANGLE(90.0f) * sideSign) * abs(right);
- bool result = GetCollidedObjects(item, LARA_RADIUS, true, CollidedItems, CollidedMeshes, 0);
+ bool isCollided = !GetCollidedObjects(*item, true, false).IsEmpty();
item->Pose = prevPose;
- return result;
+ return isCollided;
}
diff --git a/TombEngine/Game/Lara/lara_fire.cpp b/TombEngine/Game/Lara/lara_fire.cpp
index b6a7ca140..5bac95a04 100644
--- a/TombEngine/Game/Lara/lara_fire.cpp
+++ b/TombEngine/Game/Lara/lara_fire.cpp
@@ -571,7 +571,7 @@ void HandleWeapon(ItemInfo& laraItem)
player.Control.Weapon.RequestGunType = LaraWeaponType::Flare;
}
else if (player.Control.Weapon.RequestGunType == LaraWeaponType::Flare ||
- (player.Context.Vehicle == NO_ITEM &&
+ (player.Context.Vehicle == NO_VALUE &&
(player.Control.Weapon.RequestGunType == LaraWeaponType::HarpoonGun ||
player.Control.WaterStatus == WaterStatus::Dry ||
(player.Control.WaterStatus == WaterStatus::Wade &&
@@ -760,7 +760,7 @@ void HandleWeapon(ItemInfo& laraItem)
case HandStatus::Free:
if (player.Control.Weapon.GunType == LaraWeaponType::Flare)
{
- if (player.Context.Vehicle != NO_ITEM || TestState(laraItem.Animation.ActiveState, FlarePoseStates))
+ if (player.Context.Vehicle != NO_VALUE || TestState(laraItem.Animation.ActiveState, FlarePoseStates))
{
if (player.Flare.ControlLeft)
{
@@ -792,7 +792,7 @@ void HandleWeapon(ItemInfo& laraItem)
{
if (laraItem.Model.MeshIndex[LM_LHAND] == Objects[ID_FLARE_ANIM].meshIndex + LM_LHAND)
{
- player.Flare.ControlLeft = (player.Context.Vehicle != NO_ITEM || TestState(laraItem.Animation.ActiveState, FlarePoseStates));
+ player.Flare.ControlLeft = (player.Context.Vehicle != NO_VALUE || TestState(laraItem.Animation.ActiveState, FlarePoseStates));
if (Contains(UnavailableFlarePoseAnims, laraItem.Animation.AnimNumber))
player.Flare.ControlLeft = false;
@@ -843,7 +843,7 @@ FireWeaponType FireWeapon(LaraWeaponType weaponType, ItemInfo& targetEntity, Ite
auto ray = Ray(origin, directionNorm);
int num = GetSpheres(&targetEntity, CreatureSpheres, SPHERES_SPACE_WORLD, Matrix::Identity);
- int bestJointIndex = NO_JOINT;
+ int bestJointIndex = NO_VALUE;
float bestDistance = INFINITY;
for (int i = 0; i < num; i++)
{
@@ -917,7 +917,7 @@ void FindNewTarget(ItemInfo& laraItem, const WeaponInfo& weaponInfo)
for (auto* creaturePtr : ActiveCreatures)
{
// Continue loop if no item.
- if (creaturePtr->ItemNumber == NO_ITEM)
+ if (creaturePtr->ItemNumber == NO_VALUE)
continue;
auto& item = g_Level.Items[creaturePtr->ItemNumber];
diff --git a/TombEngine/Game/Lara/lara_fire.h b/TombEngine/Game/Lara/lara_fire.h
index ceeb66975..662d4b359 100644
--- a/TombEngine/Game/Lara/lara_fire.h
+++ b/TombEngine/Game/Lara/lara_fire.h
@@ -61,6 +61,6 @@ FireWeaponType FireWeapon(LaraWeaponType weaponType, ItemInfo& targetEntity, Ite
void FindNewTarget(ItemInfo& laraItem, const WeaponInfo& weaponInfo);
void LaraTargetInfo(ItemInfo& laraItem, const WeaponInfo& weaponInfo);
-void HitTarget(ItemInfo* laraItem, ItemInfo* targetEntity, GameVector* hitPos, int damage, bool isExplosive, int bestJointIndex = NO_JOINT);
+void HitTarget(ItemInfo* laraItem, ItemInfo* targetEntity, GameVector* hitPos, int damage, bool isExplosive, int bestJointIndex = NO_VALUE);
void SmashItem(short itemNumber);
diff --git a/TombEngine/Game/Lara/lara_flare.cpp b/TombEngine/Game/Lara/lara_flare.cpp
index 375562969..2cab1151e 100644
--- a/TombEngine/Game/Lara/lara_flare.cpp
+++ b/TombEngine/Game/Lara/lara_flare.cpp
@@ -123,7 +123,7 @@ void UndrawFlare(ItemInfo& laraItem)
player.Flare.ControlLeft = true;
if (laraItem.Animation.TargetState == LS_IDLE &&
- player.Context.Vehicle == NO_ITEM)
+ player.Context.Vehicle == NO_VALUE)
{
if (laraItem.Animation.AnimNumber == LA_STAND_IDLE)
{
@@ -311,7 +311,7 @@ void CreateFlare(ItemInfo& laraItem, GAME_OBJECT_ID objectID, bool isThrown)
const auto& lara = *GetLaraInfo(&laraItem);
auto itemNumber = CreateItem();
- if (itemNumber == NO_ITEM)
+ if (itemNumber == NO_VALUE)
return;
auto& flareItem = g_Level.Items[itemNumber];
@@ -326,10 +326,10 @@ void CreateFlare(ItemInfo& laraItem, GAME_OBJECT_ID objectID, bool isThrown)
flareItem.Pose.Position = pos;
int floorHeight = GetPointCollision(pos, laraItem.RoomNumber).GetFloorHeight();
- auto hasCollided = GetCollidedObjects(&flareItem, 0, true, CollidedItems, CollidedMeshes, true);
+ auto isCollided = !GetCollidedObjects(flareItem, true, true).IsEmpty();
bool hasLanded = false;
- if (floorHeight < pos.y || hasCollided)
+ if (floorHeight < pos.y || isCollided)
{
hasLanded = true;
flareItem.Pose.Position.x = laraItem.Pose.Position.x + 320 * phd_sin(flareItem.Pose.Orientation.y);
diff --git a/TombEngine/Game/Lara/lara_helpers.cpp b/TombEngine/Game/Lara/lara_helpers.cpp
index a84f0e5f9..d38ee2e44 100644
--- a/TombEngine/Game/Lara/lara_helpers.cpp
+++ b/TombEngine/Game/Lara/lara_helpers.cpp
@@ -144,7 +144,7 @@ void HandlePlayerStatusEffects(ItemInfo& item, WaterStatus waterStatus, PlayerWa
else if (player.Status.Air < LARA_AIR_MAX && item.HitPoints >= 0)
{
// HACK: Special case for UPV.
- if (player.Context.Vehicle == NO_ITEM)
+ if (player.Context.Vehicle == NO_VALUE)
{
player.Status.Air += 10;
if (player.Status.Air > LARA_AIR_MAX)
@@ -157,7 +157,7 @@ void HandlePlayerStatusEffects(ItemInfo& item, WaterStatus waterStatus, PlayerWa
if (player.Control.WaterStatus == WaterStatus::Dry)
{
// HACK: Special case for UPV.
- if (player.Context.Vehicle != NO_ITEM)
+ if (player.Context.Vehicle != NO_VALUE)
{
const auto& vehicleItem = g_Level.Items[player.Context.Vehicle];
if (vehicleItem.ObjectNumber == ID_UPV)
@@ -650,7 +650,7 @@ void HandlePlayerLookAround(ItemInfo& item, bool invertXAxis)
player.ExtraHeadRot = player.Control.Look.Orientation / 2;
if (player.Control.HandStatus != HandStatus::Busy &&
!player.LeftArm.Locked && !player.RightArm.Locked &&
- player.Context.Vehicle == NO_ITEM)
+ player.Context.Vehicle == NO_VALUE)
{
player.ExtraTorsoRot = player.ExtraHeadRot;
}
@@ -662,12 +662,12 @@ bool HandleLaraVehicle(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
- if (lara->Context.Vehicle == NO_ITEM)
+ if (lara->Context.Vehicle == NO_VALUE)
return false;
if (!g_Level.Items[lara->Context.Vehicle].Active)
{
- lara->Context.Vehicle = NO_ITEM;
+ lara->Context.Vehicle = NO_VALUE;
item->Animation.IsAirborne = true;
SetAnimation(item, LA_FALL_START);
return false;
@@ -927,7 +927,7 @@ void HandlePlayerFlyCheat(ItemInfo& item)
static bool dbFlyCheat = true;
if (KeyMap[OIS::KeyCode::KC_O] && dbFlyCheat)
{
- if (player.Context.Vehicle == NO_ITEM)
+ if (player.Context.Vehicle == NO_VALUE)
{
GivePlayerItemsCheat(item);
GivePlayerWeaponsCheat(item);
@@ -1748,10 +1748,10 @@ void SetLaraVehicle(ItemInfo* item, ItemInfo* vehicle)
if (vehicle == nullptr)
{
- if (lara->Context.Vehicle != NO_ITEM)
+ if (lara->Context.Vehicle != NO_VALUE)
g_Level.Items[lara->Context.Vehicle].Active = false;
- lara->Context.Vehicle = NO_ITEM;
+ lara->Context.Vehicle = NO_VALUE;
}
else
{
@@ -1788,7 +1788,7 @@ void ResetPlayerLookAround(ItemInfo& item, float alpha)
if (player.Control.HandStatus != HandStatus::Busy &&
!player.LeftArm.Locked && !player.RightArm.Locked &&
- player.Context.Vehicle == NO_ITEM)
+ player.Context.Vehicle == NO_VALUE)
{
player.ExtraTorsoRot = player.ExtraHeadRot;
}
diff --git a/TombEngine/Game/Lara/lara_initialise.cpp b/TombEngine/Game/Lara/lara_initialise.cpp
index 278e90e06..622d6c6c9 100644
--- a/TombEngine/Game/Lara/lara_initialise.cpp
+++ b/TombEngine/Game/Lara/lara_initialise.cpp
@@ -1,6 +1,7 @@
#include "framework.h"
#include "Game/Lara/lara_initialise.h"
+#include "Game/collision/Point.h"
#include "Game/Hud/Hud.h"
#include "Game/items.h"
#include "Game/Lara/lara.h"
@@ -18,6 +19,7 @@
#include "Objects/TR4/Vehicles/motorbike.h"
#include "Specific/level.h"
+using namespace TEN::Collision::Point;
using namespace TEN::Entities::Player;
using namespace TEN::Hud;
@@ -29,14 +31,14 @@ GAME_OBJECT_ID PlayerVehicleObjectID = GAME_OBJECT_ID::ID_NO_OBJECT;
void BackupLara()
{
- if (LaraItem == nullptr || LaraItem->Index == NO_ITEM)
+ if (LaraItem == nullptr || LaraItem->Index == NO_VALUE)
return;
PlayerHitPoints = LaraItem->HitPoints;
memcpy(&PlayerBackup, &Lara, sizeof(LaraInfo));
memcpy(&PlayerAnim, &LaraItem->Animation, sizeof(EntityAnimationData));
- if (Lara.Context.Vehicle != NO_ITEM)
+ if (Lara.Context.Vehicle != NO_VALUE)
{
PlayerVehicleObjectID = g_Level.Items[Lara.Context.Vehicle].ObjectNumber;
}
@@ -48,15 +50,15 @@ void BackupLara()
void InitializeLara(bool restore)
{
- if (LaraItem == nullptr || LaraItem->Index == NO_ITEM)
+ if (LaraItem == nullptr || LaraItem->Index == NO_VALUE)
return;
ZeroMemory(&Lara, sizeof(LaraInfo));
LaraItem->Data = &Lara;
- Lara.Context = PlayerContext(*LaraItem, LaraCollision);
-
LaraItem->Collidable = false;
+
+ Lara.Context = PlayerContext(*LaraItem, LaraCollision);
Lara.Status.Air = LARA_AIR_MAX;
Lara.Status.Exposure = LARA_EXPOSURE_MAX;
@@ -64,15 +66,15 @@ void InitializeLara(bool restore)
Lara.Status.Stamina = LARA_STAMINA_MAX;
Lara.Control.Look.Mode = LookMode::None;
- Lara.HitDirection = -1;
- Lara.Control.Weapon.WeaponItem = NO_ITEM;
+ Lara.HitDirection = NO_VALUE;
+ Lara.Control.Weapon.WeaponItem = NO_VALUE;
Lara.Context.WaterSurfaceDist = 100;
- Lara.ExtraAnim = NO_ITEM;
- Lara.Context.Vehicle = NO_ITEM;
- Lara.Location = -1;
- Lara.HighestLocation = -1;
- Lara.Control.Rope.Ptr = -1;
+ Lara.ExtraAnim = NO_VALUE;
+ Lara.Context.Vehicle = NO_VALUE;
+ Lara.Location = NO_VALUE;
+ Lara.HighestLocation = NO_VALUE;
+ Lara.Control.Rope.Ptr = NO_VALUE;
Lara.Control.HandStatus = HandStatus::Free;
InitializePlayerStateMachine();
@@ -131,8 +133,8 @@ void InitializeLaraAnims(ItemInfo* item)
player.Control.WaterStatus = WaterStatus::Dry;
// Allow player to start in crawl idle anim if start position is too low.
- auto pointColl = GetCollision(item);
- if (abs(pointColl.Position.Ceiling - pointColl.Position.Floor) < LARA_HEIGHT)
+ auto pointColl = GetPointCollision(*item);
+ if (abs(pointColl.GetCeilingHeight() - pointColl.GetFloorHeight()) < LARA_HEIGHT)
{
SetAnimation(item, LA_CRAWL_IDLE);
player.Control.IsLow =
@@ -160,18 +162,10 @@ void InitializeLaraStartPosition(ItemInfo& playerItem)
if (!item.TriggerFlags || item.TriggerFlags != RequiredStartPos)
continue;
- // HACK: For some reason, player can't be immediately updated and moved on loading.
- // Need to simulate "game loop" happening so that its position actually updates on next loop.
- // However, room number must be also be manually set in advance, so that startup anim detection
- // won't fail (otherwise player may start crouching because probe uses previous room number).
-
- InItemControlLoop = true;
-
playerItem.Pose = item.Pose;
- playerItem.RoomNumber = item.RoomNumber;
- ItemNewRoom(playerItem.Index, item.RoomNumber);
- InItemControlLoop = false;
+ if (playerItem.RoomNumber != item.RoomNumber)
+ ItemNewRoom(playerItem.Index, item.RoomNumber);
TENLog("Player start position has been set according to start position of object with ID " + std::to_string(item.TriggerFlags) + ".", LogLevel::Info);
break;
diff --git a/TombEngine/Game/Lara/lara_one_gun.cpp b/TombEngine/Game/Lara/lara_one_gun.cpp
index 708cac335..ae115a197 100644
--- a/TombEngine/Game/Lara/lara_one_gun.cpp
+++ b/TombEngine/Game/Lara/lara_one_gun.cpp
@@ -443,7 +443,7 @@ void DrawShotgun(ItemInfo& laraItem, LaraWeaponType weaponType)
ItemInfo* weaponItemPtr = nullptr;
- if (player.Control.Weapon.WeaponItem == NO_ITEM)
+ if (player.Control.Weapon.WeaponItem == NO_VALUE)
{
player.Control.Weapon.WeaponItem = CreateItem();
weaponItemPtr = &g_Level.Items[player.Control.Weapon.WeaponItem];
@@ -514,7 +514,7 @@ void UndrawShotgun(ItemInfo& laraItem, LaraWeaponType weaponType)
if (item.Status == ITEM_DEACTIVATED)
{
KillItem(player.Control.Weapon.WeaponItem);
- player.Control.Weapon.WeaponItem = NO_ITEM;
+ player.Control.Weapon.WeaponItem = NO_VALUE;
player.Control.HandStatus = HandStatus::Free;
player.TargetEntity = nullptr;
player.LeftArm.Locked =
@@ -574,7 +574,7 @@ bool FireHarpoon(ItemInfo& laraItem, const std::optional& pose)
player.Control.Weapon.HasFired = true;
int itemNumber = CreateItem();
- if (itemNumber == NO_ITEM)
+ if (itemNumber == NO_VALUE)
return false;
auto& harpoonItem = g_Level.Items[itemNumber];
@@ -682,7 +682,7 @@ void FireGrenade(ItemInfo& laraItem)
player.Control.Weapon.HasFired = true;
short itemNumber = CreateItem();
- if (itemNumber == NO_ITEM)
+ if (itemNumber == NO_VALUE)
return;
auto& grenadeItem = g_Level.Items[itemNumber];
@@ -733,7 +733,7 @@ void FireGrenade(ItemInfo& laraItem)
grenadeItem.Animation.Velocity.z = GRENADE_VELOCITY;
grenadeItem.Animation.ActiveState = grenadeItem.Pose.Orientation.x;
grenadeItem.Animation.TargetState = grenadeItem.Pose.Orientation.y;
- grenadeItem.Animation.RequiredState = NO_STATE;
+ grenadeItem.Animation.RequiredState = NO_VALUE;
grenadeItem.HitPoints = GRENADE_TIME;
grenadeItem.ItemFlags[0] = (int)WeaponAmmoType::Ammo2;
@@ -783,7 +783,7 @@ void GrenadeControl(short itemNumber)
if (grenadeItem.Animation.Velocity.z)
{
grenadeItem.Pose.Orientation.z += (short((grenadeItem.Animation.Velocity.z / 16) + 3.0f) * ANGLE(1.0f));
- if (grenadeItem.Animation.RequiredState != NO_STATE)
+ if (grenadeItem.Animation.RequiredState != NO_VALUE)
{
grenadeItem.Pose.Orientation.y += (short((grenadeItem.Animation.Velocity.z / 4) + 3.0f) * ANGLE(1.0f));
}
@@ -801,7 +801,7 @@ void GrenadeControl(short itemNumber)
if (grenadeItem.Animation.Velocity.z)
{
grenadeItem.Pose.Orientation.z += (short((grenadeItem.Animation.Velocity.z / 4) + 7.0f) * ANGLE(1.0f));
- if (grenadeItem.Animation.RequiredState != NO_STATE)
+ if (grenadeItem.Animation.RequiredState != NO_VALUE)
{
grenadeItem.Pose.Orientation.y += (short((grenadeItem.Animation.Velocity.z / 2) + 7.0f) * ANGLE(1.0f));
}
@@ -865,7 +865,7 @@ void FireRocket(ItemInfo& laraItem)
player.Control.Weapon.HasFired = true;
short itemNumber = CreateItem();
- if (itemNumber == NO_ITEM)
+ if (itemNumber == NO_VALUE)
return;
auto& rocketItem = g_Level.Items[itemNumber];
@@ -1004,7 +1004,7 @@ void FireCrossbow(ItemInfo& laraItem, const std::optional& pose)
player.Control.Weapon.HasFired = true;
short itemNumber = CreateItem();
- if (itemNumber == NO_ITEM)
+ if (itemNumber == NO_VALUE)
return;
auto& boltItem = g_Level.Items[itemNumber];
@@ -1383,7 +1383,7 @@ bool EmitFromProjectile(ItemInfo& projectile, ProjectileType type)
{
// Trigger a new fragment in the case of GRENADE_SUPER until itemFlags[1] is > 0.
int grenadeItemNumber = CreateItem();
- if (grenadeItemNumber == NO_ITEM)
+ if (grenadeItemNumber == NO_VALUE)
return true;
auto& grenadeItem = g_Level.Items[grenadeItemNumber];
@@ -1406,7 +1406,7 @@ bool EmitFromProjectile(ItemInfo& projectile, ProjectileType type)
grenadeItem.Animation.Velocity.z = 64.0f;
grenadeItem.Animation.ActiveState = grenadeItem.Pose.Orientation.x;
grenadeItem.Animation.TargetState = grenadeItem.Pose.Orientation.y;
- grenadeItem.Animation.RequiredState = NO_STATE;
+ grenadeItem.Animation.RequiredState = NO_VALUE;
AddActiveItem(grenadeItemNumber);
@@ -1558,42 +1558,34 @@ void HandleProjectile(ItemInfo& projectile, ItemInfo& emitter, const Vector3i& p
}
// Found possible collided items and statics.
- GetCollidedObjects(&projectile, radius, true, &CollidedItems[0], &CollidedMeshes[0], false);
-
- // If no collided items and meshes are found, exit the loop.
- if (!CollidedItems[0] && !CollidedMeshes[0])
+ auto collObjects = GetCollidedObjects(projectile, true, false, radius);
+ if (collObjects.IsEmpty())
break;
- for (int i = 0; i < MAX_COLLIDED_OBJECTS; i++)
+ // Run through statics.
+ for (auto* staticPtr : collObjects.StaticPtrs)
{
- auto* meshPtr = CollidedMeshes[i];
- if (!meshPtr)
- break;
-
hasHit = hasHitNotByEmitter = doShatter = true;
doExplosion = isExplosive;
- if (StaticObjects[meshPtr->staticNumber].shatterType == ShatterType::None)
+ if (StaticObjects[staticPtr->staticNumber].shatterType == ShatterType::None)
continue;
- meshPtr->HitPoints -= damage;
- if (meshPtr->HitPoints <= 0)
- ShatterObject(nullptr, meshPtr, -128, projectile.RoomNumber, 0);
+ staticPtr->HitPoints -= damage;
+ if (staticPtr->HitPoints <= 0)
+ ShatterObject(nullptr, staticPtr, -128, projectile.RoomNumber, 0);
if (!isExplosive)
continue;
- TriggerExplosionSparks(meshPtr->pos.Position.x, meshPtr->pos.Position.y, meshPtr->pos.Position.z, 3, -2, 0, projectile.RoomNumber);
- auto pose = Pose(meshPtr->pos.Position.x, meshPtr->pos.Position.y - 128, meshPtr->pos.Position.z, 0, meshPtr->pos.Orientation.y, 0);
+ TriggerExplosionSparks(staticPtr->pos.Position.x, staticPtr->pos.Position.y, staticPtr->pos.Position.z, 3, -2, 0, projectile.RoomNumber);
+ auto pose = Pose(staticPtr->pos.Position.x, staticPtr->pos.Position.y - 128, staticPtr->pos.Position.z, 0, staticPtr->pos.Orientation.y, 0);
TriggerShockwave(&pose, 40, 176, 64, 0, 96, 128, 16, EulerAngles::Identity, 0, true, false, false, (int)ShockwaveStyle::Normal);
}
- for (int i = 0; i < MAX_COLLIDED_OBJECTS; i++)
+ // Run through items.
+ for (auto* itemPtr : collObjects.ItemPtrs)
{
- auto* itemPtr = CollidedItems[i];
- if (itemPtr == nullptr)
- break;
-#
// Object was already affected by collision, skip it.
if (std::find(affectedObjects.begin(), affectedObjects.end(), itemPtr->Index) != affectedObjects.end())
continue;
@@ -1656,7 +1648,7 @@ void HandleProjectile(ItemInfo& projectile, ItemInfo& emitter, const Vector3i& p
SmashObject(itemPtr->Index);
KillItem(itemPtr->Index);
}
- else if (currentObject.collision && !(itemPtr->Status & ITEM_INVISIBLE))
+ else if (currentObject.collision && itemPtr->Status != ITEM_INVISIBLE)
{
doShatter = hasHit = true;
doExplosion = isExplosive;
diff --git a/TombEngine/Game/Lara/lara_overhang.cpp b/TombEngine/Game/Lara/lara_overhang.cpp
index 9915346a5..4af8eee62 100644
--- a/TombEngine/Game/Lara/lara_overhang.cpp
+++ b/TombEngine/Game/Lara/lara_overhang.cpp
@@ -133,7 +133,7 @@ short FindBridge(int tiltGrade, short orient, Vector3i& pos, int* returnHeight,
}
}
- return NO_ITEM;
+ return NO_VALUE;
}
// Get the signed difference between two orientations.
diff --git a/TombEngine/Game/Lara/lara_struct.h b/TombEngine/Game/Lara/lara_struct.h
index fdaaf8354..fa21dd987 100644
--- a/TombEngine/Game/Lara/lara_struct.h
+++ b/TombEngine/Game/Lara/lara_struct.h
@@ -1360,7 +1360,7 @@ struct LaraInfo
int HitFrame = 0; // Frame index.
int HitDirection = 0; // Cardinal direction.
- // Item number? Only ever set to NO_ITEM or 1. Probably anim object ID. Might not be needed since AnimObjectID is kept in item.Animation.
+ // Item number? Only ever set to NO_VALUE or 1. Probably anim object ID. Might not be needed since AnimObjectID is kept in item.Animation.
int ExtraAnim = 0;
signed char Location = 0;
diff --git a/TombEngine/Game/Lara/lara_tests.cpp b/TombEngine/Game/Lara/lara_tests.cpp
index d8412059b..4612b0217 100644
--- a/TombEngine/Game/Lara/lara_tests.cpp
+++ b/TombEngine/Game/Lara/lara_tests.cpp
@@ -926,7 +926,7 @@ bool TestLaraWaterClimbOut(ItemInfo* item, CollisionInfo* coll)
return false;
int frontFloor = coll->Front.Floor + LARA_HEIGHT_TREAD;
- if (coll->Front.Bridge == NO_ITEM &&
+ if (coll->Front.Bridge == NO_VALUE &&
(frontFloor <= -CLICK(2) ||
frontFloor > CLICK(1.25f) - 4))
{
@@ -934,7 +934,7 @@ bool TestLaraWaterClimbOut(ItemInfo* item, CollisionInfo* coll)
}
// Extra bridge check.
- if (coll->Front.Bridge != NO_ITEM)
+ if (coll->Front.Bridge != NO_VALUE)
{
int bridgeBorder = GetBridgeBorder(g_Level.Items[coll->Front.Bridge], false) - item->Pose.Position.y;
@@ -994,7 +994,7 @@ bool TestLaraWaterClimbOut(ItemInfo* item, CollisionInfo* coll)
SetAnimation(item, LA_ONWATER_TO_STAND_0_STEP);
}
- if (coll->Front.Bridge == NO_ITEM)
+ if (coll->Front.Bridge == NO_VALUE)
UpdateLaraRoom(item, -LARA_HEIGHT / 2);
else
UpdateLaraRoom(item, -LARA_HEIGHT);
@@ -1776,8 +1776,8 @@ bool TestLaraPoleCollision(ItemInfo* item, CollisionInfo* coll, bool goingUp, fl
bool atLeastOnePoleCollided = false;
- if (GetCollidedObjects(item, BLOCK(1), true, CollidedItems, nullptr, false) &&
- CollidedItems[0] != nullptr)
+ auto collObjects = GetCollidedObjects(*item, true, false, BLOCK(1), ObjectCollectionMode::Items);
+ if (!collObjects.IsEmpty())
{
auto laraBox = GameBoundingBox(item).ToBoundingOrientedBox(item->Pose);
@@ -1795,16 +1795,12 @@ bool TestLaraPoleCollision(ItemInfo* item, CollisionInfo* coll, bool goingUp, fl
//g_Renderer.AddDebugSphere(sphere.Center, 16.0f, Vector4(1, 0, 0, 1), RendererDebugPage::CollisionStats);
- int i = 0;
- while (CollidedItems[i] != nullptr)
+ for (const auto* itemPtr : collObjects.ItemPtrs)
{
- auto*& object = CollidedItems[i];
- i++;
-
- if (object->ObjectNumber != ID_POLEROPE)
+ if (itemPtr->ObjectNumber != ID_POLEROPE)
continue;
- auto poleBox = GameBoundingBox(object).ToBoundingOrientedBox(object->Pose);
+ auto poleBox = GameBoundingBox(itemPtr).ToBoundingOrientedBox(itemPtr->Pose);
poleBox.Extents = poleBox.Extents + Vector3(coll->Setup.Radius, 0.0f, coll->Setup.Radius);
//g_Renderer.AddDebugBox(poleBox, Vector4(0, 0, 1, 1), RendererDebugPage::CollisionStats);
diff --git a/TombEngine/Game/Setup.cpp b/TombEngine/Game/Setup.cpp
index 3eb0b4a1e..a427dfe71 100644
--- a/TombEngine/Game/Setup.cpp
+++ b/TombEngine/Game/Setup.cpp
@@ -20,6 +20,7 @@
#include "Objects/Generic/Traps/falling_block.h"
#include "Objects/TR1/tr1_objects.h"
#include "Objects/TR2/tr2_objects.h"
+#include "Objects/TR3/Entity/FishSwarm.h"
#include "Objects/TR3/tr3_objects.h"
#include "Objects/TR4/tr4_objects.h"
#include "Objects/TR5/tr5_objects.h"
@@ -153,6 +154,7 @@ void InitializeSpecialEffects()
NextBlood = 0;
TEN::Entities::TR4::ClearBeetleSwarm();
+ TEN::Entities::Creatures::TR3::ClearFishSwarm();
}
void CustomObjects()
@@ -187,7 +189,7 @@ void InitializeObjects()
obj->usingDrawAnimatingItem = true;
obj->damageType = DamageMode::Any;
obj->LotType = LotType::Basic;
- obj->meshSwapSlot = NO_ITEM;
+ obj->meshSwapSlot = NO_VALUE;
obj->isPickup = false;
obj->isPuzzleHole = false;
}
diff --git a/TombEngine/Game/animation.cpp b/TombEngine/Game/animation.cpp
index b9380fef5..68bdfeb36 100644
--- a/TombEngine/Game/animation.cpp
+++ b/TombEngine/Game/animation.cpp
@@ -190,7 +190,7 @@ void AnimateItem(ItemInfo* item)
if (!item->IsLara())
{
if (item->Animation.RequiredState == item->Animation.ActiveState)
- item->Animation.RequiredState = NO_STATE;
+ item->Animation.RequiredState = NO_VALUE;
}
}
@@ -212,7 +212,7 @@ void AnimateItem(ItemInfo* item)
}
if (item->Animation.RequiredState == item->Animation.ActiveState)
- item->Animation.RequiredState = NO_STATE;
+ item->Animation.RequiredState = NO_VALUE;
}
else
{
@@ -229,7 +229,7 @@ void AnimateItem(ItemInfo* item)
if (!item->IsLara())
{
if (item->Animation.RequiredState == item->Animation.ActiveState)
- item->Animation.RequiredState = NO_STATE;
+ item->Animation.RequiredState = NO_VALUE;
}*/
}
@@ -322,7 +322,7 @@ bool HasStateDispatch(const ItemInfo* item, int targetState)
if (anim.NumStateDispatches <= 0)
return false;
- if (targetState == NO_STATE)
+ if (targetState == NO_VALUE)
targetState = item->Animation.TargetState;
// Iterate over animation's state dispatches.
@@ -360,7 +360,7 @@ bool TestLastFrame(ItemInfo* item, int animNumber)
{
const auto& object = Objects[item->Animation.AnimObjectID];
- if (animNumber == NO_ANIM)
+ if (animNumber == NO_VALUE)
animNumber = item->Animation.AnimNumber - object.animIndex;
// Animation to test doesn't match; return early.
@@ -463,7 +463,7 @@ const AnimData& GetAnimData(const ObjectInfo& object, int animNumber)
const AnimData& GetAnimData(const ItemInfo& item, int animNumber)
{
- if (animNumber == NO_ANIM)
+ if (animNumber == NO_VALUE)
return GetAnimData(item.Animation.AnimNumber);
const auto& object = Objects[item.Animation.AnimObjectID];
diff --git a/TombEngine/Game/animation.h b/TombEngine/Game/animation.h
index 2e0c7798d..7cf2fc000 100644
--- a/TombEngine/Game/animation.h
+++ b/TombEngine/Game/animation.h
@@ -16,9 +16,6 @@ struct ObjectInfo;
// animNumber: Relative animation number.
// animIndex: Index of animation in giant g_Level.Anims vector.
-constexpr auto NO_STATE = -1;
-constexpr auto NO_ANIM = -1;
-
enum class AnimCommandType
{
None,
@@ -39,7 +36,7 @@ struct AnimFrame
struct StateDispatchData
{
- int TargetState = NO_STATE;
+ int TargetState = NO_VALUE;
int NumberRanges = 0;
int RangeIndex = 0;
};
@@ -48,8 +45,8 @@ struct StateDispatchRangeData
{
int StartFrame = 0; // g_Level.Frames base index.
int EndFrame = 0; // g_Level.Frames end index.
- int LinkAnimNum = NO_ANIM; // g_Level.Anims index.
- int LinkFrameNum = NO_ANIM; // g_Level.Frames index.
+ int LinkAnimNum = NO_VALUE; // g_Level.Anims index.
+ int LinkFrameNum = NO_VALUE; // g_Level.Frames index.
};
struct AnimData
@@ -65,7 +62,7 @@ struct AnimData
int frameBase = 0; // g_Level.Frames base index.
int frameEnd = 0; // g_Level.Frames end index.
- int JumpAnimNum = NO_ANIM; // g_Level.Anims index.
+ int JumpAnimNum = NO_VALUE; // g_Level.Anims index.
int JumpFrameNum = 0; // g_Level.Frames index.
int NumStateDispatches = 0;
int StateDispatchIndex = 0;
@@ -98,9 +95,9 @@ struct BoneMutator
void AnimateItem(ItemInfo* item);
// Inquirers
-bool HasStateDispatch(const ItemInfo* item, int targetState = NO_STATE);
+bool HasStateDispatch(const ItemInfo* item, int targetState = NO_VALUE);
bool TestAnimNumber(const ItemInfo& item, int animNumber);
-bool TestLastFrame(ItemInfo* item, int animNumber = NO_ANIM);
+bool TestLastFrame(ItemInfo* item, int animNumber = NO_VALUE);
bool TestAnimFrame(const ItemInfo& item, int frameStart);
bool TestAnimFrameRange(const ItemInfo& item, int frameStart, int frameEnd);
@@ -118,8 +115,8 @@ void SetAnimation(ItemInfo* item, int animNumber, int frameNumber = 0); // Depre
const AnimData& GetAnimData(int animIndex); // Deprecated.
const AnimData& GetAnimData(GAME_OBJECT_ID objectID, int animNumber);
const AnimData& GetAnimData(const ObjectInfo& object, int animNumber);
-const AnimData& GetAnimData(const ItemInfo& item, int animNumber = NO_ANIM);
-const AnimData& GetAnimData(const ItemInfo* item, int animNumber = NO_ANIM); // Deprecated.
+const AnimData& GetAnimData(const ItemInfo& item, int animNumber = NO_VALUE);
+const AnimData& GetAnimData(const ItemInfo* item, int animNumber = NO_VALUE); // Deprecated.
AnimFrameInterpData GetFrameInterpData(const ItemInfo& item);
const AnimFrame& GetAnimFrame(const ItemInfo& item, int animNumber, int frameNumber);
diff --git a/TombEngine/Game/collision/Point.cpp b/TombEngine/Game/collision/Point.cpp
index db80021a7..19312969d 100644
--- a/TombEngine/Game/collision/Point.cpp
+++ b/TombEngine/Game/collision/Point.cpp
@@ -116,7 +116,7 @@ namespace TEN::Collision::Point
return *_floorNormal;
// Set floor normal.
- if (GetFloorBridgeItemNumber() != NO_ITEM)
+ if (GetFloorBridgeItemNumber() != NO_VALUE)
{
_floorNormal = GetBridgeNormal(true);
}
@@ -134,7 +134,7 @@ namespace TEN::Collision::Point
return *_ceilingNormal;
// Set ceiling normal.
- if (GetCeilingBridgeItemNumber() != NO_ITEM)
+ if (GetCeilingBridgeItemNumber() != NO_VALUE)
{
_ceilingNormal = GetBridgeNormal(false);
}
@@ -214,7 +214,7 @@ namespace TEN::Collision::Point
bool PointCollisionData::IsIllegalFloor()
{
short slopeAngle = Geometry::GetSurfaceSlopeAngle(GetFloorNormal());
- short illegalSlopeAngle = (GetFloorBridgeItemNumber() != NO_ITEM) ?
+ short illegalSlopeAngle = (GetFloorBridgeItemNumber() != NO_VALUE) ?
DEFAULT_ILLEGAL_FLOOR_SLOPE_ANGLE :
GetBottomSector().GetSurfaceIllegalSlopeAngle(_position.x, _position.z, true);
@@ -224,7 +224,7 @@ namespace TEN::Collision::Point
bool PointCollisionData::IsIllegalCeiling()
{
short slopeAngle = Geometry::GetSurfaceSlopeAngle(GetCeilingNormal(), -Vector3::UnitY);
- short illegalSlopeAngle = (GetCeilingBridgeItemNumber() != NO_ITEM) ?
+ short illegalSlopeAngle = (GetCeilingBridgeItemNumber() != NO_VALUE) ?
DEFAULT_ILLEGAL_CEILING_SLOPE_ANGLE :
GetTopSector().GetSurfaceIllegalSlopeAngle(_position.x, _position.z, false);
diff --git a/TombEngine/Game/collision/collide_item.cpp b/TombEngine/Game/collision/collide_item.cpp
index b212b96a8..fc699db00 100644
--- a/TombEngine/Game/collision/collide_item.cpp
+++ b/TombEngine/Game/collision/collide_item.cpp
@@ -27,12 +27,11 @@ using namespace TEN::Collision::Point;
using namespace TEN::Math;
using namespace TEN::Renderer;
-GameBoundingBox GlobalCollisionBounds;
-ItemInfo* CollidedItems[MAX_COLLIDED_OBJECTS];
-MESH_INFO* CollidedMeshes[MAX_COLLIDED_OBJECTS];
-
constexpr auto ANIMATED_ALIGNMENT_FRAME_COUNT_THRESHOLD = 6;
+// Globals
+GameBoundingBox GlobalCollisionBounds;
+
void GenericSphereBoxCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
{
auto* item = &g_Level.Items[itemNumber];
@@ -104,174 +103,162 @@ void GenericSphereBoxCollision(short itemNumber, ItemInfo* laraItem, CollisionIn
}
}
-bool GetCollidedObjects(ItemInfo* collidingItem, int radius, bool onlyVisible, ItemInfo** collidedItems, MESH_INFO** collidedMeshes, bool ignoreLara)
+CollidedObjectData GetCollidedObjects(ItemInfo& collidingItem, bool onlyVisible, bool ignorePlayer, float customRadius, ObjectCollectionMode mode)
{
- short numItems = 0;
- short numMeshes = 0;
+ constexpr auto EXTENTS_LENGTH_MIN = 2.0f;
+ constexpr auto ROUGH_BOX_HEIGHT_MIN = BLOCK(1 / 8.0f);
- // Collect all the rooms where to check
- for (auto i : g_Level.Rooms[collidingItem->RoomNumber].neighbors)
+ auto collObjects = CollidedObjectData{};
+
+ int itemCount = 0;
+ int staticCount = 0;
+
+ // Establish parameters of colliding item.
+ const auto& collidingBounds = GetBestFrame(collidingItem).BoundingBox;
+ auto collidingExtents = collidingBounds.GetExtents();
+ auto collidingSphere = BoundingSphere(collidingBounds.GetCenter() + collidingItem.Pose.Position.ToVector3(), collidingExtents.Length());
+ auto collidingCircle = Vector3(collidingSphere.Center.x, collidingSphere.Center.z, (customRadius > 0.0f) ? customRadius : std::hypot(collidingExtents.x, collidingExtents.z));
+
+ // Quickly discard collision if colliding item bounds are below tolerance threshold.
+ if (collidingSphere.Radius <= EXTENTS_LENGTH_MIN)
+ return collObjects;
+
+ // Run through neighboring rooms.
+ const auto& room = g_Level.Rooms[collidingItem.RoomNumber];
+ for (int roomNumber : room.neighbors)
{
- if (!g_Level.Rooms[i].Active())
+ auto& neighborRoom = g_Level.Rooms[roomNumber];
+ if (!neighborRoom.Active())
continue;
- auto* room = &g_Level.Rooms[i];
-
- if (collidedMeshes)
+ // Collect items.
+ if (mode == ObjectCollectionMode::All ||
+ mode == ObjectCollectionMode::Items)
{
- for (int j = 0; j < room->mesh.size(); j++)
- {
- auto* mesh = &room->mesh[j];
- const auto& bBox = GetBoundsAccurate(*mesh, false);
-
- if (!(mesh->flags & StaticMeshFlags::SM_VISIBLE))
- continue;
-
- if ((collidingItem->Pose.Position.y + radius + CLICK(0.5f)) < (mesh->pos.Position.y + bBox.Y1))
- continue;
-
- if (collidingItem->Pose.Position.y > (mesh->pos.Position.y + bBox.Y2))
- continue;
-
- float sinY = phd_sin(mesh->pos.Orientation.y);
- float cosY = phd_cos(mesh->pos.Orientation.y);
-
- float rx = ((collidingItem->Pose.Position.x - mesh->pos.Position.x) * cosY) - ((collidingItem->Pose.Position.z - mesh->pos.Position.z) * sinY);
- float rz = ((collidingItem->Pose.Position.z - mesh->pos.Position.z) * cosY) + ((collidingItem->Pose.Position.x - mesh->pos.Position.x) * sinY);
-
- if ((radius + rx + CLICK(0.5f) < bBox.X1) || (rx - radius - CLICK(0.5f) > bBox.X2))
- continue;
-
- if ((radius + rz + CLICK(0.5f) < bBox.Z1) || (rz - radius - CLICK(0.5f) > bBox.Z2))
- continue;
-
- collidedMeshes[numMeshes++] = mesh;
-
- if (!radius)
- {
- collidedItems[0] = nullptr;
- return true;
- }
- }
-
- collidedMeshes[numMeshes] = nullptr;
- }
-
- if (collidedItems)
- {
- int itemNumber = room->itemNumber;
- if (itemNumber != NO_ITEM)
+ int itemNumber = neighborRoom.itemNumber;
+ if (itemNumber != NO_VALUE)
{
do
{
- auto* item = &g_Level.Items[itemNumber];
+ auto& item = g_Level.Items[itemNumber];
+ const auto& object = Objects[item.ObjectNumber];
- if (item == collidingItem ||
- (ignoreLara && item->ObjectNumber == ID_LARA) ||
- (onlyVisible && item->Status == ITEM_INVISIBLE) ||
- item->Flags & IFLAG_KILLED ||
- item->MeshBits == NO_JOINT_BITS ||
- (Objects[item->ObjectNumber].drawRoutine == nullptr && item->ObjectNumber != ID_LARA) ||
- (Objects[item->ObjectNumber].collision == nullptr && item->ObjectNumber != ID_LARA))
+ itemNumber = item.NextItem;
+
+ // Ignore player (if applicable).
+ if (ignorePlayer && item.IsLara())
+ continue;
+
+ // Ignore invisible item (if applicable).
+ if (onlyVisible && item.Status == ITEM_INVISIBLE)
+ continue;
+
+ // Ignore items not feasible for collision.
+ if (item.Index == collidingItem.Index ||
+ item.Flags & IFLAG_KILLED || item.MeshBits == NO_JOINT_BITS ||
+ (object.drawRoutine == nullptr && !item.IsLara()) ||
+ (object.collision == nullptr && !item.IsLara()))
{
- itemNumber = item->NextItem;
continue;
}
- // TODO: This is awful and we need a better system.
- if (item->ObjectNumber == ID_UPV && item->HitPoints == 1)
+ // HACK: Ignore UPV and big gun.
+ if ((item.ObjectNumber == ID_UPV || item.ObjectNumber == ID_BIGGUN) && item.HitPoints == 1)
+ continue;
+
+ // Test rough distance to discard objects more than 6 blocks away.
+ float dist = Vector3i::Distance(item.Pose.Position, collidingItem.Pose.Position);
+ if (dist > COLLISION_CHECK_DISTANCE)
+ continue;
+
+ const auto& bounds = GetBestFrame(item).BoundingBox;
+ auto extents = bounds.GetExtents();
+
+ // If item bounding box extents is below tolerance threshold, discard object.
+ if (extents.Length() <= EXTENTS_LENGTH_MIN)
+ continue;
+
+ // Test rough vertical distance to discard objects not intersecting vertically.
+ if (((collidingItem.Pose.Position.y + collidingBounds.Y1) - ROUGH_BOX_HEIGHT_MIN) >
+ ((item.Pose.Position.y + bounds.Y2) + ROUGH_BOX_HEIGHT_MIN))
{
- itemNumber = item->NextItem;
continue;
}
- if (item->ObjectNumber == ID_BIGGUN && item->HitPoints == 1)
+ if (((collidingItem.Pose.Position.y + collidingBounds.Y2) + ROUGH_BOX_HEIGHT_MIN) <
+ ((item.Pose.Position.y + bounds.Y1) - ROUGH_BOX_HEIGHT_MIN))
{
- itemNumber = item->NextItem;
continue;
}
- int dx = collidingItem->Pose.Position.x - item->Pose.Position.x;
- int dy = collidingItem->Pose.Position.y - item->Pose.Position.y;
- int dz = collidingItem->Pose.Position.z - item->Pose.Position.z;
+ // Test rough circle intersection to discard objects not intersecting horizontally.
+ auto circle = Vector3(item.Pose.Position.x, item.Pose.Position.z, std::hypot(extents.x, extents.z));
+ if (!Geometry::CircleIntersects(circle, collidingCircle))
+ continue;
- auto bounds = GetBestFrame(*item).BoundingBox;
+ auto box0 = bounds.ToBoundingOrientedBox(item.Pose);
+ auto box1 = collidingBounds.ToBoundingOrientedBox(collidingItem.Pose);
- if (dx >= -BLOCK(2) && dx <= BLOCK(2) &&
- dy >= -BLOCK(2) && dy <= BLOCK(2) &&
- dz >= -BLOCK(2) && dz <= BLOCK(2) &&
- (collidingItem->Pose.Position.y + radius + CLICK(0.5f)) >= (item->Pose.Position.y + bounds.Y1) &&
- (collidingItem->Pose.Position.y - radius - CLICK(0.5f)) <= (item->Pose.Position.y + bounds.Y2))
- {
- float sinY = phd_sin(item->Pose.Orientation.y);
- float cosY = phd_cos(item->Pose.Orientation.y);
+ // Override extents if specified.
+ if (customRadius > 0.0f)
+ box1.Extents = Vector3(customRadius);
- int rx = (dx * cosY) - (dz * sinY);
- int rz = (dz * cosY) + (dx * sinY);
-
- // TODO: Modify asset to avoid hardcoded bounds change. -- Sezz 2023.04.30
- if (item->ObjectNumber == ID_TURN_SWITCH)
- {
- bounds.X1 = -CLICK(1);
- bounds.X2 = CLICK(1);
- bounds.Z1 = -CLICK(1);
- bounds.Z1 = CLICK(1);
- }
-
- if ((radius + rx + CLICK(0.5f)) >= bounds.X1 &&
- (rx - radius - CLICK(0.5f)) <= bounds.X2)
- {
- if ((radius + rz + CLICK(0.5f)) >= bounds.Z1 &&
- (rz - radius - CLICK(0.5f)) <= bounds.Z2)
- {
- collidedItems[numItems++] = item;
- }
- }
- else
- {
- if ((collidingItem->Pose.Position.y + radius + CLICK(0.5f)) >= (item->Pose.Position.y + bounds.Y1) &&
- (collidingItem->Pose.Position.y - radius - CLICK(0.5f)) <= (item->Pose.Position.y + bounds.Y2))
- {
- float sinY = phd_sin(item->Pose.Orientation.y);
- float cosY = phd_cos(item->Pose.Orientation.y);
-
- int rx = (dx * cosY) - (dz * sinY);
- int rz = (dz * cosY) + (dx * sinY);
-
- // TODO: Modify asset to avoid hardcoded bounds change. -- Sezz 2023.04.30
- if (item->ObjectNumber == ID_TURN_SWITCH)
- {
- bounds.X1 = -CLICK(1);
- bounds.X2 = CLICK(1);
- bounds.Z1 = -CLICK(1);
- bounds.Z1 = CLICK(1);
- }
-
- if ((radius + rx + CLICK(0.5f)) >= bounds.X1 &&
- (rx - radius - CLICK(0.5f)) <= bounds.X2)
- {
- if ((radius + rz + CLICK(0.5f)) >= bounds.Z1 &&
- (rz - radius - CLICK(0.5f)) <= bounds.Z2)
- {
- collidedItems[numItems++] = item;
-
- if (!radius)
- return true;
- }
- }
- }
- }
- }
-
- itemNumber = item->NextItem;
+ // Test accurate box intersection.
+ if (box0.Intersects(box1))
+ collObjects.ItemPtrs.push_back(&item);
}
- while (itemNumber != NO_ITEM);
+ while (itemNumber != NO_VALUE);
}
+ }
- collidedItems[numItems] = nullptr;
+ // Collect statics.
+ if (mode == ObjectCollectionMode::All ||
+ mode == ObjectCollectionMode::Statics)
+ {
+ for (auto& staticObj : neighborRoom.mesh)
+ {
+ // Discard invisible statics.
+ if (!(staticObj.flags & StaticMeshFlags::SM_VISIBLE))
+ continue;
+
+ // Test rough distance to discard statics beyond collision check threshold.
+ float dist = Vector3i::Distance(staticObj.pos.Position, collidingItem.Pose.Position);
+ if (dist > COLLISION_CHECK_DISTANCE)
+ continue;
+
+ const auto& bounds = GetBoundsAccurate(staticObj, false);
+
+ // Test rough vertical distance to discard statics not intersecting vertically.
+ if (((collidingItem.Pose.Position.y + collidingBounds.Y1) - ROUGH_BOX_HEIGHT_MIN) >
+ ((staticObj.pos.Position.y + bounds.Y2) + ROUGH_BOX_HEIGHT_MIN))
+ {
+ continue;
+ }
+ if (((collidingItem.Pose.Position.y + collidingBounds.Y2) + ROUGH_BOX_HEIGHT_MIN) <
+ ((staticObj.pos.Position.y + bounds.Y1) - ROUGH_BOX_HEIGHT_MIN))
+ {
+ continue;
+ }
+
+ // Test rough circle intersection to discard statics not intersecting horizontally.
+ auto circle = Vector3(staticObj.pos.Position.x, staticObj.pos.Position.z, (bounds.GetExtents() * Vector3(1.0f, 0.0f, 1.0f)).Length());
+ if (!Geometry::CircleIntersects(circle, collidingCircle))
+ continue;
+
+ auto box0 = bounds.ToBoundingOrientedBox(staticObj.pos.Position);
+ auto box1 = collidingBounds.ToBoundingOrientedBox(collidingItem.Pose);
+
+ // Override extents if specified.
+ if (customRadius > 0.0f)
+ box1.Extents = Vector3(customRadius);
+
+ // Test accurate box intersection.
+ if (box0.Intersects(box1))
+ collObjects.StaticPtrs.push_back(&staticObj);
+ }
}
}
- return (numItems || numMeshes);
+ return collObjects;
}
bool TestWithGlobalCollisionBounds(ItemInfo* item, ItemInfo* laraItem, CollisionInfo* coll)
@@ -328,7 +315,7 @@ void TestForObjectOnLedge(ItemInfo* item, CollisionInfo* coll)
continue;
int itemNumber = g_Level.Rooms[i].itemNumber;
- while (itemNumber != NO_ITEM)
+ while (itemNumber != NO_VALUE)
{
auto* item2 = &g_Level.Items[itemNumber];
auto* object = &Objects[item2->ObjectNumber];
@@ -905,8 +892,7 @@ void ItemPushBridge(ItemInfo& item, CollisionInfo& coll)
void CollideBridgeItems(ItemInfo& item, CollisionInfo& coll, PointCollisionData& pointColl)
{
// Store offset for bridge item into shifts if it exists.
- if (coll.LastBridgeItemNumber == pointColl.GetFloorBridgeItemNumber() &&
- coll.LastBridgeItemNumber != NO_ITEM)
+ if (coll.LastBridgeItemNumber == pointColl.GetFloorBridgeItemNumber() && coll.LastBridgeItemNumber != NO_VALUE)
{
auto& bridgeItem = g_Level.Items[pointColl.GetFloorBridgeItemNumber()];
@@ -945,7 +931,7 @@ void CollideBridgeItems(ItemInfo& item, CollisionInfo& coll, PointCollisionData&
else
{
coll.LastBridgeItemPose = Pose::Zero;
- coll.LastBridgeItemNumber = NO_ITEM;
+ coll.LastBridgeItemNumber = NO_VALUE;
}
coll.LastBridgeItemNumber = pointColl.GetFloorBridgeItemNumber();
@@ -1831,7 +1817,7 @@ void DoObjectCollision(ItemInfo* item, CollisionInfo* coll)
continue;
int nextItemNumber = neighborRoom.itemNumber;
- while (nextItemNumber != NO_ITEM)
+ while (nextItemNumber != NO_VALUE)
{
auto& linkItem = g_Level.Items[nextItemNumber];
int itemNumber = nextItemNumber;
diff --git a/TombEngine/Game/collision/collide_item.h b/TombEngine/Game/collision/collide_item.h
index ee9d6a8b6..5bd91e997 100644
--- a/TombEngine/Game/collision/collide_item.h
+++ b/TombEngine/Game/collision/collide_item.h
@@ -1,23 +1,26 @@
#pragma once
+#include "Game/collision/Point.h"
#include "Math/Math.h"
-namespace TEN::Collision::Point { class PointCollisionData; };
+using namespace TEN::Collision::Point;
+
class FloorInfo;
struct CollisionInfo;
struct CollisionResult;
struct ItemInfo;
struct MESH_INFO;
-using namespace TEN::Collision::Point;
-
-constexpr auto MAX_COLLIDED_OBJECTS = 1024;
-constexpr auto ITEM_RADIUS_YMAX = BLOCK(3);
-
+constexpr auto ITEM_RADIUS_YMAX = BLOCK(3);
constexpr auto VEHICLE_COLLISION_TERMINAL_VELOCITY = 30.0f;
extern GameBoundingBox GlobalCollisionBounds;
-extern ItemInfo* CollidedItems[MAX_COLLIDED_OBJECTS];
-extern MESH_INFO* CollidedMeshes[MAX_COLLIDED_OBJECTS];
+
+enum class ObjectCollectionMode
+{
+ All,
+ Items,
+ Statics
+};
struct ObjectCollisionBounds
{
@@ -25,8 +28,16 @@ struct ObjectCollisionBounds
std::pair OrientConstraint = {};
};
+struct CollidedObjectData
+{
+ std::vector ItemPtrs = {};
+ std::vector StaticPtrs = {};
+
+ bool IsEmpty() const { return (ItemPtrs.empty() && StaticPtrs.empty()); };
+};
+
void GenericSphereBoxCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll);
-bool GetCollidedObjects(ItemInfo* collidingItem, int radius, bool onlyVisible, ItemInfo** collidedItems, MESH_INFO** collidedMeshes, bool ignoreLara);
+CollidedObjectData GetCollidedObjects(ItemInfo& collidingItem, bool onlyVisible, bool ignorePlayer, float customRadius = 0.0f, ObjectCollectionMode mode = ObjectCollectionMode::All);
bool TestWithGlobalCollisionBounds(ItemInfo* item, ItemInfo* laraItem, CollisionInfo* coll);
void TestForObjectOnLedge(ItemInfo* item, CollisionInfo* coll);
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index ce25ae013..438c8fa7c 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -121,7 +121,7 @@ bool TestItemRoomCollisionAABB(ItemInfo* item)
return collided;
}
-static CollisionPositionData GetCollisionPositionData(PointCollisionData& pointColl)
+static CollisionPositionData GetCollisionPosition(PointCollisionData& pointColl)
{
auto collPos = CollisionPositionData{};
collPos.Floor = pointColl.GetFloorHeight();
@@ -327,7 +327,7 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
if (ceiling != NO_HEIGHT)
ceiling -= probePos.y;
- coll->Middle = GetCollisionPositionData(pointColl);
+ coll->Middle = GetCollisionPosition(pointColl);
coll->Middle.Floor = height;
coll->Middle.Ceiling = ceiling;
@@ -370,7 +370,7 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
if (ceiling != NO_HEIGHT)
ceiling -= probePos.y;
- coll->Front = GetCollisionPositionData(pointColl);
+ coll->Front = GetCollisionPosition(pointColl);
coll->Front.Floor = height;
coll->Front.Ceiling = ceiling;
@@ -418,7 +418,7 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
if (ceiling != NO_HEIGHT)
ceiling -= probePos.y;
- coll->MiddleLeft = GetCollisionPositionData(pointColl);
+ coll->MiddleLeft = GetCollisionPosition(pointColl);
coll->MiddleLeft.Floor = height;
coll->MiddleLeft.Ceiling = ceiling;
@@ -449,7 +449,7 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
if (ceiling != NO_HEIGHT)
ceiling -= probePos.y;
- coll->FrontLeft = GetCollisionPositionData(pointColl);
+ coll->FrontLeft = GetCollisionPosition(pointColl);
coll->FrontLeft.Floor = height;
coll->FrontLeft.Ceiling = ceiling;
@@ -484,7 +484,7 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
if (ceiling != NO_HEIGHT)
ceiling -= probePos.y;
- coll->MiddleRight = GetCollisionPositionData(pointColl);
+ coll->MiddleRight = GetCollisionPosition(pointColl);
coll->MiddleRight.Floor = height;
coll->MiddleRight.Ceiling = ceiling;
@@ -514,7 +514,7 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
if (ceiling != NO_HEIGHT)
ceiling -= probePos.y;
- coll->FrontRight = GetCollisionPositionData(pointColl);
+ coll->FrontRight = GetCollisionPosition(pointColl);
coll->FrontRight.Floor = height;
coll->FrontRight.Ceiling = ceiling;
diff --git a/TombEngine/Game/collision/floordata.cpp b/TombEngine/Game/collision/floordata.cpp
index 8d02233e0..2bc77b462 100644
--- a/TombEngine/Game/collision/floordata.cpp
+++ b/TombEngine/Game/collision/floordata.cpp
@@ -318,7 +318,7 @@ int FloorInfo::GetInsideBridgeItemNumber(const Vector3i& pos, bool testFloorBord
}
// 2) No bridge intersection; return invalid item number.
- return NO_ITEM;
+ return NO_VALUE;
}
void FloorInfo::AddBridge(int itemNumber)
@@ -512,7 +512,7 @@ namespace TEN::Collision::Floordata
sectorPtr = &GetSideSector(*nextRoomNumber, pos.x, pos.z);
}
}
- while (sectorPtr->GetInsideBridgeItemNumber(pos, isBottom, !isBottom) != NO_ITEM);
+ while (sectorPtr->GetInsideBridgeItemNumber(pos, isBottom, !isBottom) != NO_VALUE);
return FarthestHeightData{ *sectorPtr, pos.y };
}
@@ -558,7 +558,7 @@ namespace TEN::Collision::Floordata
bool testCeilBorder = (pos.y == floorHeight);
int insideBridgeItemNumber = sectorPtr->GetInsideBridgeItemNumber(pos, testFloorBorder, testCeilBorder);
- if (insideBridgeItemNumber != NO_ITEM)
+ if (insideBridgeItemNumber != NO_VALUE)
{
if (isFloor ? (polarity <= 0) : (polarity >= 0))
{
@@ -616,7 +616,7 @@ namespace TEN::Collision::Floordata
bool testCeilBorder = (location.Height == floorHeight);
int insideBridgeItemNumber = sectorPtr->GetInsideBridgeItemNumber(Vector3i(pos.x, location.Height, pos.z), testFloorBorder, testCeilBorder);
- if (insideBridgeItemNumber != NO_ITEM)
+ if (insideBridgeItemNumber != NO_VALUE)
{
auto heightData = GetFarthestHeightData(*sectorPtr, Vector3i(pos.x, location.Height, pos.z), isBottom);
if (!heightData.has_value())
diff --git a/TombEngine/Game/control/box.cpp b/TombEngine/Game/control/box.cpp
index 90778ecf5..f4e6a43ca 100644
--- a/TombEngine/Game/control/box.cpp
+++ b/TombEngine/Game/control/box.cpp
@@ -52,7 +52,7 @@ constexpr auto FRAME_PRIO_EXP = 1.5;
void DrawBox(int boxIndex, Vector3 color)
{
- if (boxIndex == NO_BOX)
+ if (boxIndex == NO_VALUE)
return;
auto& currBox = g_Level.Boxes[boxIndex];
@@ -75,7 +75,7 @@ void DrawBox(int boxIndex, Vector3 color)
void DrawNearbyPathfinding(int boxIndex)
{
- if (boxIndex == NO_BOX)
+ if (boxIndex == NO_VALUE)
return;
auto& currBox = g_Level.Boxes[boxIndex];
@@ -156,13 +156,13 @@ bool SameZone(CreatureInfo* creature, ItemInfo* target)
auto& roomSource = g_Level.Rooms[item.RoomNumber];
auto& boxSource = GetSector(&roomSource, item.Pose.Position.x - roomSource.x, item.Pose.Position.z - roomSource.z)->Box;
- if (boxSource == NO_BOX)
+ if (boxSource == NO_VALUE)
return false;
item.BoxNumber = boxSource;
auto& roomTarget = g_Level.Rooms[target->RoomNumber];
auto& boxTarget = GetSector(&roomTarget, target->Pose.Position.x - roomTarget.x, target->Pose.Position.z - roomTarget.z)->Box;
- if (boxTarget == NO_BOX)
+ if (boxTarget == NO_VALUE)
return false;
target->BoxNumber = boxTarget;
@@ -208,7 +208,7 @@ void AlertNearbyGuards(ItemInfo* item)
for (int i = 0; i < ActiveCreatures.size(); i++)
{
auto* currentCreature = ActiveCreatures[i];
- if (currentCreature->ItemNumber == NO_ITEM)
+ if (currentCreature->ItemNumber == NO_VALUE)
continue;
auto* currentTarget = &g_Level.Items[currentCreature->ItemNumber + i];
@@ -233,7 +233,7 @@ void AlertAllGuards(short itemNumber)
for (int i = 0; i < ActiveCreatures.size(); i++)
{
auto* creature = ActiveCreatures[i];
- if (creature->ItemNumber == NO_ITEM)
+ if (creature->ItemNumber == NO_VALUE)
continue;
auto* target = &g_Level.Items[creature->ItemNumber];
@@ -256,7 +256,7 @@ bool CreaturePathfind(ItemInfo* item, Vector3i prevPos, short angle, short tilt)
int* zone = g_Level.Zones[(int)LOT->Zone][(int)FlipStatus].data();
int boxHeight;
- if (item->BoxNumber != NO_BOX)
+ if (item->BoxNumber != NO_VALUE)
boxHeight = g_Level.Boxes[item->BoxNumber].height;
else
boxHeight = item->Floor;
@@ -267,7 +267,7 @@ bool CreaturePathfind(ItemInfo* item, Vector3i prevPos, short angle, short tilt)
GetFloor(prevPos.x, y, prevPos.z, &roomNumber);
auto* floor = GetFloor(item->Pose.Position.x, y, item->Pose.Position.z, &roomNumber);
- if (floor->Box == NO_BOX)
+ if (floor->Box == NO_VALUE)
return false;
int height = g_Level.Boxes[floor->Box].height;
@@ -285,13 +285,13 @@ bool CreaturePathfind(ItemInfo* item, Vector3i prevPos, short angle, short tilt)
nextBox = floor->Box;
}
- if (nextBox == NO_BOX)
+ if (nextBox == NO_VALUE)
nextHeight = height;
else
nextHeight = g_Level.Boxes[nextBox].height;
- if (floor->Box == NO_BOX || !LOT->IsJumping &&
- (LOT->Fly == NO_FLYING && item->BoxNumber != NO_BOX && zone[item->BoxNumber] != zone[floor->Box] ||
+ if (floor->Box == NO_VALUE || !LOT->IsJumping &&
+ (LOT->Fly == NO_FLYING && item->BoxNumber != NO_VALUE && zone[item->BoxNumber] != zone[floor->Box] ||
boxHeight - height > LOT->Step ||
boxHeight - height < LOT->Drop))
{
@@ -323,7 +323,7 @@ bool CreaturePathfind(ItemInfo* item, Vector3i prevPos, short angle, short tilt)
nextBox = floor->Box;
}
- if (nextBox == NO_BOX)
+ if (nextBox == NO_VALUE)
nextHeight = height;
else
nextHeight = g_Level.Boxes[nextBox].height;
@@ -857,7 +857,7 @@ void CreatureDie(int itemNumber, bool doExplosion, int flags)
bool BadFloor(int x, int y, int z, int boxHeight, int nextHeight, short roomNumber, LOTInfo* LOT)
{
auto* floor = GetFloor(x, y, z, &roomNumber);
- if (floor->Box == NO_BOX)
+ if (floor->Box == NO_VALUE)
return true;
if (LOT->IsJumping)
@@ -912,14 +912,14 @@ int CreatureCreature(short itemNumber)
}
link = linked->NextItem;
- } while (link != NO_ITEM);
+ } while (link != NO_VALUE);
return 0;
}
bool ValidBox(ItemInfo* item, short zoneNumber, short boxNumber)
{
- if (boxNumber == NO_BOX)
+ if (boxNumber == NO_VALUE)
return false;
const auto& creature = *GetCreatureInfo(item);
@@ -945,7 +945,7 @@ bool ValidBox(ItemInfo* item, short zoneNumber, short boxNumber)
bool EscapeBox(ItemInfo* item, ItemInfo* enemy, int boxNumber)
{
- if (boxNumber == NO_BOX)
+ if (boxNumber == NO_VALUE)
return false;
const auto& box = g_Level.Boxes[boxNumber];
@@ -964,7 +964,7 @@ bool EscapeBox(ItemInfo* item, ItemInfo* enemy, int boxNumber)
void TargetBox(LOTInfo* LOT, int boxNumber)
{
- if (boxNumber == NO_BOX)
+ if (boxNumber == NO_VALUE)
return;
auto* box = &g_Level.Boxes[boxNumber];
@@ -981,23 +981,23 @@ void TargetBox(LOTInfo* LOT, int boxNumber)
bool UpdateLOT(LOTInfo* LOT, int depth)
{
- if (LOT->RequiredBox != NO_BOX && LOT->RequiredBox != LOT->TargetBox)
+ if (LOT->RequiredBox != NO_VALUE && LOT->RequiredBox != LOT->TargetBox)
{
LOT->TargetBox = LOT->RequiredBox;
auto* node = &LOT->Node[LOT->RequiredBox];
- if (node->nextExpansion == NO_BOX && LOT->Tail != LOT->RequiredBox)
+ if (node->nextExpansion == NO_VALUE && LOT->Tail != LOT->RequiredBox)
{
node->nextExpansion = LOT->Head;
- if (LOT->Head == NO_BOX)
+ if (LOT->Head == NO_VALUE)
LOT->Tail = LOT->TargetBox;
LOT->Head = LOT->TargetBox;
}
node->searchNumber = ++LOT->SearchNumber;
- node->exitBox = NO_BOX;
+ node->exitBox = NO_VALUE;
}
return SearchLOT(LOT, depth);
@@ -1010,9 +1010,9 @@ bool SearchLOT(LOTInfo* LOT, int depth)
for (int i = 0; i < depth; i++)
{
- if (LOT->Head == NO_BOX)
+ if (LOT->Head == NO_VALUE)
{
- LOT->Tail = NO_BOX;
+ LOT->Tail = NO_VALUE;
return false;
}
@@ -1068,7 +1068,7 @@ bool SearchLOT(LOTInfo* LOT, int depth)
}
}
- if (expand->nextExpansion == NO_BOX && boxNumber != LOT->Tail)
+ if (expand->nextExpansion == NO_VALUE && boxNumber != LOT->Tail)
{
LOT->Node[LOT->Tail].nextExpansion = boxNumber;
LOT->Tail = boxNumber;
@@ -1077,7 +1077,7 @@ bool SearchLOT(LOTInfo* LOT, int depth)
}
LOT->Head = node->nextExpansion;
- node->nextExpansion = NO_BOX;
+ node->nextExpansion = NO_VALUE;
}
return true;
@@ -1143,7 +1143,7 @@ void InitializeCreature(short itemNumber)
bool StalkBox(ItemInfo* item, ItemInfo* enemy, int boxNumber)
{
- if (enemy == nullptr || boxNumber == NO_BOX)
+ if (enemy == nullptr || boxNumber == NO_VALUE)
return false;
auto* box = &g_Level.Boxes[boxNumber];
@@ -1305,7 +1305,7 @@ void GetAITarget(CreatureInfo* creature)
if (enemy)
enemyObjectNumber = enemy->ObjectNumber;
else
- enemyObjectNumber = NO_ITEM;
+ enemyObjectNumber = NO_VALUE;
auto* item = &g_Level.Items[creature->ItemNumber];
@@ -1397,7 +1397,7 @@ void GetAITarget(CreatureInfo* creature)
item->AIBits &= ~FOLLOW;
}
}
- /*else if (item->objectNumber == ID_MONKEY && item->carriedItem == NO_ITEM)
+ /*else if (item->objectNumber == ID_MONKEY && item->carriedItem == NO_VALUE)
{
if (item->aiBits != MODIFY)
{
@@ -1465,7 +1465,7 @@ void FindAITargetObject(CreatureInfo* creature, int objectNumber, int ocb, bool
room = &g_Level.Rooms[aiObject.roomNumber];
aiObject.boxNumber = GetSector(room, aiObject.pos.Position.x - room->x, aiObject.pos.Position.z - room->z)->Box;
- if (item.BoxNumber == NO_BOX || aiObject.boxNumber == NO_BOX)
+ if (item.BoxNumber == NO_VALUE || aiObject.boxNumber == NO_VALUE)
return;
if (checkSameZone && (zone[item.BoxNumber] != zone[aiObject.boxNumber]))
@@ -1524,7 +1524,7 @@ int TargetReachable(ItemInfo* item, ItemInfo* enemy)
isReachable = abs(enemy->Pose.Position.y - pointColl.GetFloorHeight()) < bounds.GetHeight();
}
- return (isReachable ? floor->Box : NO_BOX);
+ return (isReachable ? floor->Box : NO_VALUE);
}
void CreatureAIInfo(ItemInfo* item, AI_INFO* AI)
@@ -1550,15 +1550,15 @@ void CreatureAIInfo(ItemInfo* item, AI_INFO* AI)
AI->zoneNumber = zone[item->BoxNumber];
enemy->BoxNumber = TargetReachable(item, enemy);
- AI->enemyZone = enemy->BoxNumber == NO_BOX ? NO_ZONE : zone[enemy->BoxNumber];
+ AI->enemyZone = enemy->BoxNumber == NO_VALUE ? NO_VALUE : zone[enemy->BoxNumber];
if (!object->nonLot)
{
- if (enemy->BoxNumber != NO_BOX && g_Level.Boxes[enemy->BoxNumber].flags & creature->LOT.BlockMask)
+ if (enemy->BoxNumber != NO_VALUE && g_Level.Boxes[enemy->BoxNumber].flags & creature->LOT.BlockMask)
{
AI->enemyZone |= BLOCKED;
}
- else if (item->BoxNumber != NO_BOX &&
+ else if (item->BoxNumber != NO_VALUE &&
creature->LOT.Node[item->BoxNumber].searchNumber == (creature->LOT.SearchNumber | BLOCKED_SEARCH))
{
AI->enemyZone |= BLOCKED;
@@ -1645,7 +1645,7 @@ void CreatureMood(ItemInfo* item, AI_INFO* AI, bool isViolent)
TargetBox(LOT, boxNumber);
creature->Mood = MoodType::Bored;
}
- else if (LOT->RequiredBox == NO_BOX)
+ else if (LOT->RequiredBox == NO_VALUE)
{
TargetBox(LOT, boxNumber);
}
@@ -1668,7 +1668,7 @@ void CreatureMood(ItemInfo* item, AI_INFO* AI, bool isViolent)
case MoodType::Escape:
boxNumber = LOT->Node[GetRandomControl() * LOT->ZoneCount >> 15].boxNumber;
- if (ValidBox(item, AI->zoneNumber, boxNumber) && LOT->RequiredBox == NO_BOX)
+ if (ValidBox(item, AI->zoneNumber, boxNumber) && LOT->RequiredBox == NO_VALUE)
{
if (EscapeBox(item, enemy, boxNumber))
{
@@ -1684,7 +1684,7 @@ void CreatureMood(ItemInfo* item, AI_INFO* AI, bool isViolent)
break;
case MoodType::Stalk:
- if (LOT->RequiredBox == NO_BOX || !StalkBox(item, enemy, LOT->RequiredBox))
+ if (LOT->RequiredBox == NO_VALUE || !StalkBox(item, enemy, LOT->RequiredBox))
{
boxNumber = LOT->Node[GetRandomControl() * LOT->ZoneCount >> 15].boxNumber;
if (ValidBox(item, AI->zoneNumber, boxNumber))
@@ -1693,7 +1693,7 @@ void CreatureMood(ItemInfo* item, AI_INFO* AI, bool isViolent)
{
TargetBox(LOT, boxNumber);
}
- else if (LOT->RequiredBox == NO_BOX)
+ else if (LOT->RequiredBox == NO_VALUE)
{
TargetBox(LOT, boxNumber);
if (AI->zoneNumber != AI->enemyZone)
@@ -1705,7 +1705,7 @@ void CreatureMood(ItemInfo* item, AI_INFO* AI, bool isViolent)
break;
}
- if (LOT->TargetBox == NO_BOX)
+ if (LOT->TargetBox == NO_VALUE)
TargetBox(LOT, item->BoxNumber);
#ifdef CREATURE_AI_PRIORITY_OPTIMIZATION
@@ -1749,10 +1749,10 @@ void CreatureMood(ItemInfo* item, AI_INFO* AI, bool isViolent)
creature->JumpAhead = false;
creature->MonkeySwingAhead = false;
- if (item->BoxNumber != NO_BOX)
+ if (item->BoxNumber != NO_VALUE)
{
int endBox = LOT->Node[item->BoxNumber].exitBox;
- if (endBox != NO_BOX)
+ if (endBox != NO_VALUE)
{
int overlapIndex = g_Level.Boxes[item->BoxNumber].overlapIndex;
int nextBox = 0;
@@ -1764,7 +1764,7 @@ void CreatureMood(ItemInfo* item, AI_INFO* AI, bool isViolent)
{
nextBox = g_Level.Overlaps[overlapIndex].box;
flags = g_Level.Overlaps[overlapIndex++].flags;
- } while (nextBox != NO_BOX && ((flags & BOX_END_BIT) == false) && (nextBox != endBox));
+ } while (nextBox != NO_VALUE && ((flags & BOX_END_BIT) == false) && (nextBox != endBox));
}
if (nextBox == endBox)
@@ -1788,15 +1788,15 @@ void GetCreatureMood(ItemInfo* item, AI_INFO* AI, bool isViolent)
auto* enemy = creature->Enemy;
auto* LOT = &creature->LOT;
- if (item->BoxNumber == NO_BOX || creature->LOT.Node[item->BoxNumber].searchNumber == (creature->LOT.SearchNumber | BLOCKED_SEARCH))
- creature->LOT.RequiredBox = NO_BOX;
+ if (item->BoxNumber == NO_VALUE || creature->LOT.Node[item->BoxNumber].searchNumber == (creature->LOT.SearchNumber | BLOCKED_SEARCH))
+ creature->LOT.RequiredBox = NO_VALUE;
- if (creature->Mood != MoodType::Attack && creature->LOT.RequiredBox != NO_BOX && !ValidBox(item, AI->zoneNumber, creature->LOT.TargetBox))
+ if (creature->Mood != MoodType::Attack && creature->LOT.RequiredBox != NO_VALUE && !ValidBox(item, AI->zoneNumber, creature->LOT.TargetBox))
{
if (AI->zoneNumber == AI->enemyZone)
creature->Mood = MoodType::Bored;
- creature->LOT.RequiredBox = NO_BOX;
+ creature->LOT.RequiredBox = NO_VALUE;
}
auto mood = creature->Mood;
@@ -1848,7 +1848,7 @@ void GetCreatureMood(ItemInfo* item, AI_INFO* AI, bool isViolent)
else if (AI->zoneNumber == AI->enemyZone)
{
if (AI->distance < ATTACK_RANGE ||
- (creature->Mood == MoodType::Stalk && LOT->RequiredBox == NO_BOX))
+ (creature->Mood == MoodType::Stalk && LOT->RequiredBox == NO_VALUE))
creature->Mood = MoodType::Attack;
else
creature->Mood = MoodType::Stalk;
@@ -1887,7 +1887,7 @@ void GetCreatureMood(ItemInfo* item, AI_INFO* AI, bool isViolent)
LOT = &creature->LOT;
}
- LOT->RequiredBox = NO_BOX;
+ LOT->RequiredBox = NO_VALUE;
}
}
@@ -1898,7 +1898,7 @@ TARGET_TYPE CalculateTarget(Vector3i* target, ItemInfo* item, LOTInfo* LOT)
*target = item->Pose.Position;
int boxNumber = item->BoxNumber;
- if (boxNumber == NO_BOX)
+ if (boxNumber == NO_VALUE)
return TARGET_TYPE::NO_TARGET;
auto* box = &g_Level.Boxes[boxNumber];
@@ -2096,9 +2096,9 @@ TARGET_TYPE CalculateTarget(Vector3i* target, ItemInfo* item, LOTInfo* LOT)
}
boxNumber = LOT->Node[boxNumber].exitBox;
- if (boxNumber != NO_BOX && (g_Level.Boxes[boxNumber].flags & LOT->BlockMask))
+ if (boxNumber != NO_VALUE && (g_Level.Boxes[boxNumber].flags & LOT->BlockMask))
break;
- } while (boxNumber != NO_BOX);
+ } while (boxNumber != NO_VALUE);
if (!(direction & SECONDARY_CLIP))
{
@@ -2157,7 +2157,7 @@ void InitializeItemBoxData()
continue;
auto* floor = &room.floor[index];
- if (floor->Box == NO_BOX)
+ if (floor->Box == NO_VALUE)
continue;
if (!(g_Level.Boxes[floor->Box].flags & BLOCKED))
diff --git a/TombEngine/Game/control/box.h b/TombEngine/Game/control/box.h
index 98e26ca1e..50ceb5142 100644
--- a/TombEngine/Game/control/box.h
+++ b/TombEngine/Game/control/box.h
@@ -60,8 +60,6 @@ constexpr auto BLOCKABLE = 0x8000;
constexpr auto BLOCKED = 0x4000;
constexpr auto SEARCH_NUMBER = 0x7FFF;
constexpr auto BLOCKED_SEARCH = 0x8000;
-constexpr auto NO_BOX = -1;
-constexpr auto NO_ZONE = -1;
constexpr auto BOX_JUMP = 0x800;
constexpr auto BOX_MONKEY = 0x2000;
constexpr auto BOX_END_BIT = 0x8000;
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index dc5f26866..f1a133a6d 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -44,6 +44,7 @@
#include "Objects/Generic/Object/objects.h"
#include "Objects/Generic/Object/rope.h"
#include "Objects/Generic/Switches/generic_switch.h"
+#include "Objects/TR3/Entity/FishSwarm.h"
#include "Objects/TR4/Entity/tr4_beetle_swarm.h"
#include "Objects/TR5/Emitter/tr5_bats_emitter.h"
#include "Objects/TR5/Emitter/tr5_rats_emitter.h"
@@ -85,6 +86,7 @@ using namespace TEN::Input;
using namespace TEN::Math;
using namespace TEN::Renderer;
using namespace TEN::Traps::TR5;
+using namespace TEN::Entities::Creatures::TR3;
int GameTimer = 0;
int GlobalCounter = 0;
@@ -232,6 +234,7 @@ GameStatus ControlPhase(int numFrames)
UpdateExplosionParticles();
UpdateShockwaves();
UpdateBeetleSwarm();
+ UpdateFishSwarm();
UpdateLocusts();
UpdateUnderwaterBloodParticles();
@@ -498,8 +501,8 @@ void DeInitializeScripting(int levelIndex, GameStatus reason)
void InitializeOrLoadGame(bool loadGame)
{
- g_Gui.SetInventoryItemChosen(NO_ITEM);
- g_Gui.SetEnterInventory(NO_ITEM);
+ g_Gui.SetInventoryItemChosen(NO_VALUE);
+ g_Gui.SetEnterInventory(NO_VALUE);
// Restore the game?
if (loadGame)
@@ -659,7 +662,7 @@ GameStatus HandleMenuCalls(bool isTitle)
if (g_Gui.CallPause())
result = GameStatus::ExitToTitle;
}
- else if ((IsClicked(In::Inventory) || g_Gui.GetEnterInventory() != NO_ITEM) &&
+ else if ((IsClicked(In::Inventory) || g_Gui.GetEnterInventory() != NO_VALUE) &&
LaraItem->HitPoints > 0 && !Lara.Control.Look.IsUsingBinoculars)
{
if (g_Gui.CallInventory(LaraItem, true))
diff --git a/TombEngine/Game/control/flipeffect.cpp b/TombEngine/Game/control/flipeffect.cpp
index 32e5a683b..b128351a8 100644
--- a/TombEngine/Game/control/flipeffect.cpp
+++ b/TombEngine/Game/control/flipeffect.cpp
@@ -18,14 +18,17 @@
#include "Sound/sound.h"
#include "Specific/level.h"
#include "Objects/Generic/puzzles_keys.h"
+#include "Objects/TR3/Entity/FishSwarm.h"
#include "Objects/TR4/Entity/tr4_beetle_swarm.h"
#include "Objects/TR5/Emitter/tr5_spider_emitter.h"
#include "Objects/TR5/Emitter/tr5_rats_emitter.h"
#include "Objects/Effects/tr4_locusts.h"
+
using namespace TEN::Effects::Environment;
using namespace TEN::Effects::Footprint;
using namespace TEN::Effects::Hair;
+using namespace TEN::Entities::Creatures::TR3;
int FlipEffect;
@@ -86,6 +89,7 @@ void ClearSwarmEnemies(ItemInfo* item)
ClearRats();
ClearBeetleSwarm();
ClearLocusts();
+ ClearFishSwarm();
}
void FlashOrange(ItemInfo* item)
@@ -203,7 +207,7 @@ void LaraHandsFree(ItemInfo* item)
void KillActiveBaddys(ItemInfo* item)
{
- if (NextItemActive != NO_ITEM)
+ if (NextItemActive != NO_VALUE)
{
short itemNumber = NextItemActive;
@@ -224,7 +228,7 @@ void KillActiveBaddys(ItemInfo* item)
}
itemNumber = targetItem->NextActive;
- } while (itemNumber != NO_ITEM);
+ } while (itemNumber != NO_VALUE);
}
FlipEffect = -1;
diff --git a/TombEngine/Game/control/los.cpp b/TombEngine/Game/control/los.cpp
index 870b12262..2c0ea4ec6 100644
--- a/TombEngine/Game/control/los.cpp
+++ b/TombEngine/Game/control/los.cpp
@@ -326,7 +326,7 @@ bool GetTargetOnLOS(GameVector* origin, GameVector* target, bool drawTarget, boo
int num = GetSpheres(item, CreatureSpheres, SPHERES_SPACE_WORLD, Matrix::Identity);
auto ray = Ray(origin->ToVector3(), dir);
float bestDistance = INFINITY;
- int bestJointIndex = NO_JOINT;
+ int bestJointIndex = NO_VALUE;
for (int i = 0; i < num; i++)
{
@@ -361,11 +361,11 @@ bool GetTargetOnLOS(GameVector* origin, GameVector* target, bool drawTarget, boo
const auto& weapon = Weapons[(int)Lara.Control.Weapon.GunType];
if (object->HitRoutine != nullptr)
{
- object->HitRoutine(*item, *LaraItem, target2, weapon.Damage, false, NO_JOINT);
+ object->HitRoutine(*item, *LaraItem, target2, weapon.Damage, false, NO_VALUE);
}
else
{
- DefaultItemHit(*item, *LaraItem, target2, weapon.Damage, false, NO_JOINT);
+ DefaultItemHit(*item, *LaraItem, target2, weapon.Damage, false, NO_VALUE);
}
}
}
@@ -668,7 +668,7 @@ int ObjectOnLOS2(GameVector* origin, GameVector* target, Vector3i* vec, MESH_INF
}
}
- for (short linkNumber = room.itemNumber; linkNumber != NO_ITEM; linkNumber = g_Level.Items[linkNumber].NextItem)
+ for (short linkNumber = room.itemNumber; linkNumber != NO_VALUE; linkNumber = g_Level.Items[linkNumber].NextItem)
{
const auto& item = g_Level.Items[linkNumber];
diff --git a/TombEngine/Game/control/lot.cpp b/TombEngine/Game/control/lot.cpp
index 9f125f49d..01dc1f065 100644
--- a/TombEngine/Game/control/lot.cpp
+++ b/TombEngine/Game/control/lot.cpp
@@ -51,7 +51,7 @@ void DisableEntityAI(short itemNumber)
return;
auto* creature = GetCreatureInfo(item);
- creature->ItemNumber = NO_ITEM;
+ creature->ItemNumber = NO_VALUE;
KillItem(creature->AITargetNumber);
ActiveCreatures.erase(std::find(ActiveCreatures.begin(), ActiveCreatures.end(), creature));
item->Data = nullptr;
@@ -90,13 +90,13 @@ void InitializeSlot(short itemNumber, bool makeTarget)
creature->LOT.IsMonkeying = false;
creature->LOT.Fly = NO_FLYING;
creature->LOT.BlockMask = BLOCKED;
- creature->AITargetNumber = NO_ITEM;
+ creature->AITargetNumber = NO_VALUE;
creature->AITarget = nullptr;
if (makeTarget)
{
creature->AITargetNumber = CreateItem();
- if (creature->AITargetNumber != NO_ITEM)
+ if (creature->AITargetNumber != NO_VALUE)
creature->AITarget = &g_Level.Items[creature->AITargetNumber];
}
@@ -212,7 +212,7 @@ void SetEntityTarget(short itemNum, short target)
creature->AITargetNumber = target;
- if (creature->AITargetNumber != NO_ITEM)
+ if (creature->AITargetNumber != NO_VALUE)
creature->AITarget = &g_Level.Items[creature->AITargetNumber];
else
creature->AITarget = nullptr;
@@ -220,17 +220,17 @@ void SetEntityTarget(short itemNum, short target)
void ClearLOT(LOTInfo* LOT)
{
- LOT->Head = NO_BOX;
- LOT->Tail = NO_BOX;
+ LOT->Head = NO_VALUE;
+ LOT->Tail = NO_VALUE;
LOT->SearchNumber = 0;
- LOT->TargetBox = NO_BOX;
- LOT->RequiredBox = NO_BOX;
+ LOT->TargetBox = NO_VALUE;
+ LOT->RequiredBox = NO_VALUE;
auto* node = LOT->Node.data();
for (auto& node : LOT->Node)
{
- node.exitBox = NO_BOX;
- node.nextExpansion = NO_BOX;
+ node.exitBox = NO_VALUE;
+ node.nextExpansion = NO_VALUE;
node.searchNumber = 0;
}
}
diff --git a/TombEngine/Game/control/trigger.cpp b/TombEngine/Game/control/trigger.cpp
index 0fc94666b..d34c99d97 100644
--- a/TombEngine/Game/control/trigger.cpp
+++ b/TombEngine/Game/control/trigger.cpp
@@ -308,15 +308,15 @@ void RefreshCamera(short type, short* data)
if (!targetOk || (targetOk == 2 && Camera.item->LookedAt && Camera.item != Camera.lastItem))
Camera.item = nullptr;
- if (Camera.number == -1 && Camera.timer > 0)
- Camera.timer = -1;
+ if (Camera.number == NO_VALUE && Camera.timer > 0)
+ Camera.timer = NO_VALUE;
}
short* GetTriggerIndex(FloorInfo* floor, int x, int y, int z)
{
const auto& bottomSector = GetPointCollision(Vector3i(x, y, z), floor->RoomNumber).GetBottomSector();
- if (bottomSector.TriggerIndex == -1)
+ if (bottomSector.TriggerIndex == NO_VALUE)
return nullptr;
return &g_Level.FloorData[bottomSector.TriggerIndex];
@@ -324,7 +324,7 @@ short* GetTriggerIndex(FloorInfo* floor, int x, int y, int z)
short* GetTriggerIndex(ItemInfo* item)
{
- auto roomNumber = item->RoomNumber;
+ short roomNumber = item->RoomNumber;
auto floor = GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &roomNumber);
return GetTriggerIndex(floor, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z);
}
@@ -823,7 +823,7 @@ void TestTriggers(int x, int y, int z, FloorInfo* floor, Activator activator, bo
void TestTriggers(ItemInfo* item, bool isHeavy, int heavyFlags)
{
- auto roomNumber = item->RoomNumber;
+ short roomNumber = item->RoomNumber;
auto floor = GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &roomNumber);
TestTriggers(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, floor, item->Index, isHeavy, heavyFlags);
@@ -844,36 +844,42 @@ void TestTriggers(int x, int y, int z, short roomNumber, bool heavy, int heavyFl
void ProcessSectorFlags(ItemInfo* item)
{
auto pointColl = GetPointCollision(*item);
- auto* sectorPtr = &GetPointCollision(*item).GetBottomSector();
+ auto& sector = GetPointCollision(*item).GetBottomSector();
bool isPlayer = item->IsLara();
- // Monkeyswing and climb (only for Lara)
+ // Set monkeyswing and wall climb statuses for player.
if (isPlayer)
{
- auto* lara = GetLaraInfo(item);
+ auto& player = GetLaraInfo(*item);
- // Set climb status
- if (TestLaraNearClimbableWall(item, sectorPtr))
- lara->Control.CanClimbLadder = true;
+ // Set wall climb status.
+ if (TestLaraNearClimbableWall(item, §or))
+ {
+ player.Control.CanClimbLadder = true;
+ }
else
- lara->Control.CanClimbLadder = false;
+ {
+ player.Control.CanClimbLadder = false;
+ }
- // Set monkeyswing status
- lara->Control.CanMonkeySwing = sectorPtr->Flags.Monkeyswing;
+ // Set monkey swing status.
+ player.Control.CanMonkeySwing = sector.Flags.Monkeyswing;
}
- // Burn or drown item
- if (sectorPtr->Flags.Death && item->Pose.Position.y == item->Floor)
+ // Burn or drown item.
+ if (sector.Flags.Death && item->Pose.Position.y == item->Floor && pointColl.GetFloorBridgeItemNumber() == NO_VALUE)
{
if (isPlayer)
{
+ const auto& player = GetLaraInfo(*item);
+
if (!IsJumpState((LaraState)item->Animation.ActiveState) ||
- GetLaraInfo(item)->Control.WaterStatus != WaterStatus::Dry)
+ player.Control.WaterStatus != WaterStatus::Dry)
{
- // To allow both lava and rapids in same level, also check floor material flag.
- if (sectorPtr->GetSurfaceMaterial(pointColl.GetPosition().x, pointColl.GetPosition().z, true) == MaterialType::Water &&
- Objects[ID_KAYAK_LARA_ANIMS].loaded)
+ // Check floor material.
+ auto material = sector.GetSurfaceMaterial(pointColl.GetPosition().x, pointColl.GetPosition().z, true);
+ if (material == MaterialType::Water && Objects[ID_KAYAK_LARA_ANIMS].loaded) // HACK: Allow both lava and rapids in same level.
{
KayakLaraRapidsDrown(item);
}
@@ -885,10 +891,11 @@ void ProcessSectorFlags(ItemInfo* item)
}
else if (Objects[item->ObjectNumber].intelligent && item->HitPoints != NOT_TARGETABLE)
{
- if (sectorPtr->GetSurfaceMaterial(pointColl.GetPosition().x, pointColl.GetPosition().z, true) == MaterialType::Water ||
- TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, sectorPtr->RoomNumber))
+ auto material = sector.GetSurfaceMaterial(pointColl.GetPosition().x, pointColl.GetPosition().z, true);
+ if (material == MaterialType::Water || TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, sector.RoomNumber))
{
- DoDamage(item, INT_MAX); // TODO: Implement correct rapids behaviour for other objects!
+ // TODO: Implement correct rapids behaviour for other objects.
+ DoDamage(item, INT_MAX);
}
else
{
diff --git a/TombEngine/Game/effects/tomb4fx.cpp b/TombEngine/Game/effects/tomb4fx.cpp
index 8d0cea30b..2d128dc87 100644
--- a/TombEngine/Game/effects/tomb4fx.cpp
+++ b/TombEngine/Game/effects/tomb4fx.cpp
@@ -1212,7 +1212,7 @@ void ExplodingDeath(short itemNumber, short flags)
if (i == 0 || ((GetRandomControl() & 3) != 0 && (flags & BODY_DO_EXPLOSION)))
{
short fxNumber = CreateNewEffect(item->RoomNumber);
- if (fxNumber != NO_ITEM)
+ if (fxNumber != NO_VALUE)
{
FX_INFO* fx = &EffectList[fxNumber];
diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp
index 4895796be..06635e097 100644
--- a/TombEngine/Game/gui.cpp
+++ b/TombEngine/Game/gui.cpp
@@ -1547,7 +1547,7 @@ namespace TEN::Gui
Rings[(int)RingTypes::Inventory].NumObjectsInList = 0;
for (int i = 0; i < INVENTORY_TABLE_SIZE; i++)
- Rings[(int)RingTypes::Inventory].CurrentObjectList[i].InventoryItem = NO_ITEM;
+ Rings[(int)RingTypes::Inventory].CurrentObjectList[i].InventoryItem = NO_VALUE;
Ammo.CurrentPistolsAmmoType = 0;
Ammo.CurrentUziAmmoType = 0;
@@ -1783,7 +1783,7 @@ namespace TEN::Gui
Rings[(int)RingTypes::Ammo].NumObjectsInList = 0;
for (int i = 0; i < INVENTORY_TABLE_SIZE; i++)
- Rings[(int)RingTypes::Ammo].CurrentObjectList[i].InventoryItem = NO_ITEM;
+ Rings[(int)RingTypes::Ammo].CurrentObjectList[i].InventoryItem = NO_VALUE;
if (!(g_GameFlow->GetLevel(CurrentLevel)->GetLaraType() == LaraType::Young))
{
@@ -1866,7 +1866,7 @@ namespace TEN::Gui
{
g_Gui.SetMenuToDisplay(Menu::Title);
g_Gui.SetSelectedOption(0);
- g_Gui.SetLastInventoryItem(NO_ITEM);
+ g_Gui.SetLastInventoryItem(NO_VALUE);
}
void GuiController::InitializeInventory(ItemInfo* item)
@@ -1875,7 +1875,7 @@ namespace TEN::Gui
AlterFOV(ANGLE(DEFAULT_FOV), false);
lara->Inventory.IsBusy = false;
- InventoryItemChosen = NO_ITEM;
+ InventoryItemChosen = NO_VALUE;
UseItem = false;
if (lara->Weapons[(int)LaraWeaponType::Shotgun].Ammo[0].HasInfinite())
@@ -1912,9 +1912,9 @@ namespace TEN::Gui
Ammo.AmountGrenadeAmmo3 = lara->Weapons[(int)LaraWeaponType::GrenadeLauncher].Ammo[(int)WeaponAmmoType::Ammo3].HasInfinite() ? -1 : lara->Weapons[(int)LaraWeaponType::GrenadeLauncher].Ammo[(int)WeaponAmmoType::Ammo3].GetCount();
ConstructObjectList(item);
- if (EnterInventory == NO_ITEM)
+ if (EnterInventory == NO_VALUE)
{
- if (LastInvItem != NO_ITEM)
+ if (LastInvItem != NO_VALUE)
{
if (IsItemInInventory(LastInvItem))
{
@@ -1946,7 +1946,7 @@ namespace TEN::Gui
}
else
{
- LastInvItem = NO_ITEM;
+ LastInvItem = NO_VALUE;
}
}
}
@@ -3385,7 +3385,7 @@ namespace TEN::Gui
if (UseItem && NoAction())
exitLoop = true;
- SetEnterInventory(NO_ITEM);
+ SetEnterInventory(NO_VALUE);
Camera.numberFrames = g_Renderer.Synchronize();
}
diff --git a/TombEngine/Game/items.cpp b/TombEngine/Game/items.cpp
index 267a4fbb7..a74c65c6e 100644
--- a/TombEngine/Game/items.cpp
+++ b/TombEngine/Game/items.cpp
@@ -36,7 +36,7 @@ using namespace TEN::Input;
using namespace TEN::Math;
using namespace TEN::Utils;
-constexpr int ITEM_DEATH_TIMEOUT = 4 * FPS;
+constexpr auto ITEM_DEATH_TIMEOUT = 4 * FPS;
bool ItemInfo::TestOcb(short ocbFlags) const
{
@@ -82,7 +82,7 @@ void ItemInfo::SetFlagField(int id, short flags)
if (id < 0 || id > 7)
return;
- this->ItemFlags[id] = flags;
+ ItemFlags[id] = flags;
}
void ItemInfo::ClearFlags(int id, short flags)
@@ -90,7 +90,7 @@ void ItemInfo::ClearFlags(int id, short flags)
if (id < 0 || id > 7)
return;
- this->ItemFlags[id] &= ~flags;
+ ItemFlags[id] &= ~flags;
}
bool ItemInfo::TestMeshSwapFlags(unsigned int flags)
@@ -109,7 +109,7 @@ bool ItemInfo::TestMeshSwapFlags(unsigned int flags)
bool ItemInfo::TestMeshSwapFlags(const std::vector& flags)
{
- auto bits = BitField();
+ auto bits = BitField::Default;
bits.Set(flags);
return TestMeshSwapFlags(bits.ToPackedBits());
}
@@ -146,21 +146,6 @@ void ItemInfo::SetMeshSwapFlags(const std::vector& flags, bool cle
SetMeshSwapFlags(bits.ToPackedBits(), clear);
}
-bool ItemInfo::IsLara() const
-{
- return Data.is();
-}
-
-bool ItemInfo::IsCreature() const
-{
- return Data.is();
-}
-
-bool ItemInfo::IsBridge() const
-{
- return Contains(BRIDGE_OBJECT_IDS, ObjectNumber);
-}
-
void ItemInfo::ResetModelToDefault()
{
if (Objects[ObjectNumber].nmeshes > 0)
@@ -182,6 +167,21 @@ void ItemInfo::ResetModelToDefault()
}
}
+bool ItemInfo::IsLara() const
+{
+ return Data.is();
+}
+
+bool ItemInfo::IsCreature() const
+{
+ return Data.is();
+}
+
+bool ItemInfo::IsBridge() const
+{
+ return Contains(BRIDGE_OBJECT_IDS, ObjectNumber);
+}
+
bool TestState(int refState, const std::vector& stateList)
{
for (const auto& state : stateList)
@@ -219,7 +219,7 @@ void KillItem(short const itemNumber)
ItemNewRooms[2 * ItemNewRoomNo] = itemNumber | 0x8000;
ItemNewRoomNo++;
}
- else// if (NextItemActive != NO_ITEM)
+ else// if (NextItemActive != NO_VALUE)
{
auto* item = &g_Level.Items[itemNumber];
@@ -233,7 +233,7 @@ void KillItem(short const itemNumber)
else
{
short linkNumber;
- for (linkNumber = NextItemActive; linkNumber != NO_ITEM; linkNumber = g_Level.Items[linkNumber].NextActive)
+ for (linkNumber = NextItemActive; linkNumber != NO_VALUE; linkNumber = g_Level.Items[linkNumber].NextActive)
{
if (g_Level.Items[linkNumber].NextActive == itemNumber)
{
@@ -252,7 +252,7 @@ void KillItem(short const itemNumber)
else
{
short linkNumber;
- for (linkNumber = g_Level.Rooms[item->RoomNumber].itemNumber; linkNumber != NO_ITEM; linkNumber = g_Level.Items[linkNumber].NextItem)
+ for (linkNumber = g_Level.Rooms[item->RoomNumber].itemNumber; linkNumber != NO_VALUE; linkNumber = g_Level.Items[linkNumber].NextItem)
{
if (g_Level.Items[linkNumber].NextItem == itemNumber)
{
@@ -290,7 +290,7 @@ void RemoveAllItemsInRoom(short roomNumber, short objectNumber)
auto* room = &g_Level.Rooms[roomNumber];
short currentItemNumber = room->itemNumber;
- while (currentItemNumber != NO_ITEM)
+ while (currentItemNumber != NO_VALUE)
{
auto* item = &g_Level.Items[currentItemNumber];
@@ -410,7 +410,7 @@ void KillEffect(short fxNumber)
NextFxActive = fx->nextActive;
else
{
- for (short linkNumber = NextFxActive; linkNumber != NO_ITEM; linkNumber = EffectList[linkNumber].nextActive)
+ for (short linkNumber = NextFxActive; linkNumber != NO_VALUE; linkNumber = EffectList[linkNumber].nextActive)
{
if (EffectList[linkNumber].nextActive == fxNumber)
{
@@ -424,7 +424,7 @@ void KillEffect(short fxNumber)
g_Level.Rooms[fx->roomNumber].fxNumber = fx->nextFx;
else
{
- for (short linkNumber = g_Level.Rooms[fx->roomNumber].fxNumber; linkNumber != NO_ITEM; linkNumber = EffectList[linkNumber].nextFx)
+ for (short linkNumber = g_Level.Rooms[fx->roomNumber].fxNumber; linkNumber != NO_VALUE; linkNumber = EffectList[linkNumber].nextFx)
{
if (EffectList[linkNumber].nextFx == fxNumber)
{
@@ -441,7 +441,7 @@ void KillEffect(short fxNumber)
// HACK: Garbage collect nextFx if no active effects were detected.
// This fixes random crashes after spawining multiple FXs (like body part).
- if (NextFxActive == NO_ITEM)
+ if (NextFxActive == NO_VALUE)
InitializeFXArray();
}
@@ -449,7 +449,7 @@ short CreateNewEffect(short roomNumber)
{
short fxNumber = NextFxFree;
- if (NextFxFree != NO_ITEM)
+ if (NextFxFree != NO_VALUE)
{
auto* fx = &EffectList[NextFxFree];
NextFxFree = fx->nextFx;
@@ -469,7 +469,7 @@ short CreateNewEffect(short roomNumber)
void InitializeFXArray()
{
- NextFxActive = NO_ITEM;
+ NextFxActive = NO_VALUE;
NextFxFree = 0;
for (int i = 0; i < NUM_EFFECTS; i++)
@@ -478,7 +478,7 @@ void InitializeFXArray()
fx->nextFx = i + 1;
}
- EffectList[NUM_EFFECTS - 1].nextFx = NO_ITEM;
+ EffectList[NUM_EFFECTS - 1].nextFx = NO_VALUE;
}
void RemoveDrawnItem(short itemNumber)
@@ -489,7 +489,7 @@ void RemoveDrawnItem(short itemNumber)
g_Level.Rooms[item->RoomNumber].itemNumber = item->NextItem;
else
{
- for (short linkNumber = g_Level.Rooms[item->RoomNumber].itemNumber; linkNumber != NO_ITEM; linkNumber = g_Level.Items[linkNumber].NextItem)
+ for (short linkNumber = g_Level.Rooms[item->RoomNumber].itemNumber; linkNumber != NO_VALUE; linkNumber = g_Level.Items[linkNumber].NextItem)
{
if (g_Level.Items[linkNumber].NextItem == itemNumber)
{
@@ -512,7 +512,7 @@ void RemoveActiveItem(short itemNumber, bool killed)
}
else
{
- for (short linkNumber = NextItemActive; linkNumber != NO_ITEM; linkNumber = g_Level.Items[linkNumber].NextActive)
+ for (short linkNumber = NextItemActive; linkNumber != NO_VALUE; linkNumber = g_Level.Items[linkNumber].NextActive)
{
if (g_Level.Items[linkNumber].NextActive == itemNumber)
{
@@ -532,10 +532,10 @@ void InitializeItem(short itemNumber)
auto* item = &g_Level.Items[itemNumber];
SetAnimation(item, 0);
- item->Animation.RequiredState = NO_STATE;
+ item->Animation.RequiredState = NO_VALUE;
item->Animation.Velocity = Vector3::Zero;
- for (int i = 0; i < NUM_ITEM_FLAGS; i++)
+ for (int i = 0; i < ITEM_FLAG_COUNT; i++)
item->ItemFlags[i] = 0;
item->Active = false;
@@ -596,8 +596,8 @@ void InitializeItem(short itemNumber)
short CreateItem()
{
- if (NextItemFree == NO_ITEM)
- return NO_ITEM;
+ if (NextItemFree == NO_VALUE)
+ return NO_VALUE;
short itemNumber = NextItemFree;
g_Level.Items[NextItemFree].Flags = 0;
@@ -626,15 +626,15 @@ void InitializeItemArray(int totalItem)
}
}
- item->NextItem = NO_ITEM;
- NextItemActive = NO_ITEM;
+ item->NextItem = NO_VALUE;
+ NextItemActive = NO_VALUE;
NextItemFree = g_Level.NumItems;
}
short SpawnItem(const ItemInfo& item, GAME_OBJECT_ID objectID)
{
int itemNumber = CreateItem();
- if (itemNumber != NO_ITEM)
+ if (itemNumber != NO_VALUE)
{
auto& newItem = g_Level.Items[itemNumber];
@@ -650,7 +650,7 @@ short SpawnItem(const ItemInfo& item, GAME_OBJECT_ID objectID)
else
{
TENLog("Failed to create new item.", LogLevel::Warning);
- itemNumber = NO_ITEM;
+ itemNumber = NO_VALUE;
}
return itemNumber;
@@ -663,7 +663,7 @@ int GlobalItemReplace(short search, GAME_OBJECT_ID replace)
{
auto* room = &g_Level.Rooms[i];
- for (short itemNumber = room->itemNumber; itemNumber != NO_ITEM; itemNumber = g_Level.Items[itemNumber].NextItem)
+ for (short itemNumber = room->itemNumber; itemNumber != NO_VALUE; itemNumber = g_Level.Items[itemNumber].NextItem)
{
if (g_Level.Items[itemNumber].ObjectNumber == search)
{
@@ -705,12 +705,12 @@ std::vector FindCreatedItems(GAME_OBJECT_ID objectID)
{
auto itemNumbers = std::vector{};
- if (NextItemActive == NO_ITEM)
+ if (NextItemActive == NO_VALUE)
return itemNumbers;
const auto* itemPtr = &g_Level.Items[NextItemActive];
- for (int nextActive = NextItemActive; nextActive != NO_ITEM; nextActive = itemPtr->NextActive)
+ for (int nextActive = NextItemActive; nextActive != NO_VALUE; nextActive = itemPtr->NextActive)
{
itemPtr = &g_Level.Items[nextActive];
@@ -751,7 +751,7 @@ void UpdateAllItems()
InItemControlLoop = true;
short itemNumber = NextItemActive;
- while (itemNumber != NO_ITEM)
+ while (itemNumber != NO_VALUE)
{
auto* item = &g_Level.Items[itemNumber];
short nextItem = item->NextActive;
@@ -787,7 +787,7 @@ void UpdateAllEffects()
InItemControlLoop = true;
short fxNumber = NextFxActive;
- while (fxNumber != NO_ITEM)
+ while (fxNumber != NO_VALUE)
{
short nextFx = EffectList[fxNumber].nextActive;
auto* fx = &EffectList[fxNumber];
diff --git a/TombEngine/Game/items.h b/TombEngine/Game/items.h
index e64453681..cda9aafee 100644
--- a/TombEngine/Game/items.h
+++ b/TombEngine/Game/items.h
@@ -1,56 +1,20 @@
#pragma once
-#include
-#include
-#include
-
#include "Game/animation.h"
#include "Game/itemdata/itemdata.h"
-#include "Objects/game_object_ids.h"
#include "Math/Math.h"
-#include "Specific/newtypes.h"
#include "Specific/BitField.h"
+#include "Objects/game_object_ids.h"
+#include "Specific/newtypes.h"
using namespace TEN::Utils;
-constexpr auto NO_ITEM = -1;
-constexpr auto NOT_TARGETABLE = -16384;
+constexpr auto ITEM_COUNT_MAX = 1024;
+constexpr auto ITEM_FLAG_COUNT = 8;
-constexpr auto NUM_ITEMS = 1024;
-constexpr auto NUM_ITEM_FLAGS = 8;
+constexpr auto NOT_TARGETABLE = SHRT_MIN / 2;
-constexpr unsigned int ALL_JOINT_BITS = UINT_MAX;
-constexpr unsigned int NO_JOINT_BITS = 0;
-constexpr int NO_JOINT = -1;
-
-enum AIObjectType
-{
- NO_AI = 0,
- GUARD = (1 << 0),
- AMBUSH = (1 << 1),
- PATROL1 = (1 << 2),
- MODIFY = (1 << 3),
- FOLLOW = (1 << 4),
- PATROL2 = (1 << 5),
- ALL_AIOBJ = (GUARD | AMBUSH | PATROL1 | MODIFY | FOLLOW | PATROL2)
-};
-
-enum ItemStatus
-{
- ITEM_NOT_ACTIVE = 0,
- ITEM_ACTIVE = 1,
- ITEM_DEACTIVATED = 2,
- ITEM_INVISIBLE = 3
-};
-
-enum ItemFlags
-{
- IFLAG_TRIGGERED = (1 << 5),
- IFLAG_CLEAR_BODY = (1 << 7),
- IFLAG_INVISIBLE = (1 << 8),
- IFLAG_ACTIVATION_MASK = (0x1F << 9), // Bits 9-13 (IFLAG_CODEBITS)
- IFLAG_REVERSE = (1 << 14),
- IFLAG_KILLED = (1 << 15)
-};
+constexpr auto ALL_JOINT_BITS = UINT_MAX;
+constexpr auto NO_JOINT_BITS = 0u;
enum class EffectType
{
@@ -63,6 +27,36 @@ enum class EffectType
Custom
};
+enum ItemStatus
+{
+ ITEM_NOT_ACTIVE = 0,
+ ITEM_ACTIVE = 1,
+ ITEM_DEACTIVATED = 2,
+ ITEM_INVISIBLE = 3
+};
+
+enum ItemFlags
+{
+ IFLAG_TRIGGERED = 1 << 5,
+ IFLAG_CLEAR_BODY = 1 << 7,
+ IFLAG_INVISIBLE = 1 << 8,
+ IFLAG_ACTIVATION_MASK = 0x1F << 9, // Bits 9-13 (IFLAG_CODEBITS)
+ IFLAG_REVERSE = 1 << 14,
+ IFLAG_KILLED = 1 << 15
+};
+
+enum AIObjectType
+{
+ NO_AI = 0,
+ GUARD = 1 << 0,
+ AMBUSH = 1 << 1,
+ PATROL1 = 1 << 2,
+ MODIFY = 1 << 3,
+ FOLLOW = 1 << 4,
+ PATROL2 = 1 << 5,
+ ALL_AIOBJ = GUARD | AMBUSH | PATROL1 | MODIFY | FOLLOW | PATROL2
+};
+
struct EntityAnimationData
{
GAME_OBJECT_ID AnimObjectID = ID_NO_OBJECT;
@@ -71,28 +65,23 @@ struct EntityAnimationData
int FrameNumber = 0; // g_Level.Frames index.
int ActiveState = 0;
int TargetState = 0;
- int RequiredState = NO_STATE;
+ int RequiredState = NO_VALUE;
- bool IsAirborne = false;
- Vector3 Velocity = Vector3::Zero; // CONVENTION: +X = Right, +Y = Down, +Z = Forward
-};
+ // TODO: Have 3 velocity members:
+ // ControlVelocity: relative velocity derived from animation.
+ // ExtraControlVelocity: relative velocity set by code (used to control swimming, falling).
+ // ExternalVelocity: absolute velocity set by environment (slippery ice, offset blending).
+ Vector3 Velocity = Vector3::Zero; // CONVENTION: +X = Right, +Y = Down, +Z = Forward.
-struct EntityModelData
-{
- int BaseMesh = 0;
-
- Vector4 Color = Vector4::Zero;
-
- std::vector MeshIndex = {};
- std::vector Mutators = {};
+ bool IsAirborne = false;
};
struct EntityCallbackData
{
- std::string OnKilled;
- std::string OnHit;
- std::string OnObjectCollided;
- std::string OnRoomCollided;
+ std::string OnKilled = {};
+ std::string OnHit = {};
+ std::string OnObjectCollided = {};
+ std::string OnRoomCollided = {};
};
struct EntityEffectData
@@ -101,75 +90,88 @@ struct EntityEffectData
Vector3 LightColor = Vector3::Zero;
Vector3 PrimaryEffectColor = Vector3::Zero;
Vector3 SecondaryEffectColor = Vector3::Zero;
- int Count = -1;
+ int Count = NO_VALUE;
+};
+
+struct EntityModelData
+{
+ int BaseMesh = 0;
+
+ std::vector MeshIndex = {};
+ std::vector Mutators = {};
+
+ Vector4 Color = Vector4::Zero;
};
-// TODO: We need to find good "default states" for a lot of these. -- squidshire 25/05/2022
struct ItemInfo
{
- GAME_OBJECT_ID ObjectNumber = ID_NO_OBJECT; // ObjectID
std::string Name = {};
+ int Index = 0; // ItemNumber // TODO: Make int.
+ GAME_OBJECT_ID ObjectNumber = ID_NO_OBJECT; // ObjectID
- int Status; // ItemStatus enum.
- bool Active;
+ /*ItemStatus*/int Status = ITEM_NOT_ACTIVE;
+ bool Active = false;
- short Index;
- short NextItem;
- short NextActive;
+ // TODO: Refactor linked list.
+ int NextItem = 0;
+ int NextActive = 0;
- ItemData Data;
- EntityAnimationData Animation;
- EntityCallbackData Callbacks;
- EntityModelData Model;
- EntityEffectData Effect;
-
- Pose StartPose;
- Pose Pose;
- RoomVector Location;
- short RoomNumber;
- int Floor;
+ ItemData Data = {};
+ EntityAnimationData Animation = {};
+ EntityCallbackData Callbacks = {};
+ EntityEffectData Effect = {};
+ EntityModelData Model = {};
- int HitPoints;
- bool HitStatus;
- bool LookedAt;
- bool Collidable;
- bool InDrawRoom;
+ Pose StartPose = Pose::Zero;
+ Pose Pose = Pose::Zero;
+ RoomVector Location = {}; // NOTE: Describes vertical position in room.
+ short RoomNumber = 0; // TODO: Make int.
+ int Floor = 0;
- int BoxNumber;
- int Timer;
+ int HitPoints = 0;
+ bool HitStatus = false;
+ bool LookedAt = false;
+ bool Collidable = false;
+ bool InDrawRoom = false;
- BitField TouchBits = BitField::Default;
- BitField MeshBits = BitField::Default;
+ int BoxNumber = 0;
+ int Timer = 0;
- unsigned short Flags; // ItemFlags enum
- short ItemFlags[NUM_ITEM_FLAGS];
- short TriggerFlags;
+ BitField TouchBits = BitField::Default; // TouchFlags
+ BitField MeshBits = BitField::Default; // MeshFlags
+
+ std::array ItemFlags = {};
+ unsigned short Flags = 0; // ItemFlags enum
+ short TriggerFlags = 0;
// TODO: Move to CreatureInfo?
- unsigned char AIBits; // AIObjectType enum.
- short AfterDeath;
- short CarriedItem;
+ unsigned char AIBits = 0; // AIObjectFlags enum.
+ short AfterDeath = 0;
+ short CarriedItem = 0;
+ // OCB utilities
bool TestOcb(short ocbFlags) const;
void RemoveOcb(short ocbFlags);
void ClearAllOcb();
-
+
+ // ItemFlags utilities
bool TestFlags(int id, short flags) const; // ItemFlags[id] & flags
bool TestFlagField(int id, short flags) const; // ItemFlags[id] == flags
short GetFlagField(int id) const; // ItemFlags[id]
void SetFlagField(int id, short flags); // ItemFlags[id] = flags
void ClearFlags(int id, short flags); // ItemFlags[id] &= ~flags
+ // Model utilities
bool TestMeshSwapFlags(unsigned int flags);
bool TestMeshSwapFlags(const std::vector& flags);
void SetMeshSwapFlags(unsigned int flags, bool clear = false);
void SetMeshSwapFlags(const std::vector& flags, bool clear = false);
+ void ResetModelToDefault();
+ // Inquirers
bool IsLara() const;
bool IsCreature() const;
bool IsBridge() const;
-
- void ResetModelToDefault();
};
bool TestState(int refState, const std::vector& stateList);
diff --git a/TombEngine/Game/misc.cpp b/TombEngine/Game/misc.cpp
index 1160bbbec..3f5af7186 100644
--- a/TombEngine/Game/misc.cpp
+++ b/TombEngine/Game/misc.cpp
@@ -2,13 +2,14 @@
#include "Game/misc.h"
#include "Game/animation.h"
+#include "Game/collision/Point.h"
#include "Game/Lara/lara.h"
#include "Game/itemdata/creature_info.h"
#include "Game/items.h"
#include "Game/Setup.h"
#include "Specific/level.h"
-using std::vector;
+using namespace TEN::Collision::Point;
CreatureInfo* GetCreatureInfo(ItemInfo* item)
{
@@ -39,3 +40,91 @@ void TargetNearestEntity(ItemInfo* item, CreatureInfo* creature)
}
}
}
+
+bool IsNextSectorValid(const ItemInfo& item, const Vector3& dir, float dist)
+{
+ auto projectedPos = Geometry::TranslatePoint(item.Pose.Position, dir, dist);
+ auto pointColl = GetPointCollision(item.Pose.Position, item.RoomNumber, dir, dist);
+ int height = GameBoundingBox(&item).GetHeight();
+
+ // TODO: Use floor normal directly.
+ auto floorTilt = GetSurfaceTilt(pointColl.GetFloorNormal(), true);
+
+ // Test for wall.
+ if (pointColl.GetSector().IsWall(projectedPos.x, projectedPos.z))
+ return false;
+
+ // Test for slippery slope.
+ if (pointColl.IsIllegalFloor())
+ return false;
+
+ // Flat floor.
+ if ((abs(floorTilt.x) == 0 && abs(floorTilt.y) == 0))
+ {
+ // Test for step.
+ int relFloorHeight = abs(pointColl.GetFloorHeight() - item.Pose.Position.y);
+ if (relFloorHeight >= CLICK(1) && item.Pose.Position.y >= pointColl.GetFloorHeight())
+ return false;
+ }
+ // Sloped floor.
+ else
+ {
+ // Half block.
+ int relFloorHeight = abs(pointColl.GetFloorHeight() - item.Pose.Position.y);
+ if (relFloorHeight > CLICK(1))
+ return false;
+
+ short slopeAngle = ANGLE(0.0f);
+ if (floorTilt.x > 0)
+ {
+ slopeAngle = ANGLE(-90.0f);
+ }
+ else if (floorTilt.x < 0)
+ {
+ slopeAngle = ANGLE(90.0f);
+ }
+
+ if (floorTilt.y > 0 && floorTilt.y > abs(floorTilt.x))
+ {
+ slopeAngle = ANGLE(180.0f);
+ }
+ else if (floorTilt.y < 0 && -floorTilt.y > abs(floorTilt.x))
+ {
+ slopeAngle = ANGLE(0.0f);
+ }
+
+ short dirAngle = phd_atan(dir.z, dir.x);
+ short alignAngle = Geometry::GetShortestAngle(slopeAngle, dirAngle);
+
+ // Test if slope aspect is aligned with direction.
+ if (alignAngle != 0 && alignAngle != ANGLE(180.0f))
+ return false;
+ }
+
+ // Check for diagonal split.
+ if (pointColl.IsDiagonalFloorStep())
+ return false;
+
+ // Test ceiling height.
+ int relCeilHeight = abs(pointColl.GetCeilingHeight() - pointColl.GetFloorHeight());
+
+ if (relCeilHeight <= height)
+ return false;
+
+ // Check for blocked grey box.
+ if (g_Level.Boxes[pointColl.GetSector().Box].flags & BLOCKABLE)
+ {
+ if (g_Level.Boxes[pointColl.GetSector().Box].flags & BLOCKED)
+ return false;
+ }
+
+ // Check for inaccessible sector.
+ if (pointColl.GetSector().Box == NO_VALUE)
+ return false;
+
+ // Check for stopper flag.
+ if (pointColl.GetSector().Stopper)
+ return false;
+
+ return true;
+}
\ No newline at end of file
diff --git a/TombEngine/Game/misc.h b/TombEngine/Game/misc.h
index 7c99542e9..ef00bf1fd 100644
--- a/TombEngine/Game/misc.h
+++ b/TombEngine/Game/misc.h
@@ -19,3 +19,4 @@ enum LaraMeshMask
CreatureInfo* GetCreatureInfo(ItemInfo* item);
void TargetNearestEntity(ItemInfo* item, CreatureInfo* creature);
+bool IsNextSectorValid(const ItemInfo& item, const Vector3& dir, float dist);
diff --git a/TombEngine/Game/missile.cpp b/TombEngine/Game/missile.cpp
index bf171f0be..29739935a 100644
--- a/TombEngine/Game/missile.cpp
+++ b/TombEngine/Game/missile.cpp
@@ -154,7 +154,7 @@ void ControlNatlaGun(short fxNumber)
}
fxNumber = CreateNewEffect(pointColl.GetRoomNumber());
- if (fxNumber != NO_ITEM)
+ if (fxNumber != NO_VALUE)
{
auto& fxNew = EffectList[fxNumber];
@@ -171,7 +171,7 @@ void ControlNatlaGun(short fxNumber)
short ShardGun(int x, int y, int z, short velocity, short yRot, short roomNumber)
{
int fxNumber = CreateNewEffect(roomNumber);
- if (fxNumber != NO_ITEM)
+ if (fxNumber != NO_VALUE)
{
auto& fx = EffectList[fxNumber];
@@ -191,7 +191,7 @@ short ShardGun(int x, int y, int z, short velocity, short yRot, short roomNumber
short BombGun(int x, int y, int z, short velocity, short yRot, short roomNumber)
{
int fxNumber = CreateNewEffect(roomNumber);
- if (fxNumber != NO_ITEM)
+ if (fxNumber != NO_VALUE)
{
auto& fx = EffectList[fxNumber];
diff --git a/TombEngine/Game/pickup/pickup.cpp b/TombEngine/Game/pickup/pickup.cpp
index c20a0a2e3..86d2fee4b 100644
--- a/TombEngine/Game/pickup/pickup.cpp
+++ b/TombEngine/Game/pickup/pickup.cpp
@@ -201,7 +201,7 @@ void RemoveObjectFromInventory(GAME_OBJECT_ID objectID, std::optional count
void CollectCarriedItems(ItemInfo* item)
{
short pickupNumber = item->CarriedItem;
- while (pickupNumber != NO_ITEM)
+ while (pickupNumber != NO_VALUE)
{
auto* pickupItem = &g_Level.Items[pickupNumber];
@@ -212,7 +212,7 @@ void CollectCarriedItems(ItemInfo* item)
pickupNumber = pickupItem->CarriedItem;
}
- item->CarriedItem = NO_ITEM;
+ item->CarriedItem = NO_VALUE;
}
static void HideOrDisablePickup(ItemInfo& pickupItem)
@@ -231,42 +231,35 @@ static void HideOrDisablePickup(ItemInfo& pickupItem)
void CollectMultiplePickups(int itemNumber)
{
- auto* firstItem = &g_Level.Items[itemNumber];
- GetCollidedObjects(firstItem, LARA_RADIUS, true, CollidedItems, CollidedMeshes, true);
-
- for (int i = 0; i < MAX_COLLIDED_OBJECTS; i++)
+ auto& firstItem = g_Level.Items[itemNumber];
+
+ auto collObjects = GetCollidedObjects(firstItem, true, true, LARA_RADIUS, ObjectCollectionMode::Items);
+ collObjects.ItemPtrs.push_back(&firstItem);
+ for (auto* itemPtr : collObjects.ItemPtrs)
{
- auto* currentItem = CollidedItems[i];
-
- if (currentItem == nullptr)
- currentItem = firstItem;
-
- if (!Objects[currentItem->ObjectNumber].isPickup)
+ if (!Objects[itemPtr->ObjectNumber].isPickup)
continue;
// HACK: Exclude flares and torches from pickup batches.
- if ((currentItem->ObjectNumber == ID_FLARE_ITEM && currentItem->Active) ||
- currentItem->ObjectNumber == ID_BURNING_TORCH_ITEM)
+ if ((itemPtr->ObjectNumber == ID_FLARE_ITEM && itemPtr->Active) ||
+ itemPtr->ObjectNumber == ID_BURNING_TORCH_ITEM)
{
- continue;
+ continue;
}
- PickedUpObject(currentItem->ObjectNumber);
- g_Hud.PickupSummary.AddDisplayPickup(currentItem->ObjectNumber, currentItem->Pose.Position.ToVector3());
+ PickedUpObject(itemPtr->ObjectNumber);
+ g_Hud.PickupSummary.AddDisplayPickup(itemPtr->ObjectNumber, itemPtr->Pose.Position.ToVector3());
- if (currentItem->TriggerFlags & (1 << 8))
+ if (itemPtr->TriggerFlags & (1 << 8))
{
for (int i = 0; i < g_Level.NumItems; i++)
{
- if (g_Level.Items[i].ObjectNumber == currentItem->ObjectNumber)
+ if (g_Level.Items[i].ObjectNumber == itemPtr->ObjectNumber)
KillItem(i);
}
}
- HideOrDisablePickup(*currentItem);
-
- if (currentItem == firstItem)
- break;
+ HideOrDisablePickup(*itemPtr);
}
}
@@ -274,7 +267,7 @@ void DoPickup(ItemInfo* laraItem)
{
auto* lara = GetLaraInfo(laraItem);
- if (lara->Context.InteractedItem == NO_ITEM)
+ if (lara->Context.InteractedItem == NO_VALUE)
return;
short pickupItemNumber = lara->Context.InteractedItem;
@@ -295,7 +288,7 @@ void DoPickup(ItemInfo* laraItem)
KillItem(pickupItemNumber);
pickupItem->Pose.Orientation = prevOrient;
- lara->Context.InteractedItem = NO_ITEM;
+ lara->Context.InteractedItem = NO_VALUE;
return;
}
else if (pickupItem->ObjectNumber == ID_FLARE_ITEM && pickupItem->Active)
@@ -321,7 +314,7 @@ void DoPickup(ItemInfo* laraItem)
if (g_GameFlow->IsMassPickupEnabled())
{
CollectMultiplePickups(lara->Context.InteractedItem);
- lara->Context.InteractedItem = NO_ITEM;
+ lara->Context.InteractedItem = NO_VALUE;
return;
}
@@ -330,7 +323,7 @@ void DoPickup(ItemInfo* laraItem)
HideOrDisablePickup(*pickupItem);
pickupItem->Pose.Orientation = prevOrient;
- lara->Context.InteractedItem = NO_ITEM;
+ lara->Context.InteractedItem = NO_VALUE;
return;
}
else
@@ -350,7 +343,7 @@ void DoPickup(ItemInfo* laraItem)
if (g_GameFlow->IsMassPickupEnabled())
{
CollectMultiplePickups(lara->Context.InteractedItem);
- lara->Context.InteractedItem = NO_ITEM;
+ lara->Context.InteractedItem = NO_VALUE;
return;
}
@@ -369,13 +362,13 @@ void DoPickup(ItemInfo* laraItem)
HideOrDisablePickup(*pickupItem);
pickupItem->Pose.Orientation = prevOrient;
- lara->Context.InteractedItem = NO_ITEM;
+ lara->Context.InteractedItem = NO_VALUE;
return;
}
}
}
- lara->Context.InteractedItem = NO_ITEM;
+ lara->Context.InteractedItem = NO_VALUE;
}
void PickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
@@ -457,7 +450,7 @@ void PickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
return;
}
- if (!IsHeld(In::Action) && (g_Gui.GetInventoryItemChosen() == NO_ITEM || triggerFlags != 2) ||
+ if (!IsHeld(In::Action) && (g_Gui.GetInventoryItemChosen() == NO_VALUE || triggerFlags != 2) ||
lara->Control.Look.IsUsingLasersight ||
(laraItem->Animation.ActiveState != LS_IDLE || laraItem->Animation.AnimNumber != LA_STAND_IDLE || lara->Control.HandStatus != HandStatus::Free) &&
(laraItem->Animation.ActiveState != LS_CROUCH_IDLE || laraItem->Animation.AnimNumber != LA_CROUCH_IDLE || lara->Control.HandStatus != HandStatus::Free) &&
@@ -542,7 +535,7 @@ void PickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
}
if (!lara->Control.IsMoving)
{
- if (g_Gui.GetInventoryItemChosen() == NO_ITEM)
+ if (g_Gui.GetInventoryItemChosen() == NO_VALUE)
{
if (g_Gui.IsObjectInInventory(ID_CROWBAR_ITEM))
g_Gui.SetEnterInventory(ID_CROWBAR_ITEM);
@@ -557,7 +550,7 @@ void PickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
return;
}
- g_Gui.SetInventoryItemChosen(NO_ITEM);
+ g_Gui.SetInventoryItemChosen(NO_VALUE);
}
if (MoveLaraPosition(CrowbarPickUpPosition, item, laraItem))
@@ -848,8 +841,7 @@ void DropPickups(ItemInfo* item)
origin.y = yPos; // Initialize drop origin Y point as floor height at centerpoint, in case all corner tests fail.
- // Also collect objects which are around.
- bool collidedWithObjects = GetCollidedObjects(item, extents.Length(), true, CollidedItems, CollidedMeshes, true);
+ auto collObjects = GetCollidedObjects(*item, true, true);
short startAngle = ANGLE(Random::GenerateInt(0, 3) * 90.0f); // Randomize start corner.
@@ -894,26 +886,22 @@ void DropPickups(ItemInfo* item)
// Iterate through all found items and statics around, and determine if dummy sphere
// intersects any of those. If so, try other corner.
- for (int i = 0; i < MAX_COLLIDED_OBJECTS; i++)
+ for (const auto* itemPtr : collObjects.ItemPtrs)
{
- auto* currentItem = CollidedItems[i];
- if (!currentItem)
- break;
-
- if (GameBoundingBox(currentItem).ToBoundingOrientedBox(currentItem->Pose).Intersects(sphere))
+ auto box = GameBoundingBox(itemPtr).ToBoundingOrientedBox(itemPtr->Pose);
+ if (box.Intersects(sphere))
{
collidedWithObject = true;
break;
}
}
- for (int i = 0; i < MAX_COLLIDED_OBJECTS; i++)
+ for (auto* staticPtr : collObjects.StaticPtrs)
{
- auto* currentMesh = CollidedMeshes[i];
- if (!currentMesh)
- break;
+ auto& object = StaticObjects[staticPtr->staticNumber];
- if (StaticObjects[currentMesh->staticNumber].collisionBox.ToBoundingOrientedBox(currentMesh->pos).Intersects(sphere))
+ auto box = object.collisionBox.ToBoundingOrientedBox(staticPtr->pos);
+ if (box.Intersects(sphere))
{
collidedWithObject = true;
break;
@@ -938,7 +926,7 @@ void DropPickups(ItemInfo* item)
break;
}
- for (short pickupNumber = item->CarriedItem; pickupNumber != NO_ITEM; pickupNumber = pickup->CarriedItem)
+ for (short pickupNumber = item->CarriedItem; pickupNumber != NO_VALUE; pickupNumber = pickup->CarriedItem)
{
pickup = &g_Level.Items[pickupNumber];
pickup->Pose.Position = origin;
@@ -1029,11 +1017,11 @@ const GameBoundingBox* FindPlinth(ItemInfo* item)
}
}
- if (room->itemNumber == NO_ITEM)
+ if (room->itemNumber == NO_VALUE)
return nullptr;
short itemNumber = room->itemNumber;
- for (itemNumber = room->itemNumber; itemNumber != NO_ITEM; itemNumber = g_Level.Items[itemNumber].NextItem)
+ for (itemNumber = room->itemNumber; itemNumber != NO_VALUE; itemNumber = g_Level.Items[itemNumber].NextItem)
{
auto* currentItem = &g_Level.Items[itemNumber];
auto* object = &Objects[currentItem->ObjectNumber];
@@ -1048,7 +1036,7 @@ const GameBoundingBox* FindPlinth(ItemInfo* item)
}
}
- if (itemNumber == NO_ITEM)
+ if (itemNumber == NO_VALUE)
{
return nullptr;
}
@@ -1091,7 +1079,7 @@ void InitializePickup(short itemNumber)
auto pointColl = GetPointCollision(*item);
int bridgeItemNumber = pointColl.GetSector().GetInsideBridgeItemNumber(item->Pose.Position, true, true);
- if (bridgeItemNumber != NO_ITEM)
+ if (bridgeItemNumber != NO_VALUE)
{
// If pickup is within bridge item, most likely it means it is
// below pushable or raising block, so ignore its collision.
@@ -1314,7 +1302,7 @@ bool UseSpecialItem(ItemInfo* laraItem)
int flag = 0;
int itemIDToUse = g_Gui.GetInventoryItemChosen();
- if (itemIDToUse != NO_ITEM &&
+ if (itemIDToUse != NO_VALUE &&
laraItem->Animation.AnimNumber == LA_STAND_IDLE &&
lara->Control.HandStatus == HandStatus::Free)
{
@@ -1368,7 +1356,7 @@ bool UseSpecialItem(ItemInfo* laraItem)
SetAnimation(laraItem, LA_WATERSKIN_POUR_LOW);
lara->Control.HandStatus = HandStatus::Busy;
- g_Gui.SetInventoryItemChosen(NO_ITEM);
+ g_Gui.SetInventoryItemChosen(NO_VALUE);
return true;
}
}
diff --git a/TombEngine/Game/room.cpp b/TombEngine/Game/room.cpp
index 3d2d36ac9..58c76bd49 100644
--- a/TombEngine/Game/room.cpp
+++ b/TombEngine/Game/room.cpp
@@ -39,7 +39,7 @@ bool ROOM_INFO::Active() const
static void AddRoomFlipItems(const ROOM_INFO& room)
{
// Run through linked items.
- for (int itemNumber = room.itemNumber; itemNumber != NO_ITEM; itemNumber = g_Level.Items[itemNumber].NextItem)
+ for (int itemNumber = room.itemNumber; itemNumber != NO_VALUE; itemNumber = g_Level.Items[itemNumber].NextItem)
{
const auto& item = g_Level.Items[itemNumber];
const auto& object = Objects[item.ObjectNumber];
@@ -53,7 +53,7 @@ static void AddRoomFlipItems(const ROOM_INFO& room)
static void RemoveRoomFlipItems(const ROOM_INFO& room)
{
// Run through linked items.
- for (int itemNumber = room.itemNumber; itemNumber != NO_ITEM; itemNumber = g_Level.Items[itemNumber].NextItem)
+ for (int itemNumber = room.itemNumber; itemNumber != NO_VALUE; itemNumber = g_Level.Items[itemNumber].NextItem)
{
const auto& item = g_Level.Items[itemNumber];
const auto& object = Objects[item.ObjectNumber];
@@ -75,6 +75,12 @@ static void RemoveRoomFlipItems(const ROOM_INFO& room)
void DoFlipMap(int group)
{
+ if (group >= MAX_FLIPMAP)
+ {
+ TENLog("Maximum flipmap group number is " + std::to_string(MAX_FLIPMAP) + ".", LogLevel::Warning);
+ return;
+ }
+
// Run through rooms.
for (int roomNumber = 0; roomNumber < g_Level.Rooms.size(); roomNumber++)
{
@@ -112,13 +118,13 @@ void DoFlipMap(int group)
FlipStats[group] = !FlipStats[group];
for (auto& creature : ActiveCreatures)
- creature->LOT.TargetBox = NO_BOX;
+ creature->LOT.TargetBox = NO_VALUE;
}
bool IsObjectInRoom(int roomNumber, GAME_OBJECT_ID objectID)
{
int itemNumber = g_Level.Rooms[roomNumber].itemNumber;
- if (itemNumber == NO_ITEM)
+ if (itemNumber == NO_VALUE)
return false;
while (true)
@@ -129,7 +135,7 @@ bool IsObjectInRoom(int roomNumber, GAME_OBJECT_ID objectID)
break;
itemNumber = item.NextItem;
- if (itemNumber == NO_ITEM)
+ if (itemNumber == NO_VALUE)
return false;
}
diff --git a/TombEngine/Game/savegame.cpp b/TombEngine/Game/savegame.cpp
index a8df10abf..98100796f 100644
--- a/TombEngine/Game/savegame.cpp
+++ b/TombEngine/Game/savegame.cpp
@@ -23,10 +23,12 @@
#include "Objects/Generic/Switches/fullblock_switch.h"
#include "Objects/Generic/puzzles_keys.h"
#include "Objects/Sink.h"
+#include "Objects/TR3/Entity/FishSwarm.h"
#include "Objects/TR4/Entity/tr4_beetle_swarm.h"
#include "Objects/TR5/Emitter/tr5_rats_emitter.h"
#include "Objects/TR5/Emitter/tr5_bats_emitter.h"
#include "Objects/TR5/Emitter/tr5_spider_emitter.h"
+#include "Renderer/Renderer.h"
#include "Scripting/Include/ScriptInterfaceGame.h"
#include "Scripting/Include/ScriptInterfaceLevel.h"
#include "Scripting/Include/Objects/ScriptInterfaceObjectsHandler.h"
@@ -34,13 +36,13 @@
#include "Specific/clock.h"
#include "Specific/level.h"
#include "Specific/savegame/flatbuffers/ten_savegame_generated.h"
-#include "Renderer/Renderer.h"
using namespace flatbuffers;
using namespace TEN::Collision::Floordata;
using namespace TEN::Control::Volumes;
-using namespace TEN::Entities::Generic;
using namespace TEN::Effects::Items;
+using namespace TEN::Entities::Creatures::TR3;
+using namespace TEN::Entities::Generic;
using namespace TEN::Entities::Switches;
using namespace TEN::Entities::TR4;
using namespace TEN::Gui;
@@ -849,6 +851,28 @@ const std::vector SaveGame::Build()
}
auto serializedItemsOffset = fbb.CreateVector(serializedItems);
+ std::vector> fishSwarm;
+ for (const auto& fish : FishSwarm)
+ {
+ Save::FishDataBuilder fishSave{ fbb };
+ fishSave.add_is_lethal(fish.IsLethal);
+ fishSave.add_is_patrolling(fish.IsPatrolling);
+ fishSave.add_leader_item_number((fish.LeaderItemPtr == nullptr) ? -1 : fish.LeaderItemPtr->Index);
+ fishSave.add_life(fish.Life);
+ fishSave.add_mesh_index(fish.MeshIndex);
+ fishSave.add_orientation(&FromEulerAngles(fish.Orientation));
+ fishSave.add_position(&FromVector3(fish.Position));
+ fishSave.add_position_target(&FromVector3(fish.PositionTarget));
+ fishSave.add_room_number(fish.RoomNumber);
+ fishSave.add_target_item_number((fish.TargetItemPtr == nullptr) ? -1 : fish.TargetItemPtr->Index);
+ fishSave.add_undulation(fish.Undulation);
+ fishSave.add_velocity(fish.Velocity);
+
+ auto fishSaveOffset = fishSave.Finish();
+ fishSwarm.push_back(fishSaveOffset);
+ }
+ auto fishSwarmOffset = fbb.CreateVector(fishSwarm);
+
// TODO: In future, we should save only active FX, not whole array.
// This may come together with Monty's branch merge -- Lwmte, 10.07.22
@@ -981,7 +1005,7 @@ const std::vector SaveGame::Build()
{
auto& entry = currVolume.StateQueue[k];
- int activator = NO_ITEM;
+ int activator = NO_VALUE;
if (std::holds_alternative(entry.Activator))
activator = std::get(entry.Activator);
else
@@ -1384,6 +1408,7 @@ const std::vector SaveGame::Build()
sgb.add_next_item_free(NextItemFree);
sgb.add_next_item_active(NextItemActive);
sgb.add_items(serializedItemsOffset);
+ sgb.add_fish_swarm(fishSwarmOffset);
sgb.add_fxinfos(serializedEffectsOffset);
sgb.add_next_fx_free(NextFxFree);
sgb.add_next_fx_active(NextFxActive);
@@ -1991,6 +2016,29 @@ static void ParseEffects(const Save::SaveGame* s)
PlaySoundTrack(track->name()->str(), (SoundTrackType)i, track->position());
}
+ // Load fish swarm.
+ for (int i = 0; i < s->fish_swarm()->size(); i++)
+ {
+ const auto& fishSave = s->fish_swarm()->Get(i);
+ auto fish = FishData{};
+
+ fish.IsLethal = fishSave->is_lethal();
+ fish.IsPatrolling = fishSave->is_patrolling();
+ fish.LeaderItemPtr = (fishSave->leader_item_number() == -1) ? nullptr : &g_Level.Items[fishSave->leader_item_number()];
+ fish.Life = fishSave->life();
+ fish.MeshIndex = fishSave->mesh_index();
+ fish.Orientation = ToEulerAngles(fishSave->orientation());
+ fish.Position = ToVector3(fishSave->position());
+ fish.PositionTarget = ToVector3(fishSave->position_target());
+ fish.RoomNumber = fishSave->room_number();
+ fish.TargetItemPtr = (fishSave->target_item_number() == -1) ? nullptr : &g_Level.Items[fishSave->target_item_number()];
+ fish.Undulation = fishSave->undulation();
+ fish.Velocity = fishSave->velocity();
+
+ FishSwarm.push_back(fish);
+ }
+
+ // Load particles.
for (int i = 0; i < s->particles()->size(); i++)
{
auto* particleInfo = s->particles()->Get(i);
@@ -2297,7 +2345,7 @@ static void ParseLevel(const Save::SaveGame* s, bool hubMode)
item->Active = savedItem->active();
item->HitStatus = savedItem->hit_stauts();
- item->Status = savedItem->status();
+ item->Status = (ItemStatus)savedItem->status();
item->AIBits = savedItem->ai_bits();
item->Animation.IsAirborne = savedItem->is_airborne();
item->Collidable = savedItem->collidable();
diff --git a/TombEngine/Game/spotcam.cpp b/TombEngine/Game/spotcam.cpp
index 49f67c4e3..36fb46751 100644
--- a/TombEngine/Game/spotcam.cpp
+++ b/TombEngine/Game/spotcam.cpp
@@ -9,17 +9,14 @@
#include "Game/items.h"
#include "Game/Lara/lara.h"
#include "Game/Lara/lara_helpers.h"
-#include "Math/Math.h"
#include "Specific/Input/Input.h"
-using namespace TEN::Control::Volumes;
using namespace TEN::Input;
-using namespace TEN::Math;
using namespace TEN::Renderer;
+using namespace TEN::Control::Volumes;
constexpr auto MAX_CAMERA = 18;
-// Globals
bool TrackCameraInit;
int SpotcamTimer;
bool SpotcamPaused;
@@ -34,8 +31,12 @@ int SplineToCamera;
int FirstCamera;
int LastCamera;
int CurrentCameraCnt;
-Vector3i CameraPosition[MAX_CAMERA];
-Vector3i CameraPositionTarget[MAX_CAMERA];
+int CameraXposition[MAX_CAMERA];
+int CameraYposition[MAX_CAMERA];
+int CameraZposition[MAX_CAMERA];
+int CameraXtarget[MAX_CAMERA];
+int CameraYtarget[MAX_CAMERA];
+int CameraZtarget[MAX_CAMERA];
int CameraRoll[MAX_CAMERA];
int CameraFOV[MAX_CAMERA];
int CameraSpeed[MAX_CAMERA];
@@ -62,6 +63,7 @@ void ClearSpotCamSequences()
SpotcamDontDrawLara = false;
SpotcamOverlay = false;
+
for (int i = 0; i < MAX_SPOTCAMS; i++)
SpotCam[i] = {};
}
@@ -70,37 +72,35 @@ void InitializeSpotCamSequences(bool startFirstSequence)
{
TrackCameraInit = false;
- int spotCamCount = NumberSpotcams;
+ int n = NumberSpotcams;
int cc = 1;
- if (spotCamCount != 0)
+ if (n != 0)
{
int ce = 0;
- int sequenceID = SpotCam[0].sequence;
+ int s = SpotCam[0].sequence;
- if (cc < spotCamCount)
+ if (cc < n)
{
- for (spotCamCount = 1; spotCamCount < NumberSpotcams; spotCamCount++)
+ for (n = 1; n < NumberSpotcams; n++)
{
// Same sequence.
- if (SpotCam[spotCamCount].sequence == sequenceID)
- {
+ if (SpotCam[n].sequence == s)
cc++;
- }
// New sequence.
else
{
CameraCnt[ce] = cc;
cc = 1;
- SpotCamRemap[sequenceID] = ce;
+ SpotCamRemap[s] = ce;
ce++;
- sequenceID = SpotCam[spotCamCount].sequence;
+ s = SpotCam[n].sequence;
}
}
}
CameraCnt[ce] = cc;
- SpotCamRemap[sequenceID] = ce;
+ SpotCamRemap[s] = ce;
}
if (startFirstSequence)
@@ -110,9 +110,9 @@ void InitializeSpotCamSequences(bool startFirstSequence)
}
}
-void InitializeSpotCam(short sequenceID)
+void InitializeSpotCam(short Sequence)
{
- if (TrackCameraInit != 0 && LastSpotCamSequence == sequenceID)
+ if (TrackCameraInit != 0 && LastSpotCamSequence == Sequence)
{
TrackCameraInit = false;
return;
@@ -131,8 +131,8 @@ void InitializeSpotCam(short sequenceID)
Lara.Inventory.IsBusy = 0;
- CameraFade = NO_VALUE;
- LastSpotCamSequence = sequenceID;
+ CameraFade = -1;
+ LastSpotCamSequence = Sequence;
TrackCameraInit = false;
SpotcamTimer = 0;
SpotcamPaused = false;
@@ -156,10 +156,10 @@ void InitializeSpotCam(short sequenceID)
LaraFixedPosition.y = LaraItem->Pose.Position.y;
LaraFixedPosition.z = LaraItem->Pose.Position.z;
- CurrentSpotcamSequence = sequenceID;
+ CurrentSpotcamSequence = Sequence;
CurrentSplineCamera = 0;
- for (int i = 0; i < SpotCamRemap[sequenceID]; i++)
+ for (int i = 0; i < SpotCamRemap[Sequence]; i++)
CurrentSplineCamera += CameraCnt[i];
CurrentSplinePosition = 0;
@@ -167,21 +167,25 @@ void InitializeSpotCam(short sequenceID)
FirstCamera = CurrentSplineCamera;
- const auto* spotCamPtr = &SpotCam[CurrentSplineCamera];
+ auto* spotcam = &SpotCam[CurrentSplineCamera];
- LastCamera = CurrentSplineCamera + (CameraCnt[SpotCamRemap[sequenceID]] - 1);
- CurrentCameraCnt = CameraCnt[SpotCamRemap[sequenceID]];
+ LastCamera = CurrentSplineCamera + (CameraCnt[SpotCamRemap[Sequence]] - 1);
+ CurrentCameraCnt = CameraCnt[SpotCamRemap[Sequence]];
- if ((spotCamPtr->flags & SCF_DISABLE_LARA_CONTROLS))
+ if ((spotcam->flags & SCF_DISABLE_LARA_CONTROLS))
{
Lara.Control.IsLocked = true;
SetCinematicBars(1.0f, SPOTCAM_CINEMATIC_BARS_SPEED);
}
- if (spotCamPtr->flags & SCF_TRACKING_CAM)
+ if (spotcam->flags & SCF_TRACKING_CAM)
{
- CameraPosition[1] = SpotCam[FirstCamera].Position;
- CameraPositionTarget[1] = SpotCam[FirstCamera].PositionTarget;
+ CameraXposition[1] = SpotCam[FirstCamera].x;
+ CameraYposition[1] = SpotCam[FirstCamera].y;
+ CameraZposition[1] = SpotCam[FirstCamera].z;
+ CameraXtarget[1] = SpotCam[FirstCamera].tx;
+ CameraYtarget[1] = SpotCam[FirstCamera].ty;
+ CameraZtarget[1] = SpotCam[FirstCamera].tz;
CameraRoll[1] = SpotCam[FirstCamera].roll;
CameraFOV[1] = SpotCam[FirstCamera].fov;
CameraSpeed[1] = SpotCam[FirstCamera].speed;
@@ -190,20 +194,28 @@ void InitializeSpotCam(short sequenceID)
if (CurrentCameraCnt > 0)
{
- spotCamPtr = &SpotCam[FirstCamera];
+ spotcam = &SpotCam[FirstCamera];
- for (int i = 0; i < CurrentCameraCnt; i++, spotCamPtr++)
+ for (int i = 0; i < CurrentCameraCnt; i++, spotcam++)
{
- CameraPosition[i + 2] = spotCamPtr->Position;
- CameraPositionTarget[i + 2] = spotCamPtr->PositionTarget;
- CameraRoll[i + 2] = spotCamPtr->roll;
- CameraFOV[i + 2] = spotCamPtr->fov;
- CameraSpeed[i + 2] = spotCamPtr->speed;
+ CameraXposition[i + 2] = spotcam->x;
+ CameraYposition[i + 2] = spotcam->y;
+ CameraZposition[i + 2] = spotcam->z;
+ CameraXtarget[i + 2] = spotcam->tx;
+ CameraYtarget[i + 2] = spotcam->ty;
+ CameraZtarget[i + 2] = spotcam->tz;
+ CameraRoll[i + 2] = spotcam->roll;
+ CameraFOV[i + 2] = spotcam->fov;
+ CameraSpeed[i + 2] = spotcam->speed;
}
}
- CameraPosition[CurrentCameraCnt + 2] = SpotCam[LastCamera].Position;
- CameraPositionTarget[CurrentCameraCnt + 2] = SpotCam[LastCamera].PositionTarget;
+ CameraXposition[CurrentCameraCnt + 2] = SpotCam[LastCamera].x;
+ CameraYposition[CurrentCameraCnt + 2] = SpotCam[LastCamera].y;
+ CameraZposition[CurrentCameraCnt + 2] = SpotCam[LastCamera].z;
+ CameraXtarget[CurrentCameraCnt + 2] = SpotCam[LastCamera].tx;
+ CameraYtarget[CurrentCameraCnt + 2] = SpotCam[LastCamera].ty;
+ CameraZtarget[CurrentCameraCnt + 2] = SpotCam[LastCamera].tz;
CameraFOV[CurrentCameraCnt + 2] = SpotCam[LastCamera].fov;
CameraRoll[CurrentCameraCnt + 2] = SpotCam[LastCamera].roll;
CameraSpeed[CurrentCameraCnt + 2] = SpotCam[LastCamera].speed;
@@ -211,10 +223,14 @@ void InitializeSpotCam(short sequenceID)
else
{
int sp = 0;
- if ((spotCamPtr->flags & SCF_CUT_PAN))
+ if ((spotcam->flags & SCF_CUT_PAN))
{
- CameraPosition[1] = SpotCam[CurrentSplineCamera].Position;
- CameraPositionTarget[1] = SpotCam[CurrentSplineCamera].PositionTarget;
+ CameraXposition[1] = SpotCam[CurrentSplineCamera].x;
+ CameraYposition[1] = SpotCam[CurrentSplineCamera].y;
+ CameraZposition[1] = SpotCam[CurrentSplineCamera].z;
+ CameraXtarget[1] = SpotCam[CurrentSplineCamera].tx;
+ CameraYtarget[1] = SpotCam[CurrentSplineCamera].ty;
+ CameraZtarget[1] = SpotCam[CurrentSplineCamera].tz;
CameraRoll[1] = SpotCam[CurrentSplineCamera].roll;
CameraFOV[1] = SpotCam[CurrentSplineCamera].fov;
CameraSpeed[1] = SpotCam[CurrentSplineCamera].speed;
@@ -227,8 +243,12 @@ void InitializeSpotCam(short sequenceID)
if (LastCamera < CurrentSplineCamera)
cn = FirstCamera;
- CameraPosition[sp + 2] = SpotCam[cn].Position;
- CameraPositionTarget[sp + 2] = SpotCam[cn].PositionTarget;
+ CameraXposition[sp + 2] = SpotCam[cn].x;
+ CameraYposition[sp + 2] = SpotCam[cn].y;
+ CameraZposition[sp + 2] = SpotCam[cn].z;
+ CameraXtarget[sp + 2] = SpotCam[cn].tx;
+ CameraYtarget[sp + 2] = SpotCam[cn].ty;
+ CameraZtarget[sp + 2] = SpotCam[cn].tz;
CameraRoll[sp + 2] = SpotCam[cn].roll;
CameraFOV[sp + 2] = SpotCam[cn].fov;
CameraSpeed[sp + 2] = SpotCam[cn].speed;
@@ -241,30 +261,42 @@ void InitializeSpotCam(short sequenceID)
if (CurrentSplineCamera > LastCamera)
CurrentSplineCamera = FirstCamera;
- if (spotCamPtr->flags & SCF_ACTIVATE_HEAVY_TRIGGERS)
+ if (spotcam->flags & SCF_ACTIVATE_HEAVY_TRIGGERS)
CheckTrigger = true;
- if (spotCamPtr->flags & SCF_HIDE_LARA)
+ if (spotcam->flags & SCF_HIDE_LARA)
SpotcamDontDrawLara = true;
}
else
{
int cn = CurrentSplineCamera;
- CameraPosition[1] = InitialCameraPosition;
- CameraPositionTarget[1] = InitialCameraTarget;
+ CameraXposition[1] = InitialCameraPosition.x;
+ CameraYposition[1] = InitialCameraPosition.y;
+ CameraZposition[1] = InitialCameraPosition.z;
+ CameraXtarget[1] = InitialCameraTarget.x;
+ CameraYtarget[1] = InitialCameraTarget.y;
+ CameraZtarget[1] = InitialCameraTarget.z;
CameraFOV[1] = CurrentFOV;
CameraRoll[1] = 0;
- CameraSpeed[1] = spotCamPtr->speed;
+ CameraSpeed[1] = spotcam->speed;
- CameraPosition[2] = InitialCameraPosition;
- CameraPositionTarget[2] = InitialCameraTarget;
+ CameraXposition[2] = InitialCameraPosition.x;
+ CameraYposition[2] = InitialCameraPosition.y;
+ CameraZposition[2] = InitialCameraPosition.z;
+ CameraXtarget[2] = InitialCameraTarget.x;
+ CameraYtarget[2] = InitialCameraTarget.y;
+ CameraZtarget[2] = InitialCameraTarget.z;
CameraFOV[2] = CurrentFOV;
CameraRoll[2] = 0;
- CameraSpeed[2] = spotCamPtr->speed;
+ CameraSpeed[2] = spotcam->speed;
- CameraPosition[3] = SpotCam[CurrentSplineCamera].Position;
- CameraPositionTarget[3] = SpotCam[CurrentSplineCamera].PositionTarget;
+ CameraXposition[3] = SpotCam[CurrentSplineCamera].x;
+ CameraYposition[3] = SpotCam[CurrentSplineCamera].y;
+ CameraZposition[3] = SpotCam[CurrentSplineCamera].z;
+ CameraXtarget[3] = SpotCam[CurrentSplineCamera].tx;
+ CameraYtarget[3] = SpotCam[CurrentSplineCamera].ty;
+ CameraZtarget[3] = SpotCam[CurrentSplineCamera].tz;
CameraRoll[3] = SpotCam[CurrentSplineCamera].roll;
CameraFOV[3] = SpotCam[CurrentSplineCamera].fov;
CameraSpeed[3] = SpotCam[CurrentSplineCamera].speed;
@@ -276,8 +308,13 @@ void InitializeSpotCam(short sequenceID)
if (LastCamera < cn)
cn = FirstCamera;
- CameraPosition[4] = SpotCam[cn].Position;
- CameraPositionTarget[4] = SpotCam[cn].PositionTarget;
+ CameraXposition[4] = SpotCam[cn].x;
+ CameraYposition[4] = SpotCam[cn].y;
+ CameraZposition[4] = SpotCam[cn].z;
+
+ CameraXtarget[4] = SpotCam[cn].tx;
+ CameraYtarget[4] = SpotCam[cn].ty;
+ CameraZtarget[4] = SpotCam[cn].tz;
CameraRoll[4] = SpotCam[cn].roll;
CameraFOV[4] = SpotCam[cn].fov;
@@ -285,13 +322,42 @@ void InitializeSpotCam(short sequenceID)
}
}
- if (spotCamPtr->flags & SCF_HIDE_LARA)
+ if (spotcam->flags & SCF_HIDE_LARA)
SpotcamDontDrawLara = true;
}
void CalculateSpotCameras()
{
- auto backup = CAMERA_INFO{};
+ int cpx; // stack offset -96
+ int cpy; // stack offset -92
+ int cpz; // stack offset -88
+ int ctx; // stack offset -84
+ int cty; // stack offset -80
+ int ctz; // stack offset -76
+ int cspeed; // stack offset -72
+ int cfov; // stack offset -68
+ int croll; // stack offset -64
+ SPOTCAM* s; // stack offset -60
+ short spline_cnt; // $s3
+ int dx; // $v1
+ int dy; // $s0
+ int dz; // $s1
+
+ //{ // line 76, offset 0x38114
+ int sp; // $s2
+ int cp; // $fp
+ int clen; // $s4
+ int tlen; // $v1
+ int cx; // $s1
+ int cy; // $s0
+ int cz; // $v0
+ int lx; // stack offset -56
+ int lz; // stack offset -52
+ int ly; // stack offset -48
+ int cn; // $s0
+
+
+ CAMERA_INFO backup;
if (Lara.Control.IsLocked)
{
@@ -299,21 +365,22 @@ void CalculateSpotCameras()
Lara.Status.Air = LaraAir;
}
- auto* s = &SpotCam[FirstCamera];
- int splineCount = 4;
+ s = &SpotCam[FirstCamera];
+ spline_cnt = 4;
if (s->flags & SCF_TRACKING_CAM)
- splineCount = CurrentCameraCnt + 2;
+ spline_cnt = CurrentCameraCnt + 2;
- int cpx = Spline(CurrentSplinePosition, &CameraPosition[1].x, splineCount);
- int cpy = Spline(CurrentSplinePosition, &CameraPosition[1].y, splineCount);
- int cpz = Spline(CurrentSplinePosition, &CameraPosition[1].z, splineCount);
- int ctx = Spline(CurrentSplinePosition, &CameraPositionTarget[1].x, splineCount);
- int cty = Spline(CurrentSplinePosition, &CameraPositionTarget[1].y, splineCount);
- int ctz = Spline(CurrentSplinePosition, &CameraPositionTarget[1].z, splineCount);
- int cspeed = Spline(CurrentSplinePosition, &CameraSpeed[1], splineCount);
- int croll = Spline(CurrentSplinePosition, &CameraRoll[1], splineCount);
- int cfov = Spline(CurrentSplinePosition, &CameraFOV[1], splineCount);
+ //loc_37F64
+ cpx = Spline(CurrentSplinePosition, &CameraXposition[1], spline_cnt);
+ cpy = Spline(CurrentSplinePosition, &CameraYposition[1], spline_cnt);
+ cpz = Spline(CurrentSplinePosition, &CameraZposition[1], spline_cnt);
+ ctx = Spline(CurrentSplinePosition, &CameraXtarget[1], spline_cnt);
+ cty = Spline(CurrentSplinePosition, &CameraYtarget[1], spline_cnt);
+ ctz = Spline(CurrentSplinePosition, &CameraZtarget[1], spline_cnt);
+ cspeed = Spline(CurrentSplinePosition, &CameraSpeed[1], spline_cnt);
+ croll = Spline(CurrentSplinePosition, &CameraRoll[1], spline_cnt);
+ cfov = Spline(CurrentSplinePosition, &CameraFOV[1], spline_cnt);
if ((SpotCam[CurrentSplineCamera].flags & SCF_SCREEN_FADE_IN) &&
CameraFade != CurrentSplineCamera)
@@ -329,17 +396,17 @@ void CalculateSpotCameras()
CameraFade = CurrentSplineCamera;
}
- int sp = 0;
- int tlen = 0;
- int clen = 0;
- int cp = 0;
+ sp = 0;
+ tlen = 0;
+ clen = 0;
+ cp = 0;
int temp = 0x2000;
if (s->flags & SCF_TRACKING_CAM)
{
- int lx = LaraItem->Pose.Position.x;
- int ly = LaraItem->Pose.Position.y;
- int lz = LaraItem->Pose.Position.z;
+ lx = LaraItem->Pose.Position.x;
+ ly = LaraItem->Pose.Position.y;
+ lz = LaraItem->Pose.Position.z;
for (int i = 0; i < 8; i++)
{
@@ -347,13 +414,13 @@ void CalculateSpotCameras()
for (int j = 0; j < 8; j++)
{
- int cx = Spline(sp, &CameraPosition[1].x, splineCount);
- int cy = Spline(sp, &CameraPosition[1].y, splineCount);
- int cz = Spline(sp, &CameraPosition[1].z, splineCount);
+ cx = Spline(sp, &CameraXposition[1], spline_cnt);
+ cy = Spline(sp, &CameraYposition[1], spline_cnt);
+ cz = Spline(sp, &CameraZposition[1], spline_cnt);
- int dx = SQUARE(cx - lx);
- int dy = SQUARE(cy - ly);
- int dz = SQUARE(cz - lz);
+ dx = SQUARE(cx - lx);
+ dy = SQUARE(cy - ly);
+ dz = SQUARE(cz - lz);
tlen = sqrt(dx + dy + dz);
@@ -385,23 +452,19 @@ void CalculateSpotCameras()
}
if (CurrentSplinePosition > 0x10000)
- {
CurrentSplinePosition = 0x10000;
- }
else if (CurrentSplinePosition < 0)
- {
CurrentSplinePosition = 0;
- }
}
else if (!SpotcamTimer)
- {
CurrentSplinePosition += cspeed;
- }
- if (!IsHeld(In::Look))
+ bool lookPressed = (IsHeld(In::Look)) != 0;
+
+ if (!lookPressed)
SpotCamFirstLook = false;
- if ((s->flags & SCF_DISABLE_BREAKOUT) || !IsHeld(In::Look))
+ if ((s->flags & SCF_DISABLE_BREAKOUT) || !lookPressed)
{
Camera.pos.x = cpx;
Camera.pos.y = cpy;
@@ -427,9 +490,7 @@ void CalculateSpotCameras()
GetFloor(Camera.pos.x, Camera.pos.y, Camera.pos.z, &Camera.pos.RoomNumber);
}
else
- {
Camera.pos.RoomNumber = outsideRoom;
- }
AlterFOV(cfov, false);
@@ -482,15 +543,10 @@ void CalculateSpotCameras()
{
CurrentSplinePosition = 0;
- int cn = 0;
if (CurrentSplineCamera != FirstCamera)
- {
cn = CurrentSplineCamera - 1;
- }
else
- {
cn = LastCamera;
- }
sp = 1;
@@ -517,8 +573,12 @@ void CalculateSpotCameras()
{
cn = FirstCamera + SpotCam[CurrentSplineCamera].timer;
- CameraPosition[1] = SpotCam[cn].Position;
- CameraPositionTarget[1] = SpotCam[cn].PositionTarget;
+ CameraXposition[1] = SpotCam[cn].x;
+ CameraYposition[1] = SpotCam[cn].y;
+ CameraZposition[1] = SpotCam[cn].z;
+ CameraXtarget[1] = SpotCam[cn].tx;
+ CameraYtarget[1] = SpotCam[cn].ty;
+ CameraZtarget[1] = SpotCam[cn].tz;
CameraRoll[1] = SpotCam[cn].roll;
CameraFOV[1] = SpotCam[cn].fov;
CameraSpeed[1] = SpotCam[cn].speed;
@@ -528,8 +588,12 @@ void CalculateSpotCameras()
sp = sp2 + 1;
- CameraPosition[sp] = SpotCam[cn].Position;
- CameraPositionTarget[sp] = SpotCam[cn].PositionTarget;
+ CameraXposition[sp] = SpotCam[cn].x;
+ CameraYposition[sp] = SpotCam[cn].y;
+ CameraZposition[sp] = SpotCam[cn].z;
+ CameraXtarget[sp] = SpotCam[cn].tx;
+ CameraYtarget[sp] = SpotCam[cn].ty;
+ CameraZtarget[sp] = SpotCam[cn].tz;
CameraRoll[sp] = SpotCam[cn].roll;
CameraFOV[sp] = SpotCam[cn].fov;
CameraSpeed[sp] = SpotCam[cn].speed;
@@ -551,8 +615,12 @@ void CalculateSpotCameras()
cn = LastCamera;
}
- CameraPosition[sp + 1] = SpotCam[cn].Position;
- CameraPositionTarget[sp + 1] = SpotCam[cn].PositionTarget;
+ CameraXposition[sp + 1] = SpotCam[cn].x;
+ CameraYposition[sp + 1] = SpotCam[cn].y;
+ CameraZposition[sp + 1] = SpotCam[cn].z;
+ CameraXtarget[sp + 1] = SpotCam[cn].tx;
+ CameraYtarget[sp + 1] = SpotCam[cn].ty;
+ CameraZtarget[sp + 1] = SpotCam[cn].tz;
CameraRoll[sp + 1] = SpotCam[cn].roll;
CameraFOV[sp + 1] = SpotCam[cn].fov;
CameraSpeed[sp + 1] = SpotCam[cn].speed;
@@ -620,14 +688,22 @@ void CalculateSpotCameras()
}
else
{
- CameraPosition[1] = SpotCam[CurrentSplineCamera - 1].Position;
- CameraPositionTarget[1] = SpotCam[CurrentSplineCamera - 1].PositionTarget;
+ CameraXposition[1] = SpotCam[CurrentSplineCamera - 1].x;
+ CameraYposition[1] = SpotCam[CurrentSplineCamera - 1].y;
+ CameraZposition[1] = SpotCam[CurrentSplineCamera - 1].z;
+ CameraXtarget[1] = SpotCam[CurrentSplineCamera - 1].tx;
+ CameraYtarget[1] = SpotCam[CurrentSplineCamera - 1].ty;
+ CameraZtarget[1] = SpotCam[CurrentSplineCamera - 1].tz;
CameraRoll[1] = SpotCam[CurrentSplineCamera - 1].roll;
CameraFOV[1] = SpotCam[CurrentSplineCamera - 1].fov;
CameraSpeed[1] = SpotCam[CurrentSplineCamera - 1].speed;
- CameraPosition[2] = SpotCam[CurrentSplineCamera - 1].Position;
- CameraPositionTarget[2] = SpotCam[CurrentSplineCamera - 1].PositionTarget;
+ CameraXposition[2] = SpotCam[CurrentSplineCamera - 1].x;
+ CameraYposition[2] = SpotCam[CurrentSplineCamera - 1].y;
+ CameraZposition[2] = SpotCam[CurrentSplineCamera - 1].z;
+ CameraXtarget[2] = SpotCam[CurrentSplineCamera - 1].tx;
+ CameraYtarget[2] = SpotCam[CurrentSplineCamera - 1].ty;
+ CameraZtarget[2] = SpotCam[CurrentSplineCamera - 1].tz;
CameraRoll[2] = SpotCam[CurrentSplineCamera - 1].roll;
CameraFOV[2] = SpotCam[CurrentSplineCamera - 1].fov;
CameraSpeed[2] = SpotCam[CurrentSplineCamera - 1].speed;
@@ -645,17 +721,30 @@ void CalculateSpotCameras()
CameraRoll[3] = 0;
CameraSpeed[2] = CameraSpeed[1];
- InitialCameraPosition = Camera.pos.ToVector3i();
- InitialCameraTarget = Camera.target.ToVector3i();
+ InitialCameraPosition.x = Camera.pos.x;
+ InitialCameraPosition.y = Camera.pos.y;
+ InitialCameraPosition.z = Camera.pos.z;
- CameraPosition[3] = Camera.pos.ToVector3i();
- CameraPositionTarget[3] = Camera.target.ToVector3i();
+ InitialCameraTarget.x = Camera.target.x;
+ InitialCameraTarget.y = Camera.target.y;
+ InitialCameraTarget.z = Camera.target.z;
+
+ CameraXposition[3] = Camera.pos.x;
+ CameraYposition[3] = Camera.pos.y;
+ CameraZposition[3] = Camera.pos.z;
+ CameraXtarget[3] = Camera.target.x;
+ CameraYtarget[3] = Camera.target.y;
+ CameraZtarget[3] = Camera.target.z;
CameraFOV[3] = LastFOV;
CameraSpeed[3] = CameraSpeed[2];
CameraRoll[3] = 0;
- CameraPosition[4] = Camera.pos.ToVector3i();
- CameraPositionTarget[4] = Camera.target.ToVector3i();
+ CameraXposition[4] = Camera.pos.x;
+ CameraYposition[4] = Camera.pos.y;
+ CameraZposition[4] = Camera.pos.z;
+ CameraXtarget[4] = Camera.target.x;
+ CameraYtarget[4] = Camera.target.y;
+ CameraZtarget[4] = Camera.target.z;
CameraFOV[4] = LastFOV;
CameraSpeed[4] = CameraSpeed[2] >> 1;
CameraRoll[4] = 0;
diff --git a/TombEngine/Game/spotcam.h b/TombEngine/Game/spotcam.h
index 2efeaf9ae..24820b1aa 100644
--- a/TombEngine/Game/spotcam.h
+++ b/TombEngine/Game/spotcam.h
@@ -1,25 +1,28 @@
#pragma once
+#include "Math/Math.h"
#include "Specific/clock.h"
-struct Vector3i;
-
constexpr auto MAX_SPOTCAMS = 256;
constexpr auto SPOTCAM_CINEMATIC_BARS_HEIGHT = 1.0f / 16;
constexpr auto SPOTCAM_CINEMATIC_BARS_SPEED = 1.0f / FPS;
struct SPOTCAM
{
- Vector3i Position = Vector3i::Zero;
- Vector3i PositionTarget = Vector3i::Zero;
-
- int roomNumber;
- int sequence;
- int camera;
+ int x;
+ int y;
+ int z;
+ int tx;
+ int ty;
+ int tz;
+ unsigned char sequence;
+ unsigned char camera;
short fov;
short roll;
- int timer;
- int speed;
- int flags;
+ short timer;
+ short speed;
+ short flags;
+ short roomNumber;
+ short pad;
};
enum SPOTCAM_FLAGS
diff --git a/TombEngine/Math/Geometry.cpp b/TombEngine/Math/Geometry.cpp
index d283a4185..22235dc26 100644
--- a/TombEngine/Math/Geometry.cpp
+++ b/TombEngine/Math/Geometry.cpp
@@ -384,4 +384,9 @@ namespace TEN::Math::Geometry
return (distSqr <= radiusSqr);
}
+
+ bool CircleIntersects(const Vector3& circle0, const Vector3& circle1)
+ {
+ return (sqrt(SQUARE(circle1.x - circle0.x) + SQUARE(circle1.y - circle0.y)) <= (circle0.z + circle1.z));
+ }
}
diff --git a/TombEngine/Math/Geometry.h b/TombEngine/Math/Geometry.h
index 53f53fa8e..25a00ed9a 100644
--- a/TombEngine/Math/Geometry.h
+++ b/TombEngine/Math/Geometry.h
@@ -54,4 +54,7 @@ namespace TEN::Math::Geometry
bool IsPointInBox(const Vector3& point, const BoundingBox& box);
bool IsPointInBox(const Vector3& point, const BoundingOrientedBox& box);
bool IsPointInSphere(const Vector3& point, const BoundingSphere& sphere);
+
+ // Intersection inquirers
+ bool CircleIntersects(const Vector3& circle0, const Vector3& circle1);
}
diff --git a/TombEngine/Math/Math.cpp b/TombEngine/Math/Math.cpp
index 6564b0178..3ede4ffd8 100644
--- a/TombEngine/Math/Math.cpp
+++ b/TombEngine/Math/Math.cpp
@@ -1,4 +1,6 @@
#include "framework.h"
+
+#include
#include "Math/Math.h"
namespace TEN::Math
diff --git a/TombEngine/Math/Random.cpp b/TombEngine/Math/Random.cpp
index 2546cb21f..0131624dc 100644
--- a/TombEngine/Math/Random.cpp
+++ b/TombEngine/Math/Random.cpp
@@ -4,6 +4,7 @@
#include
#include "Math/Constants.h"
+#include "Math/Objects/EulerAngles.h"
namespace TEN::Math::Random
{
@@ -49,7 +50,8 @@ namespace TEN::Math::Random
relPoint = Vector2(
GenerateFloat(-1.0f, 1.0f),
GenerateFloat(-1.0f, 1.0f));
- } while (relPoint.LengthSquared() > 1.0f);
+ }
+ while (relPoint.LengthSquared() > 1.0f);
return (pos + (relPoint * radius));
}
@@ -100,7 +102,8 @@ namespace TEN::Math::Random
GenerateFloat(-1.0f, 1.0f),
GenerateFloat(-1.0f, 1.0f),
GenerateFloat(-1.0f, 1.0f));
- } while (relPoint.LengthSquared() > 1.0f);
+ }
+ while (relPoint.LengthSquared() > 1.0f);
return (sphere.Center + (relPoint * sphere.Radius));
}
@@ -120,6 +123,28 @@ namespace TEN::Math::Random
return (sphere.Center + (relPoint * sphere.Radius));
}
+ Vector3 GeneratePointInSpheroid(const Vector3& center, const EulerAngles& orient, const Vector3& semiMajorAxis)
+ {
+ // Use rejection sampling method.
+ auto relPoint = Vector3::Zero;
+ do
+ {
+ relPoint = Vector3(
+ Random::GenerateFloat(-semiMajorAxis.x, semiMajorAxis.x),
+ Random::GenerateFloat(-semiMajorAxis.y, semiMajorAxis.y),
+ Random::GenerateFloat(-semiMajorAxis.z, semiMajorAxis.z));
+ }
+ while ((SQUARE(relPoint.x) / SQUARE(semiMajorAxis.x) +
+ SQUARE(relPoint.y) / SQUARE(semiMajorAxis.y) +
+ SQUARE(relPoint.z) / SQUARE(semiMajorAxis.z)) > 1.0f);
+
+ // Rotate relative point.
+ auto rotMatrix = orient.ToRotationMatrix();
+ relPoint = Vector3::Transform(relPoint, rotMatrix);
+
+ return (center + relPoint);
+ }
+
bool TestProbability(float prob)
{
if (prob <= 0.0f)
diff --git a/TombEngine/Math/Random.h b/TombEngine/Math/Random.h
index 8b4e988ac..fd7508d35 100644
--- a/TombEngine/Math/Random.h
+++ b/TombEngine/Math/Random.h
@@ -1,5 +1,7 @@
#pragma once
+class EulerAngles;
+
namespace TEN::Math::Random
{
// Value generation
@@ -18,6 +20,7 @@ namespace TEN::Math::Random
Vector3 GeneratePointInBox(const BoundingOrientedBox& box);
Vector3 GeneratePointInSphere(const BoundingSphere& sphere);
Vector3 GeneratePointOnSphere(const BoundingSphere& sphere);
+ Vector3 GeneratePointInSpheroid(const Vector3& center, const EulerAngles& orient, const Vector3& semiMajorAxis);
bool TestProbability(float prob);
}
diff --git a/TombEngine/Objects/Effects/Boss.cpp b/TombEngine/Objects/Effects/Boss.cpp
index 17a8c6162..ed7cf2af4 100644
--- a/TombEngine/Objects/Effects/Boss.cpp
+++ b/TombEngine/Objects/Effects/Boss.cpp
@@ -21,7 +21,7 @@ namespace TEN::Effects::Boss
return;
int itemNumber = CreateItem();
- if (itemNumber == NO_ITEM)
+ if (itemNumber == NO_VALUE)
return;
auto& shieldItem = g_Level.Items[itemNumber];
@@ -50,7 +50,7 @@ namespace TEN::Effects::Boss
return;
int itemNumber = CreateItem();
- if (itemNumber == NO_ITEM)
+ if (itemNumber == NO_VALUE)
return;
auto& shockwaveItem = g_Level.Items[itemNumber];
diff --git a/TombEngine/Objects/Effects/flame_emitters.cpp b/TombEngine/Objects/Effects/flame_emitters.cpp
index d790a652f..80fea9e67 100644
--- a/TombEngine/Objects/Effects/flame_emitters.cpp
+++ b/TombEngine/Objects/Effects/flame_emitters.cpp
@@ -64,24 +64,19 @@ namespace TEN::Entities::Effects
void BurnNearbyItems(ItemInfo* item, int radius)
{
- GetCollidedObjects(item, radius, true, &CollidedItems[0], &CollidedMeshes[0], false);
-
- for (int i = 0; i < MAX_COLLIDED_OBJECTS; i++)
+ auto collObjects = GetCollidedObjects(*item, true, false, radius, ObjectCollectionMode::Items);
+ for (auto* itemPtr : collObjects.ItemPtrs)
{
- auto* currentItem = CollidedItems[i];
- if (!currentItem)
- break;
-
- if (TestEnvironment(ENV_FLAG_WATER, currentItem->RoomNumber))
+ if (TestEnvironment(ENV_FLAG_WATER, itemPtr->RoomNumber))
continue;
- if ((!currentItem->IsCreature() && !currentItem->IsLara()) || currentItem->HitPoints <= 0)
+ if ((!itemPtr->IsCreature() && !itemPtr->IsLara()) || itemPtr->HitPoints <= 0)
continue;
- if (currentItem->IsLara() && GetLaraInfo(item)->Control.WaterStatus == WaterStatus::FlyCheat)
+ if (itemPtr->IsLara() && GetLaraInfo(item)->Control.WaterStatus == WaterStatus::FlyCheat)
continue;
- ItemBurn(currentItem, currentItem->IsLara() ? -1 : FLAME_ITEM_BURN_TIMEOUT);
+ ItemBurn(itemPtr, itemPtr->IsLara() ? -1 : FLAME_ITEM_BURN_TIMEOUT);
}
}
diff --git a/TombEngine/Objects/Effects/tr4_locusts.cpp b/TombEngine/Objects/Effects/tr4_locusts.cpp
index 28a6a71e7..e828ce78b 100644
--- a/TombEngine/Objects/Effects/tr4_locusts.cpp
+++ b/TombEngine/Objects/Effects/tr4_locusts.cpp
@@ -26,7 +26,7 @@ namespace TEN::Entities::TR4
return i;
}
- return NO_ITEM;
+ return NO_VALUE;
}
void SpawnLocust(ItemInfo* item)
@@ -34,7 +34,7 @@ namespace TEN::Entities::TR4
Vector3i origin, target;
short locustNumber = CreateLocust();
EulerAngles orient;
- if (locustNumber != NO_ITEM)
+ if (locustNumber != NO_VALUE)
{
auto* locust = &Locusts[locustNumber];
diff --git a/TombEngine/Objects/Effects/tr5_electricity.cpp b/TombEngine/Objects/Effects/tr5_electricity.cpp
index 3bd02ec50..abfd748a3 100644
--- a/TombEngine/Objects/Effects/tr5_electricity.cpp
+++ b/TombEngine/Objects/Effects/tr5_electricity.cpp
@@ -144,8 +144,6 @@ void ElectricityWiresControl(short itemNumber)
SoundEffect(SFX_TR5_ELECTRIC_WIRES, &item->Pose);
- GetCollidedObjects(item, BLOCK(4), true, CollidedItems, nullptr, 0) && CollidedItems[0];
-
auto* object = &Objects[item->ObjectNumber];
auto cableBox = GameBoundingBox(item).ToBoundingOrientedBox(item->Pose);
@@ -181,21 +179,18 @@ void ElectricityWiresControl(short itemNumber)
if (GetRandomControl() & 1)
return;
- int k = 0;
- while (CollidedItems[k] != nullptr)
+ auto collObjects = GetCollidedObjects(*item, true, false, BLOCK(2), ObjectCollectionMode::Items);
+ for (auto* itemPtr : collObjects.ItemPtrs)
{
- auto* collItem = CollidedItems[k];
- auto* collObj = &Objects[collItem->ObjectNumber];
+ const auto& object = Objects[itemPtr->ObjectNumber];
- k++;
-
- if (collItem->ObjectNumber != ID_LARA && !collObj->intelligent)
+ if (itemPtr->ObjectNumber != ID_LARA && !object.intelligent)
continue;
bool isWaterNearby = false;
- auto npcBox = GameBoundingBox(collItem).ToBoundingOrientedBox(collItem->Pose);
+ auto npcBox = GameBoundingBox(itemPtr).ToBoundingOrientedBox(itemPtr->Pose);
- for (int i = 0; i < object->nmeshes; i++)
+ for (int i = 0; i < object.nmeshes; i++)
{
auto pos = GetJointPosition(item, i, Vector3i(0, 0, CLICK(1)));
short roomNumber = item->RoomNumber;
@@ -219,10 +214,10 @@ void ElectricityWiresControl(short itemNumber)
if (pos.y < cableBottomPlane)
continue;
- for (int j = 0; j < collObj->nmeshes; j++)
+ for (int j = 0; j < object.nmeshes; j++)
{
- auto collPos = GetJointPosition(collItem, j);
- auto pointCollJointRoom = GetPointCollision(collPos, collItem->RoomNumber).GetRoomNumber();
+ auto collPos = GetJointPosition(itemPtr, j);
+ auto pointCollJointRoom = GetPointCollision(collPos, itemPtr->RoomNumber).GetRoomNumber();
if (!isWaterNearby && isTouchingWater && roomNumber == pointCollJointRoom)
isWaterNearby = true;
@@ -234,29 +229,35 @@ void ElectricityWiresControl(short itemNumber)
{
if (!isWaterNearby)
{
- if (collItem->Effect.Type != EffectType::Smoke)
+ if (itemPtr->Effect.Type != EffectType::Smoke)
{
- ItemBlueElectricBurn(collItem, 2 *FPS);
+ ItemBlueElectricBurn(itemPtr, 2 *FPS);
}
else
- ItemSmoke(collItem, -1);
+ {
+ ItemSmoke(itemPtr, -1);
+ }
}
if (instantKill)
- DoDamage(collItem, INT_MAX);
+ {
+ DoDamage(itemPtr, INT_MAX);
+ }
else
- DoDamage(collItem, 8);
+ {
+ DoDamage(itemPtr, 8);
+ }
- for (int j = 0; j < collObj->nmeshes; j++)
+ for (int j = 0; j < object.nmeshes; j++)
{
if ((GetRandomControl() & 127) < 16)
- TriggerElectricitySparks(collItem, j, false);
+ TriggerElectricitySparks(itemPtr, j, false);
}
TriggerDynamicLight(
- collItem->Pose.Position.x,
- collItem->Pose.Position.y,
- collItem->Pose.Position.z,
+ itemPtr->Pose.Position.x,
+ itemPtr->Pose.Position.y,
+ itemPtr->Pose.Position.z,
5,
0,
(GetRandomControl() & 0x3F) + 0x2F,
diff --git a/TombEngine/Objects/Generic/Doors/generic_doors.cpp b/TombEngine/Objects/Generic/Doors/generic_doors.cpp
index 945df867a..9db8cd967 100644
--- a/TombEngine/Objects/Generic/Doors/generic_doors.cpp
+++ b/TombEngine/Objects/Generic/Doors/generic_doors.cpp
@@ -88,7 +88,7 @@ namespace TEN::Entities::Doors
boxNumber = GetSector(b, doorItem->Pose.Position.x - b->x + xOffset, doorItem->Pose.Position.z - b->z + zOffset)->Box;
}
- doorData->d1.block = (boxNumber != NO_BOX && g_Level.Boxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_BOX;
+ doorData->d1.block = (boxNumber != NO_VALUE && g_Level.Boxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_VALUE;
doorData->d1.data = *doorData->d1.floor;
if (r->flippedRoom != -1)
@@ -105,7 +105,7 @@ namespace TEN::Entities::Doors
boxNumber = GetSector(b, doorItem->Pose.Position.x - b->x + xOffset, doorItem->Pose.Position.z - b->z + zOffset)->Box;
}
- doorData->d1flip.block = (boxNumber != NO_BOX && g_Level.Boxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_BOX;
+ doorData->d1flip.block = (boxNumber != NO_VALUE && g_Level.Boxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_VALUE;
doorData->d1flip.data = *doorData->d1flip.floor;
}
else
@@ -135,7 +135,7 @@ namespace TEN::Entities::Doors
boxNumber = GetSector(b, doorItem->Pose.Position.x - b->x, doorItem->Pose.Position.z - b->z)->Box;
}
- doorData->d2.block = (boxNumber != NO_BOX && g_Level.Boxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_BOX;
+ doorData->d2.block = (boxNumber != NO_VALUE && g_Level.Boxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_VALUE;
doorData->d2.data = *doorData->d2.floor;
if (r->flippedRoom != -1)
@@ -152,7 +152,7 @@ namespace TEN::Entities::Doors
boxNumber = GetSector(b, doorItem->Pose.Position.x - b->x, doorItem->Pose.Position.z - b->z)->Box;
}
- doorData->d2flip.block = (boxNumber != NO_BOX && g_Level.Boxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_BOX;
+ doorData->d2flip.block = (boxNumber != NO_VALUE && g_Level.Boxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_VALUE;
doorData->d2flip.data = *doorData->d2flip.floor;
}
else
@@ -187,7 +187,7 @@ namespace TEN::Entities::Doors
{
if (!laraInfo->Control.IsMoving)
{
- if (g_Gui.GetInventoryItemChosen() == NO_ITEM)
+ if (g_Gui.GetInventoryItemChosen() == NO_VALUE)
{
if (g_Gui.IsObjectInInventory(ID_CROWBAR_ITEM))
{
@@ -217,7 +217,7 @@ namespace TEN::Entities::Doors
}
}
- g_Gui.SetInventoryItemChosen(NO_ITEM);
+ g_Gui.SetInventoryItemChosen(NO_VALUE);
if (MoveLaraPosition(CrowbarDoorPos, doorItem, laraItem))
{
@@ -399,11 +399,11 @@ namespace TEN::Entities::Doors
*doorPos->floor = doorPos->data;
short boxIndex = doorPos->block;
- if (boxIndex != NO_BOX)
+ if (boxIndex != NO_VALUE)
{
g_Level.Boxes[boxIndex].flags &= ~BLOCKED;
for (auto& currentCreature : ActiveCreatures)
- currentCreature->LOT.TargetBox = NO_BOX;
+ currentCreature->LOT.TargetBox = NO_VALUE;
}
}
}
@@ -416,7 +416,7 @@ namespace TEN::Entities::Doors
if (floor)
{
- floor->Box = NO_BOX;
+ floor->Box = NO_VALUE;
floor->TriggerIndex = 0;
// FIXME: HACK!!!!!!!
@@ -433,12 +433,12 @@ namespace TEN::Entities::Doors
floor->CeilingSurface.Triangles[1].Plane = WALL_PLANE;
short boxIndex = doorPos->block;
- if (boxIndex != NO_BOX)
+ if (boxIndex != NO_VALUE)
{
g_Level.Boxes[boxIndex].flags |= BLOCKED;
for (auto& currentCreature : ActiveCreatures)
- currentCreature->LOT.TargetBox = NO_BOX;
+ currentCreature->LOT.TargetBox = NO_VALUE;
}
}
}
diff --git a/TombEngine/Objects/Generic/Object/Pushable/PushableBridge.cpp b/TombEngine/Objects/Generic/Object/Pushable/PushableBridge.cpp
index dc910c8f6..9753906a4 100644
--- a/TombEngine/Objects/Generic/Object/Pushable/PushableBridge.cpp
+++ b/TombEngine/Objects/Generic/Object/Pushable/PushableBridge.cpp
@@ -75,7 +75,7 @@ namespace TEN::Entities::Generic
if (pushablePtr->UseBridgeCollision)
addBridge ? AddBridge(pushableItem.Index) : RemoveBridge(pushableItem.Index);
- while (pushablePtr->Stack.ItemNumberAbove != NO_ITEM)
+ while (pushablePtr->Stack.ItemNumberAbove != NO_VALUE)
{
pushableItemPtr = &g_Level.Items[pushablePtr->Stack.ItemNumberAbove];
pushablePtr = &GetPushableInfo(*pushableItemPtr);
diff --git a/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp b/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
index 1c5b33210..52c681f52 100644
--- a/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
+++ b/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
@@ -84,7 +84,7 @@ namespace TEN::Entities::Generic
else
{
pushable.IsOnEdge = true;
- if (!pushable.CanFall || pushable.Stack.ItemNumberAbove != NO_ITEM)
+ if (!pushable.CanFall || pushable.Stack.ItemNumberAbove != NO_VALUE)
return false;
}
}
@@ -118,28 +118,24 @@ namespace TEN::Entities::Generic
// Test object collision.
auto prevPos = pushableItem.Pose.Position;
pushableItem.Pose.Position = targetPos;
- GetCollidedObjects(&pushableItem, BLOCK(0.25f), true, &CollidedItems[0], &CollidedMeshes[0], true);
+ auto collObjects = GetCollidedObjects(pushableItem, true, true);
pushableItem.Pose.Position = prevPos;
- if (CollidedMeshes[0])
+ if (!collObjects.StaticPtrs.empty())
return false;
- for (int i = 0; i < MAX_COLLIDED_OBJECTS; i++)
+ for (const auto* itemPtr : collObjects.ItemPtrs)
{
- if (CollidedItems[i] == nullptr)
- break;
-
- const auto& item = *CollidedItems[i];
- const auto& object = Objects[item.ObjectNumber];
+ const auto& object = Objects[itemPtr->ObjectNumber];
if (object.isPickup)
continue;
- if (!item.IsBridge())
+ if (!itemPtr->IsBridge())
return false;
- const auto& bridge = GetBridgeObject(item);
- if (!bridge.GetFloorHeight(item, item.Pose.Position).has_value())
+ const auto& bridge = GetBridgeObject(*itemPtr);
+ if (!bridge.GetFloorHeight(*itemPtr, itemPtr->Pose.Position).has_value())
return false;
}
@@ -193,34 +189,30 @@ namespace TEN::Entities::Generic
// Collide with objects.
auto prevPos = LaraItem->Pose.Position;
LaraItem->Pose.Position = pointColl.GetPosition();
- GetCollidedObjects(LaraItem, LARA_RADIUS, true, &CollidedItems[0], &CollidedMeshes[0], true);
+ auto collObjects = GetCollidedObjects(*LaraItem, true, true);
LaraItem->Pose.Position = prevPos;
- if (CollidedMeshes[0])
+ if (!collObjects.StaticPtrs.empty())
return false;
- for (int i = 0; i < MAX_COLLIDED_OBJECTS; i++)
+ for (const auto* itemPtr : collObjects.ItemPtrs)
{
- if (CollidedItems[i] == nullptr)
- break;
+ const auto& object = Objects[itemPtr->ObjectNumber];
- const auto& item = *CollidedItems[i];
- const auto& object = Objects[item.ObjectNumber];
-
- if (&item == &pushableItem)
+ if (itemPtr->Index == pushableItem.Index)
continue;
if (object.isPickup)
continue;
- if (!item.IsBridge())
+ if (!itemPtr->IsBridge())
{
return false;
}
else
{
- const auto& bridge = GetBridgeObject(item);
- if (!bridge.GetFloorHeight(item, item.Pose.Position).has_value())
+ const auto& bridge = GetBridgeObject(*itemPtr);
+ if (!bridge.GetFloorHeight(*itemPtr, itemPtr->Pose.Position).has_value())
return false;
}
}
diff --git a/TombEngine/Objects/Generic/Object/Pushable/PushableInfo.cpp b/TombEngine/Objects/Generic/Object/Pushable/PushableInfo.cpp
index 7c6a69792..a83ac1f69 100644
--- a/TombEngine/Objects/Generic/Object/Pushable/PushableInfo.cpp
+++ b/TombEngine/Objects/Generic/Object/Pushable/PushableInfo.cpp
@@ -42,8 +42,8 @@ namespace TEN::Entities::Generic
Oscillation = DEFAULT_OSC;
Stack.Limit = DEFAULT_STACK_LIMIT;
- Stack.ItemNumberAbove = NO_ITEM;
- Stack.ItemNumberBelow = NO_ITEM;
+ Stack.ItemNumberAbove = NO_VALUE;
+ Stack.ItemNumberBelow = NO_VALUE;
CanFall = false;
DoCenterAlign = true;
diff --git a/TombEngine/Objects/Generic/Object/Pushable/PushableStack.cpp b/TombEngine/Objects/Generic/Object/Pushable/PushableStack.cpp
index 9f56c8b8f..4c1fa4072 100644
--- a/TombEngine/Objects/Generic/Object/Pushable/PushableStack.cpp
+++ b/TombEngine/Objects/Generic/Object/Pushable/PushableStack.cpp
@@ -107,7 +107,7 @@ namespace TEN::Entities::Generic
void StackPushable(int itemNumber, int targetItemNumber)
{
- if (targetItemNumber == NO_ITEM)
+ if (targetItemNumber == NO_VALUE)
return;
auto& pushableItem = g_Level.Items[itemNumber];
@@ -126,14 +126,14 @@ namespace TEN::Entities::Generic
auto& pushableItem = g_Level.Items[itemNumber];
auto& pushable = GetPushableInfo(pushableItem);
- if (pushable.Stack.ItemNumberBelow == NO_ITEM)
+ if (pushable.Stack.ItemNumberBelow == NO_VALUE)
return;
auto& lowerPushableItem = g_Level.Items[pushable.Stack.ItemNumberBelow];
auto& lowerPushable = GetPushableInfo(lowerPushableItem);
- pushable.Stack.ItemNumberBelow = NO_ITEM;
- lowerPushable.Stack.ItemNumberAbove = NO_ITEM;
+ pushable.Stack.ItemNumberBelow = NO_VALUE;
+ lowerPushable.Stack.ItemNumberAbove = NO_VALUE;
}
int SearchNearPushablesStack(int itemNumber)
@@ -142,7 +142,7 @@ namespace TEN::Entities::Generic
int pushabelStackFound = FindPushableStackInRoom(itemNumber, pushableItem.RoomNumber);
- if (pushabelStackFound != NO_ITEM)
+ if (pushabelStackFound != NO_VALUE)
return pushabelStackFound;
// Otherwise, check room below.
@@ -150,7 +150,7 @@ namespace TEN::Entities::Generic
//auto roomNumberBelow = collisionResult.Block->GetRoomNumberBelow(pushableItem.Pose.Position.x, pushableItem.Pose.Position.y, pushableItem.Pose.Position.z).value();
//pushabelStackFound = FindPushableStackInRoom(itemNumber, roomNumberBelow);
- return NO_ITEM;
+ return NO_VALUE;
}
int FindPushableStackInRoom(int itemNumber, int roomNumber)
@@ -161,7 +161,7 @@ namespace TEN::Entities::Generic
if (roomNumber != NO_ROOM)
{
short currentItemNumber = g_Level.Rooms[roomNumber].itemNumber;
- while (currentItemNumber != NO_ITEM)
+ while (currentItemNumber != NO_VALUE)
{
auto& currentItem = g_Level.Items[currentItemNumber];
@@ -171,19 +171,19 @@ namespace TEN::Entities::Generic
(currentItem.Pose.Position.y > pushableItem.Pose.Position.y))
{
// Find top item.
- if (pushable.Stack.ItemNumberAbove == NO_ITEM)
+ if (pushable.Stack.ItemNumberAbove == NO_VALUE)
{
return currentItemNumber;
}
else
{
int topItemNumber = pushable.Stack.ItemNumberAbove;
- while (topItemNumber != NO_ITEM)
+ while (topItemNumber != NO_VALUE)
{
auto& topItem = g_Level.Items[topItemNumber];
auto& topPushable = GetPushableInfo(topItem);
- if (topPushable.Stack.ItemNumberAbove == NO_ITEM)
+ if (topPushable.Stack.ItemNumberAbove == NO_VALUE)
{
return topItemNumber;
}
@@ -201,7 +201,7 @@ namespace TEN::Entities::Generic
}
}
- return NO_ITEM;
+ return NO_VALUE;
}
int GetPushableCountInStack(int itemNumber)
@@ -210,7 +210,7 @@ namespace TEN::Entities::Generic
auto& pushableCopy = GetPushableInfo(pushableItemCopy);
int count = 1;
- while (pushableCopy.Stack.ItemNumberAbove != NO_ITEM)
+ while (pushableCopy.Stack.ItemNumberAbove != NO_VALUE)
{
// Filter out current pushable item.
if (pushableCopy.Stack.ItemNumberAbove == itemNumber)
@@ -241,7 +241,7 @@ namespace TEN::Entities::Generic
int totalHeight = pushableCopy.Height;
- while (pushableCopy.Stack.ItemNumberAbove != NO_ITEM)
+ while (pushableCopy.Stack.ItemNumberAbove != NO_VALUE)
{
pushableItemCopy = g_Level.Items[pushableCopy.Stack.ItemNumberAbove];
pushableCopy = GetPushableInfo(pushableItemCopy);
@@ -258,7 +258,7 @@ namespace TEN::Entities::Generic
auto& pushable = GetPushableInfo(pushableItem);
int currentItemNumber = pushable.Stack.ItemNumberAbove;
- while (currentItemNumber != NO_ITEM)
+ while (currentItemNumber != NO_VALUE)
{
auto& currentPushableItem = g_Level.Items[currentItemNumber];
auto& currentPushable = GetPushableInfo(currentPushableItem);
@@ -279,7 +279,7 @@ namespace TEN::Entities::Generic
auto& pushable = GetPushableInfo(pushableItem);
int currentItemNumber = pushable.Stack.ItemNumberAbove;
- while (currentItemNumber != NO_ITEM)
+ while (currentItemNumber != NO_VALUE)
{
auto& currentPushableItem = g_Level.Items[currentItemNumber];
auto& currentPushable = GetPushableInfo(currentPushableItem);
@@ -312,7 +312,7 @@ namespace TEN::Entities::Generic
auto* pushableItemPtr = &g_Level.Items[pushableItem.Index];
const auto* pushablePtr = &GetPushableInfo(*pushableItemPtr);
- while (pushablePtr->Stack.ItemNumberAbove != NO_ITEM)
+ while (pushablePtr->Stack.ItemNumberAbove != NO_VALUE)
{
if (pushablePtr->Stack.ItemNumberAbove == pushableItem.Index)
break;
diff --git a/TombEngine/Objects/Generic/Object/Pushable/PushableStates.cpp b/TombEngine/Objects/Generic/Object/Pushable/PushableStates.cpp
index 265d4ed78..7e9e45f21 100644
--- a/TombEngine/Objects/Generic/Object/Pushable/PushableStates.cpp
+++ b/TombEngine/Objects/Generic/Object/Pushable/PushableStates.cpp
@@ -73,7 +73,7 @@ namespace TEN::Entities::Generic
playerItem.Animation.ActiveState != LS_PUSHABLE_PUSH &&
playerItem.Animation.ActiveState != LS_PUSHABLE_EDGE_SLIP)
{
- player.Context.InteractedItem = NO_ITEM;
+ player.Context.InteractedItem = NO_VALUE;
}
}
@@ -106,7 +106,7 @@ namespace TEN::Entities::Generic
int waterheight = abs(pushableColl.FloorHeight - pushable.WaterSurfaceHeight);
if (waterheight > GetPushableHeight(pushableItem))
{
- if (pushable.IsBuoyant && pushable.Stack.ItemNumberAbove == NO_ITEM)
+ if (pushable.IsBuoyant && pushable.Stack.ItemNumberAbove == NO_VALUE)
{
pushable.BehaviorState = PushableBehaviourState::Float;
pushable.Gravity = 0.0f;
@@ -146,7 +146,7 @@ namespace TEN::Entities::Generic
RemovePushableBridge(pushableItem);
SetPushableStopperFlag(false, pushableItem.Pose.Position, pushableItem.RoomNumber);
- if (pushable.IsBuoyant && pushable.Stack.ItemNumberAbove == NO_ITEM)
+ if (pushable.IsBuoyant && pushable.Stack.ItemNumberAbove == NO_VALUE)
{
pushable.BehaviorState = PushableBehaviourState::Float;
pushable.Gravity = 0.0f;
@@ -340,7 +340,7 @@ namespace TEN::Entities::Generic
pushable.BehaviorState = PushableBehaviourState::Fall;
pushable.SoundState = PushableSoundState::None;
playerItem.Animation.TargetState = LS_IDLE;
- player.Context.InteractedItem = NO_ITEM;
+ player.Context.InteractedItem = NO_VALUE;
return;
case PushableEnvironmentType::SlopedFloor:
@@ -351,7 +351,7 @@ namespace TEN::Entities::Generic
pushable.BehaviorState = PushableBehaviourState::Sink;
pushable.SoundState = PushableSoundState::None;
playerItem.Animation.TargetState = LS_IDLE;
- player.Context.InteractedItem = NO_ITEM;
+ player.Context.InteractedItem = NO_VALUE;
break;
default:
@@ -490,7 +490,7 @@ namespace TEN::Entities::Generic
// Get pushable collision.
auto pushableColl = GetPushableCollision(pushableItem);
- int foundStack = NO_ITEM;
+ int foundStack = NO_VALUE;
switch (pushableColl.EnvType)
{
@@ -509,7 +509,7 @@ namespace TEN::Entities::Generic
pushableItem.Pose.Orientation = EulerAngles(0, pushableItem.Pose.Orientation.y, 0);
// Set stopper flag.
- if (pushable.Stack.ItemNumberBelow == NO_ITEM)
+ if (pushable.Stack.ItemNumberBelow == NO_VALUE)
SetPushableStopperFlag(true, pushableItem.Pose.Position, pushableItem.RoomNumber);
// Activate trigger.
@@ -554,7 +554,7 @@ namespace TEN::Entities::Generic
// Get pushable collision.
auto pushableColl = GetPushableCollision(pushableItem);
- int foundStack = NO_ITEM;
+ int foundStack = NO_VALUE;
switch (pushableColl.EnvType)
{
@@ -562,7 +562,7 @@ namespace TEN::Entities::Generic
case PushableEnvironmentType::FlatFloor:
case PushableEnvironmentType::SlopedFloor:
// Set stopper flag.
- if (pushable.Stack.ItemNumberBelow == NO_ITEM)
+ if (pushable.Stack.ItemNumberBelow == NO_VALUE)
SetPushableStopperFlag(true, pushableItem.Pose.Position, pushableItem.RoomNumber);
pushable.BehaviorState = PushableBehaviourState::Fall;
@@ -572,7 +572,7 @@ namespace TEN::Entities::Generic
case PushableEnvironmentType::Water:
{
// Manage influence of gravity.
- if (pushable.IsBuoyant && pushable.Stack.ItemNumberAbove == NO_ITEM)
+ if (pushable.IsBuoyant && pushable.Stack.ItemNumberAbove == NO_VALUE)
{
pushable.Gravity = pushable.Gravity - PUSHABLE_GRAVITY_ACCEL;
if (pushable.Gravity <= 0.0f)
@@ -606,7 +606,7 @@ namespace TEN::Entities::Generic
break;
case PushableEnvironmentType::WaterFloor:
- if (pushable.IsBuoyant && pushable.Stack.ItemNumberAbove == NO_ITEM)
+ if (pushable.IsBuoyant && pushable.Stack.ItemNumberAbove == NO_VALUE)
{
pushableItem.Pose.Position.y = pushableColl.FloorHeight;
pushable.BehaviorState = PushableBehaviourState::Float;
@@ -649,7 +649,7 @@ namespace TEN::Entities::Generic
case PushableEnvironmentType::SlopedFloor:
// Set stopper flag.
- if (pushable.Stack.ItemNumberBelow == NO_ITEM)
+ if (pushable.Stack.ItemNumberBelow == NO_VALUE)
SetPushableStopperFlag(true, pushableItem.Pose.Position, pushableItem.RoomNumber);
pushable.BehaviorState = PushableBehaviourState::Fall;
@@ -719,7 +719,7 @@ namespace TEN::Entities::Generic
case PushableEnvironmentType::SlopedFloor:
case PushableEnvironmentType::Air:
// Set stopper flag.
- if (pushable.Stack.ItemNumberBelow == NO_ITEM)
+ if (pushable.Stack.ItemNumberBelow == NO_VALUE)
SetPushableStopperFlag(true, pushableItem.Pose.Position, pushableItem.RoomNumber);
pushableItem.Animation.Velocity.y = 0.0f;
@@ -742,7 +742,7 @@ namespace TEN::Entities::Generic
pushable.Gravity = PUSHABLE_GRAVITY_AIR;
}
}
- else if (pushable.IsBuoyant && pushable.Stack.ItemNumberAbove == NO_ITEM)
+ else if (pushable.IsBuoyant && pushable.Stack.ItemNumberAbove == NO_VALUE)
{
pushableItem.Animation.Velocity.y = 0.0f;
pushable.BehaviorState = PushableBehaviourState::Float;
@@ -757,7 +757,7 @@ namespace TEN::Entities::Generic
break;
case PushableEnvironmentType::Water:
- if (pushable.IsBuoyant && pushable.Stack.ItemNumberAbove == NO_ITEM)
+ if (pushable.IsBuoyant && pushable.Stack.ItemNumberAbove == NO_VALUE)
{
pushableItem.Animation.Velocity.y = 0.0f;
pushable.BehaviorState = PushableBehaviourState::Float;
@@ -769,7 +769,7 @@ namespace TEN::Entities::Generic
if (abs(pushableColl.FloorHeight - pushableItem.Pose.Position.y) > CLICK(0.75f))
{
//Reset Stopper Flag
- if (pushable.Stack.ItemNumberBelow == NO_ITEM)
+ if (pushable.Stack.ItemNumberBelow == NO_VALUE)
SetPushableStopperFlag(false, pushableItem.Pose.Position, pushableItem.RoomNumber);
pushableItem.Animation.Velocity.y = 0.0f;
diff --git a/TombEngine/Objects/Generic/Object/burning_torch.cpp b/TombEngine/Objects/Generic/Object/burning_torch.cpp
index ec7882c0b..7d271b08d 100644
--- a/TombEngine/Objects/Generic/Object/burning_torch.cpp
+++ b/TombEngine/Objects/Generic/Object/burning_torch.cpp
@@ -231,14 +231,13 @@ namespace TEN::Entities::Generic
item->Pose.Orientation.z = 0;
}
- auto velocity = Vector3i(
+ auto vel = Vector3i(
item->Animation.Velocity.z * phd_sin(item->Pose.Orientation.y),
item->Animation.Velocity.y,
- item->Animation.Velocity.z * phd_cos(item->Pose.Orientation.y)
- );
+ item->Animation.Velocity.z * phd_cos(item->Pose.Orientation.y));
auto prevPos = item->Pose.Position;
- item->Pose.Position += Vector3i(velocity.x, 0, velocity.z);
+ item->Pose.Position += Vector3i(vel.x, 0, vel.z);
if (TestEnvironment(ENV_FLAG_WATER, item) ||
TestEnvironment(ENV_FLAG_SWAMP, item))
@@ -250,26 +249,31 @@ namespace TEN::Entities::Generic
item->ItemFlags[3] = 0;
}
else
+ {
item->Animation.Velocity.y += 6;
+ }
item->Pose.Position.y += item->Animation.Velocity.y;
- DoProjectileDynamics(itemNumber, prevPos.x, prevPos.y, prevPos.z, velocity.x, velocity.y, velocity.z);
+ DoProjectileDynamics(itemNumber, prevPos.x, prevPos.y, prevPos.z, vel.x, vel.y, vel.z);
// Collide with entities.
- if (GetCollidedObjects(item, 0, true, CollidedItems, CollidedMeshes, true))
+ auto collObjects = GetCollidedObjects(*item, true, true);
+ if (!collObjects.IsEmpty())
{
LaraCollision.Setup.EnableObjectPush = true;
- if (CollidedItems[0])
+ if (!collObjects.ItemPtrs.empty())
{
- if (!Objects[CollidedItems[0]->ObjectNumber].intelligent &&
- CollidedItems[0]->ObjectNumber != ID_LARA)
+ const auto& object = Objects[collObjects.ItemPtrs.front()->ObjectNumber];
+
+ if (!object.intelligent &&
+ !collObjects.ItemPtrs.front()->IsLara())
{
- ObjectCollision(CollidedItems[0]->Index, item, &LaraCollision);
+ ObjectCollision(collObjects.ItemPtrs.front()->Index, item, &LaraCollision);
}
}
- else if (CollidedMeshes[0])
+ else if (!collObjects.StaticPtrs.empty())
{
- ItemPushStatic(item, *CollidedMeshes[0], &LaraCollision);
+ ItemPushStatic(item, *collObjects.StaticPtrs.front(), &LaraCollision);
}
item->Animation.Velocity.z = -int(item->Animation.Velocity.z / 1.5f);
diff --git a/TombEngine/Objects/Generic/Switches/crowbar_switch.cpp b/TombEngine/Objects/Generic/Switches/crowbar_switch.cpp
index f3aa638b9..92fbe361b 100644
--- a/TombEngine/Objects/Generic/Switches/crowbar_switch.cpp
+++ b/TombEngine/Objects/Generic/Switches/crowbar_switch.cpp
@@ -77,7 +77,7 @@ namespace TEN::Entities::Switches
else
laraInfo->Context.InteractedItem = itemNumber;
- g_Gui.SetInventoryItemChosen(NO_ITEM);
+ g_Gui.SetInventoryItemChosen(NO_VALUE);
}
else
doSwitch = -1;
@@ -106,7 +106,7 @@ namespace TEN::Entities::Switches
else
laraInfo->Context.InteractedItem = itemNumber;
- g_Gui.SetInventoryItemChosen(NO_ITEM);
+ g_Gui.SetInventoryItemChosen(NO_VALUE);
}
else
doSwitch = -1;
diff --git a/TombEngine/Objects/Generic/Traps/dart_emitter.cpp b/TombEngine/Objects/Generic/Traps/dart_emitter.cpp
index ee746b015..eb7fa126e 100644
--- a/TombEngine/Objects/Generic/Traps/dart_emitter.cpp
+++ b/TombEngine/Objects/Generic/Traps/dart_emitter.cpp
@@ -74,7 +74,7 @@ namespace TEN::Entities::Traps
}
int dartItemNumber = CreateItem();
- if (dartItemNumber == NO_ITEM)
+ if (dartItemNumber == NO_VALUE)
return;
ItemInfo* dartItem = &g_Level.Items[dartItemNumber];
diff --git a/TombEngine/Objects/Generic/puzzles_keys.cpp b/TombEngine/Objects/Generic/puzzles_keys.cpp
index d8cadab16..811896ad1 100644
--- a/TombEngine/Objects/Generic/puzzles_keys.cpp
+++ b/TombEngine/Objects/Generic/puzzles_keys.cpp
@@ -67,7 +67,7 @@ void InitializePuzzleDone(short itemNumber)
auto& receptacleItem = g_Level.Items[itemNumber];
const auto& anim = GetAnimData(receptacleItem);
- receptacleItem.Animation.RequiredState = NO_STATE;
+ receptacleItem.Animation.RequiredState = NO_VALUE;
receptacleItem.Animation.FrameNumber = anim.frameBase + anim.frameEnd;
}
@@ -108,7 +108,7 @@ void PuzzleHoleCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* co
puzzleType = PuzzleType::Specfic;
}
- if (((IsHeld(In::Action) || g_Gui.GetInventoryItemChosen() != NO_ITEM) &&
+ if (((IsHeld(In::Action) || g_Gui.GetInventoryItemChosen() != NO_VALUE) &&
laraItem->Animation.ActiveState == LS_IDLE &&
laraItem->Animation.AnimNumber == LA_STAND_IDLE &&
player.Control.HandStatus == HandStatus::Free &&
@@ -128,7 +128,7 @@ void PuzzleHoleCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* co
{
if (!player.Control.IsMoving)
{
- if (g_Gui.GetInventoryItemChosen() == NO_ITEM)
+ if (g_Gui.GetInventoryItemChosen() == NO_VALUE)
{
if (g_Gui.IsObjectInInventory(receptacleItem.ObjectNumber - (ID_PUZZLE_HOLE1 - ID_PUZZLE_ITEM1)))
g_Gui.SetEnterInventory(receptacleItem.ObjectNumber - (ID_PUZZLE_HOLE1 - ID_PUZZLE_ITEM1));
@@ -150,7 +150,7 @@ void PuzzleHoleCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* co
if (!MoveLaraPosition(pos, &receptacleItem, laraItem))
{
player.Context.InteractedItem = itemNumber;
- g_Gui.SetInventoryItemChosen(NO_ITEM);
+ g_Gui.SetInventoryItemChosen(NO_VALUE);
receptacleItem.Pose.Orientation.y = prevYOrient;
return;
}
@@ -173,7 +173,7 @@ void PuzzleHoleCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* co
receptacleItem.ItemFlags[0] = 1;
}
- g_Gui.SetInventoryItemChosen(NO_ITEM);
+ g_Gui.SetInventoryItemChosen(NO_VALUE);
ResetPlayerFlex(laraItem);
laraItem->Animation.FrameNumber = GetAnimData(laraItem).frameBase;
player.Control.IsMoving = false;
@@ -281,7 +281,7 @@ void PuzzleDoneCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* co
if (!MoveLaraPosition(pos, &receptacleItem, laraItem))
{
player.Context.InteractedItem = itemNumber;
- g_Gui.SetInventoryItemChosen(NO_ITEM);
+ g_Gui.SetInventoryItemChosen(NO_VALUE);
receptacleItem.Pose.Orientation.y = prevYOrient;
return;
}
@@ -348,7 +348,7 @@ void PuzzleDone(ItemInfo* item, short itemNumber)
item->Animation.FrameNumber = GetAnimData(item).frameBase;
item->Animation.ActiveState = GetAnimData(item).ActiveState;
item->Animation.TargetState = GetAnimData(item).ActiveState;
- item->Animation.RequiredState = NO_STATE;
+ item->Animation.RequiredState = NO_VALUE;
item->ResetModelToDefault();
AddActiveItem(itemNumber);
@@ -447,7 +447,7 @@ void KeyHoleCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
short triggerType = (*(triggerIndexPtr++) >> 8) & TRIGGER_BITS;
- bool isActionReady = (IsHeld(In::Action) || g_Gui.GetInventoryItemChosen() != NO_ITEM);
+ bool isActionReady = (IsHeld(In::Action) || g_Gui.GetInventoryItemChosen() != NO_VALUE);
bool isPlayerAvailable = (player->Control.Look.OpticRange == 0 &&
laraItem->Animation.ActiveState == LS_IDLE &&
@@ -464,7 +464,7 @@ void KeyHoleCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
if (keyHoleItem->Status != ITEM_NOT_ACTIVE && triggerType != TRIGGER_TYPES::SWITCH)
return;
- if (g_Gui.GetInventoryItemChosen() == NO_ITEM)
+ if (g_Gui.GetInventoryItemChosen() == NO_VALUE)
{
if (g_Gui.IsObjectInInventory(keyHoleItem->ObjectNumber - (ID_KEY_HOLE1 - ID_KEY_ITEM1)))
g_Gui.SetEnterInventory(keyHoleItem->ObjectNumber - (ID_KEY_HOLE1 - ID_KEY_ITEM1));
@@ -511,7 +511,7 @@ void KeyHoleCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
keyHoleItem->Status = ITEM_ACTIVE;
}
- g_Gui.SetInventoryItemChosen(NO_ITEM);
+ g_Gui.SetInventoryItemChosen(NO_VALUE);
return;
}
diff --git a/TombEngine/Objects/TR1/Entity/Cowboy.cpp b/TombEngine/Objects/TR1/Entity/Cowboy.cpp
index d001f3d62..befd4d1f3 100644
--- a/TombEngine/Objects/TR1/Entity/Cowboy.cpp
+++ b/TombEngine/Objects/TR1/Entity/Cowboy.cpp
@@ -102,7 +102,7 @@ namespace TEN::Entities::Creatures::TR1
case COWBOY_STATE_IDLE:
creature.MaxTurn = 0;
- if (item.Animation.RequiredState != NO_STATE)
+ if (item.Animation.RequiredState != NO_VALUE)
{
item.Animation.TargetState = item.Animation.RequiredState;
}
@@ -167,7 +167,7 @@ namespace TEN::Entities::Creatures::TR1
extraTorsoRot.y = ai.angle / 2;
}
- if (item.Animation.RequiredState != NO_STATE)
+ if (item.Animation.RequiredState != NO_VALUE)
{
item.Animation.TargetState = COWBOY_STATE_IDLE;
}
diff --git a/TombEngine/Objects/TR1/Entity/Kold.cpp b/TombEngine/Objects/TR1/Entity/Kold.cpp
index 546bb6278..dfdfaf044 100644
--- a/TombEngine/Objects/TR1/Entity/Kold.cpp
+++ b/TombEngine/Objects/TR1/Entity/Kold.cpp
@@ -98,7 +98,7 @@ namespace TEN::Entities::Creatures::TR1
case KOLD_STATE_IDLE:
creature.MaxTurn = 0;
- if (item.Animation.RequiredState != NO_STATE)
+ if (item.Animation.RequiredState != NO_VALUE)
{
item.Animation.TargetState = item.Animation.RequiredState;
}
@@ -162,7 +162,7 @@ namespace TEN::Entities::Creatures::TR1
creature.MaxTurn = 0;
creature.Flags = 0;
- if (item.Animation.RequiredState != NO_STATE)
+ if (item.Animation.RequiredState != NO_VALUE)
{
item.Animation.TargetState = KOLD_STATE_IDLE;
}
diff --git a/TombEngine/Objects/TR1/Entity/SkateboardKid.cpp b/TombEngine/Objects/TR1/Entity/SkateboardKid.cpp
index c751fd541..7e9160975 100644
--- a/TombEngine/Objects/TR1/Entity/SkateboardKid.cpp
+++ b/TombEngine/Objects/TR1/Entity/SkateboardKid.cpp
@@ -61,7 +61,7 @@ namespace TEN::Entities::Creatures::TR1
static void SpawnSkateboard(ItemInfo& item)
{
int skateItemNumber = CreateItem();
- if (skateItemNumber == NO_ITEM)
+ if (skateItemNumber == NO_VALUE)
return;
auto& skate = g_Level.Items[skateItemNumber];
@@ -112,22 +112,25 @@ namespace TEN::Entities::Creatures::TR1
{
if (!CreatureActive(itemNumber))
return;
+
auto& item = g_Level.Items[itemNumber];
- if (item.ItemFlags[0] == NO_ITEM)
+
+ if (item.ItemFlags[0] == NO_VALUE)
{
TENLog("Failed to do the skateboard kid control (itemNumber: " + std::to_string(itemNumber) + "), the skateboard itemNumber is missing, probably failed to be created !");
return;
}
+
auto& creature = *GetCreatureInfo(&item);
auto& skateItem = g_Level.Items[item.ItemFlags[0]];
short headingAngle = 0;
auto extraHeadRot = EulerAngles::Identity;
auto extraTorsoRot = EulerAngles::Identity;
- if (skateItem.Status & ITEM_INVISIBLE)
+ if (skateItem.Status == ITEM_INVISIBLE)
{
skateItem.Active = true;
- skateItem.Status &= ~(ITEM_INVISIBLE);
+ skateItem.Status = ITEM_ACTIVE;
}
for (auto& flash : creature.MuzzleFlash)
@@ -164,7 +167,7 @@ namespace TEN::Entities::Creatures::TR1
creature.MaxTurn = KID_TURN_RATE_MAX;
creature.Flags = 0;
- if (item.Animation.RequiredState != NO_STATE)
+ if (item.Animation.RequiredState != NO_VALUE)
{
item.Animation.TargetState = item.Animation.RequiredState;
}
diff --git a/TombEngine/Objects/TR1/Entity/tr1_ape.cpp b/TombEngine/Objects/TR1/Entity/tr1_ape.cpp
index 9eb9876fd..2c6df8a84 100644
--- a/TombEngine/Objects/TR1/Entity/tr1_ape.cpp
+++ b/TombEngine/Objects/TR1/Entity/tr1_ape.cpp
@@ -201,7 +201,7 @@ namespace TEN::Entities::Creatures::TR1
creatureInfo->Flags -= APE_FLAG_TURN_RIGHT;
}
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else if (AI.bite && AI.distance < APE_ATTACK_RANGE)
item->Animation.TargetState = APE_STATE_ATTACK;
@@ -286,7 +286,7 @@ namespace TEN::Entities::Creatures::TR1
break;
case APE_STATE_ATTACK:
- if (item->Animation.RequiredState == NO_STATE &&
+ if (item->Animation.RequiredState == NO_VALUE &&
item->TouchBits.Test(ApeAttackJoints))
{
item->Animation.RequiredState = APE_STATE_IDLE;
diff --git a/TombEngine/Objects/TR1/Entity/tr1_bear.cpp b/TombEngine/Objects/TR1/Entity/tr1_bear.cpp
index 8d219f369..6ce1bc0c7 100644
--- a/TombEngine/Objects/TR1/Entity/tr1_bear.cpp
+++ b/TombEngine/Objects/TR1/Entity/tr1_bear.cpp
@@ -187,7 +187,7 @@ namespace TEN::Entities::Creatures::TR1
item.Animation.TargetState = BEAR_STATE_LOW_WALK;
}
}
- else if (item.Animation.RequiredState != NO_STATE)
+ else if (item.Animation.RequiredState != NO_VALUE)
{
item.Animation.TargetState = item.Animation.RequiredState;
}
@@ -210,7 +210,7 @@ namespace TEN::Entities::Creatures::TR1
if (creature.Mood == MoodType::Bored ||
isPlayerDead ||
- item.Animation.RequiredState != NO_STATE)
+ item.Animation.RequiredState != NO_VALUE)
{
// Go to WALK, EAT, or RequiredState state.
item.Animation.TargetState = BEAR_STATE_LOW_IDLE;
@@ -234,7 +234,7 @@ namespace TEN::Entities::Creatures::TR1
break;
case BEAR_STATE_LOW_CHARGE_ATTACK:
- if (item.Animation.RequiredState == NO_STATE &&
+ if (item.Animation.RequiredState == NO_VALUE &&
item.TouchBits.Test(BearAttackJoints))
{
DoDamage(creature.Enemy, BEAR_LOW_CHARGE_ATTACK_DAMAGE);
@@ -284,7 +284,7 @@ namespace TEN::Entities::Creatures::TR1
item.Animation.RequiredState = BEAR_STATE_LOW_WALK;
item.Animation.TargetState = BEAR_STATE_LOW_IDLE;
}
- else if (item.Animation.RequiredState != NO_STATE)
+ else if (item.Animation.RequiredState != NO_VALUE)
{
item.Animation.TargetState = item.Animation.RequiredState;
}
@@ -308,7 +308,7 @@ namespace TEN::Entities::Creatures::TR1
break;
case BEAR_STATE_HIGH_CLAW_ATTACK:
- if (item.Animation.RequiredState == NO_STATE &&
+ if (item.Animation.RequiredState == NO_VALUE &&
item.TouchBits.Test(BearAttackJoints))
{
DoDamage(creature.Enemy, BEAR_HIGH_CLAW_ATTACK_DAMAGE);
diff --git a/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp b/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp
index c29232faf..cfd63dc11 100644
--- a/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp
+++ b/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp
@@ -145,7 +145,7 @@ namespace TEN::Entities::Creatures::TR1
switch (item->Animation.ActiveState)
{
case BIG_RAT_STATE_IDLE:
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else if (ai.bite && ai.distance < BIG_RAT_LAND_BITE_ATTACK_RANGE)
item->Animation.TargetState = BIG_RAT_STATE_LAND_BITE_ATTACK;
@@ -180,7 +180,7 @@ namespace TEN::Entities::Creatures::TR1
break;
case BIG_RAT_STATE_LAND_BITE_ATTACK:
- if (item->Animation.RequiredState == NO_STATE && ai.ahead &&
+ if (item->Animation.RequiredState == NO_VALUE && ai.ahead &&
item->TouchBits.Test(BigRatBite.BoneID))
{
DoDamage(creature->Enemy, BIG_RAT_BITE_ATTACK_DAMAGE);
@@ -191,7 +191,7 @@ namespace TEN::Entities::Creatures::TR1
break;
case BIG_RAT_STATE_POUNCE_ATTACK:
- if (item->Animation.RequiredState == NO_STATE && ai.ahead &&
+ if (item->Animation.RequiredState == NO_VALUE && ai.ahead &&
item->TouchBits.Test(BigRatBite.BoneID))
{
DoDamage(creature->Enemy, BIG_RAT_POUNCE_ATTACK_DAMAGE);
@@ -222,7 +222,7 @@ namespace TEN::Entities::Creatures::TR1
break;
case BIG_RAT_STATE_SWIM_BITE_ATTACK:
- if (item->Animation.RequiredState == NO_STATE && ai.ahead &&
+ if (item->Animation.RequiredState == NO_VALUE && ai.ahead &&
item->TouchBits.Test(BigRatBite.BoneID))
{
DoDamage(creature->Enemy, BIG_RAT_BITE_ATTACK_DAMAGE);
diff --git a/TombEngine/Objects/TR1/Entity/tr1_centaur.cpp b/TombEngine/Objects/TR1/Entity/tr1_centaur.cpp
index 85b10484f..4e0904cdb 100644
--- a/TombEngine/Objects/TR1/Entity/tr1_centaur.cpp
+++ b/TombEngine/Objects/TR1/Entity/tr1_centaur.cpp
@@ -82,7 +82,7 @@ namespace TEN::Entities::Creatures::TR1
{
case CENTAUR_STATE_IDLE:
CreatureJoint(item, 17, 0);
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else if (AI.bite && AI.distance < pow(CENTAUR_REAR_RANGE, 2))
item->Animation.TargetState = CENTAUR_STATE_RUN_FORWARD;
@@ -113,7 +113,7 @@ namespace TEN::Entities::Creatures::TR1
break;
case CENTAUR_STATE_AIM:
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else if (Targetable(item, &AI))
item->Animation.TargetState = CENTAUR_PROJECTILE_ATTACK;
@@ -123,7 +123,7 @@ namespace TEN::Entities::Creatures::TR1
break;
case CENTAUR_PROJECTILE_ATTACK:
- if (item->Animation.RequiredState == NO_STATE)
+ if (item->Animation.RequiredState == NO_VALUE)
{
item->Animation.RequiredState = CENTAUR_STATE_AIM;
CreatureEffect2(item, CentaurRocketBite, CENTAUR_BOMB_VELOCITY, head, BombGun);
@@ -132,7 +132,7 @@ namespace TEN::Entities::Creatures::TR1
break;
case CENTAUR_STATE_WARNING:
- if (item->Animation.RequiredState == NO_STATE &&
+ if (item->Animation.RequiredState == NO_VALUE &&
item->TouchBits.Test(CentaurAttackJoints))
{
DoDamage(creature->Enemy, CENTAUR_REAR_DAMAGE);
diff --git a/TombEngine/Objects/TR1/Entity/tr1_natla.cpp b/TombEngine/Objects/TR1/Entity/tr1_natla.cpp
index b3ab6f951..2fd77fcda 100644
--- a/TombEngine/Objects/TR1/Entity/tr1_natla.cpp
+++ b/TombEngine/Objects/TR1/Entity/tr1_natla.cpp
@@ -301,7 +301,7 @@ namespace TEN::Entities::Creatures::TR1
case NATLA_STATE_AIM:
creature->MaxTurn = NATLA_FLY_ANGLE_SPEED;
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
{
item->Animation.TargetState = item->Animation.RequiredState;
}
@@ -319,7 +319,7 @@ namespace TEN::Entities::Creatures::TR1
case NATLA_STATE_SHOOT:
creature->MaxTurn = NATLA_FLY_ANGLE_SPEED;
- if (item->Animation.RequiredState == NO_STATE && ai.ahead)
+ if (item->Animation.RequiredState == NO_VALUE && ai.ahead)
{
CreatureEffect2(item, NatlaGunBite, NATLA_GUN_VELOCITY, ai.angle, BombGun);
CreatureEffect2(item, NatlaGunBite, NATLA_GUN_VELOCITY, ai.angle + (GetRandomControl() - ANGLE(45.0f)) / 4, BombGun);
diff --git a/TombEngine/Objects/TR1/Entity/tr1_winged_mutant.cpp b/TombEngine/Objects/TR1/Entity/tr1_winged_mutant.cpp
index 469ee2f20..d0f36cd62 100644
--- a/TombEngine/Objects/TR1/Entity/tr1_winged_mutant.cpp
+++ b/TombEngine/Objects/TR1/Entity/tr1_winged_mutant.cpp
@@ -450,7 +450,7 @@ namespace TEN::Entities::Creatures::TR1
break;
case WMUTANT_STATE_IDLE_JUMP_ATTACK:
- if (item->Animation.RequiredState == NO_STATE &&
+ if (item->Animation.RequiredState == NO_VALUE &&
(item->TouchBits.Test(WingedMutantHandsJoints) || item->TouchBits.Test(WingedMutantHeadJoints)) && creature->Flags == 0)
{
DoDamage(creature->Enemy, WINGED_MUTANT_IDLE_JUMP_ATTACK_DAMAGE / 2);
@@ -466,7 +466,7 @@ namespace TEN::Entities::Creatures::TR1
break;
case WMUTANT_STATE_RUN_JUMP_ATTACK:
- if (item->Animation.RequiredState == NO_STATE &&
+ if (item->Animation.RequiredState == NO_VALUE &&
(item->TouchBits.Test(WingedMutantHandsJoints) || item->TouchBits.Test(WingedMutantHeadJoints)) && creature->Flags == 0)
{
DoDamage(creature->Enemy, WINGED_MUTANT_RUN_JUMP_ATTACK_DAMAGE / 2);
@@ -482,7 +482,7 @@ namespace TEN::Entities::Creatures::TR1
break;
case WMUTANT_STATE_SWIPE_ATTACK:
- if (item->Animation.RequiredState == NO_STATE &&
+ if (item->Animation.RequiredState == NO_VALUE &&
item->TouchBits.Test(WingedMutantHandsJoints) && creature->Flags == 0)
{
DoDamage(creature->Enemy, WINGED_MUTANT_SWIPE_ATTACK_DAMAGE / 2);
diff --git a/TombEngine/Objects/TR1/Entity/tr1_wolf.cpp b/TombEngine/Objects/TR1/Entity/tr1_wolf.cpp
index 39af75005..316ad01a4 100644
--- a/TombEngine/Objects/TR1/Entity/tr1_wolf.cpp
+++ b/TombEngine/Objects/TR1/Entity/tr1_wolf.cpp
@@ -152,7 +152,7 @@ namespace TEN::Entities::Creatures::TR1
break;
case WOLF_STATE_IDLE:
- if (item.Animation.RequiredState != NO_STATE)
+ if (item.Animation.RequiredState != NO_VALUE)
{
item.Animation.TargetState = item.Animation.RequiredState;
}
@@ -169,7 +169,7 @@ namespace TEN::Entities::Creatures::TR1
if (creature.Mood != MoodType::Bored)
{
item.Animation.TargetState = WOLF_STATE_STALK;
- item.Animation.RequiredState = NO_STATE;
+ item.Animation.RequiredState = NO_VALUE;
}
else if (Random::TestProbability(WOLF_SLEEP_CHANCE))
{
@@ -180,7 +180,7 @@ namespace TEN::Entities::Creatures::TR1
break;
case WOLF_STATE_CROUCH:
- if (item.Animation.RequiredState != NO_STATE)
+ if (item.Animation.RequiredState != NO_VALUE)
{
item.Animation.TargetState = item.Animation.RequiredState;
}
@@ -257,7 +257,7 @@ namespace TEN::Entities::Creatures::TR1
else
{
item.Animation.TargetState = WOLF_STATE_JUMP_ATTACK;
- item.Animation.RequiredState = NO_STATE;
+ item.Animation.RequiredState = NO_VALUE;
}
}
else if (creature.Mood == MoodType::Stalk &&
@@ -276,7 +276,7 @@ namespace TEN::Entities::Creatures::TR1
case WOLF_STATE_JUMP_ATTACK:
tiltAngle = headingAngle;
- if (item.Animation.RequiredState == NO_STATE &&
+ if (item.Animation.RequiredState == NO_VALUE &&
item.TouchBits.Test(WolfAttackJoints))
{
item.Animation.RequiredState = WOLF_STATE_RUN;
@@ -288,7 +288,7 @@ namespace TEN::Entities::Creatures::TR1
break;
case WOLF_STATE_BITE_ATTACK:
- if (ai.ahead && item.Animation.RequiredState == NO_STATE &&
+ if (ai.ahead && item.Animation.RequiredState == NO_VALUE &&
item.TouchBits.Test(WolfAttackJoints))
{
item.Animation.RequiredState = WOLF_STATE_CROUCH;
diff --git a/TombEngine/Objects/TR2/Entity/Dragon.cpp b/TombEngine/Objects/TR2/Entity/Dragon.cpp
index 6cab05dbf..e4dc52f49 100644
--- a/TombEngine/Objects/TR2/Entity/Dragon.cpp
+++ b/TombEngine/Objects/TR2/Entity/Dragon.cpp
@@ -118,7 +118,7 @@ namespace TEN::Entities::Creatures::TR2
int frontBoneItemNumber = SpawnItem(item, ID_DRAGON_BONE_FRONT);
int backBoneItemNumber = SpawnItem(item, ID_DRAGON_BONE_BACK);
- if (backBoneItemNumber == NO_ITEM || frontBoneItemNumber == NO_ITEM)
+ if (backBoneItemNumber == NO_VALUE || frontBoneItemNumber == NO_VALUE)
{
TENLog("Failed to create dragon skeleton objects.", LogLevel::Warning);
return;
@@ -129,7 +129,7 @@ namespace TEN::Entities::Creatures::TR2
{
int backItemNumber = SpawnItem(frontItem, ID_DRAGON_BACK);
- if (backItemNumber == NO_ITEM)
+ if (backItemNumber == NO_VALUE)
{
TENLog("Failed to create dragon back body segment.", LogLevel::Warning);
return;
@@ -143,7 +143,7 @@ namespace TEN::Entities::Creatures::TR2
// Store back body segment item number.
frontItem.ItemFlags[0] = backItemNumber;
- backItem.ItemFlags[0] = NO_ITEM;
+ backItem.ItemFlags[0] = NO_VALUE;
}
void InitializeDragon(short itemNumber)
@@ -168,7 +168,7 @@ namespace TEN::Entities::Creatures::TR2
if (backItem.Status == ITEM_DEACTIVATED)
{
KillItem(backItem.Index);
- backItemNumber = NO_ITEM;
+ backItemNumber = NO_VALUE;
return;
}
diff --git a/TombEngine/Objects/TR2/Entity/tr2_eagle_or_crow.cpp b/TombEngine/Objects/TR2/Entity/tr2_eagle_or_crow.cpp
index 4dba5a129..d7f089c78 100644
--- a/TombEngine/Objects/TR2/Entity/tr2_eagle_or_crow.cpp
+++ b/TombEngine/Objects/TR2/Entity/tr2_eagle_or_crow.cpp
@@ -130,7 +130,7 @@ namespace TEN::Entities::Creatures::TR2
case 1:
creature->Flags = 0;
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
if (creature->Mood == MoodType::Bored)
item->Animation.TargetState = 2;
diff --git a/TombEngine/Objects/TR2/Entity/tr2_knife_thrower.cpp b/TombEngine/Objects/TR2/Entity/tr2_knife_thrower.cpp
index 5388d56ad..e528fac37 100644
--- a/TombEngine/Objects/TR2/Entity/tr2_knife_thrower.cpp
+++ b/TombEngine/Objects/TR2/Entity/tr2_knife_thrower.cpp
@@ -74,7 +74,7 @@ namespace TEN::Entities::Creatures::TR2
short ThrowKnife(int x, int y, int z, float vel, short yRot, int roomNumber)
{
int fxNumber = CreateNewEffect(roomNumber);
- if (fxNumber == NO_ITEM)
+ if (fxNumber == NO_VALUE)
return fxNumber;
auto& fx = EffectList[fxNumber];
diff --git a/TombEngine/Objects/TR2/Entity/tr2_rat.cpp b/TombEngine/Objects/TR2/Entity/tr2_rat.cpp
index 398a74d3c..365ec4eb5 100644
--- a/TombEngine/Objects/TR2/Entity/tr2_rat.cpp
+++ b/TombEngine/Objects/TR2/Entity/tr2_rat.cpp
@@ -97,7 +97,7 @@ namespace TEN::Entities::Creatures::TR2
else
item->Animation.RequiredState = RAT_STATE_WALK_FORWARD;
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = RAT_STATE_IDLE;
break;
@@ -105,7 +105,7 @@ namespace TEN::Entities::Creatures::TR2
case RAT_STATE_IDLE:
creature->MaxTurn = 0;
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
break;
@@ -130,7 +130,7 @@ namespace TEN::Entities::Creatures::TR2
break;
case RAT_STATE_POUNCE_ATTACK:
- if (item->Animation.RequiredState == NO_STATE &&
+ if (item->Animation.RequiredState == NO_VALUE &&
item->TouchBits.Test(RatBite.BoneID))
{
item->Animation.RequiredState = RAT_STATE_IDLE;
diff --git a/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp b/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp
index d5093d5a6..cdbb893a8 100644
--- a/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp
+++ b/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp
@@ -116,7 +116,7 @@ namespace TEN::Entities::Creatures::TR2
if (ai.ahead)
extraHeadRot.y = ai.angle;
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
break;
@@ -321,7 +321,7 @@ namespace TEN::Entities::Creatures::TR2
extraHeadRot.y = ai.angle;
}
- if (item->Animation.RequiredState == NO_STATE &&
+ if (item->Animation.RequiredState == NO_VALUE &&
(item->Animation.AnimNumber == GetAnimIndex(*item, SILENCER_ANIM_RUN_FORWARD_SHOOT_LEFT) &&
item->Animation.FrameNumber == GetFrameIndex(item, 1) ||
item->Animation.AnimNumber == GetAnimIndex(*item, SILENCER_ANIM_RUN_FORWARD_SHOOT_RIGHT) &&
diff --git a/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp b/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp
index 6f3a2f029..4b573f7b5 100644
--- a/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp
+++ b/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp
@@ -54,7 +54,7 @@ namespace TEN::Entities::Creatures::TR2
static void CreateSkidooGun(ItemInfo& riderItem)
{
int skidooItemNumber = CreateItem();
- if (skidooItemNumber == NO_ITEM)
+ if (skidooItemNumber == NO_VALUE)
{
TENLog("Failed to create ID_SNOWMOBILE_GUN from ID_SNOWMOBILE_DRIVER.", LogLevel::Warning);
return;
@@ -111,7 +111,7 @@ namespace TEN::Entities::Creatures::TR2
}
}
- if (Lara.Context.Vehicle == NO_ITEM && item.Animation.Velocity.z > 0.0f)
+ if (Lara.Context.Vehicle == NO_VALUE && item.Animation.Velocity.z > 0.0f)
DoDamage(laraItem, 100);
}
@@ -250,7 +250,7 @@ namespace TEN::Entities::Creatures::TR2
{
if (creature->Flags == 0 && abs(ai.angle) < SKIDOO_MAN_TARGET_ANGLE && creature->Enemy->HitPoints > 0)
{
- int damage = (creature->Enemy->IsLara() && GetLaraInfo(creature->Enemy)->Context.Vehicle != NO_ITEM) ? 10 : 50;
+ int damage = (creature->Enemy->IsLara() && GetLaraInfo(creature->Enemy)->Context.Vehicle != NO_VALUE) ? 10 : 50;
ShotLara(skidooItem, &ai, SkidooBiteLeft, 0, damage);
diff --git a/TombEngine/Objects/TR2/Entity/tr2_yeti.cpp b/TombEngine/Objects/TR2/Entity/tr2_yeti.cpp
index 26b39a5bd..14b8e5f0c 100644
--- a/TombEngine/Objects/TR2/Entity/tr2_yeti.cpp
+++ b/TombEngine/Objects/TR2/Entity/tr2_yeti.cpp
@@ -96,7 +96,7 @@ namespace TEN::Entities::Creatures::TR2
if (creature->Mood == MoodType::Escape)
item->Animation.TargetState = 1;
- else if (item->Animation.RequiredState != NO_STATE)
+ else if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else if (creature->Mood == MoodType::Bored)
{
diff --git a/TombEngine/Objects/TR2/Vehicles/skidoo.cpp b/TombEngine/Objects/TR2/Vehicles/skidoo.cpp
index cff60fb15..47ec2fa3c 100644
--- a/TombEngine/Objects/TR2/Vehicles/skidoo.cpp
+++ b/TombEngine/Objects/TR2/Vehicles/skidoo.cpp
@@ -139,7 +139,7 @@ namespace TEN::Entities::Vehicles
auto* skidooItem = &g_Level.Items[itemNumber];
auto* lara = GetLaraInfo(laraItem);
- if (laraItem->HitPoints < 0 || lara->Context.Vehicle != NO_ITEM)
+ if (laraItem->HitPoints < 0 || lara->Context.Vehicle != NO_VALUE)
return;
auto mountType = GetVehicleMountType(skidooItem, laraItem, coll, SkidooMountTypes, SKIDOO_MOUNT_DISTANCE);
@@ -205,7 +205,7 @@ namespace TEN::Entities::Vehicles
auto* lara = GetLaraInfo(laraItem);
auto* skidoo = GetSkidooInfo(skidooItem);
- if (lara->Context.Vehicle != NO_ITEM)
+ if (lara->Context.Vehicle != NO_VALUE)
{
if ((laraItem->Animation.ActiveState == SKIDOO_STATE_DISMOUNT_RIGHT || laraItem->Animation.ActiveState == SKIDOO_STATE_DISMOUNT_LEFT) &&
TestLastFrame(laraItem))
diff --git a/TombEngine/Objects/TR2/Vehicles/speedboat.cpp b/TombEngine/Objects/TR2/Vehicles/speedboat.cpp
index 5f85dba8e..037c06ab8 100644
--- a/TombEngine/Objects/TR2/Vehicles/speedboat.cpp
+++ b/TombEngine/Objects/TR2/Vehicles/speedboat.cpp
@@ -167,7 +167,7 @@ namespace TEN::Entities::Vehicles
auto* speedboatItem = &g_Level.Items[itemNumber];
auto* lara = GetLaraInfo(laraItem);
- if (laraItem->HitPoints < 0 || lara->Context.Vehicle != NO_ITEM)
+ if (laraItem->HitPoints < 0 || lara->Context.Vehicle != NO_VALUE)
return;
auto mountType = GetVehicleMountType(speedboatItem, laraItem, coll, SpeedboatMountTypes, SPEEDBOAT_MOUNT_DISTANCE, LARA_HEIGHT);
@@ -278,7 +278,7 @@ namespace TEN::Entities::Vehicles
laraItem->Animation.Velocity.y = -50;
laraItem->Pose.Orientation.x = 0;
laraItem->Pose.Orientation.z = 0;
- lara->Context.Vehicle = NO_ITEM; // Leave vehicle itself active for inertia.
+ lara->Context.Vehicle = NO_VALUE; // Leave vehicle itself active for inertia.
int x = laraItem->Pose.Position.x + 360 * phd_sin(laraItem->Pose.Orientation.y);
int y = laraItem->Pose.Position.y - 90;
@@ -302,7 +302,7 @@ namespace TEN::Entities::Vehicles
void SpeedboatDoBoatShift(ItemInfo* speedboatItem, int itemNumber)
{
short itemNumber2 = g_Level.Rooms[speedboatItem->RoomNumber].itemNumber;
- while (itemNumber2 != NO_ITEM)
+ while (itemNumber2 != NO_VALUE)
{
auto* item = &g_Level.Items[itemNumber2];
diff --git a/TombEngine/Objects/TR3/Entity/Compsognathus.cpp b/TombEngine/Objects/TR3/Entity/Compsognathus.cpp
index 0f418aadc..6c891f5da 100644
--- a/TombEngine/Objects/TR3/Entity/Compsognathus.cpp
+++ b/TombEngine/Objects/TR3/Entity/Compsognathus.cpp
@@ -15,8 +15,8 @@
#include "Objects/TR3/Object/Corpse.h"
#include "Specific/level.h"
-using namespace TEN::Math;
using namespace TEN::Entities::TR3;
+using namespace TEN::Math;
namespace TEN::Entities::Creatures::TR3
{
@@ -117,7 +117,7 @@ namespace TEN::Entities::Creatures::TR3
if (cadaverPos == INVALID_CADAVER_POSITION)
{
- float shortestDistance = INFINITY;
+ float shortestDist = INFINITY;
for (auto& targetItem : g_Level.Items)
{
if (!Objects.CheckID(targetItem.ObjectNumber) || targetItem.Index == itemNumber || targetItem.RoomNumber == NO_ROOM)
@@ -125,11 +125,12 @@ namespace TEN::Entities::Creatures::TR3
if (SameZone(creature, &targetItem))
{
- float distance = Vector3i::Distance(item->Pose.Position, targetItem.Pose.Position);
- if (distance < shortestDistance && targetItem.ObjectNumber == ID_CORPSE && targetItem.Active && TriggerActive(&targetItem) && targetItem.ItemFlags[1] == (int)CorpseFlags::Lying)
+ float dist = Vector3i::Distance(item->Pose.Position, targetItem.Pose.Position);
+ if (dist < shortestDist && targetItem.ObjectNumber == ID_CORPSE && targetItem.Active &&
+ TriggerActive(&targetItem) && targetItem.ItemFlags[1] == (int)CorpseFlag::Grounded)
{
cadaverPos = targetItem.Pose.Position.ToVector3();
- shortestDistance = distance;
+ shortestDist = dist;
item->ItemFlags[1] = ATTACK_CADAVER;
}
}
@@ -163,7 +164,7 @@ namespace TEN::Entities::Creatures::TR3
{
item->ItemFlags[0] = (random + 0x700) >> 7;
- // Scared for less time the more compys there are - adjust this when we've got lots of them.
+ // Spooked for less time the more compys there are. Adjust when there are many of them.
item->ItemFlags[3] = LaraItem->Animation.Velocity.z * 2;
}
}
@@ -260,9 +261,13 @@ namespace TEN::Entities::Creatures::TR3
if (item->ItemFlags[1] == ATTACK_PLAYER)
{
if (Random::TestProbability(1 / 2.0f))
+ {
item->Animation.TargetState = COMPY_STATE_ATTACK;
+ }
else
+ {
item->Animation.TargetState = COMPY_STATE_JUMP_ATTACK;
+ }
}
else
{
@@ -279,9 +284,13 @@ namespace TEN::Entities::Creatures::TR3
if (ai.ahead && ai.distance < (COMPY_ATTACK_RANGE * 3) && item->ItemFlags[1] == ATTACK_CADAVER)
{
if (Random::TestProbability(1 / 2.0f))
+ {
item->Animation.TargetState = COMPY_STATE_ATTACK;
+ }
else
+ {
item->Animation.TargetState = COMPY_STATE_JUMP_ATTACK;
+ }
}
else if (ai.distance > (COMPY_ATTACK_RANGE * 3))
{
@@ -291,9 +300,13 @@ namespace TEN::Entities::Creatures::TR3
else
{
if (Random::TestProbability(COMPY_JUMP_ATTACK_CHANCE))
+ {
item->Animation.TargetState = COMPY_STATE_JUMP_ATTACK;
+ }
else
+ {
item->Animation.TargetState = COMPY_STATE_RUN_FORWARD;
+ }
}
break;
diff --git a/TombEngine/Objects/TR3/Entity/FishSwarm.cpp b/TombEngine/Objects/TR3/Entity/FishSwarm.cpp
new file mode 100644
index 000000000..4701ee348
--- /dev/null
+++ b/TombEngine/Objects/TR3/Entity/FishSwarm.cpp
@@ -0,0 +1,427 @@
+#include "framework.h"
+#include "Objects/TR3/Entity/FishSwarm.h"
+
+#include "Game/collision/collide_item.h"
+#include "Game/collision/collide_room.h"
+#include "Game/collision/Point.h"
+#include "Game/control/box.h"
+#include "Game/control/flipeffect.h"
+#include "Game/effects/effects.h"
+#include "Game/effects/tomb4fx.h"
+#include "Game/items.h"
+#include "Game/Lara/lara.h"
+#include "Game/Lara/lara_helpers.h"
+#include "Game/misc.h"
+#include "Game/Setup.h"
+#include "Math/Math.h"
+#include "Objects/TR3/Object/Corpse.h"
+#include "Renderer/Renderer.h"
+#include "Specific/clock.h"
+#include "Specific/level.h"
+
+using namespace TEN::Collision::Point;
+using namespace TEN::Entities::TR3;
+using namespace TEN::Math;
+using namespace TEN::Renderer;
+
+// NOTES:
+// HitPoints = Fish count on spawn.
+// ItemFlags[0] = leader item number.
+// ItemFlags[1] = target item number.
+// ItemFlags[2] = OCB orientation when in patrol mode.
+// ItemFlags[3] = Start OCB of AI_FOLLOW. NOTE: Cannot change.
+// ItemFlags[4] = Check if target is a corpse.
+// ItemFlags[5] = Fish count.
+// ItemFlags[6] = Is patrolling.
+// ItemFlags[7] = Distance to player.
+
+namespace TEN::Entities::Creatures::TR3
+{
+ constexpr auto FISH_HARM_DAMAGE = 3;
+ constexpr auto FISH_VELOCITY_MAX = 10.0f;
+ constexpr auto FISH_COHESION_FACTOR = 100.1f;
+ constexpr auto FISH_SPACING_FACTOR = 600.0f;
+ constexpr auto FISH_CATCH_UP_FACTOR = 0.2f;
+ constexpr auto FISH_TARGET_DISTANCE_MAX = SQUARE(BLOCK(0.01f));
+ constexpr auto FISH_BASE_SEPARATION_DISTANCE = 210.0f;
+ constexpr auto FISH_UPDATE_INTERVAL_TIME = 0.2f;
+
+ std::vector FishSwarm = {};
+
+ void InitializeFishSwarm(short itemNumber)
+ {
+ constexpr auto DEFAULT_FISH_COUNT = 24;
+
+ auto& item = g_Level.Items[itemNumber];
+
+ item.StartPose.Position = item.Pose.Position;
+ item.Animation.Velocity.z = Random::GenerateFloat(32.0f, 160.0f);
+ item.HitPoints = DEFAULT_FISH_COUNT;
+ item.ItemFlags[0] = item.Index;
+ item.ItemFlags[1] = item.Index;
+ item.ItemFlags[5] = 0;
+
+ if (item.AIBits)
+ item.ItemFlags[6] = true;
+ }
+
+ static void SpawnFishSwarm(ItemInfo& item)
+ {
+ constexpr auto VEL_MAX = 48.0f;
+ constexpr auto VEL_MIN = 16.0f;
+ constexpr auto START_ORIENT_CONSTRAINT = std::pair(
+ EulerAngles(ANGLE(-3.0f), ANGLE(-6.0f), 0),
+ EulerAngles(ANGLE(3.0f), ANGLE(6.0f), 0));
+
+ // Create new fish.
+ auto& fish = GetNewEffect(FishSwarm, FISH_COUNT_MAX);
+
+ fish.MeshIndex = abs(item.TriggerFlags);
+ fish.IsLethal = (item.TriggerFlags < 0) ? true : false;
+ fish.IsPatrolling = item.ItemFlags[6];
+
+ fish.Position = item.Pose.Position.ToVector3();
+ fish.RoomNumber = item.RoomNumber;
+ fish.Orientation.x = Random::GenerateAngle(START_ORIENT_CONSTRAINT.first.x, START_ORIENT_CONSTRAINT.second.x);
+ fish.Orientation.y = (item.Pose.Orientation.y + ANGLE(180.0f)) + Random::GenerateAngle(START_ORIENT_CONSTRAINT.first.y, START_ORIENT_CONSTRAINT.second.y);
+ fish.Velocity = Random::GenerateFloat(VEL_MIN, VEL_MAX);
+
+ fish.Life = 1.0f;
+ fish.Undulation = Random::GenerateFloat(0.0f, PI_MUL_2);
+
+ fish.LeaderItemPtr = &g_Level.Items[item.ItemFlags[0]];
+ }
+
+ void ControlFishSwarm(short itemNumber)
+ {
+ if (!CreatureActive(itemNumber))
+ return;
+
+ auto& item = g_Level.Items[itemNumber];
+ auto& creature = *GetCreatureInfo(&item);
+ const auto& playerItem = *LaraItem;
+
+ AI_INFO ai;
+ CreatureAIInfo(&item, &ai);
+
+ if (item.HitPoints != NOT_TARGETABLE)
+ {
+ int fishCount = item.HitPoints - item.ItemFlags[5];
+
+ if (fishCount < 0)
+ {
+ int fishToTurnOff = -fishCount;
+ for (auto& fish : FishSwarm)
+ {
+ if (fish.LeaderItemPtr == &item && fish.Life > 0.0f)
+ {
+ fish.Life = 0.0f;
+ fishToTurnOff--;
+ if (fishToTurnOff == 0)
+ break;
+ }
+ }
+ }
+ else if (fishCount > 0)
+ {
+ for (int i = 0; i < fishCount; i++)
+ SpawnFishSwarm(item);
+ }
+
+ item.ItemFlags[5] = item.HitPoints;
+ item.HitPoints = NOT_TARGETABLE;
+ }
+
+ int dx = creature.Target.x - item.Pose.Position.x;
+ int dz = creature.Target.z - item.Pose.Position.z;
+ ai.distance = SQUARE(dx) + SQUARE(dz);
+
+ item.Animation.Velocity.z = FISH_VELOCITY_MAX;
+
+ auto& playerRoom = g_Level.Rooms[playerItem.RoomNumber];
+
+ // Check if corpse is near.
+ // TODO: In future also check for other enemies like sharks or crocodile.
+ if (!item.ItemFlags[4] && TestGlobalTimeInterval(FISH_UPDATE_INTERVAL_TIME))
+ {
+ float closestDist = INFINITY;
+ for (auto& targetItem : g_Level.Items)
+ {
+ if (!Objects.CheckID(targetItem.ObjectNumber) || targetItem.Index == itemNumber || targetItem.RoomNumber == NO_ROOM)
+ continue;
+
+ if (SameZone(&creature, &targetItem) && item.TriggerFlags < 0)
+ {
+ float dist = Vector3i::Distance(item.Pose.Position, targetItem.Pose.Position);
+ if (dist < closestDist &&
+ targetItem.ObjectNumber == ID_CORPSE &&
+ targetItem.Active && TriggerActive(&targetItem) &&
+ targetItem.ItemFlags[1] == (int)CorpseFlag::Grounded &&
+ TestEnvironment(ENV_FLAG_WATER, targetItem.RoomNumber))
+ {
+ item.ItemFlags[4] = 1;
+ closestDist = dist;
+ item.ItemFlags[1] = targetItem.Index; // Target corpse.
+ }
+ }
+ }
+ }
+
+ if (item.ItemFlags[7] < BLOCK(7) && TestEnvironment(ENV_FLAG_WATER, &playerRoom) &&
+ item.TriggerFlags < 0 && !item.ItemFlags[4])
+ {
+ item.ItemFlags[1] = playerItem.Index;
+ item.ItemFlags[4] = 0;
+ item.ItemFlags[2] = 0;
+ }
+ // Circle around leader item.
+ else if (!item.ItemFlags[4])
+ {
+ item.ItemFlags[1] = item.ItemFlags[0];
+ item.ItemFlags[4] = 0;
+ }
+
+ // Follow path.
+ if (item.AIBits && !item.ItemFlags[4])
+ {
+ FindAITargetObject(&creature, ID_AI_FOLLOW, item.ItemFlags[3] + item.ItemFlags[2], false);
+
+ if (creature.AITarget->TriggerFlags == (item.ItemFlags[3] + item.ItemFlags[2]) &&
+ creature.AITarget->ObjectNumber == ID_AI_FOLLOW)
+ {
+ item.ItemFlags[1] = creature.AITarget->Index;
+ }
+ else
+ {
+ item.ItemFlags[2] = 0;
+ }
+
+ item.ItemFlags[4] = 0;
+ }
+
+ for (auto& fish : FishSwarm)
+ {
+ if (fish.LeaderItemPtr == &item)
+ {
+ if (fish.Life <= 0.0f)
+ continue;
+
+ fish.RoomNumber = item.RoomNumber;
+ fish.TargetItemPtr = &g_Level.Items[item.ItemFlags[1]];
+ }
+ }
+ }
+
+ static Vector3 GetFishStartPosition(const ItemInfo& item)
+ {
+ constexpr auto BUFFER = BLOCK(0.1f);
+ constexpr auto SPHEROID_SEMI_MAJOR_AXIS = Vector3(BLOCK(2), BLOCK(1), BLOCK(5));
+
+ auto pos = Random::GeneratePointInSpheroid(item.StartPose.Position.ToVector3(), EulerAngles::Identity, SPHEROID_SEMI_MAJOR_AXIS);
+
+ // Get point collision.
+ auto pointColl = GetPointCollision(pos, item.RoomNumber);
+ int waterHeight = GetWaterHeight(pointColl.GetPosition().x, pointColl.GetPosition().y, pointColl.GetPosition().z, pointColl.GetRoomNumber());
+
+ // 1) Test for water room.
+ if (!TestEnvironment(ENV_FLAG_WATER, pointColl.GetRoomNumber()))
+ return Vector3::Zero;
+
+ // 2) Assess point collision.
+ if (pos.y >= (pointColl.GetFloorHeight() - BUFFER) ||
+ pos.y <= (waterHeight + BUFFER) ||
+ pointColl.GetSector().IsWall(item.Pose.Position.x + BUFFER, item.Pose.Position.z + BUFFER) ||
+ pointColl.GetSector().IsWall(item.Pose.Position.x - BUFFER, item.Pose.Position.z - BUFFER))
+ {
+ return Vector3::Zero;
+ }
+
+ return pos;
+ }
+
+ void UpdateFishSwarm()
+ {
+ constexpr auto WATER_SURFACE_OFFSET = CLICK(0.5f);
+ constexpr auto FLEE_VEL = 20.0f;
+
+ static const auto SPHERE = BoundingSphere(Vector3::Zero, BLOCK(1 / 8.0f));
+
+ if (FishSwarm.empty())
+ return;
+
+ const auto& playerItem = *LaraItem;
+ const auto& player = GetLaraInfo(playerItem);
+
+ const FishData* closestFishPtr = nullptr;
+ float minDistToTarget = INFINITY;
+ int minDist = INT_MAX;
+
+ int fishID = 0;
+ for (auto& fish : FishSwarm)
+ {
+ if (fish.Life <= 0.0f)
+ continue;
+
+ // Increase separation distance for each fish.
+ float separationDist = FISH_BASE_SEPARATION_DISTANCE + (fishID * 3);
+ fishID += 1;
+
+ auto& leaderItem = *fish.LeaderItemPtr;
+ if (!leaderItem.ItemFlags[2] && fish.TargetItemPtr == fish.LeaderItemPtr)
+ {
+ if (!fish.IsPatrolling)
+ {
+ fish.TargetItemPtr->Pose.Position = GetFishStartPosition(leaderItem);
+
+ if (fish.TargetItemPtr->Pose.Position != Vector3::Zero)
+ leaderItem.ItemFlags[2] = 1;
+ }
+ }
+
+ int enemyVel = (fish.TargetItemPtr != fish.LeaderItemPtr) ? 16.0f : 26.0f;
+
+ fish.PositionTarget = Random::GeneratePointInSphere(SPHERE);
+
+ // Calculate desired position based on target object and random offsets.
+ auto desiredPos = fish.TargetItemPtr->Pose.Position + fish.PositionTarget;
+ auto dir = desiredPos - fish.Position;
+
+ auto dirs = dir.ToVector3();
+ dirs.Normalize();
+ auto dirNorm = dirs;
+
+ // Define cohesion factor to keep fish close together.
+ float distToTarget = dirs.Length();
+
+ float targetVel = (distToTarget * FISH_COHESION_FACTOR) + Random::GenerateFloat(3.0f, 5.0f);
+ fish.Velocity = std::min(targetVel, fish.TargetItemPtr->Animation.Velocity.z - 21.0f);
+
+ // If fish is too far from target, increase velocity to catch up.
+ if (distToTarget > FISH_TARGET_DISTANCE_MAX)
+ fish.Velocity += FISH_CATCH_UP_FACTOR;
+
+ // Translate.
+ auto moveDir = fish.Orientation.ToDirection();
+ moveDir.Normalize();
+ fish.Position += (moveDir * fish.Velocity) / enemyVel;
+ fish.Position += (moveDir * FISH_SPACING_FACTOR) / enemyVel;
+
+ auto orientTo = Geometry::GetOrientToPoint(fish.Position, desiredPos.ToVector3());
+ fish.Orientation.Lerp(orientTo, 0.1f);
+
+ for (const auto& otherFish : FishSwarm)
+ {
+ if (&fish == &otherFish)
+ continue;
+
+ float distToOtherFish = Vector3i::Distance(fish.Position, otherFish.Position);
+ float distToPlayer = Vector3i::Distance(fish.Position, playerItem.Pose.Position);
+ float distToTarget = Vector3i::Distance(fish.Position, otherFish.PositionTarget);
+
+ leaderItem.ItemFlags[7] = distToPlayer;
+
+ // Update the index of the nearest fish to the target
+ if (distToTarget < minDistToTarget &&
+ (fish.TargetItemPtr == fish.LeaderItemPtr || fish.TargetItemPtr->ObjectNumber == ID_AI_FOLLOW))
+ {
+ minDistToTarget = distToTarget;
+ closestFishPtr = &otherFish;
+ }
+
+ if (fish.TargetItemPtr != fish.LeaderItemPtr && fish.TargetItemPtr->ObjectNumber != ID_AI_FOLLOW)
+ separationDist = 80.0f;
+
+ if (distToOtherFish < separationDist)
+ {
+ auto separationDir = fish.Position - otherFish.Position;
+ separationDir.Normalize();
+
+ fish.Position += separationDir * (separationDist - distToOtherFish);
+ }
+ else
+ {
+ fish.Velocity += FISH_CATCH_UP_FACTOR;
+ }
+
+ // Orient to fish nearest to target. Prevents other fish from swimming forward but oriented elsewhere.
+ if (closestFishPtr != nullptr &&
+ fish.Orientation.x != closestFishPtr->Orientation.x && separationDist > 30.0f &&
+ (fish.TargetItemPtr == fish.LeaderItemPtr || fish.TargetItemPtr->ObjectNumber == ID_AI_FOLLOW))
+ {
+ separationDist--;
+ auto orientTo = Geometry::GetOrientToPoint(fish.Position, closestFishPtr->Position);
+ fish.Velocity += FISH_CATCH_UP_FACTOR;
+ }
+
+ // If player is too close and fish are not lethal, flee.
+ if ((distToPlayer < separationDist * 3) && fish.IsLethal == false)
+ {
+ auto separationDir = fish.Position - playerItem.Pose.Position.ToVector3();
+ separationDir.Normalize();
+
+ fish.Position += separationDir * FLEE_VEL;
+
+ auto orientTo = Geometry::GetOrientToPoint(fish.Position, separationDir);
+ fish.Orientation.Lerp(orientTo, 0.05f);
+
+ fish.Velocity -= std::min(FLEE_VEL, fish.TargetItemPtr->Animation.Velocity.z - 1.0f);
+ }
+ }
+
+ auto pointColl = GetPointCollision(fish.Position, fish.RoomNumber);
+ const auto& room = g_Level.Rooms[fish.RoomNumber];
+
+ // Update fish room number.
+ if (pointColl.GetRoomNumber() != fish.RoomNumber &&
+ pointColl.GetRoomNumber() != NO_VALUE &&
+ TestEnvironment(ENV_FLAG_WATER, pointColl.GetRoomNumber()))
+ {
+ fish.RoomNumber = pointColl.GetRoomNumber();
+ }
+
+ // Clamp position to slightly below water surface.
+ int waterHeight = GetWaterHeight(fish.Position.x, fish.Position.y, fish.Position.z, fish.RoomNumber);
+ if (fish.Position.y < (waterHeight + WATER_SURFACE_OFFSET))
+ fish.Position.y = waterHeight + WATER_SURFACE_OFFSET;
+
+ if (ItemNearTarget(fish.Position, fish.TargetItemPtr, CLICK(0.5f)) &&
+ fish.LeaderItemPtr != fish.TargetItemPtr)
+ {
+ if (fish.TargetItemPtr->ObjectNumber != ID_AI_FOLLOW)
+ {
+ DoBloodSplat(
+ fish.Position.x, fish.Position.y, fish.Position.z,
+ Random::GenerateFloat(4.0f, 8.0f),
+ fish.TargetItemPtr->Pose.Orientation.y, fish.TargetItemPtr->RoomNumber);
+ DoDamage(fish.TargetItemPtr, FISH_HARM_DAMAGE);
+ }
+ else
+ {
+ leaderItem.ItemFlags[2]++;
+ }
+ }
+ else if (ItemNearTarget(fish.Position, fish.TargetItemPtr, BLOCK(2)) &&
+ fish.LeaderItemPtr == fish.TargetItemPtr)
+ {
+ leaderItem.ItemFlags[2] = 0;
+ }
+
+ // Calculate undulation angle based on sine wave and fish velocity.
+ float movementValue = abs(moveDir.z);
+ float undulationAngle = sin(fish.Undulation) * ANGLE(std::clamp(movementValue * 7.0f, 4.0f, 7.0f));
+
+ // Apply undulation.
+ fish.Orientation.y += undulationAngle;
+
+ // Update undulation.
+ fish.Undulation += std::clamp(movementValue / 2, 0.3f, 1.0f);
+ if (fish.Undulation > PI_MUL_2)
+ fish.Undulation -= PI_MUL_2;
+ }
+ }
+
+ void ClearFishSwarm()
+ {
+ FishSwarm.clear();
+ }
+}
diff --git a/TombEngine/Objects/TR3/Entity/FishSwarm.h b/TombEngine/Objects/TR3/Entity/FishSwarm.h
new file mode 100644
index 000000000..1a1dfe471
--- /dev/null
+++ b/TombEngine/Objects/TR3/Entity/FishSwarm.h
@@ -0,0 +1,37 @@
+#pragma once
+#include "Game/items.h"
+#include "Math/Math.h"
+
+using namespace TEN::Math;
+
+namespace TEN::Entities::Creatures::TR3
+{
+ constexpr auto FISH_COUNT_MAX = 512;
+
+ struct FishData
+ {
+ int MeshIndex = 0;
+ bool IsPatrolling = false;
+ bool IsLethal = false;
+
+ Vector3 Position = Vector3::Zero;
+ int RoomNumber = 0;
+ Vector3 PositionTarget = Vector3::Zero;
+ EulerAngles Orientation = EulerAngles::Identity;
+ float Velocity = 0.0f;
+
+ float Life = 0.0f;
+ float Undulation = 0.0f;
+
+ ItemInfo* TargetItemPtr = nullptr;
+ ItemInfo* LeaderItemPtr = nullptr;
+ };
+
+ extern std::vector FishSwarm;
+
+ void InitializeFishSwarm(short itemNumber);
+ void ControlFishSwarm(short itemNumber);
+
+ void UpdateFishSwarm();
+ void ClearFishSwarm();
+}
diff --git a/TombEngine/Objects/TR3/Entity/Lizard.cpp b/TombEngine/Objects/TR3/Entity/Lizard.cpp
index da395f0d3..d5a10e72b 100644
--- a/TombEngine/Objects/TR3/Entity/Lizard.cpp
+++ b/TombEngine/Objects/TR3/Entity/Lizard.cpp
@@ -68,7 +68,7 @@ namespace TEN::Entities::Creatures::TR3
{
auto& creature = *GetCreatureInfo(&item);
- return (creature.Enemy && creature.Enemy->BoxNumber != NO_BOX &&
+ return (creature.Enemy && creature.Enemy->BoxNumber != NO_VALUE &&
(g_Level.Boxes[creature.Enemy->BoxNumber].flags & BLOCKABLE));
}
@@ -140,7 +140,7 @@ namespace TEN::Entities::Creatures::TR3
}
else if (creature.Mood == MoodType::Bored)
{
- if (item.Animation.RequiredState != NO_STATE)
+ if (item.Animation.RequiredState != NO_VALUE)
{
item.Animation.TargetState = item.Animation.RequiredState;
}
diff --git a/TombEngine/Objects/TR3/Entity/PunaBoss.cpp b/TombEngine/Objects/TR3/Entity/PunaBoss.cpp
index 9fe54f0a2..0597ede22 100644
--- a/TombEngine/Objects/TR3/Entity/PunaBoss.cpp
+++ b/TombEngine/Objects/TR3/Entity/PunaBoss.cpp
@@ -66,7 +66,7 @@ namespace TEN::Entities::Creatures::TR3
static short GetPunaHeadOrientToTarget(ItemInfo& item, const Vector3& target)
{
if (!item.TestFlags((int)BossItemFlags::Object, (short)BossFlagValue::Lizard))
- return NO_ITEM;
+ return NO_VALUE;
auto pos = GetJointPosition(&item, PunaBossHeadBite).ToVector3();
auto orient = Geometry::GetOrientToPoint(pos, target);
@@ -94,7 +94,7 @@ namespace TEN::Entities::Creatures::TR3
static Vector3 GetLizardTargetPosition(ItemInfo& item)
{
- if (!item.TestFlagField((int)BossItemFlags::ItemNumber, NO_ITEM))
+ if (!item.TestFlagField((int)BossItemFlags::ItemNumber, NO_VALUE))
{
const auto& targetEntity = g_Level.Items[item.GetFlagField((int)BossItemFlags::ItemNumber)];
return targetEntity.Pose.Position.ToVector3();
@@ -108,11 +108,11 @@ namespace TEN::Entities::Creatures::TR3
static int GetLizardItemNumber(const ItemInfo& item)
{
if (!item.TestFlags((int)BossItemFlags::Object, (short)BossFlagValue::Lizard))
- return NO_ITEM;
+ return NO_VALUE;
auto lizardList = GetLizardEntityList(item);
if (lizardList.empty())
- return NO_ITEM;
+ return NO_VALUE;
if (lizardList.size() == 1)
return lizardList[0];
@@ -199,7 +199,7 @@ namespace TEN::Entities::Creatures::TR3
static void SpawnLizard(ItemInfo& item)
{
- if (!item.TestFlagField((int)BossItemFlags::ItemNumber, NO_ITEM))
+ if (!item.TestFlagField((int)BossItemFlags::ItemNumber, NO_VALUE))
{
auto itemNumber = item.GetFlagField((int)BossItemFlags::ItemNumber);
auto& currentItem = g_Level.Items[itemNumber];
@@ -289,7 +289,7 @@ namespace TEN::Entities::Creatures::TR3
item.SetFlagField((int)BossItemFlags::ShieldIsEnabled, 1); // Activated at start.
item.SetFlagField((int)BossItemFlags::AttackCount, 0);
item.SetFlagField((int)BossItemFlags::DeathCount, 0);
- item.SetFlagField((int)BossItemFlags::ItemNumber, NO_ITEM);
+ item.SetFlagField((int)BossItemFlags::ItemNumber, NO_VALUE);
item.SetFlagField((int)BossItemFlags::ExplodeCount, 0);
// If there is no lizard nearby, remove the lizard flag.
@@ -379,7 +379,7 @@ namespace TEN::Entities::Creatures::TR3
}
else if (item.TestFlags((int)BossItemFlags::Object, (short)BossFlagValue::Lizard) &&
item.TestFlagField((int)BossItemFlags::AttackType, (int)PunaAttackType::SummonLightning) &&
- item.TestFlagField((int)BossItemFlags::ItemNumber, NO_ITEM) &&
+ item.TestFlagField((int)BossItemFlags::ItemNumber, NO_VALUE) &&
!item.TestFlagField((int)BossItemFlags::AttackType, (int)PunaAttackType::Wait) && isLizardActiveNearby)
{
// Get random lizard item number.
@@ -388,7 +388,7 @@ namespace TEN::Entities::Creatures::TR3
}
else if (item.TestFlags((int)BossItemFlags::Object, (short)BossFlagValue::Lizard) &&
item.TestFlagField((int)BossItemFlags::AttackType, (int)PunaAttackType::Wait) &&
- !item.TestFlagField((int)BossItemFlags::ItemNumber, NO_ITEM))
+ !item.TestFlagField((int)BossItemFlags::ItemNumber, NO_VALUE))
{
// Rotate to idle position while player fights lizard.
auto targetOrient = EulerAngles(item.Pose.Orientation.x, item.GetFlagField((int)BossItemFlags::Rotation), item.Pose.Orientation.z);
@@ -402,7 +402,7 @@ namespace TEN::Entities::Creatures::TR3
// Reset the attack type, attack count, itemNumber, and restart the sequence.
item.SetFlagField((int)BossItemFlags::AttackType, (int)PunaAttackType::DeathLightning);
item.SetFlagField((int)BossItemFlags::AttackCount, 0);
- item.SetFlagField((int)BossItemFlags::ItemNumber, NO_ITEM);
+ item.SetFlagField((int)BossItemFlags::ItemNumber, NO_VALUE);
}
}
@@ -440,7 +440,7 @@ namespace TEN::Entities::Creatures::TR3
{
item.SetFlagField((int)BossItemFlags::AttackType, (int)PunaAttackType::SummonLightning);
- if (!item.TestFlagField((int)BossItemFlags::ItemNumber, NO_ITEM))
+ if (!item.TestFlagField((int)BossItemFlags::ItemNumber, NO_VALUE))
{
if (headYOrient > ANGLE(-1.0f) && headYOrient < ANGLE(1.0f))
{
@@ -470,7 +470,7 @@ namespace TEN::Entities::Creatures::TR3
{
if (item.TestFlags((int)BossItemFlags::Object, (short)BossFlagValue::Lizard) &&
item.TestFlagField((int)BossItemFlags::AttackType, (int)PunaAttackType::SummonLightning) &&
- !item.TestFlagField((int)BossItemFlags::ItemNumber, NO_ITEM) && isLizardActiveNearby)
+ !item.TestFlagField((int)BossItemFlags::ItemNumber, NO_VALUE) && isLizardActiveNearby)
{
SpawnPunaLightning(item, targetPos.ToVector3(), PunaBossHandBite, true);
}
diff --git a/TombEngine/Objects/TR3/Entity/Shiva.cpp b/TombEngine/Objects/TR3/Entity/Shiva.cpp
index 3d74ab035..21ccd1586 100644
--- a/TombEngine/Objects/TR3/Entity/Shiva.cpp
+++ b/TombEngine/Objects/TR3/Entity/Shiva.cpp
@@ -343,7 +343,7 @@ namespace TEN::Entities::Creatures::TR3
int z = item->Pose.Position.z + BLOCK(1) * phd_cos(item->Pose.Orientation.y + ANGLE(180.0f));
auto box = GetPointCollision(Vector3i(x, item->Pose.Position.y, z), item->RoomNumber).GetBottomSector().Box;
- if (box != NO_BOX && !(g_Level.Boxes[box].flags & BLOCKABLE) && !creature.Flags)
+ if (box != NO_VALUE && !(g_Level.Boxes[box].flags & BLOCKABLE) && !creature.Flags)
item->Animation.TargetState = SHIVA_STATE_WALK_BACK;
else
item->Animation.TargetState = SHIVA_STATE_GUARD_IDLE;
diff --git a/TombEngine/Objects/TR3/Entity/SophiaLeigh.cpp b/TombEngine/Objects/TR3/Entity/SophiaLeigh.cpp
index b358d0fd4..ea752dae8 100644
--- a/TombEngine/Objects/TR3/Entity/SophiaLeigh.cpp
+++ b/TombEngine/Objects/TR3/Entity/SophiaLeigh.cpp
@@ -246,7 +246,7 @@ namespace TEN::Entities::Creatures::TR3
static void SpawnSophiaLeighProjectileBolt(ItemInfo& item, ItemInfo* enemy, const CreatureBiteInfo& bite, SophiaData* data, bool isBoltLarge, short angleAdd)
{
int fxNumber = CreateNewEffect(item.RoomNumber);
- if (fxNumber == NO_ITEM)
+ if (fxNumber == NO_VALUE)
return;
auto& fx = EffectList[fxNumber];
diff --git a/TombEngine/Objects/TR3/Entity/WaspMutant.cpp b/TombEngine/Objects/TR3/Entity/WaspMutant.cpp
index dab4f691a..1e858ae6f 100644
--- a/TombEngine/Objects/TR3/Entity/WaspMutant.cpp
+++ b/TombEngine/Objects/TR3/Entity/WaspMutant.cpp
@@ -219,7 +219,7 @@ namespace TEN::Entities::Creatures::TR3
creature.MaxTurn = WASP_AIR_TURN_RATE_MAX;
creature.Flags = 0;
- if (item.Animation.RequiredState != NO_STATE)
+ if (item.Animation.RequiredState != NO_VALUE)
{
item.Animation.TargetState = item.Animation.RequiredState;
}
@@ -243,7 +243,7 @@ namespace TEN::Entities::Creatures::TR3
creature.MaxTurn = WASP_AIR_TURN_RATE_MAX;
creature.Flags = 0;
- if (item.Animation.RequiredState != NO_STATE)
+ if (item.Animation.RequiredState != NO_VALUE)
{
item.Animation.TargetState = item.Animation.RequiredState;
}
diff --git a/TombEngine/Objects/TR3/Entity/Winston.cpp b/TombEngine/Objects/TR3/Entity/Winston.cpp
index 8c794bf7e..484d99524 100644
--- a/TombEngine/Objects/TR3/Entity/Winston.cpp
+++ b/TombEngine/Objects/TR3/Entity/Winston.cpp
@@ -231,7 +231,7 @@ namespace TEN::Entities::Creatures::TR3
case WINSTON_STATE_GUARD_MID:
creature.MaxTurn = WINSTON_TURN_RATE_MAX;
- if (item.Animation.RequiredState != NO_STATE)
+ if (item.Animation.RequiredState != NO_VALUE)
item.Animation.TargetState = item.Animation.RequiredState;
if (!item.TriggerFlags)
@@ -251,7 +251,7 @@ namespace TEN::Entities::Creatures::TR3
case WINSTON_STATE_GUARD_LOW:
creature.MaxTurn = WINSTON_TURN_RATE_MAX;
- if (item.Animation.RequiredState != NO_STATE)
+ if (item.Animation.RequiredState != NO_VALUE)
item.Animation.TargetState = item.Animation.RequiredState;
if (item.HitStatus)
@@ -262,7 +262,7 @@ namespace TEN::Entities::Creatures::TR3
case WINSTON_STATE_GUARD_HIGH:
creature.MaxTurn = WINSTON_TURN_RATE_MAX;
- if (item.Animation.RequiredState != NO_STATE)
+ if (item.Animation.RequiredState != NO_VALUE)
item.Animation.TargetState = item.Animation.RequiredState;
if (item.HitStatus)
diff --git a/TombEngine/Objects/TR3/Entity/tr3_civvy.cpp b/TombEngine/Objects/TR3/Entity/tr3_civvy.cpp
index ff2153d80..7a86c5c01 100644
--- a/TombEngine/Objects/TR3/Entity/tr3_civvy.cpp
+++ b/TombEngine/Objects/TR3/Entity/tr3_civvy.cpp
@@ -124,7 +124,7 @@ namespace TEN::Entities::Creatures::TR3
for (auto& targetCreature : ActiveCreatures)
{
// Ignore itself and invalid entities.
- if (targetCreature->ItemNumber == NO_ITEM || targetCreature->ItemNumber == item.Index)
+ if (targetCreature->ItemNumber == NO_VALUE || targetCreature->ItemNumber == item.Index)
continue;
auto& currentItem = g_Level.Items[targetCreature->ItemNumber];
@@ -182,7 +182,7 @@ namespace TEN::Entities::Creatures::TR3
auto jointHeadRot = EulerAngles::Identity;
auto jointTorsoRot = EulerAngles::Identity;
- if (item.BoxNumber != NO_BOX && (g_Level.Boxes[item.BoxNumber].flags & BLOCKED) && item.HitPoints > 0)
+ if (item.BoxNumber != NO_VALUE && (g_Level.Boxes[item.BoxNumber].flags & BLOCKED) && item.HitPoints > 0)
{
DoDamage(&item, INT_MAX);
DoLotsOfBlood(item.Pose.Position.x, item.Pose.Position.y - (GetRandomControl() & 255) - 32, item.Pose.Position.z, (GetRandomControl() & 127) + 128, GetRandomControl() << 1, item.RoomNumber, 3);
diff --git a/TombEngine/Objects/TR3/Entity/tr3_claw_mutant.cpp b/TombEngine/Objects/TR3/Entity/tr3_claw_mutant.cpp
index a3f368987..a92765cf8 100644
--- a/TombEngine/Objects/TR3/Entity/tr3_claw_mutant.cpp
+++ b/TombEngine/Objects/TR3/Entity/tr3_claw_mutant.cpp
@@ -149,7 +149,7 @@ namespace TEN::Entities::Creatures::TR3
const auto& creature = *GetCreatureInfo(&item);
int plasmaBall = CreateNewEffect(item.RoomNumber);
- if (plasmaBall == NO_ITEM)
+ if (plasmaBall == NO_VALUE)
return;
auto enemyPos = creature.Enemy->Pose.Position;
@@ -378,7 +378,7 @@ namespace TEN::Entities::Creatures::TR3
if (Random::TestProbability(CLAW_MUTANT_WALK_CHANCE))
item.Animation.TargetState = CLAW_MUTANT_STATE_WALK;
}
- else if (item.Animation.RequiredState != NO_STATE)
+ else if (item.Animation.RequiredState != NO_VALUE)
{
item.Animation.TargetState = item.Animation.RequiredState;
}
diff --git a/TombEngine/Objects/TR3/Entity/tr3_fish_emitter.cpp b/TombEngine/Objects/TR3/Entity/tr3_fish_emitter.cpp
deleted file mode 100644
index b1e1107a4..000000000
--- a/TombEngine/Objects/TR3/Entity/tr3_fish_emitter.cpp
+++ /dev/null
@@ -1,424 +0,0 @@
-#include "framework.h"
-#include "Objects/TR3/Entity/tr3_fish_emitter.h"
-
-#include "Game/animation.h"
-#include "Game/control/control.h"
-#include "Game/effects/effects.h"
-#include "Game/items.h"
-#include "Game/Lara/lara.h"
-#include "Math/Math.h"
-#include "Objects/TR3/fish.h"
-#include "Specific/level.h"
-
-using namespace TEN::Math;
-
-namespace TEN::Entities::Creatures::TR3
-{
- int PirahnaHitWait = false;
- int CarcassItem = NO_ITEM;
-
- #define PIRAHNA_DAMAGE 4
- #define X 0
- #define Y 1
- #define Z 2
- #define XYZ 3
- #define MAX_FISH 8
- #define OCB_FISH_LETAL 0x1000
- #define OCB_FISH_EAT_CARCASS 0x2000
-
- FishLeaderInfo LeaderInfo[MAX_FISH];
- FishInfo Fishes[MAX_FISH + (MAX_FISH * 24)];
-
- unsigned char FishRanges[1][3] =
- {
- {
- 8,
- 20,
- 3
- }
- };
-
- void SetupShoal(int shoalNumber)
- {
- LeaderInfo[shoalNumber].xRange = (FishRanges[shoalNumber][0] + 2) << 8;
- LeaderInfo[shoalNumber].zRange = (FishRanges[shoalNumber][1] + 2) << 8;
- LeaderInfo[shoalNumber].yRange = (FishRanges[shoalNumber][2]) << 8;
- }
-
- void SetupFish(int leader, ItemInfo* item)
- {
- int fishXRange = LeaderInfo[leader].xRange;
- int fishYRange = LeaderInfo[leader].yRange;
- int fishZRange = LeaderInfo[leader].zRange;
-
- Fishes[leader].x = 0;
- Fishes[leader].y = 0;
- Fishes[leader].z = 0;
- Fishes[leader].angle = 0;
- Fishes[leader].speed = (Random::GenerateInt() & 63) + 8;
- Fishes[leader].swim = Random::GenerateInt() & 63;
-
- for (int i = 0; i < 24; i++)
- {
- Fishes[MAX_FISH + (leader * 24) + i].x = (Random::GenerateInt() % (fishXRange * 2)) - fishXRange;
- Fishes[MAX_FISH + (leader * 24) + i].y = (Random::GenerateInt() % fishYRange);
- Fishes[MAX_FISH + (leader * 24) + i].destY = (Random::GenerateInt() % fishYRange);
- Fishes[MAX_FISH + (leader * 24) + i].z = (Random::GenerateInt() % (fishZRange * 2)) - fishZRange;
- Fishes[MAX_FISH + (leader * 24) + i].angle = Random::GenerateInt() & 4095;
- Fishes[MAX_FISH + (leader * 24) + i].speed = (Random::GenerateInt() & 31) + 32;
- Fishes[MAX_FISH + (leader * 24) + i].swim = Random::GenerateInt() & 63;
- }
-
- LeaderInfo[leader].on = 1;
- LeaderInfo[leader].angle = 0;
- LeaderInfo[leader].speed = (Random::GenerateInt() & 127) + 32;
- LeaderInfo[leader].angleTime = 0;
- LeaderInfo[leader].speedTime = 0;
- }
-
- void ControlFish(short itemNumber)
- {
- auto* item = &g_Level.Items[itemNumber];
- auto* enemy = item;
-
- if (!TriggerActive(item))
- return;
-
- int pirahnaAttack = 0;
- int angle = 0;
-
- int leader = item->HitPoints;
- if (!LeaderInfo[leader].on)
- SetupFish(leader, item);
-
- if (item->TriggerFlags & OCB_FISH_LETAL)
- {
- if ((item->TriggerFlags == OCB_FISH_EAT_CARCASS) == 0)
- pirahnaAttack = (LaraItem->RoomNumber == item->RoomNumber);
- else
- {
- if (CarcassItem != -1)
- pirahnaAttack = 2;
- else
- pirahnaAttack = (LaraItem->RoomNumber == item->RoomNumber);
- }
- }
- else
- pirahnaAttack = 0;
-
- if (PirahnaHitWait)
- PirahnaHitWait--;
-
- auto* fish = &Fishes[leader];
-
- if (pirahnaAttack)
- {
- if (pirahnaAttack == 1)
- enemy = LaraItem;
- else
- enemy = &g_Level.Items[CarcassItem];
-
- LeaderInfo[leader].angle = fish->angle = ((-(Geometry::GetOrientToPoint(Vector3(fish->x + item->Pose.Position.x, 0.0f, fish->z + item->Pose.Position.z), enemy->Pose.Position.ToVector3()).y + ANGLE(90.0f))) / 16) & ANGLE(22.5f);
- LeaderInfo[leader].speed = (Random::GenerateInt() & 63) + 192;
- }
-
- int deltaAngle = fish->angle - LeaderInfo[leader].angle;
-
- if (deltaAngle > 2048)
- deltaAngle -= 4096;
- else if (deltaAngle < -2048)
- deltaAngle += 4096;
-
- if (deltaAngle > 128)
- {
- fish->angAdd -= 4;
- if (fish->angAdd < -120)
- fish->angAdd = -120;
- }
- else if (deltaAngle < -128)
- {
- fish->angAdd += 4;
- if (fish->angAdd > 120)
- fish->angAdd = 120;
- }
- else
- {
- fish->angAdd -= fish->angAdd / 4;
- if (abs(fish->angAdd) < 4)
- fish->angAdd = 0;
- }
-
- fish->angle += fish->angAdd;
-
- if (deltaAngle > 1024)
- fish->angle += fish->angAdd / 4;
- fish->angle &= 4095;
-
- deltaAngle = fish->speed - LeaderInfo[leader].speed;
-
- if (deltaAngle < -4)
- {
- deltaAngle = fish->speed + (Random::GenerateInt() & 3) + 1;
- if (deltaAngle < 0)
- deltaAngle = 0;
-
- fish->speed = deltaAngle;
- }
- else if (deltaAngle > 4)
- {
- deltaAngle = fish->speed - (Random::GenerateInt() & 3) - 1;
- if (deltaAngle > 255)
- deltaAngle = 255;
-
- fish->speed = deltaAngle;
- }
-
- fish->swim += fish->speed / 16;
- fish->swim &= 63;
-
- int x = fish->x;
- int z = fish->z;
-
- x -= fish->speed * phd_sin(fish->angle * 16) / 2;
- z += fish->speed * phd_cos(fish->angle * 16) / 2;
-
- if (pirahnaAttack == 0)
- {
- int fishXRange = LeaderInfo[leader].xRange;
- int fishZRange = LeaderInfo[leader].zRange;
-
- if (z < -fishZRange)
- {
- z = -fishZRange;
-
- if (fish->angle < 2048)
- LeaderInfo[leader].angle = fish->angle - ((Random::GenerateInt() & 127) + 128);
- else
- LeaderInfo[leader].angle = fish->angle + ((Random::GenerateInt() & 127) + 128);
-
- LeaderInfo[leader].angleTime = (Random::GenerateInt() & 15) + 8;
- LeaderInfo[leader].speedTime = 0;
- }
- else if (z > fishZRange)
- {
- z = fishZRange;
-
- if (fish->angle > 3072)
- LeaderInfo[leader].angle = fish->angle - ((Random::GenerateInt() & 127) + 128);
- else
- LeaderInfo[leader].angle = fish->angle + ((Random::GenerateInt() & 127) + 128);
-
- LeaderInfo[leader].angleTime = (Random::GenerateInt() & 15) + 8;
- LeaderInfo[leader].speedTime = 0;
- }
-
- if (x < -fishXRange)
- {
- x = -fishXRange;
-
- if (fish->angle < 1024)
- LeaderInfo[leader].angle = fish->angle - ((Random::GenerateInt() & 127) + 128);
- else
- LeaderInfo[leader].angle = fish->angle + ((Random::GenerateInt() & 127) + 128);
-
- LeaderInfo[leader].angleTime = (Random::GenerateInt() & 15) + 8;
- LeaderInfo[leader].speedTime = 0;
- }
- else if (x > fishXRange)
- {
- x = fishXRange;
-
- if (fish->angle < 3072)
- LeaderInfo[leader].angle = fish->angle - ((Random::GenerateInt() & 127) + 128);
- else
- LeaderInfo[leader].angle = fish->angle + ((Random::GenerateInt() & 127) + 128);
-
- LeaderInfo[leader].angleTime = (Random::GenerateInt() & 15) + 8;
- LeaderInfo[leader].speedTime = 0;
- }
-
- if ((Random::GenerateInt() & 15) == 0)
- LeaderInfo[leader].angleTime = 0;
-
- if (LeaderInfo[leader].angleTime)
- LeaderInfo[leader].angleTime--;
- else
- {
- LeaderInfo[leader].angleTime = (Random::GenerateInt() & 15) + 8;
- int angAdd = ((Random::GenerateInt() & 63) + 16) - 8 - 32;
-
- if ((Random::GenerateInt() & 3) == 0)
- LeaderInfo[leader].angle += angAdd * 32;
- else
- LeaderInfo[leader].angle += angAdd;
-
- LeaderInfo[leader].angle &= 4095;
- }
-
- if (LeaderInfo[leader].speedTime)
- LeaderInfo[leader].speedTime--;
- else
- {
- LeaderInfo[leader].speedTime = (Random::GenerateInt() & 31) + 32;
-
- if ((Random::GenerateInt() & 7) == 0)
- LeaderInfo[leader].speed = (Random::GenerateInt() & 127) + 128;
- else if ((Random::GenerateInt() & 3) == 0)
- LeaderInfo[leader].speed += (Random::GenerateInt() & 127) + 32;
- else if (LeaderInfo[leader].speed > 140)
- LeaderInfo[leader].speed -= (Random::GenerateInt() & 31) + 48;
- else
- {
- LeaderInfo[leader].speedTime = (Random::GenerateInt() & 3) + 4;
- LeaderInfo[leader].speed += (Random::GenerateInt() & 31) - 15;
- }
- }
-
- }
-
- int ftx = x;
- int ftz = z;
-
- fish->x = x;
- fish->z = z;
-
- fish = (FishInfo*)&Fishes[MAX_FISH + (leader * 24)];
-
- for (int i = 0; i < 24; i++)
- {
- if (item->Flags & OCB_FISH_LETAL)
- {
- Pose pos;
- pos.Position.x = item->Pose.Position.x + fish->x;
- pos.Position.y = item->Pose.Position.y + fish->y;
- pos.Position.z = item->Pose.Position.z + fish->z;
-
- if (FishNearLara(&pos, 256, (pirahnaAttack < 2) ? LaraItem : enemy))
- {
- if (PirahnaHitWait == 0)
- {
- DoBloodSplat(item->Pose.Position.x + fish->x, item->Pose.Position.y + fish->y, item->Pose.Position.z + fish->z, 0, 0, (pirahnaAttack < 2) ? LaraItem->RoomNumber : enemy->RoomNumber);
- PirahnaHitWait = 8;
- }
-
- if (pirahnaAttack != 2)
- DoDamage(LaraItem, PIRAHNA_DAMAGE);
- }
- }
-
- angle = ((-(Geometry::GetOrientToPoint(Vector3(fish->x, 0.0f, fish->z), Vector3(ftx, 0.0f, ftz)).y + ANGLE(90.0f))) / 16) & ANGLE(22.5f);
- int dx = fish->x - ftx + ((24 - i) * 128);
- int dz = fish->z - ftz - ((24 - i) * 128);
-
- dx *= dx;
- dz *= dz;
-
- deltaAngle = fish->angle - angle;
-
- if (deltaAngle > 2048)
- deltaAngle -= 4096;
- else if (deltaAngle < -2048)
- deltaAngle += 4096;
-
- if (deltaAngle > 128)
- {
- fish->angAdd -= 4;
- if (fish->angAdd < -92 - (i / 2))
- fish->angAdd = -92 - (i / 2);
- }
- else if (deltaAngle < -128)
- {
- fish->angAdd += 4;
- if (fish->angAdd > 92 + (i / 2))
- fish->angAdd = 92 + (i / 2);
- }
- else
- {
- fish->angAdd -= fish->angAdd / 4;
- if (abs(fish->angAdd) < 4)
- fish->angAdd = 0;
- }
-
- fish->angle += fish->angAdd;
-
- if (deltaAngle > 1024)
- fish->angle += fish->angAdd / 4;
- fish->angle &= 4095;
-
- if ((dx + dz) < (0x100000 + ((i * 128) * (i * 128))))
- {
- if (fish->speed > 32 + (i * 2))
- fish->speed -= fish->speed / 32;
- }
- else
- {
- if (fish->speed < 160 + (i / 2))
- fish->speed += (Random::GenerateInt() & 3) + 1 + (i / 2);
-
- if (fish->speed > 160 + (i / 2) - (i * 4))
- fish->speed = 160 + (i / 2) - (i * 4);
- }
-
- if (Random::GenerateInt() & 1)
- fish->speed -= Random::GenerateInt() & 1;
- else
- fish->speed += Random::GenerateInt() & 1;
-
- if (fish->speed < 32)
- fish->speed = 32;
- else if (fish->speed > 200)
- fish->speed = 200;
-
- fish->swim += (fish->speed / 16) + (fish->speed / 32);
- fish->swim &= 63;
-
- x = fish->x - fish->speed * phd_sin(fish->angle * 16) / 2;
- z = fish->z + fish->speed * phd_cos(fish->angle * 16) / 2;
-
- if (z < -32000)
- z = -32000;
- else if (z > 32000)
- z = 32000;
- if (x < -32000)
- x = -32000;
- else if (x > 32000)
- x = 32000;
-
- fish->x = x;
- fish->z = z;
-
- if (pirahnaAttack == 0)
- {
- if (abs(fish->y - fish->destY) < 16)
- fish->destY = Random::GenerateInt() % LeaderInfo[leader].yRange;
- }
- else
- {
- int y = enemy->Pose.Position.y - item->Pose.Position.y;
- if (abs(fish->y - fish->destY) < 16)
- fish->destY = y + (Random::GenerateInt() & 255);
- }
-
- fish->y += (fish->destY - fish->y) / 16;
- fish++;
- }
- }
-
- bool FishNearLara(Pose* pos, int distance, ItemInfo* item)
- {
- int x = pos->Position.x - item->Pose.Position.x;
- int y = abs(pos->Position.y - item->Pose.Position.y);
- int z = pos->Position.z - item->Pose.Position.z;
-
- if (x < -distance || x > distance || z < -distance || z > distance || y < -BLOCK(3) || y > BLOCK(3))
- return false;
-
- if ((pow(x, 2) + pow(z, 2)) > pow(distance, 2))
- return false;
-
- if (y > distance)
- return false;
-
- return true;
- }
-}
diff --git a/TombEngine/Objects/TR3/Entity/tr3_fish_emitter.h b/TombEngine/Objects/TR3/Entity/tr3_fish_emitter.h
deleted file mode 100644
index 0e067fccc..000000000
--- a/TombEngine/Objects/TR3/Entity/tr3_fish_emitter.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#pragma once
-#include "Game/items.h"
-
-namespace TEN::Entities::Creatures::TR3
-{
- void SetupShoal(int shoalNumber);
- void ControlFish(short itemNumber);
- bool FishNearLara(Pose* pos, int distance, ItemInfo* item);
-}
diff --git a/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp b/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp
index a8d867df7..57d37d488 100644
--- a/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp
+++ b/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp
@@ -101,7 +101,7 @@ namespace TEN::Entities::Creatures::TR3
for (auto& currentCreature : ActiveCreatures)
{
- if (currentCreature->ItemNumber == NO_ITEM || currentCreature->ItemNumber == itemNumber)
+ if (currentCreature->ItemNumber == NO_VALUE || currentCreature->ItemNumber == itemNumber)
continue;
target = &g_Level.Items[currentCreature->ItemNumber];
diff --git a/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp b/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp
index 8da52b5ef..2e5f81b20 100644
--- a/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp
+++ b/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp
@@ -127,7 +127,7 @@ namespace TEN::Entities::Creatures::TR3
for (auto& currentCreature : ActiveCreatures)
{
- if (currentCreature->ItemNumber == NO_ITEM || currentCreature->ItemNumber == itemNumber)
+ if (currentCreature->ItemNumber == NO_VALUE || currentCreature->ItemNumber == itemNumber)
continue;
auto* target = &g_Level.Items[currentCreature->ItemNumber];
@@ -151,14 +151,14 @@ namespace TEN::Entities::Creatures::TR3
if (item->AIBits != MODIFY)
{
- if (item->CarriedItem != NO_ITEM)
+ if (item->CarriedItem != NO_VALUE)
item->MeshBits = 0xFFFFFEFF;
else
item->MeshBits = ALL_JOINT_BITS;
}
else
{
- if (item->CarriedItem != NO_ITEM)
+ if (item->CarriedItem != NO_VALUE)
item->MeshBits = 0xFFFF6E6F;
else
item->MeshBits = 0xFFFF6F6F;
@@ -190,7 +190,7 @@ namespace TEN::Entities::Creatures::TR3
GetCreatureMood(item, &AI, true);
- if (Lara.Context.Vehicle != NO_ITEM)
+ if (Lara.Context.Vehicle != NO_VALUE)
creature->Mood = MoodType::Escape;
CreatureMood(item, &AI, true);
@@ -231,7 +231,7 @@ namespace TEN::Entities::Creatures::TR3
item->Animation.TargetState = MONKEY_STATE_IDLE;
else if (creature->Mood == MoodType::Bored)
{
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else if (Random::TestProbability(0.06f))
item->Animation.TargetState = MONKEY_STATE_WALK_FORWARD;
@@ -246,7 +246,7 @@ namespace TEN::Entities::Creatures::TR3
else if ((item->AIBits & FOLLOW) &&
(creature->ReachedGoal || laraAI.distance > pow(BLOCK(2), 2)))
{
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else if (AI.ahead)
item->Animation.TargetState = MONKEY_STATE_SIT;
@@ -292,7 +292,7 @@ namespace TEN::Entities::Creatures::TR3
}
else if (creature->Mood == MoodType::Bored)
{
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else if (Random::TestProbability(0.06f))
item->Animation.TargetState = MONKEY_STATE_WALK_FORWARD;
@@ -307,7 +307,7 @@ namespace TEN::Entities::Creatures::TR3
else if (item->AIBits & FOLLOW &&
(creature->ReachedGoal || laraAI.distance > pow(BLOCK(2), 2)))
{
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else if (AI.ahead)
item->Animation.TargetState = MONKEY_STATE_SIT;
@@ -360,11 +360,11 @@ namespace TEN::Entities::Creatures::TR3
item->CarriedItem = creature->Enemy->Index;
RemoveDrawnItem(creature->Enemy->Index);
creature->Enemy->RoomNumber = NO_ROOM;
- creature->Enemy->CarriedItem = NO_ITEM;
+ creature->Enemy->CarriedItem = NO_VALUE;
for (auto& currentCreature : ActiveCreatures)
{
- if (currentCreature->ItemNumber == NO_ITEM || currentCreature->ItemNumber == itemNumber)
+ if (currentCreature->ItemNumber == NO_VALUE || currentCreature->ItemNumber == itemNumber)
continue;
auto* target = &g_Level.Items[currentCreature->ItemNumber];
@@ -391,7 +391,7 @@ namespace TEN::Entities::Creatures::TR3
carriedItem->Pose.Position = item->Pose.Position;
ItemNewRoom(item->CarriedItem, item->RoomNumber);
- item->CarriedItem = NO_ITEM;
+ item->CarriedItem = NO_VALUE;
carriedItem->AIBits = GUARD;
creature->Enemy = nullptr;
diff --git a/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp b/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp
index 96f4b2a76..7383b8925 100644
--- a/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp
+++ b/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp
@@ -72,7 +72,7 @@ namespace TEN::Entities::Creatures::TR3
if (creature->MuzzleFlash[0].Delay != 0)
creature->MuzzleFlash[0].Delay--;
- if (item->BoxNumber != NO_BOX && (g_Level.Boxes[item->BoxNumber].flags & BLOCKED))
+ if (item->BoxNumber != NO_VALUE && (g_Level.Boxes[item->BoxNumber].flags & BLOCKED))
{
DoDamage(item, 20);
DoLotsOfBlood(item->Pose.Position.x, item->Pose.Position.y - (GetRandomControl() & 255) - 32, item->Pose.Position.z, (GetRandomControl() & 127) + 128, GetRandomControl() * 2, item->RoomNumber, 3);
@@ -125,7 +125,7 @@ namespace TEN::Entities::Creatures::TR3
for (auto& currentCreature : ActiveCreatures)
{
- if (currentCreature->ItemNumber == NO_ITEM || currentCreature->ItemNumber == itemNumber)
+ if (currentCreature->ItemNumber == NO_VALUE || currentCreature->ItemNumber == itemNumber)
continue;
auto* target = &g_Level.Items[currentCreature->ItemNumber];
diff --git a/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp b/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp
index 56c5182f3..643f4d6c6 100644
--- a/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp
+++ b/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp
@@ -77,7 +77,7 @@ namespace TEN::Entities::Creatures::TR3
short head = 0;
auto extraTorsoRot = EulerAngles::Identity;
- if (item->BoxNumber != NO_BOX && (g_Level.Boxes[item->BoxNumber].flags & BLOCKED))
+ if (item->BoxNumber != NO_VALUE && (g_Level.Boxes[item->BoxNumber].flags & BLOCKED))
{
DoDamage(item, 20);
DoLotsOfBlood(item->Pose.Position.x, item->Pose.Position.y - (GetRandomControl() & 255) - 32, item->Pose.Position.z, (GetRandomControl() & 127) + 128, GetRandomControl() * 2, item->RoomNumber, 3);
@@ -107,7 +107,7 @@ namespace TEN::Entities::Creatures::TR3
int bestDistance = INT_MAX;
for (auto& currentCreature : ActiveCreatures)
{
- if (currentCreature->ItemNumber == NO_ITEM || currentCreature->ItemNumber == itemNumber)
+ if (currentCreature->ItemNumber == NO_VALUE || currentCreature->ItemNumber == itemNumber)
continue;
auto* target = &g_Level.Items[currentCreature->ItemNumber];
@@ -207,7 +207,7 @@ namespace TEN::Entities::Creatures::TR3
else if (creature->Mood == MoodType::Bored ||
(item->AIBits & FOLLOW && (creature->ReachedGoal || laraAI.distance > pow(BLOCK(2), 2))))
{
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else if (AI.ahead)
item->Animation.TargetState = MPSTICK_STATE_STOP;
diff --git a/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp b/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp
index 7387baab4..77d4c0558 100644
--- a/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp
+++ b/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp
@@ -99,7 +99,7 @@ namespace TEN::Entities::Creatures::TR3
for (auto& currentCreature : ActiveCreatures)
{
- if (currentCreature->ItemNumber == NO_ITEM || currentCreature->ItemNumber == itemNumber)
+ if (currentCreature->ItemNumber == NO_VALUE || currentCreature->ItemNumber == itemNumber)
continue;
auto* targetItem = &g_Level.Items[currentCreature->ItemNumber];
@@ -148,7 +148,7 @@ namespace TEN::Entities::Creatures::TR3
creature->MaxTurn = 0;
creature->Flags &= ~1;
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else if (creature->Flags & 2)
{
diff --git a/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp b/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp
index 2b7f9bf0d..92b5c5a95 100644
--- a/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp
+++ b/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp
@@ -62,7 +62,7 @@ namespace TEN::Entities::Creatures::TR3
static void ShootHarpoon(ItemInfo* item, Vector3i pos, short velocity, short yRot, short roomNumber)
{
short harpoonItemNumber = CreateItem();
- if (harpoonItemNumber == NO_ITEM)
+ if (harpoonItemNumber == NO_VALUE)
return;
auto* harpoonItem = &g_Level.Items[harpoonItemNumber];
diff --git a/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp b/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp
index db8e7320c..2977c9c87 100644
--- a/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp
+++ b/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp
@@ -109,7 +109,7 @@ namespace TEN::Entities::Creatures::TR3
creature->MaxTurn = 0;
creature->Flags = 0;
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
{
item->Animation.TargetState = item->Animation.RequiredState;
}
diff --git a/TombEngine/Objects/TR3/Entity/tr3_tony.cpp b/TombEngine/Objects/TR3/Entity/tr3_tony.cpp
index 27728f2a3..9a4ed5ac5 100644
--- a/TombEngine/Objects/TR3/Entity/tr3_tony.cpp
+++ b/TombEngine/Objects/TR3/Entity/tr3_tony.cpp
@@ -87,7 +87,7 @@ namespace TEN::Entities::Creatures::TR3
static void TriggerTonyEffect(const TonyFlame& flame)
{
int fxNumber = CreateNewEffect(flame.RoomNumber);
- if (fxNumber == NO_ITEM)
+ if (fxNumber == NO_VALUE)
return;
auto& fx = EffectList[fxNumber];
diff --git a/TombEngine/Objects/TR3/Entity/tr3_trex.cpp b/TombEngine/Objects/TR3/Entity/tr3_trex.cpp
index 015516bb7..d530196a0 100644
--- a/TombEngine/Objects/TR3/Entity/tr3_trex.cpp
+++ b/TombEngine/Objects/TR3/Entity/tr3_trex.cpp
@@ -124,7 +124,7 @@ namespace TEN::Entities::Creatures::TR3
switch (item->Animation.ActiveState)
{
case TREX_STATE_IDLE:
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else if (ai.distance < pow(1500, 2) && ai.bite)
item->Animation.TargetState = TREX_STATE_ATTACK;
diff --git a/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp b/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp
index 3ead12fa9..f97c28937 100644
--- a/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp
+++ b/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp
@@ -363,7 +363,7 @@ namespace TEN::Entities::Creatures::TR3
void TribesmanShotDart(ItemInfo* item)
{
int dartItemNumber = CreateItem();
- if (dartItemNumber == NO_ITEM)
+ if (dartItemNumber == NO_VALUE)
return;
auto* dartItem = &g_Level.Items[dartItemNumber];
diff --git a/TombEngine/Objects/TR3/Object/corpse.cpp b/TombEngine/Objects/TR3/Object/corpse.cpp
index 54df7cbfa..c646f49f4 100644
--- a/TombEngine/Objects/TR3/Object/corpse.cpp
+++ b/TombEngine/Objects/TR3/Object/corpse.cpp
@@ -16,60 +16,63 @@
#include "Game/Lara/lara.h"
#include "Game/Lara/lara_helpers.h"
#include "Game/Setup.h"
+#include "Math/Math.h"
#include "Sound/sound.h"
#include "Specific/level.h"
using namespace TEN::Collision::Point;
using namespace TEN::Effects::Ripple;
-using namespace TEN::Math::Random;
+using namespace TEN::Math;
namespace TEN::Entities::TR3
{
enum CorpseState
{
- CORPSE_STATE_LYING = 0,
- CORPSE_STATE_HANGING = 1,
- CORPSE_STATE_FALLING = 2,
- CORPSE_STATE_LANDING = 3
+ CORPSE_STATE_GROUNDED = 0,
+ CORPSE_STATE_HANG = 1,
+ CORPSE_STATE_FALL = 2,
+ CORPSE_STATE_LAND = 3
};
enum CorpseAnim
{
- CORPSE_ANIM_LYING = 0,
- CORPSE_ANIM_HANGING = 1,
- CORPSE_ANIM_FALLING = 2,
- CORPSE_ANIM_LANDING = 3
+ CORPSE_ANIM_GROUNDED = 0,
+ CORPSE_ANIM_HANG = 1,
+ CORPSE_ANIM_FALL = 2,
+ CORPSE_ANIM_LAND = 3
};
void InitializeCorpse(short itemNumber)
{
auto& item = g_Level.Items[itemNumber];
+ const auto& object = Objects[item.ObjectNumber];
if (item.TriggerFlags == 1)
{
- item.ItemFlags[1] = (int)CorpseFlags::Hanging;
- item.Animation.AnimNumber = Objects[item.ObjectNumber].animIndex + CORPSE_ANIM_HANGING;
- item.Animation.ActiveState = CORPSE_STATE_HANGING;
+ item.ItemFlags[1] = (int)CorpseFlag::Hang;
+ item.Animation.AnimNumber = object.animIndex + CORPSE_ANIM_HANG;
+ item.Animation.ActiveState = CORPSE_STATE_HANG;
}
else
{
- item.ItemFlags[1] = (int)CorpseFlags::Lying;
- item.Animation.AnimNumber = Objects[item.ObjectNumber].animIndex + CORPSE_ANIM_LYING;
- item.Animation.ActiveState = CORPSE_STATE_LYING;
+ item.ItemFlags[1] = (int)CorpseFlag::Grounded;
+ item.Animation.AnimNumber = object.animIndex + CORPSE_ANIM_GROUNDED;
+ item.Animation.ActiveState = CORPSE_STATE_GROUNDED;
}
AddActiveItem(itemNumber);
item.Status = ITEM_ACTIVE;
}
- void CorpseControl(short itemNumber)
+ void ControlCorpse(short itemNumber)
{
auto& item = g_Level.Items[itemNumber];
-
- if (item.ItemFlags[1] == (int)CorpseFlags::Falling)
+ const auto& object = Objects[item.ObjectNumber];
+
+ if (item.ItemFlags[1] == (int)CorpseFlag::Fall)
{
bool isWater = TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, item.RoomNumber);
- int VerticalVelCoeff = isWater ? 81.0f : 1.0f;
+ float verticalVelCoeff = isWater ? 81.0f : 1.0f;
int roomNumber = GetPointCollision(item).GetRoomNumber();
if (item.RoomNumber != roomNumber)
@@ -108,19 +111,18 @@ namespace TEN::Entities::TR3
item.Animation.IsAirborne = false;
item.Animation.Velocity = Vector3::Zero;
- item.Animation.TargetState = CORPSE_STATE_LANDING;
- item.Animation.AnimNumber = Objects[item.ObjectNumber].animIndex + CORPSE_ANIM_LANDING;
- AlignEntityToSurface(&item, Vector2(Objects[item.ObjectNumber].radius));
+ item.Animation.TargetState = CORPSE_STATE_LAND;
+ item.Animation.AnimNumber = object.animIndex + CORPSE_ANIM_LAND;
+ AlignEntityToSurface(&item, Vector2(object.radius));
- item.ItemFlags[1] = (int)CorpseFlags::Lying;
+ item.ItemFlags[1] = (int)CorpseFlag::Grounded;
return;
}
else
{
if (isWater)
-
{
- item.Animation.Velocity.y += 0.1f / VerticalVelCoeff;
+ item.Animation.Velocity.y += 0.1f / verticalVelCoeff;
}
else
{
@@ -134,18 +136,20 @@ namespace TEN::Entities::TR3
if (!TriggerActive(&item))
return;
- int numMeshes = Objects[item.ObjectNumber].nmeshes;
- for (int i = 0; i < numMeshes; i++)
+ int meshCount = object.nmeshes;
+ for (int i = 0; i < meshCount; i++)
{
- auto pos = GetJointPosition(&item, i);
-
- if (TestProbability(1 / 72.0f))
- SpawnCorpseEffect(pos.ToVector3());
+ if (Random::TestProbability(1 / 72.0f))
+ {
+ auto pos = GetJointPosition(&item, i).ToVector3();
+ SpawnCorpseEffect(pos);
+ }
}
}
- void CorpseHit(ItemInfo& target, ItemInfo& source, std::optional pos, int damage, bool isExplosive, int jointIndex)
+ void HitCorpse(ItemInfo& target, ItemInfo& source, std::optional pos, int damage, bool isExplosive, int jointIndex)
{
+ const auto& object = Objects[target.ObjectNumber];
const auto& player = *GetLaraInfo(&source);
if (pos.has_value() && (player.Control.Weapon.GunType == LaraWeaponType::Pistol ||
@@ -156,13 +160,12 @@ namespace TEN::Entities::TR3
{
DoBloodSplat(pos->x, pos->y, pos->z, Random::GenerateInt(4, 8), source.Pose.Orientation.y, pos->RoomNumber);
- if (target.ItemFlags[1] == (int)CorpseFlags::Hanging)
+ if (target.ItemFlags[1] == (int)CorpseFlag::Hang)
{
- target.ItemFlags[1] = (int)CorpseFlags::Falling;
- target.Animation.AnimNumber = Objects[target.ObjectNumber].animIndex + CORPSE_ANIM_FALLING;
- target.Animation.ActiveState = CORPSE_STATE_FALLING;
+ target.ItemFlags[1] = (int)CorpseFlag::Fall;
+ target.Animation.AnimNumber = object.animIndex + CORPSE_ANIM_FALL;
+ target.Animation.ActiveState = CORPSE_STATE_FALL;
}
-
}
else if (player.Weapons[(int)LaraWeaponType::GrenadeLauncher].SelectedAmmo == WeaponAmmoType::Ammo2)
{
diff --git a/TombEngine/Objects/TR3/Object/corpse.h b/TombEngine/Objects/TR3/Object/corpse.h
index b2a146a25..1500faf4c 100644
--- a/TombEngine/Objects/TR3/Object/corpse.h
+++ b/TombEngine/Objects/TR3/Object/corpse.h
@@ -5,15 +5,15 @@ struct ItemInfo;
namespace TEN::Entities::TR3
{
-
- enum class CorpseFlags
+ enum class CorpseFlag
{
- Lying = (1 << 0),
- Hanging = (1 << 1),
- Falling = (1 << 2)
+ None = 0,
+ Grounded = 1,
+ Hang = 2,
+ Fall = 3
};
void InitializeCorpse(short itemNumber);
- void CorpseControl(short itemNumber);
- void CorpseHit(ItemInfo& target, ItemInfo& source, std::optional pos, int damage, bool isExplosive, int jointIndex);
+ void ControlCorpse(short itemNumber);
+ void HitCorpse(ItemInfo& target, ItemInfo& source, std::optional pos, int damage, bool isExplosive, int jointIndex);
}
diff --git a/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp b/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp
index 13404cbae..3289a1196 100644
--- a/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp
+++ b/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp
@@ -9,6 +9,7 @@
#include "Game/effects/spark.h"
#include "Game/effects/tomb4fx.h"
#include "Game/Lara/lara_helpers.h"
+#include "Game/misc.h"
#include "Game/Setup.h"
using namespace TEN::Collision::Point;
@@ -73,102 +74,15 @@ namespace TEN::Entities::Traps
}
}
- static bool IsNextSectorValid(const ItemInfo& item, const Vector3& dir)
- {
- auto projectedPos = Geometry::TranslatePoint(item.Pose.Position, dir, BLOCK(1));
- auto pointColl = GetPointCollision(item.Pose.Position, item.RoomNumber, dir, BLOCK(1));
-
- // TODO: Use floor normal directly.
- auto floorTilt = GetSurfaceTilt(pointColl.GetFloorNormal(), true);
-
- // Test for wall.
- if (pointColl.GetSector().IsWall(projectedPos.x, projectedPos.z))
- return false;
-
- // Test for slippery slope.
- if (pointColl.IsIllegalFloor())
- return false;
-
- // Flat floor.
- if (abs(floorTilt.x) == 0 && abs(floorTilt.y) == 0)
- {
- // Test for step.
- int relFloorHeight = abs(pointColl.GetFloorHeight() - item.Pose.Position.y);
- if (relFloorHeight >= CLICK(1))
- return false;
- }
- // Sloped floor.
- else
- {
- // Half block.
- int relFloorHeight = abs(pointColl.GetFloorHeight() - item.Pose.Position.y);
- if (relFloorHeight > CLICK(2))
- return false;
-
- short slopeAngle = ANGLE(0.0f);
- if (floorTilt.x > 0)
- {
- slopeAngle = ANGLE(-90.0f);
- }
- else if (floorTilt.x < 0)
- {
- slopeAngle = ANGLE(90.0f);
- }
-
- if (floorTilt.y > 0 && floorTilt.y > abs(floorTilt.x))
- {
- slopeAngle = ANGLE(180.0f);
- }
- else if (floorTilt.y < 0 && -floorTilt.y > abs(floorTilt.x))
- {
- slopeAngle = ANGLE(0.0f);
- }
-
- short dirAngle = phd_atan(dir.z, dir.x);
- short alignAngle = Geometry::GetShortestAngle(slopeAngle, dirAngle);
-
- // Test if slope aspect is aligned with direction.
- if (alignAngle != 0 && alignAngle != ANGLE(180.0f))
- return false;
- }
-
- // Check for diagonal split.
- if (pointColl.IsDiagonalFloorStep())
- return false;
-
- // Test ceiling height.
- int relCeilHeight = abs(pointColl.GetCeilingHeight() - pointColl.GetFloorHeight());
- int cleanerHeight = BLOCK(1);
- if (relCeilHeight < cleanerHeight)
- return false;
-
- // Check for inaccessible sector.
- if (pointColl.GetSector().Box == NO_BOX)
- return false;
-
- // Check for blocked grey box.
- if (g_Level.Boxes[pointColl.GetSector().Box].flags & BLOCKABLE)
- {
- if (g_Level.Boxes[pointColl.GetSector().Box].flags& BLOCKED)
- return false;
- }
-
- // Check for stopper flag.
- if (pointColl.GetSector().Stopper)
- return false;
-
- return true;
- }
-
static Vector3 GetElectricCleanerMovementDirection(const ItemInfo& item, const Vector3& dir0, const Vector3& dir1, const Vector3& dir2)
{
- if (IsNextSectorValid(item, dir0))
+ if (IsNextSectorValid(item, dir0, BLOCK(1)))
return dir0;
- if (IsNextSectorValid(item, dir1))
+ if (IsNextSectorValid(item, dir1, BLOCK(1)))
return dir1;
- if (IsNextSectorValid(item, dir2))
+ if (IsNextSectorValid(item, dir2, BLOCK(1)))
return dir2;
return Vector3::Zero;
@@ -197,18 +111,18 @@ namespace TEN::Entities::Traps
break;
}
- if (GetCollidedObjects(&item, CLICK(1), true, CollidedItems, CollidedMeshes, true))
+ auto collObjects = GetCollidedObjects(item, true, true);
+ if (!collObjects.IsEmpty())
{
- int lp = 0;
- while (CollidedItems[lp] != nullptr)
+ for (auto* itemPtr : collObjects.ItemPtrs)
{
- if (Objects[CollidedItems[lp]->ObjectNumber].intelligent)
- {
- CollidedItems[lp]->HitPoints = 0;
- ItemElectricBurn(CollidedItems[lp], 120);
- }
+ const auto& object = Objects[itemPtr->ObjectNumber];
- lp++;
+ if (object.intelligent)
+ {
+ itemPtr->HitPoints = 0;
+ ItemElectricBurn(itemPtr, 120);
+ }
}
}
diff --git a/TombEngine/Objects/TR3/Vehicles/big_gun.cpp b/TombEngine/Objects/TR3/Vehicles/big_gun.cpp
index 2e49fb8b9..3c94992a0 100644
--- a/TombEngine/Objects/TR3/Vehicles/big_gun.cpp
+++ b/TombEngine/Objects/TR3/Vehicles/big_gun.cpp
@@ -120,7 +120,7 @@ namespace TEN::Entities::Vehicles
void BigGunFire(ItemInfo* bigGunItem, ItemInfo* laraItem)
{
short itemNumber = CreateItem();
- if (itemNumber == NO_ITEM)
+ if (itemNumber == NO_VALUE)
return;
auto* lara = GetLaraInfo(laraItem);
auto* bigGun = GetBigGunInfo(bigGunItem);
@@ -156,7 +156,7 @@ namespace TEN::Entities::Vehicles
auto* bigGun = GetBigGunInfo(bigGunItem);
auto* lara = GetLaraInfo(laraItem);
- if (laraItem->HitPoints <= 0 || lara->Context.Vehicle != NO_ITEM)
+ if (laraItem->HitPoints <= 0 || lara->Context.Vehicle != NO_VALUE)
return;
if (BigGunTestMount(laraItem, bigGunItem))
diff --git a/TombEngine/Objects/TR3/Vehicles/kayak.cpp b/TombEngine/Objects/TR3/Vehicles/kayak.cpp
index e3ae3d7a8..c0e9dfdb0 100644
--- a/TombEngine/Objects/TR3/Vehicles/kayak.cpp
+++ b/TombEngine/Objects/TR3/Vehicles/kayak.cpp
@@ -148,7 +148,7 @@ namespace TEN::Entities::Vehicles
auto* kayak = GetKayakInfo(kayakItem);
auto* lara = GetLaraInfo(laraItem);
- if (laraItem->HitPoints < 0 || lara->Context.Vehicle != NO_ITEM)
+ if (laraItem->HitPoints < 0 || lara->Context.Vehicle != NO_VALUE)
return;
auto mountType = GetVehicleMountType(kayakItem, laraItem, coll, KayakMountTypes, KAYAK_MOUNT_DISTANCE, LARA_HEIGHT);
@@ -1005,12 +1005,14 @@ namespace TEN::Entities::Vehicles
short itemNum = g_Level.Rooms[i].itemNumber;
- while (itemNum != NO_ITEM)
+ while (itemNum != NO_VALUE)
{
auto* item = &g_Level.Items[itemNum];
short nextItem = item->NextItem;
- if (item->Collidable && item->Status != ITEM_INVISIBLE)
+ if (item->Collidable &&
+ item->Status != ITEM_INVISIBLE &&
+ item != laraItem && item != kayakItem)
{
auto* object = &Objects[item->ObjectNumber];
@@ -1106,7 +1108,7 @@ namespace TEN::Entities::Vehicles
DoDamage(laraItem, (damage - 160) * 8);
}
- if (lara->Context.Vehicle != NO_ITEM)
+ if (lara->Context.Vehicle != NO_VALUE)
{
if (kayakItem->RoomNumber != probe.GetRoomNumber())
{
@@ -1158,6 +1160,6 @@ namespace TEN::Entities::Vehicles
KayakToItemCollision(kayakItem, laraItem);
- return (lara->Context.Vehicle != NO_ITEM) ? true : false;
+ return (lara->Context.Vehicle != NO_VALUE) ? true : false;
}
}
diff --git a/TombEngine/Objects/TR3/Vehicles/minecart.cpp b/TombEngine/Objects/TR3/Vehicles/minecart.cpp
index 888cc1ab6..21215c3f9 100644
--- a/TombEngine/Objects/TR3/Vehicles/minecart.cpp
+++ b/TombEngine/Objects/TR3/Vehicles/minecart.cpp
@@ -155,7 +155,7 @@ namespace TEN::Entities::Vehicles
MINECART_FLAG_DISMOUNT_RIGHT = (1 << 3),
MINECART_FLAG_CONTROL = (1 << 4),
MINECART_FLAG_STOPPED = (1 << 5),
- MINECART_FLAG_NO_ANIM = (1 << 6),
+ MINECART_FLAG_NO_VALUE = (1 << 6),
MINECART_FLAG_DEAD = (1 << 7)
};
@@ -175,7 +175,7 @@ namespace TEN::Entities::Vehicles
auto* minecartItem = &g_Level.Items[itemNumber];
auto* lara = GetLaraInfo(laraItem);
- if (laraItem->HitPoints < 0 || lara->Context.Vehicle != NO_ITEM)
+ if (laraItem->HitPoints < 0 || lara->Context.Vehicle != NO_VALUE)
return;
// Don't get into minecart if there are two stop blocks in front.
@@ -288,7 +288,7 @@ namespace TEN::Entities::Vehicles
short itemNumber = g_Level.Rooms[i].itemNumber;
- while (itemNumber != NO_ITEM)
+ while (itemNumber != NO_VALUE)
{
auto* item = &g_Level.Items[itemNumber];
@@ -832,7 +832,7 @@ namespace TEN::Entities::Vehicles
{
if (TestAnimNumber(*laraItem, MINECART_ANIM_FALL_DEATH))
{
- minecart->Flags |= MINECART_FLAG_NO_ANIM;
+ minecart->Flags |= MINECART_FLAG_NO_VALUE;
laraItem->HitPoints = -1;
}
}
@@ -846,7 +846,7 @@ namespace TEN::Entities::Vehicles
laraItem->Animation.FrameNumber = GetFrameIndex(minecartItem, 34) + 28;
minecartItem->Animation.Velocity.z = 0.0f;
minecart->Velocity = 0;
- minecart->Flags = (minecart->Flags & ~MINECART_FLAG_CONTROL) | MINECART_FLAG_NO_ANIM;
+ minecart->Flags = (minecart->Flags & ~MINECART_FLAG_CONTROL) | MINECART_FLAG_NO_VALUE;
}
break;
@@ -864,8 +864,8 @@ namespace TEN::Entities::Vehicles
break;
}
- if (lara->Context.Vehicle != NO_ITEM &&
- !(minecart->Flags & MINECART_FLAG_NO_ANIM))
+ if (lara->Context.Vehicle != NO_VALUE &&
+ !(minecart->Flags & MINECART_FLAG_NO_VALUE))
{
AnimateItem(laraItem);
SyncVehicleAnimation(*minecartItem, *laraItem);
@@ -968,7 +968,7 @@ namespace TEN::Entities::Vehicles
if (minecart->Flags & MINECART_FLAG_CONTROL)
MoveCart(minecartItem, laraItem);
- if (lara->Context.Vehicle != NO_ITEM)
+ if (lara->Context.Vehicle != NO_VALUE)
laraItem->Pose = minecartItem->Pose;
short probedRoomNumber = GetPointCollision(*minecartItem).GetRoomNumber();
@@ -986,6 +986,6 @@ namespace TEN::Entities::Vehicles
Camera.targetDistance = BLOCK(2);
}
- return (lara->Context.Vehicle == NO_ITEM) ? false : true;
+ return (lara->Context.Vehicle == NO_VALUE) ? false : true;
}
}
diff --git a/TombEngine/Objects/TR3/Vehicles/quad_bike.cpp b/TombEngine/Objects/TR3/Vehicles/quad_bike.cpp
index 8711384ef..6dc3a4f5f 100644
--- a/TombEngine/Objects/TR3/Vehicles/quad_bike.cpp
+++ b/TombEngine/Objects/TR3/Vehicles/quad_bike.cpp
@@ -180,7 +180,7 @@ namespace TEN::Entities::Vehicles
auto* quadBikeItem = &g_Level.Items[itemNumber];
auto* lara = GetLaraInfo(laraItem);
- if (laraItem->HitPoints < 0 || lara->Context.Vehicle != NO_ITEM)
+ if (laraItem->HitPoints < 0 || lara->Context.Vehicle != NO_VALUE)
return;
auto mountType = GetVehicleMountType(quadBikeItem, laraItem, coll, QuadBikeMountTypes, QBIKE_MOUNT_DISTANCE);
@@ -263,7 +263,7 @@ namespace TEN::Entities::Vehicles
auto* quadBike = GetQuadBikeInfo(quadBikeItem);
auto* lara = GetLaraInfo(laraItem);
- if (lara->Context.Vehicle == NO_ITEM)
+ if (lara->Context.Vehicle == NO_VALUE)
return true;
if ((laraItem->Animation.ActiveState == QBIKE_STATE_DISMOUNT_RIGHT || laraItem->Animation.ActiveState == QBIKE_STATE_DISMOUNT_LEFT) &&
diff --git a/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp b/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp
index 78f938ab2..4466ff811 100644
--- a/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp
+++ b/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp
@@ -116,7 +116,7 @@ namespace TEN::Entities::Vehicles
auto* rBoatItem = &g_Level.Items[itemNumber];
auto* lara = GetLaraInfo(laraItem);
- if (laraItem->HitPoints < 0 || lara->Context.Vehicle != NO_ITEM)
+ if (laraItem->HitPoints < 0 || lara->Context.Vehicle != NO_VALUE)
return;
auto mountType = GetVehicleMountType(rBoatItem, laraItem, coll, RubberBoatMountTypes, RBOAT_MOUNT_DISTANCE, LARA_HEIGHT);
@@ -194,7 +194,7 @@ namespace TEN::Entities::Vehicles
auto* lara = GetLaraInfo(laraItem);
int itemNumber2 = g_Level.Rooms[boatItem->RoomNumber].itemNumber;
- while (itemNumber2 != NO_ITEM)
+ while (itemNumber2 != NO_VALUE)
{
auto* item = &g_Level.Items[itemNumber2];
@@ -782,7 +782,7 @@ namespace TEN::Entities::Vehicles
laraItem->Animation.IsAirborne = true;
laraItem->Animation.Velocity.z = 20;
laraItem->Animation.Velocity.y = -40;
- lara->Context.Vehicle = NO_ITEM; // Leave vehicle itself active for inertia.
+ lara->Context.Vehicle = NO_VALUE; // Leave vehicle itself active for inertia.
int x = laraItem->Pose.Position.x + 360 * phd_sin(laraItem->Pose.Orientation.y);
int y = laraItem->Pose.Position.y - 90;
diff --git a/TombEngine/Objects/TR3/Vehicles/upv.cpp b/TombEngine/Objects/TR3/Vehicles/upv.cpp
index bbd37ad60..2a5928033 100644
--- a/TombEngine/Objects/TR3/Vehicles/upv.cpp
+++ b/TombEngine/Objects/TR3/Vehicles/upv.cpp
@@ -178,7 +178,7 @@ namespace TEN::Entities::Vehicles
auto* UPVItem = &g_Level.Items[itemNumber];
auto* lara = GetLaraInfo(laraItem);
- if (laraItem->HitPoints <= 0 || lara->Context.Vehicle != NO_ITEM)
+ if (laraItem->HitPoints <= 0 || lara->Context.Vehicle != NO_VALUE)
return;
auto mountType = GetVehicleMountType(UPVItem, laraItem, coll, UPVMountTypes, UPV_MOUNT_DISTANCE);
@@ -290,7 +290,7 @@ namespace TEN::Entities::Vehicles
void UPVEffects(short itemNumber)
{
- if (itemNumber == NO_ITEM)
+ if (itemNumber == NO_VALUE)
return;
auto* UPVItem = &g_Level.Items[itemNumber];
@@ -948,7 +948,7 @@ namespace TEN::Entities::Vehicles
}
if (!(UPV->Flags & UPV_FLAG_DEAD) &&
- lara->Context.Vehicle != NO_ITEM)
+ lara->Context.Vehicle != NO_VALUE)
{
DoCurrent(UPVItem, laraItem);
diff --git a/TombEngine/Objects/TR3/fish.h b/TombEngine/Objects/TR3/fish.h
deleted file mode 100644
index cb497408c..000000000
--- a/TombEngine/Objects/TR3/fish.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#pragma once
-
-struct FishInfo
-{
- short x;
- short y;
- short z;
- int angle;
- short destY;
- short angAdd;
- unsigned char speed;
- unsigned char acc;
- unsigned char swim;
-};
-
-struct FishLeaderInfo
-{
- short angle;
- unsigned char speed;
- unsigned char on;
- short angleTime;
- short speedTime;
- short xRange, yRange, zRange;
-};
diff --git a/TombEngine/Objects/TR3/tr3_objects.cpp b/TombEngine/Objects/TR3/tr3_objects.cpp
index fd9377b80..2b607a6ca 100644
--- a/TombEngine/Objects/TR3/tr3_objects.cpp
+++ b/TombEngine/Objects/TR3/tr3_objects.cpp
@@ -20,7 +20,7 @@
#include "Objects/TR3/Entity/tr3_civvy.h" // OK
#include "Objects/TR3/Entity/tr3_claw_mutant.h" // OK
#include "Objects/TR3/Entity/tr3_cobra.h" // OK
-#include "Objects/TR3/Entity/tr3_fish_emitter.h" // OK
+#include "Objects/TR3/Entity/FishSwarm.h" // OK
#include "Objects/TR3/Entity/tr3_flamethrower.h" // OK
#include "Objects/TR3/Entity/tr3_monkey.h" // OK
#include "Objects/TR3/Entity/tr3_mp_gun.h" // OK
@@ -425,6 +425,15 @@ static void StartEntity(ObjectInfo* obj)
obj->intelligent = true;
obj->SetHitEffect();
}
+
+ obj = &Objects[ID_FISH_EMITTER];
+ if (obj->loaded)
+ {
+ obj->Initialize = InitializeFishSwarm;
+ obj->control = ControlFishSwarm;
+ obj->intelligent = true;
+ obj->drawRoutine = NULL;
+ }
}
static void StartObject(ObjectInfo* obj)
@@ -462,8 +471,8 @@ static void StartObject(ObjectInfo* obj)
obj->Initialize = InitializeCorpse;
obj->collision = CreatureCollision;
obj->damageType = DamageMode::None;
- obj->control = CorpseControl;
- obj->HitRoutine = CorpseHit;
+ obj->control = ControlCorpse;
+ obj->HitRoutine = HitCorpse;
obj->HitPoints = NOT_TARGETABLE;
obj->shadowType = ShadowMode::None;
obj->SetHitEffect();
diff --git a/TombEngine/Objects/TR4/Entity/Wraith.cpp b/TombEngine/Objects/TR4/Entity/Wraith.cpp
index e3e536366..b03fefcb9 100644
--- a/TombEngine/Objects/TR4/Entity/Wraith.cpp
+++ b/TombEngine/Objects/TR4/Entity/Wraith.cpp
@@ -322,7 +322,7 @@ namespace TEN::Entities::TR4
if (pointColl.GetRoomNumber() != item.RoomNumber)
ItemNewRoom(itemNumber, pointColl.GetRoomNumber());
- for (int linkItemNumber = g_Level.Rooms[item.RoomNumber].itemNumber; linkItemNumber != NO_ITEM; linkItemNumber = g_Level.Items[linkItemNumber].NextItem)
+ for (int linkItemNumber = g_Level.Rooms[item.RoomNumber].itemNumber; linkItemNumber != NO_VALUE; linkItemNumber = g_Level.Items[linkItemNumber].NextItem)
{
auto& targetItem = g_Level.Items[linkItemNumber];
@@ -702,15 +702,15 @@ namespace TEN::Entities::TR4
{
ItemInfo* item2 = nullptr;
- if (NextItemActive != NO_ITEM)
+ if (NextItemActive != NO_VALUE)
{
- for (; NextItemActive != NO_ITEM;)
+ for (; NextItemActive != NO_VALUE;)
{
auto* item2 = &g_Level.Items[NextItemActive];
if (item2->ObjectNumber == ID_WRAITH3 && !item2->HitPoints)
break;
- if (item2->NextActive == NO_ITEM)
+ if (item2->NextActive == NO_VALUE)
{
FlipEffect = -1;
return;
diff --git a/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp b/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp
index 5ae2b9394..a2754fb84 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp
@@ -215,7 +215,7 @@ namespace TEN::Entities::TR4
else if ((AI.angle >= AHMET_VIEW_ANGLE || AI.angle <= -AHMET_VIEW_ANGLE) ||
AI.distance >= AHMET_IDLE_RANGE)
{
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else
{
diff --git a/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp b/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp
index 262a36d62..c94ebd6a0 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp
@@ -112,7 +112,7 @@ namespace TEN::Entities::TR4
static void TriggerBaboonShockwave(Pose pos, short xRot)
{
short shockwaveID = GetFreeShockwave();
- if (shockwaveID != NO_ITEM)
+ if (shockwaveID != NO_VALUE)
{
auto* deathEffect = &ShockWaves[shockwaveID];
@@ -363,12 +363,12 @@ namespace TEN::Entities::TR4
else
item->Animation.TargetState = BABOON_STATE_RUN_FORWARD;
}
- else if (item->Animation.RequiredState != NO_STATE)
+ else if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else if (Random::TestProbability(1 / 2.0f))
item->Animation.TargetState = BABOON_STATE_SIT_IDLE;
}
- else if (item->Animation.RequiredState != NO_STATE)
+ else if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else if (Random::TestProbability(0.25f))
item->Animation.TargetState = BABOON_STATE_WALK_FORWARD;
@@ -401,7 +401,7 @@ namespace TEN::Entities::TR4
// NOTE: It's not true to the original functionality, but to avoid repetitive actions,
// the SIT_IDLE state was given a higher chance of occurring. The EAT state was also added here. -- TokyoSU
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else if (Random::TestProbability(1 / 2.0f))
item->Animation.TargetState = BABOON_STATE_SIT_IDLE;
@@ -417,7 +417,7 @@ namespace TEN::Entities::TR4
}
else if ((item->AIBits & FOLLOW) && AI.distance > BABOON_IDLE_RANGE)
{
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else
item->Animation.TargetState = BABOON_STATE_WALK_FORWARD;
diff --git a/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp b/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp
index 4490c0f0a..951b1305c 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp
@@ -395,7 +395,7 @@ namespace TEN::Entities::TR4
auto* currentCreature = creature;
if (item->ItemFlags[1] == item->RoomNumber ||
- g_Level.Rooms[item->RoomNumber].itemNumber == NO_ITEM)
+ g_Level.Rooms[item->RoomNumber].itemNumber == NO_VALUE)
{
currentCreature = creature;
}
@@ -404,7 +404,7 @@ namespace TEN::Entities::TR4
currentCreature = creature;
creature->Enemy = LaraItem;
ItemInfo* currentItem = nullptr;
- for (short itemNum = g_Level.Rooms[item->RoomNumber].itemNumber; itemNum != NO_ITEM; itemNum = currentItem->NextItem)
+ for (short itemNum = g_Level.Rooms[item->RoomNumber].itemNumber; itemNum != NO_VALUE; itemNum = currentItem->NextItem)
{
currentItem = &g_Level.Items[itemNum];
if ((currentItem->ObjectNumber == ID_SMALLMEDI_ITEM ||
@@ -540,7 +540,7 @@ namespace TEN::Entities::TR4
GetCreatureMood(item, &AI, true);
// Vehicle handling
- if (Lara.Context.Vehicle != NO_ITEM && AI.bite)
+ if (Lara.Context.Vehicle != NO_VALUE && AI.bite)
currentCreature->Mood = MoodType::Escape;
CreatureMood(item, &AI, true);
@@ -1112,7 +1112,7 @@ namespace TEN::Entities::TR4
// Cancel enemy pointer for other active baddys
for (int i = 0; i < ActiveCreatures.size(); i++)
{
- if (ActiveCreatures[i]->ItemNumber != NO_ITEM && ActiveCreatures[i]->ItemNumber != itemNumber && ActiveCreatures[i]->Enemy == creature->Enemy)
+ if (ActiveCreatures[i]->ItemNumber != NO_VALUE && ActiveCreatures[i]->ItemNumber != itemNumber && ActiveCreatures[i]->Enemy == creature->Enemy)
ActiveCreatures[i]->Enemy = nullptr;
}
diff --git a/TombEngine/Objects/TR4/Entity/tr4_beetle_swarm.cpp b/TombEngine/Objects/TR4/Entity/tr4_beetle_swarm.cpp
index c8e5b90ee..9951cd441 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_beetle_swarm.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_beetle_swarm.cpp
@@ -70,7 +70,7 @@ namespace TEN::Entities::TR4
}
short beetleNumber = GetFreeBeetle();
- if (beetleNumber != NO_ITEM)
+ if (beetleNumber != NO_VALUE)
{
auto* beetle = &BeetleSwarm[beetleNumber];
@@ -128,7 +128,7 @@ namespace TEN::Entities::TR4
}
if (++i >= NUM_BEETLES)
- return NO_ITEM;
+ return NO_VALUE;
}
NextBeetle = (result + 1) & (NUM_BEETLES - 1);
diff --git a/TombEngine/Objects/TR4/Entity/tr4_big_beetle.cpp b/TombEngine/Objects/TR4/Entity/tr4_big_beetle.cpp
index 664eb4f62..a2cc1ed9d 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_big_beetle.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_big_beetle.cpp
@@ -144,7 +144,7 @@ namespace TEN::Entities::TR4
case BBEETLE_STATE_FLY_FORWARD:
creature->MaxTurn = ANGLE(7.0f);
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else if (AI.ahead && AI.distance < BIG_BEETLE_ATTACK_RANGE)
item->Animation.TargetState = BBEETLE_STATE_FLY_IDLE;
@@ -194,7 +194,7 @@ namespace TEN::Entities::TR4
case BBEETLE_STATE_FLY_IDLE:
creature->MaxTurn = ANGLE(7.0f);
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else if (!item->HitStatus && item->AIBits != MODIFY &&
Random::TestProbability(0.99f) &&
diff --git a/TombEngine/Objects/TR4/Entity/tr4_big_scorpion.cpp b/TombEngine/Objects/TR4/Entity/tr4_big_scorpion.cpp
index 520548fd9..fe4ce6c80 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_big_scorpion.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_big_scorpion.cpp
@@ -95,9 +95,9 @@ namespace TEN::Entities::TR4
creature->MaxTurn = 0;
short linkNumber = g_Level.Rooms[item->RoomNumber].itemNumber;
- if (linkNumber != NO_ITEM)
+ if (linkNumber != NO_VALUE)
{
- for (linkNumber = g_Level.Rooms[item->RoomNumber].itemNumber; linkNumber != NO_ITEM; linkNumber = g_Level.Items[linkNumber].NextItem)
+ for (linkNumber = g_Level.Rooms[item->RoomNumber].itemNumber; linkNumber != NO_VALUE; linkNumber = g_Level.Items[linkNumber].NextItem)
{
auto* currentItem = &g_Level.Items[linkNumber];
@@ -140,7 +140,7 @@ namespace TEN::Entities::TR4
for (auto& currentCreature : ActiveCreatures)
{
- if (currentCreature->ItemNumber != NO_ITEM && currentCreature->ItemNumber != itemNumber)
+ if (currentCreature->ItemNumber != NO_VALUE && currentCreature->ItemNumber != itemNumber)
{
auto* currentItem = &g_Level.Items[currentCreature->ItemNumber];
if (currentItem->ObjectNumber != ID_LARA)
diff --git a/TombEngine/Objects/TR4/Entity/tr4_crocodile.cpp b/TombEngine/Objects/TR4/Entity/tr4_crocodile.cpp
index 19ec0f631..22b35629a 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_crocodile.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_crocodile.cpp
@@ -219,7 +219,7 @@ namespace TEN::Entities::TR4
break;
}
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else if (ai.bite && ai.distance < CROC_ATTACK_RANGE)
item->Animation.TargetState = CROC_STATE_IDLE;
@@ -239,7 +239,7 @@ namespace TEN::Entities::TR4
break;
}
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else if (ai.bite && ai.distance < CROC_ATTACK_RANGE)
item->Animation.TargetState = CROC_STATE_IDLE;
@@ -250,12 +250,12 @@ namespace TEN::Entities::TR4
case CROC_STATE_BITE_ATTACK:
if (item->Animation.FrameNumber == GetAnimData(item).frameBase)
- item->Animation.RequiredState = NO_STATE;
+ item->Animation.RequiredState = NO_VALUE;
if (ai.bite &&
item->TouchBits.Test(CrocodileBiteAttackJoints))
{
- if (item->Animation.RequiredState == NO_STATE)
+ if (item->Animation.RequiredState == NO_VALUE)
{
CreatureEffect2(item, CrocodileBite, 10, -1, DoBloodSplat);
DoDamage(creature->Enemy, CROC_ATTACK_DAMAGE);
@@ -277,7 +277,7 @@ namespace TEN::Entities::TR4
break;
}
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else if (ai.bite)
{
@@ -289,11 +289,11 @@ namespace TEN::Entities::TR4
case CROC_STATE_WATER_BITE_ATTACK:
if (item->Animation.FrameNumber == GetAnimData(item).frameBase)
- item->Animation.RequiredState = NO_STATE;
+ item->Animation.RequiredState = NO_VALUE;
if (ai.bite && item->TouchBits.Test(CrocodileBiteAttackJoints))
{
- if (item->Animation.RequiredState == NO_STATE)
+ if (item->Animation.RequiredState == NO_VALUE)
{
CreatureEffect2(item, CrocodileBite, 10, -1, DoBloodSplat);
DoDamage(creature->Enemy, CROC_ATTACK_DAMAGE);
diff --git a/TombEngine/Objects/TR4/Entity/tr4_dog.cpp b/TombEngine/Objects/TR4/Entity/tr4_dog.cpp
index bc603df7d..734f4b192 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_dog.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_dog.cpp
@@ -179,7 +179,7 @@ namespace TEN::Entities::TR4
creature->MaxTurn = 0;
if (item->Animation.ActiveState == DOG_STATE_STALK_IDLE &&
- item->Animation.RequiredState != NO_STATE)
+ item->Animation.RequiredState != NO_VALUE)
{
item->Animation.TargetState = item->Animation.RequiredState;
break;
diff --git a/TombEngine/Objects/TR4/Entity/tr4_enemy_jeep.cpp b/TombEngine/Objects/TR4/Entity/tr4_enemy_jeep.cpp
index c540afd27..404066b31 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_enemy_jeep.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_enemy_jeep.cpp
@@ -27,7 +27,7 @@ namespace TEN::Entities::TR4
{
short grenadeItemNumber = CreateItem();
- if (grenadeItemNumber != NO_ITEM)
+ if (grenadeItemNumber != NO_VALUE)
{
auto* grenadeItem = &g_Level.Items[grenadeItemNumber];
@@ -55,7 +55,7 @@ namespace TEN::Entities::TR4
grenadeItem->Animation.ActiveState = grenadeItem->Pose.Orientation.x;
grenadeItem->Animation.TargetState = grenadeItem->Pose.Orientation.y;
- grenadeItem->Animation.RequiredState = NO_STATE;
+ grenadeItem->Animation.RequiredState = NO_VALUE;
grenadeItem->Animation.Velocity.z = 32;
grenadeItem->Animation.Velocity.y = -32 * phd_sin(grenadeItem->Pose.Orientation.x);
grenadeItem->HitPoints = 120;
@@ -164,7 +164,7 @@ namespace TEN::Entities::TR4
if (item->ItemFlags[0] < 0)
item->ItemFlags[0] = 0;
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else if (AI.distance > pow(BLOCK(1), 2) || Lara.Location >= item->ItemFlags[3])
item->Animation.TargetState = 1;
diff --git a/TombEngine/Objects/TR4/Entity/tr4_guide.cpp b/TombEngine/Objects/TR4/Entity/tr4_guide.cpp
index c5bca20b2..cd657f137 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_guide.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_guide.cpp
@@ -191,7 +191,7 @@ namespace TEN::Entities::TR4
for (auto& currentCreature : ActiveCreatures)
{
- if (currentCreature->ItemNumber == NO_ITEM ||
+ if (currentCreature->ItemNumber == NO_VALUE ||
currentCreature->ItemNumber == itemNumber)
{
continue;
@@ -280,7 +280,7 @@ namespace TEN::Entities::TR4
joint2 = AI.angle / 2;
}
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else if (goalNode >= item->ItemFlags[3] ||
item->ItemFlags[1] != 2)
@@ -660,7 +660,7 @@ namespace TEN::Entities::TR4
ItemInfo* currentItem = nullptr;
short currentitemNumber = room->itemNumber;
- while (currentitemNumber != NO_ITEM)
+ while (currentitemNumber != NO_VALUE)
{
currentItem = &g_Level.Items[currentitemNumber];
diff --git a/TombEngine/Objects/TR4/Entity/tr4_harpy.cpp b/TombEngine/Objects/TR4/Entity/tr4_harpy.cpp
index 0dbb0efd4..d0477e4db 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_harpy.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_harpy.cpp
@@ -243,7 +243,7 @@ namespace TEN::Entities::TR4
for (auto& currentCreature : ActiveCreatures)
{
- if (currentCreature->ItemNumber == NO_ITEM || currentCreature->ItemNumber == itemNumber)
+ if (currentCreature->ItemNumber == NO_VALUE || currentCreature->ItemNumber == itemNumber)
continue;
auto* target = &g_Level.Items[currentCreature->ItemNumber];
@@ -335,7 +335,7 @@ namespace TEN::Entities::TR4
creature->MaxTurn = ANGLE(7.0f);
creature->Flags = 0;
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
{
item->Animation.TargetState = item->Animation.RequiredState;
if (item->Animation.RequiredState == HARPY_STATE_FLAME_ATTACK)
diff --git a/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp b/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp
index ef35f9efb..c486535a6 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp
@@ -136,7 +136,7 @@ namespace TEN::Entities::TR4
InitializeCreature(itemNumber);
SetAnimation(item, HORSEMAN_ANIM_IDLE);
- item->ItemFlags[0] = NO_ITEM; // No horse yet.
+ item->ItemFlags[0] = NO_VALUE; // No horse yet.
}
void HorsemanSparks(Vector3i* pos, int param1, int maxSparks)
@@ -221,7 +221,7 @@ namespace TEN::Entities::TR4
auto* creature = GetCreatureInfo(item);
// Try to find a horse.
- if (item->ItemFlags[0] == NO_ITEM)
+ if (item->ItemFlags[0] == NO_VALUE)
{
for (int i = 0; i < g_Level.NumItems; i++)
{
@@ -237,7 +237,7 @@ namespace TEN::Entities::TR4
}
// If no horse was found, set ItemFlags[0] to 0 so it isn't searched for again.
- if (item->ItemFlags[0] == NO_ITEM)
+ if (item->ItemFlags[0] == NO_VALUE)
item->ItemFlags[0] = 0;
// Get horse.
@@ -381,7 +381,7 @@ namespace TEN::Entities::TR4
case HORSEMAN_STATE_MOUNTED_RUN_FORWARD:
creature->MaxTurn = ANGLE(3.0f);
horseItem->Animation.TargetState = HORSEMAN_STATE_MOUNTED_WALK_FORWARD;
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
{
item->Animation.TargetState = HORSEMAN_STATE_MOUNTED_SPRINT;
horseItem->Animation.TargetState = HORSEMAN_STATE_MOUNT_HORSE;
@@ -491,7 +491,7 @@ namespace TEN::Entities::TR4
else
creature->Flags = 0;
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
{
item->Animation.TargetState = HORSEMAN_STATE_MOUNTED_RUN_FORWARD;
horseItem->Animation.TargetState = HORSEMAN_STATE_MOUNTED_WALK_FORWARD;
@@ -582,7 +582,7 @@ namespace TEN::Entities::TR4
if (!item->AIBits || item->ItemFlags[3])
{
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else if (AI.bite && AI.distance < pow(682,2))
item->Animation.TargetState = HORSEMAN_STATE_IDLE_ATTACK;
diff --git a/TombEngine/Objects/TR4/Entity/tr4_mutant.cpp b/TombEngine/Objects/TR4/Entity/tr4_mutant.cpp
index 7194eb2fc..41cc2809d 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_mutant.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_mutant.cpp
@@ -64,10 +64,10 @@ namespace TEN::Entities::TR4
void TriggerCrocgodMissile(Pose* src, short roomNumber, short counter)
{
- short fxNumber = NO_ITEM;
+ short fxNumber = NO_VALUE;
fxNumber = CreateNewEffect(roomNumber);
- if (fxNumber != NO_ITEM)
+ if (fxNumber != NO_VALUE)
{
auto* fx = &EffectList[fxNumber];
fx->pos.Position.x = src->Position.x;
diff --git a/TombEngine/Objects/TR4/Entity/tr4_sas.cpp b/TombEngine/Objects/TR4/Entity/tr4_sas.cpp
index 7c94d44d5..d8be29188 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_sas.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_sas.cpp
@@ -177,7 +177,7 @@ namespace TEN::Entities::TR4
GetCreatureMood(&item, &AI, !creature.Enemy->IsLara());
// Vehicle handling
- if (Lara.Context.Vehicle != NO_ITEM && AI.bite)
+ if (Lara.Context.Vehicle != NO_VALUE && AI.bite)
creature.Mood = MoodType::Escape;
CreatureMood(&item, &AI, !creature.Enemy->IsLara());
@@ -205,7 +205,7 @@ namespace TEN::Entities::TR4
else
item.Pose.Orientation.y += ANGLE(10.0f);
}
- else if (item.AIBits & MODIFY || Lara.Context.Vehicle != NO_ITEM)
+ else if (item.AIBits & MODIFY || Lara.Context.Vehicle != NO_VALUE)
{
if (abs(AI.angle) < ANGLE(2.0f))
item.Pose.Orientation.y += AI.angle;
@@ -229,7 +229,7 @@ namespace TEN::Entities::TR4
}
else if (item.AIBits & PATROL1 &&
item.AIBits != MODIFY &&
- Lara.Context.Vehicle == NO_ITEM)
+ Lara.Context.Vehicle == NO_VALUE)
{
item.Animation.TargetState = SAS_STATE_WALK;
joint2 = 0;
@@ -299,7 +299,7 @@ namespace TEN::Entities::TR4
creature.Mood == MoodType::Bored ||
!AI.ahead ||
item.AIBits & MODIFY ||
- Lara.Context.Vehicle != NO_ITEM)
+ Lara.Context.Vehicle != NO_VALUE)
{
item.Animation.TargetState = SAS_STATE_IDLE;
}
@@ -315,7 +315,7 @@ namespace TEN::Entities::TR4
{
item.Animation.TargetState = SAS_STATE_WALK;
}
- else if (Lara.Context.Vehicle != NO_ITEM &&
+ else if (Lara.Context.Vehicle != NO_VALUE &&
(item.AIBits == MODIFY ||
!item.AIBits))
{
@@ -363,7 +363,7 @@ namespace TEN::Entities::TR4
if (AI.ahead)
joint2 = AI.angle;
- if (Lara.Context.Vehicle != NO_ITEM)
+ if (Lara.Context.Vehicle != NO_VALUE)
{
if (item.AIBits == MODIFY || !item.AIBits)
{
@@ -645,7 +645,7 @@ namespace TEN::Entities::TR4
void SasFireGrenade(ItemInfo& item, short angle1, short angle2)
{
short itemNumber = CreateItem();
- if (itemNumber == NO_ITEM)
+ if (itemNumber == NO_VALUE)
return;
auto grenadeItem = &g_Level.Items[itemNumber];
@@ -677,7 +677,7 @@ namespace TEN::Entities::TR4
grenadeItem->Animation.Velocity.z = 128;
grenadeItem->Animation.ActiveState = grenadeItem->Pose.Orientation.x;
grenadeItem->Animation.TargetState = grenadeItem->Pose.Orientation.y;
- grenadeItem->Animation.RequiredState = NO_STATE;
+ grenadeItem->Animation.RequiredState = NO_VALUE;
if (Random::TestProbability(3 / 4.0f))
grenadeItem->ItemFlags[0] = (int)ProjectileType::Grenade;
diff --git a/TombEngine/Objects/TR4/Entity/tr4_setha.cpp b/TombEngine/Objects/TR4/Entity/tr4_setha.cpp
index 03c5963c4..45af4e5f1 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_setha.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_setha.cpp
@@ -183,7 +183,7 @@ namespace TEN::Entities::TR4
creature.Flags = 0;
creature.LOT.IsJumping = false;
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
{
item->Animation.TargetState = item->Animation.RequiredState;
break;
diff --git a/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp b/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp
index b2ddd7053..b530c99b2 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp
@@ -144,7 +144,7 @@ namespace TEN::Entities::TR4
void TriggerRiseEffect(ItemInfo* item)
{
int fxNumber = CreateNewEffect(item->RoomNumber);
- if (fxNumber == NO_ITEM)
+ if (fxNumber == NO_VALUE)
return;
auto* fx = &EffectList[fxNumber];
@@ -452,7 +452,7 @@ namespace TEN::Entities::TR4
item->AIBits & FOLLOW &&
(creature->ReachedGoal || laraAI.distance > SQUARE(BLOCK(2))))
{
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else if (Random::TestProbability(1 / 64.0f))
item->Animation.TargetState = 15;
@@ -477,7 +477,7 @@ namespace TEN::Entities::TR4
else
item->Animation.TargetState = SKELETON_STATE_ATTACK_3;
}
- else if (item->HitStatus || item->Animation.RequiredState != NO_STATE)
+ else if (item->HitStatus || item->Animation.RequiredState != NO_VALUE)
{
if (Random::TestProbability(1 / 2.0f))
{
diff --git a/TombEngine/Objects/TR4/Entity/tr4_troops.cpp b/TombEngine/Objects/TR4/Entity/tr4_troops.cpp
index 3aba0aafd..46f9de8da 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_troops.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_troops.cpp
@@ -145,7 +145,7 @@ namespace TEN::Entities::TR4
for (auto& currentCreature : ActiveCreatures)
{
- if (currentCreature->ItemNumber != NO_ITEM && currentCreature->ItemNumber != itemNumber)
+ if (currentCreature->ItemNumber != NO_VALUE && currentCreature->ItemNumber != itemNumber)
{
auto* currentItem = &g_Level.Items[currentCreature->ItemNumber];
if (currentItem->ObjectNumber != ID_LARA)
@@ -192,7 +192,7 @@ namespace TEN::Entities::TR4
CreatureMood(item, &AI, false);
// Vehicle handling
- if (Lara.Context.Vehicle != NO_ITEM && AI.bite)
+ if (Lara.Context.Vehicle != NO_VALUE && AI.bite)
creature->Mood = MoodType::Escape;
angle = CreatureTurn(item, creature->MaxTurn);
diff --git a/TombEngine/Objects/TR4/Entity/tr4_von_croy.cpp b/TombEngine/Objects/TR4/Entity/tr4_von_croy.cpp
index 6b4c44690..4f7f7b93e 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_von_croy.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_von_croy.cpp
@@ -233,7 +233,7 @@ namespace TEN::Entities::TR4
for (auto& currentCreature : ActiveCreatures)
{
targetCreature = currentCreature;
- if (targetCreature->ItemNumber == NO_ITEM ||
+ if (targetCreature->ItemNumber == NO_VALUE ||
targetCreature->ItemNumber == itemNumber ||
g_Level.Items[targetCreature->ItemNumber].ObjectNumber == ID_VON_CROY ||
g_Level.Items[targetCreature->ItemNumber].ObjectNumber == ID_GUIDE)
diff --git a/TombEngine/Objects/TR4/Entity/tr4_wild_boar.cpp b/TombEngine/Objects/TR4/Entity/tr4_wild_boar.cpp
index 3c820a632..69fbed225 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_wild_boar.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_wild_boar.cpp
@@ -85,7 +85,7 @@ namespace TEN::Entities::TR4
for (auto& currentCreature : ActiveCreatures)
{
auto* currentItem = currentCreature;
- if (currentItem->ItemNumber == NO_ITEM || currentItem->ItemNumber == itemNumber)
+ if (currentItem->ItemNumber == NO_VALUE || currentItem->ItemNumber == itemNumber)
continue;
auto* target = &g_Level.Items[currentItem->ItemNumber];
diff --git a/TombEngine/Objects/TR4/Object/tr4_clockwork_beetle.cpp b/TombEngine/Objects/TR4/Object/tr4_clockwork_beetle.cpp
index 0535ae8d2..3fa9113f3 100644
--- a/TombEngine/Objects/TR4/Object/tr4_clockwork_beetle.cpp
+++ b/TombEngine/Objects/TR4/Object/tr4_clockwork_beetle.cpp
@@ -169,7 +169,7 @@ void ClockworkBeetleControl(short itemNumber)
beetle->ItemFlags[2] = 5;
short itemRoom = g_Level.Rooms[beetle->RoomNumber].itemNumber;
- if (itemRoom != NO_ITEM)
+ if (itemRoom != NO_VALUE)
{
ItemInfo* item;
short nextItem;
@@ -195,7 +195,7 @@ void ClockworkBeetleControl(short itemNumber)
itemRoom = nextItem;
- if (itemRoom == NO_ITEM)
+ if (itemRoom == NO_VALUE)
return;
}
@@ -310,7 +310,7 @@ void UseClockworkBeetle(short flag)
{
short itemNumber = CreateItem();
- if (itemNumber != NO_ITEM)
+ if (itemNumber != NO_VALUE)
{
auto* item = &g_Level.Items[itemNumber];
@@ -338,7 +338,7 @@ void UseClockworkBeetle(short flag)
ItemInfo* item2;
short itemRoom = g_Level.Rooms[item->RoomNumber].itemNumber;
- if (itemRoom != NO_ITEM)
+ if (itemRoom != NO_VALUE)
{
while (true)
{
@@ -361,7 +361,7 @@ void UseClockworkBeetle(short flag)
itemRoom = nextItem;
- if (itemRoom == NO_ITEM)
+ if (itemRoom == NO_VALUE)
{
if (!item->ItemFlags[0])
item->ItemFlags[3] = 150;
diff --git a/TombEngine/Objects/TR4/Object/tr4_element_puzzle.cpp b/TombEngine/Objects/TR4/Object/tr4_element_puzzle.cpp
index 1c24c690b..5bb0117ff 100644
--- a/TombEngine/Objects/TR4/Object/tr4_element_puzzle.cpp
+++ b/TombEngine/Objects/TR4/Object/tr4_element_puzzle.cpp
@@ -106,10 +106,10 @@ namespace TEN::Entities::TR4
}
short currentItemNumber = g_Level.Rooms[item->RoomNumber].itemNumber;
- if (currentItemNumber == NO_ITEM)
+ if (currentItemNumber == NO_VALUE)
return;
- while (currentItemNumber != NO_ITEM)
+ while (currentItemNumber != NO_VALUE)
{
auto* currentItem = &g_Level.Items[currentItemNumber];
diff --git a/TombEngine/Objects/TR4/Object/tr4_obelisk.cpp b/TombEngine/Objects/TR4/Object/tr4_obelisk.cpp
index 213e9ece0..aa21894f0 100644
--- a/TombEngine/Objects/TR4/Object/tr4_obelisk.cpp
+++ b/TombEngine/Objects/TR4/Object/tr4_obelisk.cpp
@@ -123,7 +123,7 @@ void ObeliskControl(short itemNumber)
abs(pos2.y - LaraItem->Pose.Position.y) < BLOCK(20) &&
abs(pos2.z - LaraItem->Pose.Position.z) < BLOCK(20))
{
- if (item->ItemFlags[2] != NO_ITEM)
+ if (item->ItemFlags[2] != NO_VALUE)
{
auto* item2 = &g_Level.Items[item->ItemFlags[2]];
ExplodeItemNode(item2, 0, 0, 128);
@@ -132,7 +132,7 @@ void ObeliskControl(short itemNumber)
TriggerExplosionSparks(pos.x, pos.y, pos.z, 3, -2, 0, item2->RoomNumber);
TriggerExplosionSparks(pos.x, pos.y, pos.z, 3, -1, 0, item2->RoomNumber);
- item->ItemFlags[2] = NO_ITEM;
+ item->ItemFlags[2] = NO_VALUE;
item2 = FindItem(ID_PUZZLE_ITEM1_COMBO1);
item2->Status = ITEM_NOT_ACTIVE;
diff --git a/TombEngine/Objects/TR4/Object/tr4_senet.cpp b/TombEngine/Objects/TR4/Object/tr4_senet.cpp
index 0568a42c6..d8dde9c1f 100644
--- a/TombEngine/Objects/TR4/Object/tr4_senet.cpp
+++ b/TombEngine/Objects/TR4/Object/tr4_senet.cpp
@@ -331,7 +331,7 @@ void SenetPieceExplosionEffect(ItemInfo* item, int color, int speed)
void TriggerItemInRoom(short room_number, int object)//originally this is in deltapak
{
short num = g_Level.Rooms[room_number].itemNumber;
- while (num != NO_ITEM)
+ while (num != NO_VALUE)
{
auto* item = &g_Level.Items[num];
short nex = item->NextItem;
diff --git a/TombEngine/Objects/TR4/Trap/SpikyWall.cpp b/TombEngine/Objects/TR4/Trap/SpikyWall.cpp
index 0554f13c5..bd1f55d5e 100644
--- a/TombEngine/Objects/TR4/Trap/SpikyWall.cpp
+++ b/TombEngine/Objects/TR4/Trap/SpikyWall.cpp
@@ -52,18 +52,20 @@ namespace TEN::Entities::Traps
auto pointColl0 = GetPointCollision(item, item.Pose.Orientation.y, (forwardVel >= 0) ? bounds.Z2 : bounds.Z1, bounds.Y2);
auto pointColl1 = GetPointCollision(item, item.Pose.Orientation.y, (forwardVel >= 0) ? bounds.Z2 : bounds.Z1, bounds.Y2, (bounds.X2 - bounds.X1) / 2);
- if (GetCollidedObjects(&item, CLICK(1), true, CollidedItems, CollidedMeshes, true))
+ auto collObjects = GetCollidedObjects(item, true, true);
+ if (!collObjects.IsEmpty())
{
- int collidedItemNumber = 0;
- while (CollidedItems[collidedItemNumber] != nullptr)
+ for (auto* itemPtr : collObjects.ItemPtrs)
{
- if (Objects[CollidedItems[collidedItemNumber]->ObjectNumber].intelligent)
+ const auto& object = Objects[itemPtr->ObjectNumber];
+
+ if (object.intelligent)
{
- CollidedItems[collidedItemNumber]->HitPoints = 0;
+ itemPtr->HitPoints = 0;
}
- else if (CollidedItems[collidedItemNumber]->ObjectNumber == ID_SPIKY_WALL && !item.ItemFlags[1])
+ else if (itemPtr->ObjectNumber == ID_SPIKY_WALL && !item.ItemFlags[1])
{
- CollidedItems[collidedItemNumber]->TriggerFlags = 0;
+ itemPtr->TriggerFlags = 0;
item.TriggerFlags = 0;
item.Status = ITEM_DEACTIVATED;
@@ -71,8 +73,6 @@ namespace TEN::Entities::Traps
StopSoundEffect(SFX_TR4_ROLLING_BALL);
}
-
- collidedItemNumber++;
}
}
diff --git a/TombEngine/Objects/TR4/Trap/SquishyBlock.cpp b/TombEngine/Objects/TR4/Trap/SquishyBlock.cpp
new file mode 100644
index 000000000..3a00504e1
--- /dev/null
+++ b/TombEngine/Objects/TR4/Trap/SquishyBlock.cpp
@@ -0,0 +1,221 @@
+#include "framework.h"
+#include "Objects/TR4/Trap/SquishyBlock.h"
+
+#include "Game/animation.h"
+#include "Game/camera.h"
+#include "Game/collision/collide_item.h"
+#include "Game/collision/collide_room.h"
+#include "Game/collision/Point.h"
+#include "Game/collision/sphere.h"
+#include "Game/control/control.h"
+#include "Game/effects/effects.h"
+#include "Game/items.h"
+#include "Game/Lara/lara.h"
+#include "Game/misc.h"
+#include "Game/Setup.h"
+#include "Sound/sound.h"
+#include "Specific/level.h"
+
+using namespace TEN::Collision::Point;
+
+// NOTES:
+// item.ItemFlags[0]: use dynamic motion.
+// item.ItemFlags[1]: ??
+// item.ItemFlags[4]: heading angle.
+// TODO: In future add support for 4 directions.
+
+namespace TEN::Entities::Traps
+{
+ constexpr auto SQUISHY_BLOCK_LETHAL_FRAME = 33;
+ constexpr auto MAX_FALLING_VELOCITY = 60;
+ constexpr auto MAX_VELOCITY = 300;
+ constexpr auto FALLING_BLOCK_IMPACT_FRAME = 8;
+ constexpr auto FALLING_BLOCK_NEXT_FRAME = 2;
+
+ enum SquishyBlockState
+ {
+ SQUISHY_BLOCK_STATE_MOVE = 0,
+ SQUISHY_BLOCK_STATE_COLLIDE_LEFT = 1,
+ SQUISHY_BLOCK_STATE_COLLIDE_RIGHT = 2,
+ SQUISHY_BLOCK_STATE_BAKED_MOTION = 3,
+ SQUISHY_BLOCK_STATE_COLLIDE_FRONT = 4,
+ SQUISHY_BLOCK_STATE_COLLIDE_BACK = 5
+ };
+
+ enum SquishyBlockAnim
+ {
+ SQUISHY_BLOCK_ANIM_MOVE = 0,
+ SQUISHY_BLOCK_ANIM_IMPACT_BACK = 1,
+ SQUISHY_BLOCK_ANIM_IMPACT_FRONT = 2,
+ SQUISHY_BLOCK_ANIM_BAKED_MOTION = 3,
+ SQUISHY_BLOCK_ANIM_COLLIDE_FRONT = 4,
+ SQUISHY_BLOCK_ANIM_COLLIDE_BACK = 5
+ };
+
+ void InitializeSquishyBlock(short itemNumber)
+ {
+ auto& item = g_Level.Items[itemNumber];
+
+ if (!item.TriggerFlags)
+ SetAnimation(item, SQUISHY_BLOCK_ANIM_BAKED_MOTION);
+
+ item.HitPoints = NOT_TARGETABLE;
+ item.ItemFlags[0] = item.TriggerFlags;
+ item.ItemFlags[1] = 0;
+ item.ItemFlags[4] = 0;
+ }
+
+ void ControlSquishyBlock(short itemNumber)
+ {
+ auto& item = g_Level.Items[itemNumber];
+
+ if (!TriggerActive(&item))
+ return;
+
+ const auto& object = Objects[item.ObjectNumber];
+
+ short& velocity = item.ItemFlags[0];
+ short& someAngle = item.ItemFlags[1];
+ short& headingAngle = item.ItemFlags[4];
+
+ if (!item.TriggerFlags)
+ {
+ if (item.Animation.ActiveState != SQUISHY_BLOCK_STATE_BAKED_MOTION)
+ SetAnimation(item, SQUISHY_BLOCK_ANIM_BAKED_MOTION);
+ }
+ else
+ {
+ if (item.Animation.ActiveState == SQUISHY_BLOCK_ANIM_BAKED_MOTION)
+ SetAnimation(item, SQUISHY_BLOCK_STATE_MOVE);
+
+ velocity = item.TriggerFlags;
+
+ if (velocity > MAX_VELOCITY)
+ velocity = MAX_VELOCITY;
+
+ if (item.Animation.ActiveState == SQUISHY_BLOCK_STATE_MOVE)
+ {
+ auto forwardDir = EulerAngles(0, item.Pose.Orientation.y + headingAngle, 0).ToDirection();
+
+ auto pointColl = GetPointCollision(item.Pose.Position, item.RoomNumber, forwardDir, BLOCK(0.5f));
+
+ if (pointColl.GetRoomNumber() != item.RoomNumber)
+ ItemNewRoom(itemNumber, pointColl.GetRoomNumber());
+
+ if (!IsNextSectorValid(item, forwardDir, BLOCK(0.5f)))
+ {
+ switch (headingAngle)
+ {
+ default:
+ case ANGLE(0.0f):
+ SetAnimation(item, SQUISHY_BLOCK_ANIM_IMPACT_FRONT);
+ break;
+
+ case ANGLE(-180.0f):
+ SetAnimation(item, SQUISHY_BLOCK_ANIM_IMPACT_BACK);
+ break;
+ }
+ }
+ else
+ {
+ float dist = Lerp(item.TriggerFlags / 4, item.TriggerFlags, velocity);
+ item.Pose.Position = Geometry::TranslatePoint(item.Pose.Position, forwardDir, dist);
+ }
+ }
+ else
+ {
+ if (item.Animation.FrameNumber == GetAnimData(item).frameEnd)
+ {
+ if (item.HitPoints != NOT_TARGETABLE && item.HitPoints)
+ {
+ someAngle = item.HitPoints;
+ item.HitPoints = NOT_TARGETABLE;
+ }
+
+ headingAngle += ANGLE(180.0f);
+ item.Pose.Orientation.y += ANGLE(someAngle);
+ }
+ }
+ }
+
+ AnimateItem(&item);
+ }
+
+ void ControlFallingSquishyBlock(short itemNumber)
+ {
+ auto& item = g_Level.Items[itemNumber];
+
+ if (!TriggerActive(&item))
+ return;
+
+ short& velocity = item.ItemFlags[0];
+
+ if (velocity < MAX_FALLING_VELOCITY)
+ {
+ SoundEffect(SFX_TR4_EARTHQUAKE_LOOP, &item.Pose);
+ Camera.bounce = (velocity - 92) / 2;
+ velocity++;
+ }
+ else
+ {
+ if ((item.Animation.FrameNumber - GetAnimData(item).frameBase) == FALLING_BLOCK_IMPACT_FRAME)
+ Camera.bounce = -96;
+
+ AnimateItem(&item);
+ }
+ }
+
+ void CollideSquishyBlock(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll)
+ {
+ if (playerItem->HitPoints <= 0)
+ return;
+
+ auto& item = g_Level.Items[itemNumber];
+
+ if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius))
+ return;
+
+ if (!TestCollision(&item, playerItem))
+ return;
+
+ if (!ItemPushItem(&item, playerItem, coll, false, 1))
+ return;
+
+ if (item.Animation.ActiveState == SQUISHY_BLOCK_STATE_BAKED_MOTION)
+ {
+ int frameNumber = item.Animation.FrameNumber - GetAnimData(item).frameBase;
+ if (!frameNumber || frameNumber == SQUISHY_BLOCK_LETHAL_FRAME)
+ DoDamage(playerItem, INT_MAX);
+ }
+ else if (item.Animation.ActiveState == SQUISHY_BLOCK_STATE_COLLIDE_RIGHT ||
+ item.Animation.ActiveState == SQUISHY_BLOCK_STATE_COLLIDE_LEFT)
+ {
+ DoDamage(playerItem, INT_MAX);
+ }
+ }
+
+ void CollideFallingSquishyBlock(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll)
+ {
+ auto& item = g_Level.Items[itemNumber];
+
+ if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius))
+ return;
+
+ if (!TestCollision(&item, playerItem))
+ return;
+
+ if ((item.Animation.FrameNumber - GetAnimData(item).frameBase) <= FALLING_BLOCK_IMPACT_FRAME)
+ {
+ item.Animation.FrameNumber += FALLING_BLOCK_NEXT_FRAME;
+
+ DoDamage(playerItem, INT_MAX);
+ SetAnimation(playerItem, LA_BOULDER_DEATH);
+ playerItem->Animation.Velocity.y = 0.0f;
+ playerItem->Animation.Velocity.z = 0.0f;
+ }
+ else if (playerItem->HitPoints > 0)
+ {
+ ItemPushItem(&item, playerItem, coll, false, 1);
+ }
+ }
+}
diff --git a/TombEngine/Objects/TR4/Trap/SquishyBlock.h b/TombEngine/Objects/TR4/Trap/SquishyBlock.h
new file mode 100644
index 000000000..42b13766e
--- /dev/null
+++ b/TombEngine/Objects/TR4/Trap/SquishyBlock.h
@@ -0,0 +1,13 @@
+#pragma once
+
+struct CollisionInfo;
+struct ItemInfo;
+
+namespace TEN::Entities::Traps
+{
+ void InitializeSquishyBlock(short itemNumber);
+ void ControlSquishyBlock(short itemNumber);
+ void ControlFallingSquishyBlock(short itemNumber);
+ void CollideSquishyBlock(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll);
+ void CollideFallingSquishyBlock(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll);
+}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_hammer.cpp b/TombEngine/Objects/TR4/Trap/tr4_hammer.cpp
index 890b234d1..8dcd9c655 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_hammer.cpp
+++ b/TombEngine/Objects/TR4/Trap/tr4_hammer.cpp
@@ -100,10 +100,10 @@ namespace TEN::Entities::TR4
{
short targetItem = g_Level.Rooms[item->RoomNumber].itemNumber;
- if (targetItem != NO_ITEM)
+ if (targetItem != NO_VALUE)
{
auto* target = &g_Level.Items[targetItem];
- for (; targetItem != NO_ITEM; targetItem = target->NextItem)
+ for (; targetItem != NO_VALUE; targetItem = target->NextItem)
{
target = &g_Level.Items[targetItem];
@@ -126,10 +126,10 @@ namespace TEN::Entities::TR4
{
short targetItem = g_Level.Rooms[item->RoomNumber].itemNumber;
- if (targetItem != NO_ITEM)
+ if (targetItem != NO_VALUE)
{
auto* target = &g_Level.Items[targetItem];
- for (; targetItem != NO_ITEM; targetItem = target->NextItem)
+ for (; targetItem != NO_VALUE; targetItem = target->NextItem)
{
target = &g_Level.Items[targetItem];
@@ -151,10 +151,10 @@ namespace TEN::Entities::TR4
{
targetItem = g_Level.Rooms[item->RoomNumber].itemNumber;
- if (targetItem != NO_ITEM)
+ if (targetItem != NO_VALUE)
{
auto* target = &g_Level.Items[targetItem];
- for (; targetItem != NO_ITEM; targetItem = target->NextItem)
+ for (; targetItem != NO_VALUE; targetItem = target->NextItem)
{
target = &g_Level.Items[targetItem];
diff --git a/TombEngine/Objects/TR4/Trap/tr4_mine.cpp b/TombEngine/Objects/TR4/Trap/tr4_mine.cpp
index d5b5558c2..41c38608d 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_mine.cpp
+++ b/TombEngine/Objects/TR4/Trap/tr4_mine.cpp
@@ -57,7 +57,7 @@ namespace TEN::Entities::TR4
short currentItemNumber = g_Level.Rooms[item->RoomNumber].itemNumber;
// Make the sentry gun explode?
- while (currentItemNumber != NO_ITEM)
+ while (currentItemNumber != NO_VALUE)
{
auto* currentItem = &g_Level.Items[currentItemNumber];
diff --git a/TombEngine/Objects/TR4/Trap/tr4_teethspike.cpp b/TombEngine/Objects/TR4/Trap/tr4_teethspike.cpp
index 28f043852..2983d3832 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_teethspike.cpp
+++ b/TombEngine/Objects/TR4/Trap/tr4_teethspike.cpp
@@ -151,7 +151,7 @@ namespace TEN::Entities::TR4
TriggerBlood(dx, yBottom - (GetRandomControl() % dy), dz, GetRandomControl() << 1, 1);
}
- if (LaraItem->HitPoints <= 0 && Lara.Context.Vehicle == NO_ITEM)
+ if (LaraItem->HitPoints <= 0 && Lara.Context.Vehicle == NO_VALUE)
{
int heightFromFloor = GetPointCollision(*LaraItem).GetFloorHeight() - LaraItem->Pose.Position.y;
diff --git a/TombEngine/Objects/TR4/Vehicles/jeep.cpp b/TombEngine/Objects/TR4/Vehicles/jeep.cpp
index d06cdbd3d..169e254e6 100644
--- a/TombEngine/Objects/TR4/Vehicles/jeep.cpp
+++ b/TombEngine/Objects/TR4/Vehicles/jeep.cpp
@@ -157,7 +157,7 @@ namespace TEN::Entities::Vehicles
auto* jeep = GetJeepInfo(jeepItem);
auto* lara = GetLaraInfo(laraItem);
- if (laraItem->HitPoints <= 0 && lara->Context.Vehicle != NO_ITEM)
+ if (laraItem->HitPoints <= 0 && lara->Context.Vehicle != NO_VALUE)
return;
auto mountType = GetVehicleMountType(jeepItem, laraItem, coll, JeepMountTypes, JEEP_MOUNT_DISTANCE);
@@ -178,7 +178,7 @@ namespace TEN::Entities::Vehicles
// HACK: Hardcoded jeep keys check.
/*if (g_Gui.GetInventoryItemChosen() == ID_PUZZLE_ITEM1)
{
- g_Gui.SetInventoryItemChosen(NO_ITEM);
+ g_Gui.SetInventoryItemChosen(NO_VALUE);
return true;
}
else
diff --git a/TombEngine/Objects/TR4/Vehicles/motorbike.cpp b/TombEngine/Objects/TR4/Vehicles/motorbike.cpp
index 358878548..985ab5360 100644
--- a/TombEngine/Objects/TR4/Vehicles/motorbike.cpp
+++ b/TombEngine/Objects/TR4/Vehicles/motorbike.cpp
@@ -160,7 +160,7 @@ namespace TEN::Entities::Vehicles
auto* motorbike = GetMotorbikeInfo(motorbikeItem);
auto* lara = GetLaraInfo(laraItem);
- if (laraItem->HitPoints < 0 || lara->Context.Vehicle != NO_ITEM)
+ if (laraItem->HitPoints < 0 || lara->Context.Vehicle != NO_VALUE)
return;
auto mountType = GetVehicleMountType(motorbikeItem, laraItem, coll, MotorbikeMountTypes, MOTORBIKE_MOUNT_DISTANCE);
@@ -190,7 +190,7 @@ namespace TEN::Entities::Vehicles
/*if (g_Gui.GetInventoryItemChosen() == ID_PUZZLE_ITEM1)
{
SetAnimation(*laraItem, ID_MOTORBIKE_LARA_ANIMS, MOTORBIKE_ANIM_UNLOCK);
- g_Gui.SetInventoryItemChosen(NO_ITEM);
+ g_Gui.SetInventoryItemChosen(NO_VALUE);
motorbike->Flags |= MOTORBIKE_FLAG_NITRO;
}
else
@@ -400,7 +400,7 @@ namespace TEN::Entities::Vehicles
auto* motorbike = GetMotorbikeInfo(motorbikeItem);
auto* lara = GetLaraInfo(laraItem);
- if (lara->Context.Vehicle == NO_ITEM)
+ if (lara->Context.Vehicle == NO_VALUE)
return;
if (laraItem->Animation.ActiveState != MOTORBIKE_STATE_MOUNT && laraItem->Animation.ActiveState != MOTORBIKE_STATE_DISMOUNT)
@@ -432,7 +432,7 @@ namespace TEN::Entities::Vehicles
{
auto* lara = GetLaraInfo(laraItem);
- if (lara->Context.Vehicle != NO_ITEM)
+ if (lara->Context.Vehicle != NO_VALUE)
{
auto* item = &g_Level.Items[lara->Context.Vehicle];
diff --git a/TombEngine/Objects/TR4/tr4_objects.cpp b/TombEngine/Objects/TR4/tr4_objects.cpp
index 87476a078..b54171260 100644
--- a/TombEngine/Objects/TR4/tr4_objects.cpp
+++ b/TombEngine/Objects/TR4/tr4_objects.cpp
@@ -70,6 +70,7 @@
#include "Objects/TR4/Trap/tr4_plough.h"
#include "Objects/TR4/Trap/tr4_sethblade.h"
#include "Objects/TR4/Trap/tr4_slicerdicer.h"
+#include "Objects/TR4/Trap/SquishyBlock.h"
#include "Objects/TR4/Trap/tr4_spikeball.h"
#include "Objects/TR4/Trap/tr4_stargate.h"
#include "Objects/TR4/Trap/tr4_cog.h"
@@ -949,6 +950,23 @@ namespace TEN::Entities
obj->collision = GenericSphereBoxCollision;
obj->SetHitEffect(true);
}
+
+ obj = &Objects[ID_SQUISHY_BLOCK_HORIZONTAL];
+ if (obj->loaded)
+ {
+ obj->Initialize = InitializeSquishyBlock;
+ obj->control = ControlSquishyBlock;
+ obj->collision = CollideSquishyBlock;
+ obj->SetHitEffect(true);
+ }
+
+ obj = &Objects[ID_SQUISHY_BLOCK_VERTICAL];
+ if (obj->loaded)
+ {
+ obj->control = ControlFallingSquishyBlock;
+ obj->collision = CollideFallingSquishyBlock;
+ obj->SetHitEffect(true);
+ }
}
static void StartVehicles(ObjectInfo* obj)
diff --git a/TombEngine/Objects/TR5/Emitter/tr5_bats_emitter.cpp b/TombEngine/Objects/TR5/Emitter/tr5_bats_emitter.cpp
index cb870c0c8..a071909d9 100644
--- a/TombEngine/Objects/TR5/Emitter/tr5_bats_emitter.cpp
+++ b/TombEngine/Objects/TR5/Emitter/tr5_bats_emitter.cpp
@@ -74,7 +74,7 @@ short GetNextBat()
index++;
if (index >= NUM_BATS)
- return NO_ITEM;
+ return NO_VALUE;
}
NextBat = (batNumber + 1) & (NUM_BATS - 1);
@@ -86,7 +86,7 @@ void TriggerLittleBat(ItemInfo* item)
{
short batNumber = GetNextBat();
- if (batNumber != NO_ITEM)
+ if (batNumber != NO_VALUE)
{
auto* bat = &Bats[batNumber];
diff --git a/TombEngine/Objects/TR5/Emitter/tr5_rats_emitter.cpp b/TombEngine/Objects/TR5/Emitter/tr5_rats_emitter.cpp
index 6d6848002..bb1a1403a 100644
--- a/TombEngine/Objects/TR5/Emitter/tr5_rats_emitter.cpp
+++ b/TombEngine/Objects/TR5/Emitter/tr5_rats_emitter.cpp
@@ -39,7 +39,7 @@ short GetNextRat()
i++;
if (i >= NUM_RATS)
- return NO_ITEM;
+ return NO_VALUE;
}
NextRat = (ratNumber + 1) & 0x1F;
diff --git a/TombEngine/Objects/TR5/Emitter/tr5_spider_emitter.cpp b/TombEngine/Objects/TR5/Emitter/tr5_spider_emitter.cpp
index b4eb28d9c..8e201afe2 100644
--- a/TombEngine/Objects/TR5/Emitter/tr5_spider_emitter.cpp
+++ b/TombEngine/Objects/TR5/Emitter/tr5_spider_emitter.cpp
@@ -34,7 +34,7 @@ short GetNextSpider()
}
if (++i >= NUM_SPIDERS)
- return NO_ITEM;
+ return NO_VALUE;
}
NextSpider = (spiderNumber + 1) & (NUM_SPIDERS - 1);
@@ -96,7 +96,7 @@ void SpidersEmitterControl(short itemNumber)
item->ItemFlags[2]--;
short spiderNumber = GetNextSpider();
- if (spiderNumber != NO_ITEM)
+ if (spiderNumber != NO_VALUE)
{
auto* spider = &Spiders[spiderNumber];
diff --git a/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp b/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp
index f618f3145..65d0fdd13 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp
@@ -319,7 +319,7 @@ namespace TEN::Entities::Creatures::TR5
joint1 = AI.xAngle;
}
- if (item.Animation.RequiredState != NO_STATE)
+ if (item.Animation.RequiredState != NO_VALUE)
{
item.Animation.TargetState = item.Animation.RequiredState;
}
diff --git a/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp b/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp
index f8856cc55..3de10ca75 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp
@@ -166,7 +166,7 @@ namespace TEN::Entities::Creatures::TR5
}
else
{
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else
{
diff --git a/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp b/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp
index 52d97af04..2e10b3cbc 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp
@@ -176,7 +176,7 @@ namespace TEN::Entities::Creatures::TR5
if (creature->Mood == MoodType::Bored ||
(item->AIBits & FOLLOW && (creature->ReachedGoal || distance > pow(BLOCK(2), 2))))
{
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else if (Random::TestProbability(1 / 64.0f))
item->Animation.TargetState = GLADIATOR_STATE_IDLE;
diff --git a/TombEngine/Objects/TR5/Entity/tr5_guard.cpp b/TombEngine/Objects/TR5/Entity/tr5_guard.cpp
index b4867f799..b405ab487 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_guard.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_guard.cpp
@@ -229,7 +229,7 @@ namespace TEN::Entities::Creatures::TR5
item->SetMeshSwapFlags(9216);
roomItemNumber = g_Level.Rooms[item->RoomNumber].itemNumber;
- if (roomItemNumber != NO_ITEM)
+ if (roomItemNumber != NO_VALUE)
{
ItemInfo* item2 = nullptr;
while (true)
@@ -244,7 +244,7 @@ namespace TEN::Entities::Creatures::TR5
}
roomItemNumber = item2->NextItem;
- if (roomItemNumber == NO_ITEM)
+ if (roomItemNumber == NO_VALUE)
{
item->Animation.FrameNumber = GetAnimData(item).frameBase;
item->Animation.ActiveState = item->Animation.TargetState;
@@ -467,7 +467,7 @@ namespace TEN::Entities::Creatures::TR5
if (item->ObjectNumber == ID_SCIENTIST && item == Lara.TargetEntity)
item->Animation.TargetState = GUARD_STATE_SURRENDER;
- else if (item->Animation.RequiredState != NO_STATE)
+ else if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else if (item->AIBits & GUARD)
{
@@ -767,7 +767,7 @@ namespace TEN::Entities::Creatures::TR5
item->SetMeshSwapFlags(NO_JOINT_BITS);
short currentItemNumber = g_Level.Rooms[item->RoomNumber].itemNumber;
- if (currentItemNumber == NO_ITEM)
+ if (currentItemNumber == NO_VALUE)
break;
while (true)
@@ -783,11 +783,11 @@ namespace TEN::Entities::Creatures::TR5
}
currentItemNumber = currentItem->NextItem;
- if (currentItemNumber == NO_ITEM)
+ if (currentItemNumber == NO_VALUE)
break;
}
- if (currentItemNumber == NO_ITEM)
+ if (currentItemNumber == NO_VALUE)
break;
currentItem->MeshBits = -3;
@@ -849,7 +849,7 @@ namespace TEN::Entities::Creatures::TR5
creature->MaxTurn = 0;
currentItem = nullptr;
- for (currentItemNumber = g_Level.Rooms[item->RoomNumber].itemNumber; currentItemNumber != NO_ITEM; currentItemNumber = currentItem->NextItem)
+ for (currentItemNumber = g_Level.Rooms[item->RoomNumber].itemNumber; currentItemNumber != NO_VALUE; currentItemNumber = currentItem->NextItem)
{
currentItem = &g_Level.Items[currentItemNumber];
if (item->ObjectNumber == ID_PUZZLE_HOLE8) // TODO: Avoid hardcoded object number. -- TokyoSU 24/12/2022
diff --git a/TombEngine/Objects/TR5/Entity/tr5_hydra.cpp b/TombEngine/Objects/TR5/Entity/tr5_hydra.cpp
index f20b47a91..70e8a43e6 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_hydra.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_hydra.cpp
@@ -59,7 +59,7 @@ namespace TEN::Entities::Creatures::TR5
static void HydraBubblesAttack(Pose* pos, short roomNumber, int count)
{
short fxNumber = CreateNewEffect(roomNumber);
- if (fxNumber != NO_ITEM)
+ if (fxNumber != NO_VALUE)
{
auto* fx = &EffectList[fxNumber];
diff --git a/TombEngine/Objects/TR5/Entity/tr5_imp.cpp b/TombEngine/Objects/TR5/Entity/tr5_imp.cpp
index 79bf1e917..350254539 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_imp.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_imp.cpp
@@ -110,7 +110,7 @@ namespace TEN::Entities::Creatures::TR5
orient.y += short(GetRandomControl() % (distance / 4) - (distance / 8));
int fxNumber = CreateNewEffect(item->RoomNumber);
- if (fxNumber == NO_ITEM)
+ if (fxNumber == NO_VALUE)
return;
auto& fx = EffectList[fxNumber];
@@ -150,7 +150,7 @@ namespace TEN::Entities::Creatures::TR5
auto torchItemsNumbers = FindCreatedItems(ID_BURNING_TORCH_ITEM);
for (auto& itemNumber : torchItemsNumbers)
{
- if (itemNumber == NO_ITEM)
+ if (itemNumber == NO_VALUE)
continue;
const auto& torchItem = g_Level.Items[itemNumber];
diff --git a/TombEngine/Objects/TR5/Entity/tr5_larson.cpp b/TombEngine/Objects/TR5/Entity/tr5_larson.cpp
index 535fe9ee0..a9adcaf22 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_larson.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_larson.cpp
@@ -153,7 +153,7 @@ namespace TEN::Entities::Creatures::TR5
if (AI.ahead)
joint1 = AI.xAngle;
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
item->Animation.TargetState = item->Animation.RequiredState;
else if (item->AIBits & AMBUSH)
item->Animation.TargetState = STATE_TR5_LARSON_RUN;
diff --git a/TombEngine/Objects/TR5/Entity/tr5_lion.cpp b/TombEngine/Objects/TR5/Entity/tr5_lion.cpp
index ac6e20bf8..d7ec76a4f 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_lion.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_lion.cpp
@@ -136,7 +136,7 @@ namespace TEN::Entities::Creatures::TR5
creature->MaxTurn = 0;
creature->Flags = 0;
- if (item->Animation.RequiredState != NO_STATE)
+ if (item->Animation.RequiredState != NO_VALUE)
{
item->Animation.TargetState = item->Animation.RequiredState;
break;
diff --git a/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp b/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp
index e13dad101..2e041645b 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp
@@ -82,7 +82,7 @@ namespace TEN::Entities::Creatures::TR5
if (!(GetRandomControl() & 0x1F))
{
int fxNumber = CreateNewEffect(item->RoomNumber);
- if (fxNumber != NO_ITEM)
+ if (fxNumber != NO_VALUE)
{
auto* fx = &EffectList[fxNumber];
@@ -206,7 +206,7 @@ namespace TEN::Entities::Creatures::TR5
static void RomanStatueAttack(Pose* pos, short roomNumber, short count)
{
int fxNumber = CreateNewEffect(roomNumber);
- if (fxNumber == NO_ITEM)
+ if (fxNumber == NO_VALUE)
return;
auto* fx = &EffectList[fxNumber];
diff --git a/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp b/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp
index ee7bb7b9e..081e13aa8 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp
@@ -137,7 +137,7 @@ namespace TEN::Entities::Creatures::TR5
void SubmarineAttack(ItemInfo* item)
{
short itemNumber = CreateItem();
- if (itemNumber == NO_ITEM)
+ if (itemNumber == NO_VALUE)
return;
auto* torpedoItem = &g_Level.Items[itemNumber];
@@ -398,7 +398,7 @@ namespace TEN::Entities::Creatures::TR5
Vector3i pos;
- if (item->ItemFlags[0] == NO_ITEM)
+ if (item->ItemFlags[0] == NO_VALUE)
{
bool found = false;
for (int i = g_Level.NumItems; i < 256; i++)
@@ -432,7 +432,7 @@ namespace TEN::Entities::Creatures::TR5
{
pos.x = 4 * item->Animation.ActiveState;
pos.y = 4 * item->Animation.TargetState;
- pos.z = 4 * (item->Animation.RequiredState == NO_STATE) ? 0 : item->Animation.RequiredState;
+ pos.z = 4 * (item->Animation.RequiredState == NO_VALUE) ? 0 : item->Animation.RequiredState;
}
}
diff --git a/TombEngine/Objects/TR5/Object/tr5_raisingblock.cpp b/TombEngine/Objects/TR5/Object/tr5_raisingblock.cpp
index 31de65aeb..24835ed4d 100644
--- a/TombEngine/Objects/TR5/Object/tr5_raisingblock.cpp
+++ b/TombEngine/Objects/TR5/Object/tr5_raisingblock.cpp
@@ -74,7 +74,7 @@ namespace TEN::Entities::Generic
short roomNumber = item->RoomNumber;
auto* floor = GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &roomNumber);
- if (floor->Box != NO_BOX)
+ if (floor->Box != NO_VALUE)
g_Level.Boxes[floor->Box].flags &= ~BLOCKED;
// Set mutators to EulerAngles identity by default.
diff --git a/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp b/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp
index 4c92f76e1..5b46ad3b0 100644
--- a/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp
+++ b/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp
@@ -484,7 +484,7 @@ void ClassicRollingBallControl(short itemNum)
item->Animation.FrameNumber = GetAnimData(item).frameBase;
item->Animation.ActiveState = GetAnimData(item).ActiveState;
item->Animation.TargetState = GetAnimData(item).ActiveState;
- item->Animation.RequiredState = NO_STATE;
+ item->Animation.RequiredState = NO_VALUE;
RemoveActiveItem(itemNum);
}
}
diff --git a/TombEngine/Objects/TR5/Shatter/tr5_smashobject.cpp b/TombEngine/Objects/TR5/Shatter/tr5_smashobject.cpp
index bb75a6201..4125df0a4 100644
--- a/TombEngine/Objects/TR5/Shatter/tr5_smashobject.cpp
+++ b/TombEngine/Objects/TR5/Shatter/tr5_smashobject.cpp
@@ -16,9 +16,9 @@ void InitializeSmashObject(short itemNumber)
auto* room = &g_Level.Rooms[item->RoomNumber];
- // NOTE: Avoids crash when attempting to access Boxes[] array while box is equal to NO_BOX. -- TokyoSU 2022.12.20
+ // NOTE: Avoids crash when attempting to access Boxes[] array while box is equal to NO_VALUE. -- TokyoSU 2022.12.20
FloorInfo* floor = GetSector(room, item->Pose.Position.x - room->x, item->Pose.Position.z - room->z);
- if (floor->Box == NO_BOX)
+ if (floor->Box == NO_VALUE)
{
TENLog("Smash object with ID " + std::to_string(itemNumber) + " may be inside a wall." , LogLevel::Warning);
return;
@@ -42,7 +42,7 @@ void SmashObject(short itemNumber)
SoundEffect(SFX_TR5_SMASH_GLASS, &item->Pose);
- item->Collidable = 0;
+ item->Collidable = false;
item->MeshBits = 0xFFFE;
ExplodingDeath(itemNumber, BODY_DO_EXPLOSION | BODY_NO_BOUNCE);
diff --git a/TombEngine/Objects/TR5/Trap/LaserBeam.cpp b/TombEngine/Objects/TR5/Trap/LaserBeam.cpp
index 24faab523..ae227bcbc 100644
--- a/TombEngine/Objects/TR5/Trap/LaserBeam.cpp
+++ b/TombEngine/Objects/TR5/Trap/LaserBeam.cpp
@@ -3,6 +3,7 @@
#include "Game/collision/collide_room.h"
#include "Game/collision/floordata.h"
+#include "Game/collision/Point.h"
#include "Game/control/los.h"
#include "Game/effects/effects.h"
#include "Game/effects/item_fx.h"
@@ -14,6 +15,7 @@
#include "Renderer/Renderer.h"
#include "Specific/level.h"
+using namespace TEN::Collision::Point;
using namespace TEN::Effects::Items;
using namespace TEN::Effects::Spark;
using namespace TEN::Math;
@@ -87,7 +89,7 @@ namespace TEN::Traps::TR5
auto origin = GameVector(item.Pose.Position, item.RoomNumber);
auto target = GameVector(
Geometry::TranslatePoint(origin.ToVector3(), dir, MAX_VISIBILITY_DISTANCE),
- GetCollision(origin.ToVector3i(), origin.RoomNumber, dir, MAX_VISIBILITY_DISTANCE).RoomNumber);
+ GetPointCollision(origin.ToVector3i(), origin.RoomNumber, dir, MAX_VISIBILITY_DISTANCE).GetRoomNumber());
// Hit wall; spawn sparks and light.
if (!LOS(&origin, &target))
@@ -177,9 +179,6 @@ namespace TEN::Traps::TR5
void CollideLaserBeam(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll)
{
- constexpr auto LIGHT_INTENSITY = 1.0f;
- constexpr auto LIGHT_AMPLITUDE_MAX = 0.4f;
-
if (!LaserBeams.count(itemNumber))
return;
@@ -195,9 +194,9 @@ namespace TEN::Traps::TR5
auto rotMatrix = EulerAngles(item.Pose.Orientation.x + ANGLE(180.0f), item.Pose.Orientation.y, item.Pose.Orientation.z);
auto target = GameVector(Geometry::TranslatePoint(origin.ToVector3(), rotMatrix, MAX_VISIBILITY_DISTANCE), 0);
- auto pointColl = GetCollision(target.ToVector3i(),item.RoomNumber);
- if (pointColl.RoomNumber != target.RoomNumber)
- target.RoomNumber = pointColl.RoomNumber;
+ auto pointColl = GetPointCollision(target.ToVector3i(), item.RoomNumber);
+ if (pointColl.GetRoomNumber() != target.RoomNumber)
+ target.RoomNumber = pointColl.GetRoomNumber();
bool los2 = LOS(&origin, &target);
@@ -216,7 +215,7 @@ namespace TEN::Traps::TR5
}
beam.Color.w = Random::GenerateFloat(0.6f, 1.0f);
- SpawnLaserBeamLight(item.Pose.Position.ToVector3(), item.RoomNumber, item.Model.Color, LIGHT_INTENSITY, LIGHT_AMPLITUDE_MAX);
+ SpawnLaserBeamLight(item.Pose.Position.ToVector3(), item.RoomNumber, item.Model.Color, LASER_BEAM_LIGHT_INTENSITY, LASER_BEAM_LIGHT_AMPLITUDE_MAX);
}
}
diff --git a/TombEngine/Objects/TR5/Trap/tr5_explosion.cpp b/TombEngine/Objects/TR5/Trap/tr5_explosion.cpp
index bb5bb3654..8b33196a2 100644
--- a/TombEngine/Objects/TR5/Trap/tr5_explosion.cpp
+++ b/TombEngine/Objects/TR5/Trap/tr5_explosion.cpp
@@ -129,49 +129,43 @@ void ExplosionControl(short itemNumber)
}
}
- GetCollidedObjects(item, 2048, true, CollidedItems, CollidedMeshes, 1);
- if (CollidedItems[0] || CollidedMeshes[0])
+ auto collObjects = GetCollidedObjects(*item, true, true, BLOCK(2), ObjectCollectionMode::All);
+ if (!collObjects.IsEmpty())
{
- int i = 0;
- while (CollidedItems[i])
+ for (auto* itemPtr : collObjects.ItemPtrs)
{
- if (CollidedItems[i]->ObjectNumber >= ID_SMASH_OBJECT1 && CollidedItems[i]->ObjectNumber <= ID_SMASH_OBJECT16)
+ if (itemPtr->ObjectNumber >= ID_SMASH_OBJECT1 && itemPtr->ObjectNumber <= ID_SMASH_OBJECT16)
{
- TriggerExplosionSparks(CollidedItems[i]->Pose.Position.x, CollidedItems[i]->Pose.Position.y, CollidedItems[i]->Pose.Position.z, 3, -2, 0, CollidedItems[i]->RoomNumber);
- CollidedItems[i]->Pose.Position.y -= 128;
- TriggerShockwave(&CollidedItems[i]->Pose, 48, 304, 96, 128, 96, 0, 24, EulerAngles::Identity, 0, true, false, false, (int)ShockwaveStyle::Normal);
- CollidedItems[i]->Pose.Position.y += 128;
- ExplodeItemNode(CollidedItems[i], 0, 0, 80);
- SmashObject(CollidedItems[i]->Index);
- KillItem(CollidedItems[i]->Index);
+ TriggerExplosionSparks(itemPtr->Pose.Position.x, itemPtr->Pose.Position.y, itemPtr->Pose.Position.z, 3, -2, 0, itemPtr->RoomNumber);
+ itemPtr->Pose.Position.y -= 128;
+ TriggerShockwave(&itemPtr->Pose, 48, 304, 96, 128, 96, 0, 24, EulerAngles::Identity, 0, true, false, false, (int)ShockwaveStyle::Normal);
+ itemPtr->Pose.Position.y += 128;
+ ExplodeItemNode(itemPtr, 0, 0, 80);
+ SmashObject(itemPtr->Index);
+ KillItem(itemPtr->Index);
}
- else if (CollidedItems[i]->ObjectNumber != ID_SWITCH_TYPE7 && CollidedItems[i]->ObjectNumber != ID_SWITCH_TYPE8)
+ else if (itemPtr->ObjectNumber != ID_SWITCH_TYPE7 && itemPtr->ObjectNumber != ID_SWITCH_TYPE8)
{
- if (Objects[CollidedItems[i]->ObjectNumber].intelligent)
- DoExplosiveDamage(*LaraItem, *CollidedItems[i], *item, Weapons[(int)LaraWeaponType::GrenadeLauncher].ExplosiveDamage);
+ if (Objects[itemPtr->ObjectNumber].intelligent)
+ DoExplosiveDamage(*LaraItem, *itemPtr, *item, Weapons[(int)LaraWeaponType::GrenadeLauncher].ExplosiveDamage);
}
else
{
- /* @FIXME This calls CrossbowHitSwitchType78() */
+ // @FIXME: This calls CrossbowHitSwitchType78()
}
-
- ++i;
}
- i = 0;
- while (CollidedMeshes[i])
+ for (auto* staticPtr : collObjects.StaticPtrs)
{
- if (StaticObjects[CollidedMeshes[i]->staticNumber].shatterType != ShatterType::None)
+ if (StaticObjects[staticPtr->staticNumber].shatterType != ShatterType::None)
{
- TriggerExplosionSparks(CollidedMeshes[i]->pos.Position.x, CollidedMeshes[i]->pos.Position.y, CollidedMeshes[i]->pos.Position.z, 3, -2, 0, item->RoomNumber);
- CollidedMeshes[i]->pos.Position.y -= 128;
- TriggerShockwave(&CollidedMeshes[i]->pos, 40, 176, 64, 128, 96, 0, 16, EulerAngles::Identity, 0, true, false, false, (int)ShockwaveStyle::Normal);
- CollidedMeshes[i]->pos.Position.y += 128;
- SoundEffect(GetShatterSound(CollidedMeshes[i]->staticNumber), &CollidedMeshes[i]->pos);
- ShatterObject(NULL, CollidedMeshes[i], -128, item->RoomNumber, 0);
+ TriggerExplosionSparks(staticPtr->pos.Position.x, staticPtr->pos.Position.y, staticPtr->pos.Position.z, 3, -2, 0, item->RoomNumber);
+ staticPtr->pos.Position.y -= 128;
+ TriggerShockwave(&staticPtr->pos, 40, 176, 64, 128, 96, 0, 16, EulerAngles::Identity, 0, true, false, false, (int)ShockwaveStyle::Normal);
+ staticPtr->pos.Position.y += 128;
+ SoundEffect(GetShatterSound(staticPtr->staticNumber), &staticPtr->pos);
+ ShatterObject(nullptr, staticPtr, -128, item->RoomNumber, 0);
}
-
- ++i;
}
AlertNearbyGuards(item);
diff --git a/TombEngine/Objects/game_object_ids.h b/TombEngine/Objects/game_object_ids.h
index 485951b01..f04d93296 100644
--- a/TombEngine/Objects/game_object_ids.h
+++ b/TombEngine/Objects/game_object_ids.h
@@ -341,8 +341,8 @@ enum GAME_OBJECT_ID : short
ID_SARCOPHAGUS,
ID_ENEMY_PIECE,
ID_EXPANDING_PLATFORM,
- ID_SQUISHY_BLOCK1,
- ID_SQUISHY_BLOCK2,
+ ID_SQUISHY_BLOCK_HORIZONTAL,
+ ID_SQUISHY_BLOCK_VERTICAL,
ID_LASER_BEAM,
ID_MINE_DETECTOR,
ID_MAP,
diff --git a/TombEngine/Renderer/ConstantBuffers/InstancedStaticBuffer.h b/TombEngine/Renderer/ConstantBuffers/InstancedStaticBuffer.h
index 6a9f54008..8b5fc8033 100644
--- a/TombEngine/Renderer/ConstantBuffers/InstancedStaticBuffer.h
+++ b/TombEngine/Renderer/ConstantBuffers/InstancedStaticBuffer.h
@@ -17,7 +17,7 @@ namespace TEN::Renderer::ConstantBuffers
//--
Vector4 Ambient;
//--
- ShaderLight Lights[8];
+ ShaderLight Lights[MAX_LIGHTS_PER_ITEM];
//--
int NumLights;
int LightMode;
diff --git a/TombEngine/Renderer/Renderer.cpp b/TombEngine/Renderer/Renderer.cpp
index e7bfe0859..42db9a9c6 100644
--- a/TombEngine/Renderer/Renderer.cpp
+++ b/TombEngine/Renderer/Renderer.cpp
@@ -52,7 +52,7 @@ namespace TEN::Renderer
{
item.PrevRoomNumber = NO_ROOM;
item.RoomNumber = NO_ROOM;
- item.ItemNumber = NO_ITEM;
+ item.ItemNumber = NO_VALUE;
item.LightsToDraw.clear();
}
}
diff --git a/TombEngine/Renderer/Renderer.h b/TombEngine/Renderer/Renderer.h
index 037545d6b..d738ae413 100644
--- a/TombEngine/Renderer/Renderer.h
+++ b/TombEngine/Renderer/Renderer.h
@@ -258,8 +258,8 @@ namespace TEN::Renderer
// Preallocated pools of objects for avoiding new/delete
// Items and effects are safe (can't be more than 1024 items in TR),
// lights should be oversized (eventually ignore lights more than MAX_LIGHTS)
- RendererItem _items[NUM_ITEMS];
- RendererEffect _effects[NUM_ITEMS];
+ RendererItem _items[ITEM_COUNT_MAX];
+ RendererEffect _effects[ITEM_COUNT_MAX];
// Debug variables
int _numDrawCalls = 0;
@@ -447,6 +447,7 @@ namespace TEN::Renderer
void DrawTriangles3D(RenderView& view);
void DrawOverlays(RenderView& view);
void PrepareRopes(RenderView& view);
+ void DrawFishSwarm(RenderView& view, RendererPass rendererPass);
void DrawBats(RenderView& view, RendererPass rendererPass);
void DrawRats(RenderView& view, RendererPass rendererPass);
void DrawScarabs(RenderView& view, RendererPass rendererPass);
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index 8a96725ef..8093ca8d3 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -21,6 +21,7 @@
#include "Game/Setup.h"
#include "Objects/Effects/tr4_locusts.h"
#include "Objects/Generic/Object/rope.h"
+#include "Objects/TR3/Entity/FishSwarm.h"
#include "Objects/TR4/Entity/tr4_beetle_swarm.h"
#include "Objects/TR5/Emitter/tr5_bats_emitter.h"
#include "Objects/TR5/Emitter/tr5_rats_emitter.h"
@@ -31,16 +32,17 @@
#include "Specific/winmain.h"
#include "Renderer/Structures/RendererSortableObject.h"
+using namespace std::chrono;
+using namespace TEN::Effects::Hair;
+using namespace TEN::Entities::Creatures::TR3;
+using namespace TEN::Entities::Generic;
+using namespace TEN::Hud;
+using namespace TEN::Renderer::Structures;
+
extern GUNSHELL_STRUCT Gunshells[MAX_GUNSHELL];
namespace TEN::Renderer
{
- using namespace std::chrono;
- using namespace TEN::Effects::Hair;
- using namespace TEN::Entities::Generic;
- using namespace TEN::Hud;
- using namespace TEN::Renderer::Structures;
-
void Renderer::RenderBlobShadows(RenderView& renderView)
{
auto nearestSpheres = std::vector{};
@@ -610,14 +612,126 @@ namespace TEN::Renderer
}
}
+ void Renderer::DrawFishSwarm(RenderView& view, RendererPass rendererPass)
+ {
+ if (!Objects[ID_FISH_EMITTER].loaded)
+ return;
+
+ if (rendererPass == RendererPass::CollectTransparentFaces)
+ {
+ for (const auto& fish : FishSwarm)
+ {
+ if (fish.Life <= 0.0f)
+ continue;
+
+ auto& mesh = *GetMesh(Objects[ID_FISH_EMITTER].meshIndex + fish.MeshIndex);
+ for (auto& bucket : mesh.Buckets)
+ {
+ if (!IsSortedBlendMode(bucket.BlendMode))
+ continue;
+
+ for (auto& poly : bucket.Polygons)
+ {
+ auto worldMatrix = fish.Orientation.ToRotationMatrix() * Matrix::CreateTranslation(fish.Position);
+ auto center = Vector3::Transform(poly.Centre, worldMatrix);
+ float dist = Vector3::Distance(center, view.Camera.WorldPosition);
+
+ auto object = RendererSortableObject{};
+ object.ObjectType = RendererObjectType::MoveableAsStatic;
+ object.Centre = center;
+ object.Distance = dist;
+ object.Bucket = &bucket;
+ object.Mesh = &mesh;
+ object.Polygon = &poly;
+ object.World = worldMatrix;
+ object.Room = &_rooms[fish.RoomNumber];
+
+ view.TransparentObjectsToDraw.push_back(object);
+ }
+ }
+ }
+ }
+ else
+ {
+ bool doesActiveFishExist = false;
+ for (const auto& fish : FishSwarm)
+ {
+ if (fish.Life > 0.0f)
+ {
+ doesActiveFishExist = true;
+ break;
+ }
+ }
+
+ if (doesActiveFishExist)
+ {
+ if (rendererPass == RendererPass::GBuffer)
+ {
+ _context->VSSetShader(_vsGBufferStatics.Get(), nullptr, 0);
+ _context->PSSetShader(_psGBuffer.Get(), nullptr, 0);
+ }
+ else
+ {
+ _context->VSSetShader(_vsStatics.Get(), nullptr, 0);
+ _context->PSSetShader(_psStatics.Get(), nullptr, 0);
+ }
+
+ unsigned int stride = sizeof(Vertex);
+ unsigned int offset = 0;
+
+ _context->IASetVertexBuffers(0, 1, _moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
+ _context->IASetIndexBuffer(_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
+
+ const auto& moveableObj = *_moveableObjects[ID_FISH_EMITTER];
+
+ _stStatic.LightMode = (int)moveableObj.ObjectMeshes[0]->LightMode;
+
+ for (const auto& fish : FishSwarm)
+ {
+ if (fish.Life <= 0.0f)
+ continue;
+
+ const auto& mesh = *GetMesh(Objects[ID_FISH_EMITTER].meshIndex + fish.MeshIndex);
+
+ _stStatic.World = fish.Orientation.ToRotationMatrix() * Matrix::CreateTranslation(fish.Position);
+ _stStatic.Color = Vector4::One;
+ _stStatic.AmbientLight = _rooms[fish.RoomNumber].AmbientLight;
+
+ if (rendererPass != RendererPass::GBuffer)
+ BindStaticLights(_rooms[fish.RoomNumber].LightsToDraw);
+
+ _cbStatic.UpdateData(_stStatic, _context.Get());
+
+ for (const auto& bucket : mesh.Buckets)
+ {
+ if (bucket.NumVertices == 0)
+ continue;
+
+ int passCount = (rendererPass == RendererPass::Opaque && bucket.BlendMode == BlendMode::AlphaTest) ? 2 : 1;
+ for (int p = 0; p < passCount; p++)
+ {
+ if (!SetupBlendModeAndAlphaTest(bucket.BlendMode, rendererPass, p))
+ continue;
+
+ BindTexture(TextureRegister::ColorMap, &std::get<0>(_moveablesTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp);
+ BindTexture(TextureRegister::NormalMap, &std::get<1>(_moveablesTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp);
+
+ DrawIndexedTriangles(bucket.NumIndices, bucket.StartIndex, 0);
+
+ _numMoveablesDrawCalls++;
+ }
+ }
+ }
+ }
+ }
+ }
+
void Renderer::DrawBats(RenderView& view, RendererPass rendererPass)
{
if (!Objects[ID_BATS_EMITTER].loaded)
- {
return;
- }
- RendererMesh* mesh = GetMesh(Objects[ID_BATS_EMITTER].meshIndex + (GlobalCounter & 3));
+ auto* mesh = GetMesh(Objects[ID_BATS_EMITTER].meshIndex + (GlobalCounter & 3));
if (rendererPass == RendererPass::CollectTransparentFaces)
{
@@ -680,52 +794,55 @@ namespace TEN::Renderer
batsCount++;
}
- }
- if (batsCount > 0)
- {
- if (rendererPass == RendererPass::GBuffer)
+ if (batsCount == INSTANCED_STATIC_MESH_BUCKET_SIZE ||
+ (i == NUM_BATS - 1 && batsCount > 0))
{
- _context->VSSetShader(_vsGBufferInstancedStatics.Get(), nullptr, 0);
- _context->PSSetShader(_psGBuffer.Get(), nullptr, 0);
- }
- else
- {
- _context->VSSetShader(_vsInstancedStaticMeshes.Get(), nullptr, 0);
- _context->PSSetShader(_psInstancedStaticMeshes.Get(), nullptr, 0);
- }
-
- UINT stride = sizeof(Vertex);
- UINT offset = 0;
-
- _context->IASetVertexBuffers(0, 1, _moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
- _context->IASetIndexBuffer(_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
-
- _cbInstancedSpriteBuffer.UpdateData(_stInstancedSpriteBuffer, _context.Get());
-
- for (auto& bucket : mesh->Buckets)
- {
- if (bucket.NumVertices == 0)
+ if (rendererPass == RendererPass::GBuffer)
{
- continue;
+ _context->VSSetShader(_vsGBufferInstancedStatics.Get(), nullptr, 0);
+ _context->PSSetShader(_psGBuffer.Get(), nullptr, 0);
+ }
+ else
+ {
+ _context->VSSetShader(_vsInstancedStaticMeshes.Get(), nullptr, 0);
+ _context->PSSetShader(_psInstancedStaticMeshes.Get(), nullptr, 0);
}
- int passes = rendererPass == RendererPass::Opaque && bucket.BlendMode == BlendMode::AlphaTest ? 2 : 1;
+ UINT stride = sizeof(Vertex);
+ UINT offset = 0;
- for (int p = 0; p < passes; p++)
+ _context->IASetVertexBuffers(0, 1, _moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
+ _context->IASetIndexBuffer(_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
+
+ _cbInstancedStaticMeshBuffer.UpdateData(_stInstancedStaticMeshBuffer, _context.Get());
+
+ for (auto& bucket : mesh->Buckets)
{
- if (!SetupBlendModeAndAlphaTest(bucket.BlendMode, rendererPass, p))
+ if (bucket.NumVertices == 0)
{
continue;
}
- BindTexture(TextureRegister::ColorMap, &std::get<0>(_moveablesTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp);
- BindTexture(TextureRegister::NormalMap, &std::get<1>(_moveablesTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp);
+ int passes = rendererPass == RendererPass::Opaque && bucket.BlendMode == BlendMode::AlphaTest ? 2 : 1;
- DrawIndexedInstancedTriangles(bucket.NumIndices, batsCount, bucket.StartIndex, 0);
+ for (int p = 0; p < passes; p++)
+ {
+ if (!SetupBlendModeAndAlphaTest(bucket.BlendMode, rendererPass, p))
+ {
+ continue;
+ }
- _numMoveablesDrawCalls++;
+ BindTexture(TextureRegister::ColorMap, &std::get<0>(_moveablesTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp);
+ BindTexture(TextureRegister::NormalMap, &std::get<1>(_moveablesTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp);
+
+ DrawIndexedInstancedTriangles(bucket.NumIndices, batsCount, bucket.StartIndex, 0);
+
+ _numMoveablesDrawCalls++;
+ }
}
+
+ batsCount = 0;
}
}
}
@@ -779,7 +896,10 @@ namespace TEN::Renderer
}
else
{
+ std::vector> beetlesBuckets;
+
unsigned int beetleCount = 0;
+
for (int i = 0; i < TEN::Entities::TR4::NUM_BEETLES; i++)
{
const auto& beetle = TEN::Entities::TR4::BeetleSwarm[i];
@@ -795,57 +915,65 @@ namespace TEN::Renderer
if (rendererPass != RendererPass::GBuffer)
{
- BindInstancedStaticLights(room.LightsToDraw, beetleCount);
+ std::vector lights;
+ for (int i = 0; i < std::min((int)room.LightsToDraw.size(), MAX_LIGHTS_PER_ITEM); i++)
+ {
+ lights.push_back(room.LightsToDraw[i]);
+ }
+ BindInstancedStaticLights(lights, beetleCount);
}
beetleCount++;
}
- }
- if (beetleCount > 0)
- {
- if (rendererPass == RendererPass::GBuffer)
+ if (beetleCount == INSTANCED_STATIC_MESH_BUCKET_SIZE ||
+ (i == TEN::Entities::TR4::NUM_BEETLES - 1 && beetleCount > 0))
{
- _context->VSSetShader(_vsGBufferInstancedStatics.Get(), nullptr, 0);
- _context->PSSetShader(_psGBuffer.Get(), nullptr, 0);
- }
- else
- {
- _context->VSSetShader(_vsInstancedStaticMeshes.Get(), nullptr, 0);
- _context->PSSetShader(_psInstancedStaticMeshes.Get(), nullptr, 0);
- }
-
- unsigned int stride = sizeof(Vertex);
- unsigned int offset = 0;
-
- _context->IASetVertexBuffers(0, 1, _moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
- _context->IASetIndexBuffer(_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
-
- _cbInstancedSpriteBuffer.UpdateData(_stInstancedSpriteBuffer, _context.Get());
-
- for (const auto& bucket : mesh->Buckets)
- {
- if (bucket.NumVertices == 0)
+ if (rendererPass == RendererPass::GBuffer)
{
- continue;
+ _context->VSSetShader(_vsGBufferInstancedStatics.Get(), nullptr, 0);
+ _context->PSSetShader(_psGBuffer.Get(), nullptr, 0);
+ }
+ else
+ {
+ _context->VSSetShader(_vsInstancedStaticMeshes.Get(), nullptr, 0);
+ _context->PSSetShader(_psInstancedStaticMeshes.Get(), nullptr, 0);
}
- int passes = rendererPass == RendererPass::Opaque && bucket.BlendMode == BlendMode::AlphaTest ? 2 : 1;
+ unsigned int stride = sizeof(Vertex);
+ unsigned int offset = 0;
- for (int p = 0; p < passes; p++)
+ _context->IASetVertexBuffers(0, 1, _moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
+ _context->IASetIndexBuffer(_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
+
+ _cbInstancedStaticMeshBuffer.UpdateData(_stInstancedStaticMeshBuffer, _context.Get());
+
+ for (const auto& bucket : mesh->Buckets)
{
- if (!SetupBlendModeAndAlphaTest(bucket.BlendMode, rendererPass, p))
+ if (bucket.NumVertices == 0)
{
continue;
}
- BindTexture(TextureRegister::ColorMap, &std::get<0>(_moveablesTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp);
- BindTexture(TextureRegister::NormalMap, &std::get<1>(_moveablesTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp);
+ int passes = rendererPass == RendererPass::Opaque && bucket.BlendMode == BlendMode::AlphaTest ? 2 : 1;
- DrawIndexedInstancedTriangles(bucket.NumIndices, beetleCount, bucket.StartIndex, 0);
+ for (int p = 0; p < passes; p++)
+ {
+ if (!SetupBlendModeAndAlphaTest(bucket.BlendMode, rendererPass, p))
+ {
+ continue;
+ }
- _numInstancedStaticsDrawCalls++;
+ BindTexture(TextureRegister::ColorMap, &std::get<0>(_moveablesTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp);
+ BindTexture(TextureRegister::NormalMap, &std::get<1>(_moveablesTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp);
+
+ DrawIndexedInstancedTriangles(bucket.NumIndices, beetleCount, bucket.StartIndex, 0);
+
+ _numInstancedStaticsDrawCalls++;
+ }
}
+
+ beetleCount = 0;
}
}
}
@@ -1710,6 +1838,7 @@ namespace TEN::Renderer
DrawLocusts(view, RendererPass::Opaque);
DrawDebris(view, RendererPass::Opaque);
DrawSprites(view, RendererPass::Opaque);
+ DrawFishSwarm(view, RendererPass::Opaque);
// Draw additive faces.
DrawRooms(view, RendererPass::Additive);
@@ -1723,6 +1852,7 @@ namespace TEN::Renderer
DrawLocusts(view, RendererPass::Additive);
DrawDebris(view, RendererPass::Additive);
DrawSprites(view, RendererPass::Additive);
+ DrawFishSwarm(view, RendererPass::Additive);
// Collect all non-commutative transparent faces.
// NOTE: Sorted sprites are already collected at the beginning of the frame.
@@ -1733,6 +1863,7 @@ namespace TEN::Renderer
DrawEffects(view, RendererPass::CollectTransparentFaces);
DrawRats(view, RendererPass::CollectTransparentFaces);
DrawLocusts(view, RendererPass::CollectTransparentFaces);
+ DrawFishSwarm(view, RendererPass::CollectTransparentFaces);
// Draw sorted faces.
DrawSortedFaces(view);
@@ -3120,7 +3251,7 @@ namespace TEN::Renderer
}
SetBlendMode(objectInfo->Bucket->BlendMode);
- SetAlphaTest(AlphaTestMode::GreatherThan, ALPHA_TEST_THRESHOLD);
+ SetAlphaTest(AlphaTestMode::None, ALPHA_TEST_THRESHOLD);
// Draw geometry
if (objectInfo->Bucket->Animated)
@@ -3181,10 +3312,10 @@ namespace TEN::Renderer
SetDepthState(DepthState::Read);
SetCullMode(CullMode::CounterClockwise);
SetBlendMode(objectInfo->Bucket->BlendMode);
- SetAlphaTest(AlphaTestMode::GreatherThan, ALPHA_TEST_THRESHOLD);
+ SetAlphaTest(AlphaTestMode::None, ALPHA_TEST_THRESHOLD);
- _context->VSSetShader(_vsItems.Get(), nullptr, 0);
- _context->PSSetShader(_psItems.Get(), nullptr, 0);
+ _context->VSSetShader(_vsItems.Get(), nullptr, 0);
+ _context->PSSetShader(_psItems.Get(), nullptr, 0);
ItemInfo* nativeItem = &g_Level.Items[objectInfo->Item->ItemNumber];
RendererRoom* room = &_rooms[objectInfo->Item->RoomNumber];
@@ -3237,7 +3368,7 @@ namespace TEN::Renderer
SetDepthState(DepthState::Read);
SetCullMode(CullMode::CounterClockwise);
SetBlendMode(objectInfo->Bucket->BlendMode);
- SetAlphaTest(AlphaTestMode::GreatherThan, ALPHA_TEST_THRESHOLD);
+ SetAlphaTest(AlphaTestMode::None, ALPHA_TEST_THRESHOLD);
BindTexture(TextureRegister::ColorMap, &std::get<0>(_staticTextures[objectInfo->Bucket->Texture]),
SamplerStateRegister::AnisotropicClamp);
diff --git a/TombEngine/Renderer/RendererFrame.cpp b/TombEngine/Renderer/RendererFrame.cpp
index f56578d0a..91b188a16 100644
--- a/TombEngine/Renderer/RendererFrame.cpp
+++ b/TombEngine/Renderer/RendererFrame.cpp
@@ -318,8 +318,8 @@ namespace TEN::Renderer
RendererRoom& room = _rooms[roomNumber];
ROOM_INFO* r = &g_Level.Rooms[room.RoomNumber];
- short itemNum = NO_ITEM;
- for (itemNum = r->itemNumber; itemNum != NO_ITEM; itemNum = g_Level.Items[itemNum].NextItem)
+ short itemNum = NO_VALUE;
+ for (itemNum = r->itemNumber; itemNum != NO_VALUE; itemNum = g_Level.Items[itemNum].NextItem)
{
ItemInfo* item = &g_Level.Items[itemNum];
@@ -798,8 +798,8 @@ namespace TEN::Renderer
RendererRoom& room = _rooms[roomNumber];
ROOM_INFO* r = &g_Level.Rooms[room.RoomNumber];
- short fxNum = NO_ITEM;
- for (fxNum = r->fxNumber; fxNum != NO_ITEM; fxNum = EffectList[fxNum].nextFx)
+ short fxNum = NO_VALUE;
+ for (fxNum = r->fxNumber; fxNum != NO_VALUE; fxNum = EffectList[fxNum].nextFx)
{
FX_INFO *fx = &EffectList[fxNum];
if (fx->objectNumber < 0 || fx->color.w <= 0)
@@ -828,7 +828,7 @@ namespace TEN::Renderer
void Renderer::ResetAnimations()
{
- for (int i = 0; i < NUM_ITEMS; i++)
+ for (int i = 0; i < ITEM_COUNT_MAX; i++)
_items[i].DoneAnimations = false;
}
diff --git a/TombEngine/Renderer/RendererInit.cpp b/TombEngine/Renderer/RendererInit.cpp
index b94d8c92e..c6d339c5e 100644
--- a/TombEngine/Renderer/RendererInit.cpp
+++ b/TombEngine/Renderer/RendererInit.cpp
@@ -130,7 +130,7 @@ namespace TEN::Renderer
_lines3DToDraw = createVector(MAX_LINES_3D);
_triangles3DToDraw = createVector(MAX_TRIANGLES_3D);
- for (int i = 0; i < NUM_ITEMS; i++)
+ for (int i = 0; i < ITEM_COUNT_MAX; i++)
{
_items[i].LightsToDraw = createVector(MAX_LIGHTS_PER_ITEM);
_effects[i].LightsToDraw = createVector(MAX_LIGHTS_PER_ITEM);
diff --git a/TombEngine/Renderer/RendererSprites.cpp b/TombEngine/Renderer/RendererSprites.cpp
index 490a7b3d6..b969a0efe 100644
--- a/TombEngine/Renderer/RendererSprites.cpp
+++ b/TombEngine/Renderer/RendererSprites.cpp
@@ -540,9 +540,10 @@ namespace TEN::Renderer
SetDepthState(DepthState::Read);
SetCullMode(CullMode::None);
SetBlendMode(objectInfo->Sprite->BlendMode);
- SetAlphaTest(AlphaTestMode::GreatherThan, ALPHA_TEST_THRESHOLD);
+ SetAlphaTest(AlphaTestMode::None, ALPHA_TEST_THRESHOLD);
BindTexture(TextureRegister::ColorMap, objectInfo->Sprite->Sprite->Texture, SamplerStateRegister::LinearClamp);
+ BindRenderTargetAsTexture(TextureRegister::DepthMap, &_depthRenderTarget, SamplerStateRegister::PointWrap);
DrawTriangles((int)_sortedPolygonsVertices.size(), 0);
diff --git a/TombEngine/Resources.rc b/TombEngine/Resources.rc
index 45ac7cd20..c475bfd5e 100644
--- a/TombEngine/Resources.rc
+++ b/TombEngine/Resources.rc
@@ -26,8 +26,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,3,0,0
- PRODUCTVERSION 1,7,0,0
+ FILEVERSION 1,4,0,0
+ PRODUCTVERSION 1,7,1,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -43,12 +43,12 @@ BEGIN
BLOCK "000904b0"
BEGIN
VALUE "CompanyName", "Tomb Engine Development Community"
- VALUE "FileVersion", "1.3.0.0"
+ VALUE "FileVersion", "1.4.0.0"
VALUE "InternalName", "TombEngine.exe"
VALUE "LegalCopyright", "Copyright (c) 2024"
VALUE "OriginalFilename", "TombEngine.exe"
VALUE "ProductName", "Tomb Engine"
- VALUE "ProductVersion", "1.7.0.0"
+ VALUE "ProductVersion", "1.7.1.0"
END
END
BLOCK "VarFileInfo"
diff --git a/TombEngine/Scripting/Internal/ReservedScriptNames.h b/TombEngine/Scripting/Internal/ReservedScriptNames.h
index bacae1d8f..e8821218c 100644
--- a/TombEngine/Scripting/Internal/ReservedScriptNames.h
+++ b/TombEngine/Scripting/Internal/ReservedScriptNames.h
@@ -315,6 +315,7 @@ static constexpr char ScriptReserved_KeyPush[] = "KeyPush";
static constexpr char ScriptReserved_KeyClear[] = "KeyClear";
static constexpr char ScriptReserved_FlipMap[] = "FlipMap";
+static constexpr char ScriptReserved_GetFlipMapStatus[] = "GetFlipMapStatus";
static constexpr char ScriptReserved_PlayFlyBy[] = "PlayFlyBy";
static constexpr char ScriptReserved_PlayCamera[] = "PlayCamera";
diff --git a/TombEngine/Scripting/Internal/TEN/Effects/EffectsFunctions.cpp b/TombEngine/Scripting/Internal/TEN/Effects/EffectsFunctions.cpp
index 8e403a9d3..e76903b6b 100644
--- a/TombEngine/Scripting/Internal/TEN/Effects/EffectsFunctions.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Effects/EffectsFunctions.cpp
@@ -167,7 +167,7 @@ namespace TEN::Scripting::Effects
constexpr float secsPerFrame = 1.0f / (float)FPS;
float life = USE_IF_HAVE(float, lifetime, 2.0f);
- life = std::max(0.0f, life);
+ life = std::max(0.1f, life);
int lifeInFrames = (int)round(life / secsPerFrame);
s->life = s->sLife = lifeInFrames;
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp
index e2e99aef4..5240789f8 100644
--- a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp
@@ -198,6 +198,19 @@ Must be an integer value (0 means no secrets).
@tparam int total number of secrets
*/
tableFlow.set_function(ScriptReserved_SetTotalSecretCount, &FlowHandler::SetTotalSecretCount, this);
+
+/*** Do FlipMap with specific group ID.
+@function FlipMap
+@tparam int flipmap (ID of flipmap group to actuvate / deactivate)
+*/
+ tableFlow.set_function(ScriptReserved_FlipMap, &FlowHandler::FlipMap, this);
+
+/*** Get current FlipMap status for specific group ID.
+@function GetFlipMapStatus
+@int[opt] index Flipmap group ID to check. If no group specified or group is -1, function returns overall flipmap status (on or off).
+@treturn int Status of the flipmap group (true means on, false means off).
+*/
+ tableFlow.set_function(ScriptReserved_GetFlipMapStatus, &FlowHandler::GetFlipMapStatus, this);
/*** settings.lua.
These functions are called in settings.lua, a file which holds your local settings.
@@ -240,12 +253,6 @@ Specify which translations in the strings table correspond to which languages.
*/
tableFlow.set_function(ScriptReserved_SetLanguageNames, &FlowHandler::SetLanguageNames, this);
-/*** Do FlipMap with specific ID.
-//@function FlipMap
-//@tparam int flipmap (ID of flipmap)
-*/
- tableFlow.set_function(ScriptReserved_FlipMap, &FlowHandler::FlipMap, this);
-
ScriptColor::Register(parent);
Rotation::Register(parent);
Vec2::Register(parent);
@@ -444,9 +451,25 @@ GameStatus FlowHandler::GetGameStatus()
return this->LastGameStatus;
}
-void FlowHandler::FlipMap(int flipmap)
+void FlowHandler::FlipMap(int group)
{
- DoFlipMap(flipmap);
+ DoFlipMap(group);
+}
+
+bool FlowHandler::GetFlipMapStatus(std::optional group)
+{
+ if (!group.has_value() || group.value() == NO_VALUE)
+ {
+ return FlipStatus;
+ }
+
+ if (group.value() < 0 || group.value() >= MAX_FLIPMAP)
+ {
+ TENLog("Maximum flipmap group number is " + std::to_string(MAX_FLIPMAP) + ". Please specify another index.", LogLevel::Warning);
+ return false;
+ }
+
+ return FlipStatus && FlipStats[group.value()];
}
void FlowHandler::SaveGame(int slot)
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.h b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.h
index b72d70f08..b6aa5a417 100644
--- a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.h
+++ b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.h
@@ -63,7 +63,8 @@ public:
int GetNumLevels() const;
void EndLevel(std::optional nextLevel, std::optional startPosIndex);
GameStatus GetGameStatus();
- void FlipMap(int flipmap);
+ void FlipMap(int group);
+ bool GetFlipMapStatus(std::optional group);
void SaveGame(int slot);
void LoadGame(int slot);
void DeleteSaveGame(int slot);
diff --git a/TombEngine/Scripting/Internal/TEN/Objects/AIObject/AIObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/AIObject/AIObject.cpp
index 403d31ca9..49bfe900c 100644
--- a/TombEngine/Scripting/Internal/TEN/Objects/AIObject/AIObject.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Objects/AIObject/AIObject.cpp
@@ -13,8 +13,8 @@ AI object
@pragma nostrip
*/
-static auto index_error = index_error_maker(AIObject, ScriptReserved_AIObject);
-static auto newindex_error = newindex_error_maker(AIObject, ScriptReserved_AIObject);
+static auto IndexError = index_error_maker(AIObject, ScriptReserved_AIObject);
+static auto NewIndexError = newindex_error_maker(AIObject, ScriptReserved_AIObject);
AIObject::AIObject(AI_OBJECT & ref) : m_aiObject{ref}
{};
@@ -23,8 +23,8 @@ void AIObject::Register(sol::table& parent)
{
parent.new_usertype(ScriptReserved_AIObject,
sol::no_constructor, // ability to spawn new ones could be added later
- sol::meta_function::index, index_error,
- sol::meta_function::new_index, newindex_error,
+ sol::meta_function::index, IndexError,
+ sol::meta_function::new_index, NewIndexError,
/// Get the object's position
// @function AIObject:GetPosition
diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Camera/CameraObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Camera/CameraObject.cpp
index 05547a72f..557d24bb8 100644
--- a/TombEngine/Scripting/Internal/TEN/Objects/Camera/CameraObject.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Objects/Camera/CameraObject.cpp
@@ -16,8 +16,8 @@ Basic cameras that can point at Lara or at a CAMERA_TARGET.
@pragma nostrip
*/
-static auto index_error = index_error_maker(CameraObject, ScriptReserved_Camera);
-static auto newindex_error = newindex_error_maker(CameraObject, ScriptReserved_Camera);
+static auto IndexError = index_error_maker(CameraObject, ScriptReserved_Camera);
+static auto NewIndexError = newindex_error_maker(CameraObject, ScriptReserved_Camera);
CameraObject::CameraObject(LevelCameraInfo & ref) : m_camera{ref}
{};
@@ -26,8 +26,8 @@ void CameraObject::Register(sol::table& parent)
{
parent.new_usertype(ScriptReserved_Camera,
sol::no_constructor, // ability to spawn new ones could be added later
- sol::meta_function::index, index_error,
- sol::meta_function::new_index, newindex_error,
+ sol::meta_function::index, IndexError,
+ sol::meta_function::new_index, NewIndexError,
/// Get the camera's position
// @function Camera:GetPosition
diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Lara/LaraObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Lara/LaraObject.cpp
index 7bdbc18c8..c3e2cb273 100644
--- a/TombEngine/Scripting/Internal/TEN/Objects/Lara/LaraObject.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Objects/Lara/LaraObject.cpp
@@ -356,7 +356,7 @@ std::unique_ptr LaraObject::GetVehicle() const
{
auto* lara = GetLaraInfo(m_item);
- if (lara->Context.Vehicle == NO_ITEM)
+ if (lara->Context.Vehicle == NO_VALUE)
return nullptr;
return std::make_unique(lara->Context.Vehicle);
@@ -386,7 +386,7 @@ std::unique_ptr LaraObject::GetPlayerInteractedMoveable() const
{
const auto& player = GetLaraInfo(*m_item);
- if (player.Context.InteractedItem == NO_ITEM)
+ if (player.Context.InteractedItem == NO_VALUE)
return nullptr;
return std::make_unique(player.Context.InteractedItem);
diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp
index 05925ffcc..9df528d08 100644
--- a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp
@@ -36,8 +36,8 @@ pickups, and Lara herself (see also @{Objects.LaraObject} for Lara-specific feat
constexpr auto LUA_CLASS_NAME{ ScriptReserved_Moveable };
-static auto index_error = index_error_maker(Moveable, LUA_CLASS_NAME);
-static auto newindex_error = newindex_error_maker(Moveable, LUA_CLASS_NAME);
+static auto IndexError = index_error_maker(Moveable, LUA_CLASS_NAME);
+static auto NewIndexError = newindex_error_maker(Moveable, LUA_CLASS_NAME);
Moveable::Moveable(short num, bool alreadyInitialized) : m_item{ &g_Level.Items[num] }, m_num{ num }, m_initialized{ alreadyInitialized }
@@ -48,7 +48,7 @@ Moveable::Moveable(short num, bool alreadyInitialized) : m_item{ &g_Level.Items[
Moveable::Moveable(Moveable&& other) noexcept :
m_item{ std::exchange(other.m_item, nullptr) },
- m_num{ std::exchange(other.m_num, NO_ITEM) },
+ m_num{ std::exchange(other.m_num, NO_VALUE) },
m_initialized{ std::exchange(other.m_initialized, false) }
{
if (GetValid())
@@ -69,26 +69,29 @@ bool operator ==(const Moveable& first, const Moveable& second)
return first.m_item == second.m_item;
}
-/*** For more information on each parameter, see the
+/*** Used to generate a new moveable dynamically at runtime.
+For more information on each parameter, see the
associated getters and setters. If you do not know what to set for these,
most can just be ignored (see usage).
+
@function Moveable
@tparam Objects.ObjID object ID
@tparam string name Lua name of the item
@tparam Vec3 position position in level
- @tparam[opt] Rotation rotation rotation about x, y, and z axes (default Rotation(0, 0, 0))
- @int[opt] roomID room ID item is in (default: calculated automatically)
- @int[opt=0] animNumber anim number
- @int[opt=0] frameNumber frame number
- @int[opt=10] hp HP of item
- @int[opt=0] OCB ocb of item
- @tparam[opt] table AIBits table with AI bits (default { 0, 0, 0, 0, 0, 0 })
+ @tparam Rotation rotation rotation rotation about x, y, and z axes (default Rotation(0, 0, 0))
+ @tparam int roomID room ID item is in (default: calculated automatically)
+ @tparam int animNumber animation number
+ @tparam int frameNumber frame number
+ @tparam int hp HP of item
+ @tparam int OCB ocb of item
+ @tparam table AIBits table with AI bits (default { 0, 0, 0, 0, 0, 0 })
@treturn Moveable A new Moveable object (a wrapper around the new object)
+
@usage
local item = Moveable(
TEN.Objects.ObjID.PISTOLS_ITEM, -- object id
"test", -- name
- Vec3(18907, 0, 21201))
+ Vec3(18907, 0, 21201)) -- position
*/
static std::unique_ptr Create(
GAME_OBJECT_ID objID,
@@ -139,7 +142,7 @@ static std::unique_ptr Create(
ptr->SetOCB(USE_IF_HAVE(short, ocb, 0));
ptr->SetAIBits(USE_IF_HAVE(aiBitsType, aiBits, aiBitsType{}));
ptr->SetColor(ScriptColor(Vector4::One));
- item->CarriedItem = NO_ITEM;
+ item->CarriedItem = NO_VALUE;
// call this when resetting name too?
dynamic_cast(g_GameScriptEntities)->AddMoveableToMap(item, ptr.get());
@@ -153,8 +156,8 @@ void Moveable::Register(sol::state& state, sol::table& parent)
{
parent.new_usertype(LUA_CLASS_NAME,
sol::call_constructor, Create,
- sol::meta_function::index, index_error,
- sol::meta_function::new_index, newindex_error,
+ sol::meta_function::index, IndexError,
+ sol::meta_function::new_index, NewIndexError,
sol::meta_function::equal_to, std::equal_to(),
ScriptReserved_Enable, &Moveable::EnableItem,
@@ -165,62 +168,42 @@ void Moveable::Register(sol::state& state, sol::table& parent)
ScriptReserved_SetVisible, &Moveable::SetVisible,
- /// Explode item. This also kills and disables item.
- // @function Moveable:Explode
+/// Explode item. This also kills and disables item.
+// @function Moveable:Explode
ScriptReserved_Explode, &Moveable::Explode,
- /// Shatter item. This also kills and disables item.
- // @function Moveable:Shatter
+/// Shatter item. This also kills and disables item.
+// @function Moveable:Shatter
ScriptReserved_Shatter, &Moveable::Shatter,
- /// Set effect to moveable
- // @function Moveable:SetEffect
- // @tparam Effects.EffectID effect Type of effect to assign.
- // @tparam float timeout time (in seconds) after which effect turns off (optional).
+/// Set effect to moveable
+// @function Moveable:SetEffect
+// @tparam Effects.EffectID effect Type of effect to assign.
+// @tparam float timeout time (in seconds) after which effect turns off (optional).
ScriptReserved_SetEffect, &Moveable::SetEffect,
- /// Set custom colored burn effect to moveable
- // @function Moveable:SetCustomEffect
- // @tparam Color Color1 color the primary color of the effect (also used for lighting).
- // @tparam Color Color2 color the secondary color of the effect.
- // @tparam float timeout time (in seconds) after which effect turns off (optional).
+/// Set custom colored burn effect to moveable
+// @function Moveable:SetCustomEffect
+// @tparam Color Color1 color the primary color of the effect (also used for lighting).
+// @tparam Color Color2 color the secondary color of the effect.
+// @tparam float timeout time (in seconds) after which effect turns off (optional).
ScriptReserved_SetCustomEffect, &Moveable::SetCustomEffect,
- /// Get current moveable effect
- // @function Moveable:GetEffect
- // @treturn Effects.EffectID effect type currently assigned to moveable.
+/// Get current moveable effect
+// @function Moveable:GetEffect
+// @treturn Effects.EffectID effect type currently assigned to moveable.
ScriptReserved_GetEffect, &Moveable::GetEffect,
- /// Get the moveable's status.
- // @function Moveable:GetStatus()
- // @treturn Objects.MoveableStatus The moveable's status.
+/// Get the moveable's status.
+// @function Moveable:GetStatus()
+// @treturn Objects.MoveableStatus The moveable's status.
ScriptReserved_GetStatus, &Moveable::GetStatus,
- /// Set the moveable's status.
- // @function Moveable:SetStatus()
- // @tparam Objects.MoveableStatus status The new status of the moveable.
+/// Set the moveable's status.
+// @function Moveable:SetStatus()
+// @tparam Objects.MoveableStatus status The new status of the moveable.
ScriptReserved_SetStatus, &Moveable::SetStatus,
- /// Set the name of the function to be called when the moveable is shot by Lara.
- // Note that this will be triggered twice when shot with both pistols at once.
- // @function Moveable:SetOnHit
- // @tparam function callback function in LevelFuncs hierarchy to call when moveable is shot
- ScriptReserved_SetOnHit, &Moveable::SetOnHit,
-
- ScriptReserved_SetOnCollidedWithObject, &Moveable::SetOnCollidedWithObject,
-
- ScriptReserved_SetOnCollidedWithRoom, &Moveable::SetOnCollidedWithRoom,
-
-/// Set the name of the function to be called when the moveable is destroyed/killed
-// Note that enemy death often occurs at the end of an animation, and not at the exact moment
-// the enemy's HP becomes zero.
-// @function Moveable:SetOnKilled
-// @tparam function callback function in LevelFuncs hierarchy to call when enemy is killed
-// @usage
-// LevelFuncs.baddyKilled = function(theBaddy) print("You killed a baddy!") end
-// baddy:SetOnKilled(LevelFuncs.baddyKilled)
- ScriptReserved_SetOnKilled, &Moveable::SetOnKilled,
-
/// Retrieve the object ID
// @function Moveable:GetObjectID
// @treturn int a number representing the ID of the object
@@ -433,7 +416,43 @@ ScriptReserved_GetSlotHP, & Moveable::GetSlotHP,
// @tparam Objects.ObjID ObjectID to take animation and stateID from,
// @tparam int animNumber animation from object
// @tparam int stateID state from object
- ScriptReserved_AnimFromObject, &Moveable::AnimFromObject);
+ ScriptReserved_AnimFromObject, &Moveable::AnimFromObject,
+
+/// Set the name of the function to be called when the moveable is shot by Lara.
+// Note that this will be triggered twice when shot with both pistols at once.
+// @function Moveable:SetOnHit
+// @tparam function callback function in LevelFuncs hierarchy to call when moveable is shot
+ ScriptReserved_SetOnHit, &Moveable::SetOnHit,
+
+/// Set the function to be called when this moveable collides with another moveable
+// @function Moveable:SetOnCollidedWithObject
+// @tparam function func callback function to be called (must be in LevelFuncs hierarchy). This function can take two arguments; these will store the two @{Moveable}s taking part in the collision.
+// @usage
+// LevelFuncs.objCollided = function(obj1, obj2)
+// print(obj1:GetName() .. " collided with " .. obj2:GetName())
+// end
+// baddy:SetOnCollidedWithObject(LevelFuncs.objCollided)
+ ScriptReserved_SetOnCollidedWithObject, &Moveable::SetOnCollidedWithObject,
+
+/// Set the function called when this moveable collides with room geometry (e.g. a wall or floor). This function can take an argument that holds the @{Moveable} that collided with geometry.
+// @function Moveable:SetOnCollidedWithRoom
+// @tparam function func callback function to be called (must be in LevelFuncs hierarchy)
+// @usage
+// LevelFuncs.roomCollided = function(obj)
+// print(obj:GetName() .. " collided with room geometry")
+// end
+// baddy:SetOnCollidedWithRoom(LevelFuncs.roomCollided)
+ ScriptReserved_SetOnCollidedWithRoom, &Moveable::SetOnCollidedWithRoom,
+
+/// Set the name of the function to be called when the moveable is destroyed/killed
+// Note that enemy death often occurs at the end of an animation, and not at the exact moment
+// the enemy's HP becomes zero.
+// @function Moveable:SetOnKilled
+// @tparam function callback function in LevelFuncs hierarchy to call when enemy is killed
+// @usage
+// LevelFuncs.baddyKilled = function(theBaddy) print("You killed a baddy!") end
+// baddy:SetOnKilled(LevelFuncs.baddyKilled)
+ ScriptReserved_SetOnKilled, &Moveable::SetOnKilled);
}
void Moveable::Init()
@@ -502,27 +521,11 @@ void Moveable::SetOnKilled(const TypeOrNil& cb)
SetLevelFuncCallback(cb, ScriptReserved_SetOnKilled, *this, m_item->Callbacks.OnKilled);
}
-/// Set the function to be called when this moveable collides with another moveable
-// @function Moveable:SetOnCollidedWithObject
-// @tparam function func callback function to be called (must be in LevelFuncs hierarchy). This function can take two arguments; these will store the two @{Moveable}s taking part in the collision.
-// @usage
-// LevelFuncs.objCollided = function(obj1, obj2)
-// print(obj1:GetName() .. " collided with " .. obj2:GetName())
-// end
-// baddy:SetOnCollidedWithObject(LevelFuncs.objCollided)
void Moveable::SetOnCollidedWithObject(const TypeOrNil& cb)
{
SetLevelFuncCallback(cb, ScriptReserved_SetOnCollidedWithObject, *this, m_item->Callbacks.OnObjectCollided);
}
-/// Set the function called when this moveable collides with room geometry (e.g. a wall or floor). This function can take an argument that holds the @{Moveable} that collided with geometry.
-// @function Moveable:SetOnCollidedWithRoom
-// @tparam function func callback function to be called (must be in LevelFuncs hierarchy)
-// @usage
-// LevelFuncs.roomCollided = function(obj)
-// print(obj:GetName() .. " collided with room geometry")
-// end
-// baddy:SetOnCollidedWithRoom(LevelFuncs.roomCollided)
void Moveable::SetOnCollidedWithRoom(const TypeOrNil& cb)
{
SetLevelFuncCallback(cb, ScriptReserved_SetOnCollidedWithRoom, *this, m_item->Callbacks.OnRoomCollided);
@@ -1072,7 +1075,7 @@ void Moveable::UnswapMesh(int meshId)
// @function Moveable:Enable
void Moveable::EnableItem()
{
- if (m_num == NO_ITEM)
+ if (m_num == NO_VALUE)
return;
bool wasInvisible = false;
@@ -1092,12 +1095,12 @@ void Moveable::EnableItem()
// @function Moveable:Disable
void Moveable::DisableItem()
{
- if (m_num == NO_ITEM)
+ if (m_num == NO_VALUE)
return;
Antitrigger(m_num);
- if (m_num > NO_ITEM && (m_item->Status == ITEM_INVISIBLE))
+ if (m_num > NO_VALUE && (m_item->Status == ITEM_INVISIBLE))
dynamic_cast(g_GameScriptEntities)->TryRemoveColliding(m_num);
}
@@ -1146,7 +1149,7 @@ void Moveable::SetVisible(bool isVisible)
m_item->Status = ITEM_INVISIBLE;
- if (m_num > NO_ITEM)
+ if (m_num > NO_VALUE)
dynamic_cast(g_GameScriptEntities)->TryRemoveColliding(m_num);
}
else
@@ -1168,7 +1171,7 @@ void Moveable::SetVisible(bool isVisible)
m_item->Status = ITEM_ACTIVE;
}
- if (m_num > NO_ITEM)
+ if (m_num > NO_VALUE)
dynamic_cast(g_GameScriptEntities)->TryAddColliding(m_num);
}
}
@@ -1176,18 +1179,18 @@ void Moveable::SetVisible(bool isVisible)
void Moveable::Invalidate()
{
// Keep m_item as-is so it can be properly removed from moveables set when destructor is called.
- m_num = NO_ITEM;
+ m_num = NO_VALUE;
m_initialized = false;
}
bool Moveable::GetValid() const
{
- return m_num > NO_ITEM;
+ return m_num > NO_VALUE;
}
void Moveable::Destroy()
{
- if (m_num > NO_ITEM)
+ if (m_num > NO_VALUE)
{
dynamic_cast(g_GameScriptEntities)->RemoveMoveableFromMap(m_item, this);
s_callbackRemoveName(m_item->Name);
diff --git a/TombEngine/Scripting/Internal/TEN/Objects/ObjectIDs.h b/TombEngine/Scripting/Internal/TEN/Objects/ObjectIDs.h
index 069908be0..351402296 100644
--- a/TombEngine/Scripting/Internal/TEN/Objects/ObjectIDs.h
+++ b/TombEngine/Scripting/Internal/TEN/Objects/ObjectIDs.h
@@ -344,8 +344,8 @@ The following constants are inside ObjID.
SARCOPHAGUS
ENEMY_PIECE
EXPANDING_PLATFORM
- SQUISHY_BLOCK1
- SQUISHY_BLOCK2
+ SQUISHY_BLOCK_HORIZONTAL
+ SQUISHY_BLOCK_VERTICAL
LASER_BEAM
MINE_DETECTOR
MAP
@@ -1519,8 +1519,8 @@ static const std::unordered_map kObjIDs {
{ "SARCOPHAGUS", ID_SARCOPHAGUS },
{ "ENEMY_PIECE", ID_ENEMY_PIECE },
{ "EXPANDING_PLATFORM", ID_EXPANDING_PLATFORM },
- { "SQUISHY_BLOCK1", ID_SQUISHY_BLOCK1 },
- { "SQUISHY_BLOCK2", ID_SQUISHY_BLOCK2 },
+ { "SQUISHY_BLOCK_HORIZONTAL", ID_SQUISHY_BLOCK_HORIZONTAL },
+ { "SQUISHY_BLOCK_VERTICAL", ID_SQUISHY_BLOCK_VERTICAL },
{ "LASER_BEAM", ID_LASER_BEAM },
{ "MINE_DETECTOR", ID_MINE_DETECTOR },
{ "MAP", ID_MAP },
diff --git a/TombEngine/Scripting/Internal/TEN/Objects/ObjectsHandler.cpp b/TombEngine/Scripting/Internal/TEN/Objects/ObjectsHandler.cpp
index 513123b29..64b74ca70 100644
--- a/TombEngine/Scripting/Internal/TEN/Objects/ObjectsHandler.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Objects/ObjectsHandler.cpp
@@ -172,32 +172,27 @@ ObjectsHandler::ObjectsHandler(sol::state* lua, sol::table& parent) :
void ObjectsHandler::TestCollidingObjects()
{
- // Remove any items which can't collide.
- for (const auto id : m_collidingItemsToRemove)
- m_collidingItems.erase(id);
+ // Remove items which can't collide.
+ for (int itemNumber : m_collidingItemsToRemove)
+ m_collidingItems.erase(itemNumber);
m_collidingItemsToRemove.clear();
- for (const auto idOne : m_collidingItems)
+ for (int itemNumber0 : m_collidingItems)
{
- auto item = &g_Level.Items[idOne];
- if (!item->Callbacks.OnObjectCollided.empty())
+ auto& item = g_Level.Items[itemNumber0];
+ if (!item.Callbacks.OnObjectCollided.empty())
{
// Test against other moveables.
- GetCollidedObjects(item, 0, true, CollidedItems, nullptr, false);
- size_t i = 0;
- while (CollidedItems[i])
- {
- short idTwo = CollidedItems[i] - &g_Level.Items[0];
- g_GameScript->ExecuteFunction(item->Callbacks.OnObjectCollided, idOne, idTwo);
- ++i;
- }
+ auto collObjects = GetCollidedObjects(item, true, false);
+ for (const auto& collidedItemPtr : collObjects.ItemPtrs)
+ g_GameScript->ExecuteFunction(item.Callbacks.OnObjectCollided, itemNumber0, collidedItemPtr->Index);
}
- if (!item->Callbacks.OnRoomCollided.empty())
+ if (!item.Callbacks.OnRoomCollided.empty())
{
// Test against room geometry.
- if (TestItemRoomCollisionAABB(item))
- g_GameScript->ExecuteFunction(item->Callbacks.OnRoomCollided, idOne);
+ if (TestItemRoomCollisionAABB(&item))
+ g_GameScript->ExecuteFunction(item.Callbacks.OnRoomCollided, itemNumber0);
}
}
}
@@ -210,10 +205,10 @@ void ObjectsHandler::AssignLara()
bool ObjectsHandler::NotifyKilled(ItemInfo* key)
{
auto it = moveables.find(key);
- if (std::end(moveables) != it)
+ if (it != std::end(moveables))
{
- for (auto& m : moveables[key])
- m->Invalidate();
+ for (auto* movPtr : moveables[key])
+ movPtr->Invalidate();
return true;
}
diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Room/RoomObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Room/RoomObject.cpp
index 6e67e7fbc..3ca57da71 100644
--- a/TombEngine/Scripting/Internal/TEN/Objects/Room/RoomObject.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Objects/Room/RoomObject.cpp
@@ -20,8 +20,8 @@ Rooms
@pragma nostrip
*/
-static auto index_error = index_error_maker(Room, ScriptReserved_Volume);
-static auto newindex_error = newindex_error_maker(Room, ScriptReserved_Volume);
+static auto IndexError = index_error_maker(Room, ScriptReserved_Volume);
+static auto NewIndexError = newindex_error_maker(Room, ScriptReserved_Volume);
Room::Room(ROOM_INFO& room) : m_room{ room }
{};
@@ -30,8 +30,8 @@ void Room::Register(sol::table& parent)
{
parent.new_usertype(ScriptReserved_Room,
sol::no_constructor,
- sol::meta_function::index, index_error,
- sol::meta_function::new_index, newindex_error,
+ sol::meta_function::index, IndexError,
+ sol::meta_function::new_index, NewIndexError,
/// Determine whether the room is active or not
// @function Room:GetActive
diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Sink/SinkObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Sink/SinkObject.cpp
index 5bd864e04..2c0a57d00 100644
--- a/TombEngine/Scripting/Internal/TEN/Objects/Sink/SinkObject.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Objects/Sink/SinkObject.cpp
@@ -14,8 +14,8 @@ Sink
@pragma nostrip
*/
-static auto index_error = index_error_maker(Sink, ScriptReserved_Sink);
-static auto newindex_error = newindex_error_maker(Sink, ScriptReserved_Sink);
+static auto IndexError = index_error_maker(Sink, ScriptReserved_Sink);
+static auto NewIndexError = newindex_error_maker(Sink, ScriptReserved_Sink);
Sink::Sink(SinkInfo& ref) : m_sink{ref}
{};
@@ -24,8 +24,8 @@ void Sink::Register(sol::table& parent)
{
parent.new_usertype(ScriptReserved_Sink,
sol::no_constructor, // ability to spawn new ones could be added later
- sol::meta_function::index, index_error,
- sol::meta_function::new_index, newindex_error,
+ sol::meta_function::index, IndexError,
+ sol::meta_function::new_index, NewIndexError,
/// Get the sink's position
// @function Sink:GetPosition
diff --git a/TombEngine/Scripting/Internal/TEN/Objects/SoundSource/SoundSourceObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/SoundSource/SoundSourceObject.cpp
index 1271f0bd1..84eba0177 100644
--- a/TombEngine/Scripting/Internal/TEN/Objects/SoundSource/SoundSourceObject.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Objects/SoundSource/SoundSourceObject.cpp
@@ -13,8 +13,8 @@ Sound source
@pragma nostrip
*/
-static auto index_error = index_error_maker(SoundSource, ScriptReserved_SoundSource);
-static auto newindex_error = newindex_error_maker(SoundSource, ScriptReserved_SoundSource);
+static auto IndexError = index_error_maker(SoundSource, ScriptReserved_SoundSource);
+static auto NewIndexError = newindex_error_maker(SoundSource, ScriptReserved_SoundSource);
SoundSource::SoundSource(SoundSourceInfo& ref) : m_soundSource{ref}
{};
@@ -23,8 +23,8 @@ void SoundSource::Register(sol::table& parent)
{
parent.new_usertype(ScriptReserved_SoundSource,
sol::no_constructor, // ability to spawn new ones could be added later
- sol::meta_function::index, index_error,
- sol::meta_function::new_index, newindex_error,
+ sol::meta_function::index, IndexError,
+ sol::meta_function::new_index, NewIndexError,
/// Get the sound source's position
// @function SoundSource:GetPosition
diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Static/StaticObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Static/StaticObject.cpp
index c07b93abe..2715fea57 100644
--- a/TombEngine/Scripting/Internal/TEN/Objects/Static/StaticObject.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Objects/Static/StaticObject.cpp
@@ -16,8 +16,8 @@ Statics
@pragma nostrip
*/
-static auto index_error = index_error_maker(Static, ScriptReserved_Static);
-static auto newindex_error = newindex_error_maker(Static, ScriptReserved_Static);
+static auto IndexError = index_error_maker(Static, ScriptReserved_Static);
+static auto NewIndexError = newindex_error_maker(Static, ScriptReserved_Static);
Static::Static(MESH_INFO & ref) : m_mesh{ref}
{};
@@ -26,8 +26,8 @@ void Static::Register(sol::table & parent)
{
parent.new_usertype(ScriptReserved_Static,
sol::no_constructor, // ability to spawn new ones could be added later
- sol::meta_function::index, index_error,
- sol::meta_function::new_index, newindex_error,
+ sol::meta_function::index, IndexError,
+ sol::meta_function::new_index, NewIndexError,
/// Enable the static, for cases when it was shattered or manually disabled before.
// @function Static:Enable
diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Volume/VolumeObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Volume/VolumeObject.cpp
index 10b70d67c..4338ce52f 100644
--- a/TombEngine/Scripting/Internal/TEN/Objects/Volume/VolumeObject.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Objects/Volume/VolumeObject.cpp
@@ -5,185 +5,178 @@
#include "Scripting/Internal/ReservedScriptNames.h"
#include "Scripting/Internal/ScriptAssert.h"
#include "Scripting/Internal/ScriptUtil.h"
-#include "Scripting/Internal/TEN/Vec3/Vec3.h"
#include "Scripting/Internal/TEN/Rotation/Rotation.h"
+#include "Scripting/Internal/TEN/Vec3/Vec3.h"
#include "Specific/level.h"
/***
-Volumes
+Activator volume.
@tenclass Objects.Volume
@pragma nostrip
*/
-static auto index_error = index_error_maker(Volume, ScriptReserved_Volume);
-static auto newindex_error = newindex_error_maker(Volume, ScriptReserved_Volume);
+static auto IndexError = index_error_maker(Volume, ScriptReserved_Volume);
+static auto NewIndexError = newindex_error_maker(Volume, ScriptReserved_Volume);
-Volume::Volume(TriggerVolume& volume) : m_volume{ volume }
+Volume::Volume(TriggerVolume& volume) :
+ _volume(volume)
{};
void Volume::Register(sol::table& parent)
{
parent.new_usertype(ScriptReserved_Volume,
- sol::no_constructor, // TODO: Ability to spawn new ones could be added later.
- sol::meta_function::index, index_error,
- sol::meta_function::new_index, newindex_error,
+ sol::no_constructor, // TODO: Ability to spawn new volumes could be added later.
+ sol::meta_function::index, IndexError,
+ sol::meta_function::new_index, NewIndexError,
- /// Enable the volume.
- // @function Volume:Enable
- ScriptReserved_Enable, &Volume::Enable,
-
- /// Disable the volume.
- // @function Volume:Disable
- ScriptReserved_Disable, &Volume::Disable,
-
- /// Determine whether the volume is active or not
- // @function Volume:GetActive
- // @treturn bool true if the volume is active
- ScriptReserved_GetName, &Volume::GetActive,
-
- /// Get the volume's position.
- // @function Volume:GetPosition
- // @treturn Vec3 a copy of the volume's position
+ ScriptReserved_GetName, &Volume::GetName,
ScriptReserved_GetPosition, &Volume::GetPos,
-
- /// Set the volume's position.
- // @function Volume:SetPosition
- // @tparam Vec3 position the new position of the volume
- ScriptReserved_SetPosition, &Volume::SetPos,
-
- /// Get the volume's rotation.
- // @function Volume:GetRotation
- // @treturn Rotation a copy of the volume's rotation
ScriptReserved_GetRotation, &Volume::GetRot,
-
- /// Set the volume's rotation.
- // @function Volume:SetRotation
- // @tparam Rotation rotation the volume's new rotation
- ScriptReserved_SetRotation, &Volume::SetRot,
-
- /// Get the volume's scale (separately on all 3 axes).
- // @function Volume:GetScale
- // @treturn Vec3 current volume scale
ScriptReserved_GetScale, &Volume::GetScale,
- /// Set the volume's scale (separately on all 3 axes).
- // @function Volume:SetScale
- // @tparam Vec3 scale the volume's new scale
+ ScriptReserved_SetName, &Volume::SetName,
+ ScriptReserved_SetPosition, &Volume::SetPos,
+ ScriptReserved_SetRotation, &Volume::SetRot,
ScriptReserved_SetScale, &Volume::SetScale,
- /// Get the volume's unique string identifier.
- // @function Volume:GetName
- // @treturn string the volume's name
- ScriptReserved_GetName, &Volume::GetName,
-
- /// Set the volume's name (its unique string identifier).
- // @function Volume:SetName
- // @tparam string name The volume's new name
- ScriptReserved_SetName, &Volume::SetName,
-
- /// Clear activator list for volumes (makes volume trigger everything again)
- // @function Volume:ClearActivators
+ ScriptReserved_Enable, &Volume::Enable,
+ ScriptReserved_Disable, &Volume::Disable,
ScriptReserved_ClearActivators, &Volume::ClearActivators,
- /// Check if specified moveable is inside the volume
- // @function Volume:IsMoveableInside
- // @tparam Objects.Moveable Moveable which should be checked for containment
- // @treturn bool state of the moveable, true if contained, false if not
+ ScriptReserved_GetName, &Volume::GetActive,
ScriptReserved_IsMoveableInside, &Volume::IsMoveableInside);
}
-void Volume::Enable()
+/// Get the unique string identifier of this volume.
+// @function Volume:GetName()
+// @treturn string Name.
+std::string Volume::GetName() const
{
- m_volume.Enabled = true;
-}
-
-void Volume::Disable()
-{
- ClearActivators();
- m_volume.Enabled = false;
-}
-
-bool Volume::GetActive() const
-{
- return m_volume.Enabled;
+ return _volume.Name;
}
+/// Get the position of this volume.
+// @function Volume:GetPosition()
+// @treturn Vec3 Position.
Vec3 Volume::GetPos() const
{
- return Vec3(m_volume.Box.Center.x, m_volume.Box.Center.y, m_volume.Box.Center.z);
-}
-
-void Volume::SetPos(const Vec3& pos)
-{
- m_volume.Box.Center =
- m_volume.Sphere.Center = Vector3i(pos).ToVector3();
+ return Vec3(_volume.Box.Center.x, _volume.Box.Center.y, _volume.Box.Center.z);
}
+/// Get the rotation of this volume.
+// @function Volume:GetRotation()
+// @treturn Rotation Rotation.
Rotation Volume::GetRot() const
{
- auto eulers = EulerAngles(m_volume.Box.Orientation);
+ auto eulers = EulerAngles(_volume.Box.Orientation);
return Rotation(TO_DEGREES(eulers.x), TO_DEGREES(eulers.y), TO_DEGREES(eulers.z));
}
-void Volume::SetRot(const Rotation& rot)
-{
- auto eulers = EulerAngles(ANGLE(rot.x), ANGLE(rot.y), ANGLE(rot.z));
- m_volume.Box.Orientation = eulers.ToQuaternion();
-}
-
+/// Get this scale of this volume.
+// @function Volume:GetScale()
+// @treturn Vec3 Scale.
Vec3 Volume::GetScale() const
{
- return Vec3((Vector3)m_volume.Box.Extents);
-}
-
-void Volume::SetScale(const Vec3& scale)
-{
- m_volume.Box.Extents = Vector3(scale.x, scale.y, scale.z);
- m_volume.Sphere.Radius = m_volume.Box.Extents.x;
-}
-
-std::string Volume::GetName() const
-{
- return m_volume.Name;
+ return Vec3((Vector3)_volume.Box.Extents);
}
+/// Set the unique string identifier of this volume.
+// @function Volume:SetName()
+// @tparam string name New name.
void Volume::SetName(const std::string& name)
{
- if (!ScriptAssert(!name.empty(), "Name cannot be blank. Not setting name."))
+ if (!ScriptAssert(!name.empty(), "Attempted to set name to blank string."))
return;
- if (s_callbackSetName(name, m_volume))
+ // Remove previous name if it exists.
+ if (s_callbackSetName(name, _volume))
{
- // Remove the old name if we have one.
- s_callbackRemoveName(m_volume.Name);
- m_volume.Name = name;
+ s_callbackRemoveName(_volume.Name);
+ _volume.Name = name;
}
else
{
- ScriptAssertF(false, "Could not add name {} - does an object with this name already exist?", name);
- TENLog("Name will not be set", LogLevel::Warning, LogConfig::All);
+ ScriptAssertF(false, "Could not add name {}. Object with this name may already exist.", name);
+ TENLog("Name not set.", LogLevel::Warning, LogConfig::All);
}
}
-void Volume::ClearActivators()
+/// Set the position of this volume.
+// @function Volume:SetPosition()
+// @tparam Vec3 pos New position.
+void Volume::SetPos(const Vec3& pos)
{
- m_volume.StateQueue.clear();
+ _volume.Box.Center =
+ _volume.Sphere.Center = pos.ToVector3();
}
-bool Volume::IsMoveableInside(const Moveable& moveable)
+/// Set the rotation of this volume.
+// @function Volume:SetRotation()
+// @tparam Rotation rot New rotation.
+void Volume::SetRot(const Rotation& rot)
{
- for (auto& entry : m_volume.StateQueue)
+ auto eulers = EulerAngles(ANGLE(rot.x), ANGLE(rot.y), ANGLE(rot.z));
+ _volume.Box.Orientation = eulers.ToQuaternion();
+}
+
+/// Set the scale of the volume.
+// @function Volume:SetScale()
+// @tparam Vec3 scale New scale.
+void Volume::SetScale(const Vec3& scale)
+{
+ _volume.Box.Extents = scale.ToVector3();
+ _volume.Sphere.Radius = _volume.Box.Extents.x;
+}
+
+/// Determine if this volume is active.
+// @function Volume:GetActive()
+// @treturn bool Boolean representing active status.
+bool Volume::GetActive() const
+{
+ return _volume.Enabled;
+}
+
+/// Determine if a moveable is inside this volume.
+// @function Volume:IsMoveableInside()
+// @tparam Objects.Moveable Moveable to be checked for containment.
+// @treturn bool Boolean representing containment status.
+bool Volume::IsMoveableInside(const Moveable& mov)
+{
+ for (const auto& entry : _volume.StateQueue)
{
+ // TODO: Use int, not short.
if (std::holds_alternative(entry.Activator))
{
- short id = std::get(entry.Activator);
- auto& mov = std::make_unique(id);
+ int id = std::get(entry.Activator);
+ auto& mov2 = std::make_unique(id);
- if (mov.get()->GetName() == moveable.GetName())
+ if (mov2.get()->GetName() == mov.GetName())
return true;
}
}
return false;
}
+
+/// Enable this volume.
+// @function Volume:Enable()
+void Volume::Enable()
+{
+ _volume.Enabled = true;
+}
+
+/// Disable this volume.
+// @function Volume:Disable()
+void Volume::Disable()
+{
+ ClearActivators();
+ _volume.Enabled = false;
+}
+
+/// Clear the activators for this volume, allowing it to trigger again.
+// @function Volume:ClearActivators()
+void Volume::ClearActivators()
+{
+ _volume.StateQueue.clear();
+}
diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Volume/VolumeObject.h b/TombEngine/Scripting/Internal/TEN/Objects/Volume/VolumeObject.h
index fba9bb0ec..12c463632 100644
--- a/TombEngine/Scripting/Internal/TEN/Objects/Volume/VolumeObject.h
+++ b/TombEngine/Scripting/Internal/TEN/Objects/Volume/VolumeObject.h
@@ -9,31 +9,40 @@ class Vec3;
class Volume : public NamedBase
{
+private:
+ TriggerVolume& _volume;
+
public:
using IdentifierType = std::reference_wrapper;
- Volume(TriggerVolume& volume);
- ~Volume() = default;
-
- Volume& operator =(const Volume& other) = delete;
- Volume(const Volume& other) = delete;
static void Register(sol::table& parent);
+ // Cosntructors and destructors
+ Volume(TriggerVolume& volume);
+ Volume(const Volume& other) = delete;
+ ~Volume() = default;
+
+ // Getters
+ std::string GetName() const;
+ Vec3 GetPos() const;
+ Rotation GetRot() const;
+ Vec3 GetScale() const;
+
+ // Setters
+ void SetName(const std::string& name);
+ void SetRot(const Rotation& rot);
+ void SetPos(const Vec3& pos);
+ void SetScale(const Vec3& scale);
+
+ // Inquirers
+ bool GetActive() const;
+ bool IsMoveableInside(const Moveable& mov);
+
+ // Utilities
void Enable();
void Disable();
- [[nodiscard]] bool GetActive() const;
- [[nodiscard]] Rotation GetRot() const;
- void SetRot(const Rotation& rot);
- [[nodiscard]] Vec3 GetPos() const;
- void SetPos(const Vec3& pos);
- [[nodiscard]] Vec3 GetScale() const;
- void SetScale(const Vec3& scale);
- [[nodiscard]] std::string GetName() const;
- void SetName(const std::string& name);
-
void ClearActivators();
- [[nodiscard]] bool IsMoveableInside(const Moveable& moveable);
-private:
- TriggerVolume& m_volume;
+ // Operators
+ Volume& operator =(const Volume& other) = delete;
};
diff --git a/TombEngine/Specific/clock.cpp b/TombEngine/Specific/clock.cpp
index 4812b9511..6f79c529c 100644
--- a/TombEngine/Specific/clock.cpp
+++ b/TombEngine/Specific/clock.cpp
@@ -1,52 +1,68 @@
#include "framework.h"
#include "Specific/clock.h"
-LARGE_INTEGER PerformanceCount;
-double LdFreq;
-double LdSync;
+// Globals
+LARGE_INTEGER PerformanceCount = {};
+double LdFreq = 0.0;
+double LdSync = 0.0;
+
+int Sync()
+{
+ auto ct = LARGE_INTEGER{};
+ QueryPerformanceCounter(&ct);
+
+ double dCounter = (double)ct.LowPart + (double)ct.HighPart * (double)0xffffffff;
+ dCounter /= LdFreq;
+
+ long gameFrames = (long)dCounter - (long)LdSync;
+ LdSync = dCounter;
+ return gameFrames;
+}
bool TimeReset()
{
- LARGE_INTEGER fq;
+ auto fq = LARGE_INTEGER{};
QueryPerformanceCounter(&fq);
- LdSync = (double)fq.LowPart + (double)fq.HighPart * (double)0xffffffff;
+
+ LdSync = (double)fq.LowPart + ((double)fq.HighPart * (double)0xffffffff);
LdSync /= LdFreq;
return true;
}
bool TimeInit()
{
- LARGE_INTEGER fq;
+ auto fq = LARGE_INTEGER{};
if (!QueryPerformanceFrequency(&fq))
return false;
- LdFreq = (double)fq.LowPart + (double)fq.HighPart * (double)0xFFFFFFFF;
+
+ LdFreq = (double)fq.LowPart + ((double)fq.HighPart * (double)0xffffffff);
LdFreq /= 60.0;
TimeReset();
return true;
}
-int Sync()
+GameTime GetGameTime(int ticks)
{
- LARGE_INTEGER ct;
- double dCounter;
- QueryPerformanceCounter(&ct);
- dCounter = (double)ct.LowPart + (double)ct.HighPart * (double)0xFFFFFFFF;
- dCounter /= LdFreq;
- long nFrames = long(dCounter) - long(LdSync);
- LdSync = dCounter;
- return nFrames;
+ auto gameTime = GameTime{};
+ int seconds = ticks / FPS;
+
+ gameTime.Days = (seconds / (DAY_UNIT * SQUARE(TIME_UNIT)));
+ gameTime.Hours = (seconds % (DAY_UNIT * SQUARE(TIME_UNIT))) / SQUARE(TIME_UNIT);
+ gameTime.Minutes = (seconds / TIME_UNIT) % TIME_UNIT;
+ gameTime.Seconds = seconds % TIME_UNIT;
+ return gameTime;
}
-GameTime GetGameTime(int frameCount)
+bool TestGlobalTimeInterval(float intervalSecs, float offsetSecs)
{
- GameTime result = {};
+ int intervalGameFrames = (int)round(intervalSecs * FPS);
+ int offsetGameFrames = (int)round(offsetSecs * FPS);
- auto seconds = GameTimer / FPS;
+ if (offsetGameFrames >= intervalGameFrames)
+ {
+ TENLog("TestGlobalTimeInterval(): interval must be greater than offset.", LogLevel::Warning);
+ return false;
+ }
- result.Days = (seconds / (DAY_UNIT * TIME_UNIT * TIME_UNIT));
- result.Hours = (seconds % (DAY_UNIT * TIME_UNIT * TIME_UNIT)) / (TIME_UNIT * TIME_UNIT);
- result.Minutes = (seconds / TIME_UNIT) % TIME_UNIT;
- result.Seconds = (seconds % TIME_UNIT);
-
- return result;
-}
\ No newline at end of file
+ return ((GlobalCounter % intervalGameFrames) == offsetGameFrames);
+}
diff --git a/TombEngine/Specific/clock.h b/TombEngine/Specific/clock.h
index 2fd36373b..883b89085 100644
--- a/TombEngine/Specific/clock.h
+++ b/TombEngine/Specific/clock.h
@@ -11,14 +11,16 @@ constexpr auto DAY_UNIT = 24;
struct GameTime
{
- int Days;
- int Hours;
- int Minutes;
- int Seconds;
+ int Days = 0;
+ int Hours = 0;
+ int Minutes = 0;
+ int Seconds = 0;
};
-int Sync();
+int Sync();
bool TimeInit();
bool TimeReset();
-GameTime GetGameTime(int frameCount);
+GameTime GetGameTime(int ticks);
+
+bool TestGlobalTimeInterval(float intervalSecs, float offsetSecs = 0.0f);
diff --git a/TombEngine/Specific/level.cpp b/TombEngine/Specific/level.cpp
index d355ac0bc..3cccca52a 100644
--- a/TombEngine/Specific/level.cpp
+++ b/TombEngine/Specific/level.cpp
@@ -38,8 +38,8 @@ using namespace TEN::Utils;
const std::vector BRIDGE_OBJECT_IDS =
{
ID_EXPANDING_PLATFORM,
- ID_SQUISHY_BLOCK1,
- ID_SQUISHY_BLOCK2,
+ ID_SQUISHY_BLOCK_HORIZONTAL,
+ ID_SQUISHY_BLOCK_VERTICAL,
ID_FALLING_BLOCK,
ID_FALLING_BLOCK2,
@@ -205,7 +205,7 @@ void LoadItems()
if (g_Level.NumItems == 0)
return;
- InitializeItemArray(NUM_ITEMS);
+ InitializeItemArray(ITEM_COUNT_MAX);
if (g_Level.NumItems > 0)
{
@@ -499,6 +499,7 @@ void LoadCameras()
NumberSpotcams = ReadInt32();
+ // TODO: Read properly!
if (NumberSpotcams != 0)
ReadBytes(SpotCam, NumberSpotcams * sizeof(SPOTCAM));
@@ -907,8 +908,8 @@ void ReadRooms()
room.reverbType = (ReverbType)ReadInt32();
room.flipNumber = ReadInt32();
- room.itemNumber = NO_ITEM;
- room.fxNumber = NO_ITEM;
+ room.itemNumber = NO_VALUE;
+ room.fxNumber = NO_VALUE;
room.index = i;
g_GameScriptEntities->AddName(room.name, room);
@@ -1463,7 +1464,7 @@ void LoadSprites()
void GetCarriedItems()
{
for (int i = 0; i < g_Level.NumItems; ++i)
- g_Level.Items[i].CarriedItem = NO_ITEM;
+ g_Level.Items[i].CarriedItem = NO_VALUE;
for (int i = 0; i < g_Level.NumItems; ++i)
{
@@ -1473,7 +1474,7 @@ void GetCarriedItems()
if (object.intelligent ||
(item.ObjectNumber >= ID_SEARCH_OBJECT1 && item.ObjectNumber <= ID_SEARCH_OBJECT3))
{
- for (short linkNumber = g_Level.Rooms[item.RoomNumber].itemNumber; linkNumber != NO_ITEM; linkNumber = g_Level.Items[linkNumber].NextItem)
+ for (short linkNumber = g_Level.Rooms[item.RoomNumber].itemNumber; linkNumber != NO_VALUE; linkNumber = g_Level.Items[linkNumber].NextItem)
{
auto& item2 = g_Level.Items[linkNumber];
diff --git a/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h b/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h
index 2fa321185..de658eaa8 100644
--- a/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h
+++ b/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h
@@ -149,6 +149,10 @@ struct Volume;
struct VolumeBuilder;
struct VolumeT;
+struct FishData;
+struct FishDataBuilder;
+struct FishDataT;
+
struct KeyValPair;
struct ScriptTable;
@@ -5877,6 +5881,185 @@ inline flatbuffers::Offset CreateVolumeDirect(
flatbuffers::Offset CreateVolume(flatbuffers::FlatBufferBuilder &_fbb, const VolumeT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+struct FishDataT : public flatbuffers::NativeTable {
+ typedef FishData TableType;
+ bool is_patrolling = false;
+ bool is_lethal = false;
+ int32_t leader_item_number = 0;
+ float life = 0.0f;
+ int32_t mesh_index = 0;
+ std::unique_ptr orientation{};
+ std::unique_ptr position{};
+ std::unique_ptr position_target{};
+ int32_t room_number = 0;
+ int32_t target_item_number = 0;
+ float undulation = 0.0f;
+ float velocity = 0.0f;
+};
+
+struct FishData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef FishDataT NativeTableType;
+ typedef FishDataBuilder Builder;
+ struct Traits;
+ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+ VT_IS_PATROLLING = 4,
+ VT_IS_LETHAL = 6,
+ VT_LEADER_ITEM_NUMBER = 8,
+ VT_LIFE = 10,
+ VT_MESH_INDEX = 12,
+ VT_ORIENTATION = 14,
+ VT_POSITION = 16,
+ VT_POSITION_TARGET = 18,
+ VT_ROOM_NUMBER = 20,
+ VT_TARGET_ITEM_NUMBER = 22,
+ VT_UNDULATION = 24,
+ VT_VELOCITY = 26
+ };
+ bool is_patrolling() const {
+ return GetField(VT_IS_PATROLLING, 0) != 0;
+ }
+ bool is_lethal() const {
+ return GetField(VT_IS_LETHAL, 0) != 0;
+ }
+ int32_t leader_item_number() const {
+ return GetField(VT_LEADER_ITEM_NUMBER, 0);
+ }
+ float life() const {
+ return GetField(VT_LIFE, 0.0f);
+ }
+ int32_t mesh_index() const {
+ return GetField(VT_MESH_INDEX, 0);
+ }
+ const TEN::Save::EulerAngles *orientation() const {
+ return GetStruct(VT_ORIENTATION);
+ }
+ const TEN::Save::Vector3 *position() const {
+ return GetStruct(VT_POSITION);
+ }
+ const TEN::Save::Vector3 *position_target() const {
+ return GetStruct(VT_POSITION_TARGET);
+ }
+ int32_t room_number() const {
+ return GetField(VT_ROOM_NUMBER, 0);
+ }
+ int32_t target_item_number() const {
+ return GetField(VT_TARGET_ITEM_NUMBER, 0);
+ }
+ float undulation() const {
+ return GetField(VT_UNDULATION, 0.0f);
+ }
+ float velocity() const {
+ return GetField(VT_VELOCITY, 0.0f);
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ VerifyField(verifier, VT_IS_PATROLLING) &&
+ VerifyField(verifier, VT_IS_LETHAL) &&
+ VerifyField(verifier, VT_LEADER_ITEM_NUMBER) &&
+ VerifyField(verifier, VT_LIFE) &&
+ VerifyField(verifier, VT_MESH_INDEX) &&
+ VerifyField(verifier, VT_ORIENTATION) &&
+ VerifyField(verifier, VT_POSITION) &&
+ VerifyField(verifier, VT_POSITION_TARGET) &&
+ VerifyField(verifier, VT_ROOM_NUMBER) &&
+ VerifyField(verifier, VT_TARGET_ITEM_NUMBER) &&
+ VerifyField(verifier, VT_UNDULATION) &&
+ VerifyField(verifier, VT_VELOCITY) &&
+ verifier.EndTable();
+ }
+ FishDataT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ void UnPackTo(FishDataT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const FishDataT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct FishDataBuilder {
+ typedef FishData Table;
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ void add_is_patrolling(bool is_patrolling) {
+ fbb_.AddElement(FishData::VT_IS_PATROLLING, static_cast(is_patrolling), 0);
+ }
+ void add_is_lethal(bool is_lethal) {
+ fbb_.AddElement(FishData::VT_IS_LETHAL, static_cast(is_lethal), 0);
+ }
+ void add_leader_item_number(int32_t leader_item_number) {
+ fbb_.AddElement(FishData::VT_LEADER_ITEM_NUMBER, leader_item_number, 0);
+ }
+ void add_life(float life) {
+ fbb_.AddElement(FishData::VT_LIFE, life, 0.0f);
+ }
+ void add_mesh_index(int32_t mesh_index) {
+ fbb_.AddElement(FishData::VT_MESH_INDEX, mesh_index, 0);
+ }
+ void add_orientation(const TEN::Save::EulerAngles *orientation) {
+ fbb_.AddStruct(FishData::VT_ORIENTATION, orientation);
+ }
+ void add_position(const TEN::Save::Vector3 *position) {
+ fbb_.AddStruct(FishData::VT_POSITION, position);
+ }
+ void add_position_target(const TEN::Save::Vector3 *position_target) {
+ fbb_.AddStruct(FishData::VT_POSITION_TARGET, position_target);
+ }
+ void add_room_number(int32_t room_number) {
+ fbb_.AddElement(FishData::VT_ROOM_NUMBER, room_number, 0);
+ }
+ void add_target_item_number(int32_t target_item_number) {
+ fbb_.AddElement(FishData::VT_TARGET_ITEM_NUMBER, target_item_number, 0);
+ }
+ void add_undulation(float undulation) {
+ fbb_.AddElement(FishData::VT_UNDULATION, undulation, 0.0f);
+ }
+ void add_velocity(float velocity) {
+ fbb_.AddElement(FishData::VT_VELOCITY, velocity, 0.0f);
+ }
+ explicit FishDataBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ flatbuffers::Offset Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset(end);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset CreateFishData(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ bool is_patrolling = false,
+ bool is_lethal = false,
+ int32_t leader_item_number = 0,
+ float life = 0.0f,
+ int32_t mesh_index = 0,
+ const TEN::Save::EulerAngles *orientation = 0,
+ const TEN::Save::Vector3 *position = 0,
+ const TEN::Save::Vector3 *position_target = 0,
+ int32_t room_number = 0,
+ int32_t target_item_number = 0,
+ float undulation = 0.0f,
+ float velocity = 0.0f) {
+ FishDataBuilder builder_(_fbb);
+ builder_.add_velocity(velocity);
+ builder_.add_undulation(undulation);
+ builder_.add_target_item_number(target_item_number);
+ builder_.add_room_number(room_number);
+ builder_.add_position_target(position_target);
+ builder_.add_position(position);
+ builder_.add_orientation(orientation);
+ builder_.add_mesh_index(mesh_index);
+ builder_.add_life(life);
+ builder_.add_leader_item_number(leader_item_number);
+ builder_.add_is_lethal(is_lethal);
+ builder_.add_is_patrolling(is_patrolling);
+ return builder_.Finish();
+}
+
+struct FishData::Traits {
+ using type = FishData;
+ static auto constexpr Create = CreateFishData;
+};
+
+flatbuffers::Offset CreateFishData(flatbuffers::FlatBufferBuilder &_fbb, const FishDataT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
struct ScriptTableT : public flatbuffers::NativeTable {
typedef ScriptTable TableType;
std::vector keys_vals{};
@@ -6925,6 +7108,7 @@ struct SaveGameT : public flatbuffers::NativeTable {
int32_t next_item_free = 0;
int32_t next_item_active = 0;
std::vector room_items{};
+ std::vector> fish_swarm{};
std::vector> fxinfos{};
int32_t next_fx_free = 0;
int32_t next_fx_active = 0;
@@ -6983,48 +7167,49 @@ struct SaveGame FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VT_NEXT_ITEM_FREE = 16,
VT_NEXT_ITEM_ACTIVE = 18,
VT_ROOM_ITEMS = 20,
- VT_FXINFOS = 22,
- VT_NEXT_FX_FREE = 24,
- VT_NEXT_FX_ACTIVE = 26,
- VT_FIXED_CAMERAS = 28,
- VT_SINKS = 30,
- VT_STATIC_MESHES = 32,
- VT_FLYBY_CAMERAS = 34,
- VT_PARTICLES = 36,
- VT_RATS = 38,
- VT_SPIDERS = 40,
- VT_SCARABS = 42,
- VT_BATS = 44,
- VT_FLIP_MAPS = 46,
- VT_FLIP_STATS = 48,
- VT_FLIP_EFFECT = 50,
- VT_FLIP_TIMER = 52,
- VT_FLIP_STATUS = 54,
- VT_CURRENT_FOV = 56,
- VT_LAST_INV_ITEM = 58,
- VT_ACTION_QUEUE = 60,
- VT_SOUNDTRACKS = 62,
- VT_CD_FLAGS = 64,
- VT_POSTPROCESS_MODE = 66,
- VT_POSTPROCESS_STRENGTH = 68,
- VT_POSTPROCESS_TINT = 70,
- VT_ROPE = 72,
- VT_PENDULUM = 74,
- VT_ALTERNATE_PENDULUM = 76,
- VT_VOLUMES = 78,
- VT_GLOBAL_EVENT_SETS = 80,
- VT_VOLUME_EVENT_SETS = 82,
- VT_SCRIPT_VARS = 84,
- VT_CALLBACKS_PRE_START = 86,
- VT_CALLBACKS_POST_START = 88,
- VT_CALLBACKS_PRE_END = 90,
- VT_CALLBACKS_POST_END = 92,
- VT_CALLBACKS_PRE_SAVE = 94,
- VT_CALLBACKS_POST_SAVE = 96,
- VT_CALLBACKS_PRE_LOAD = 98,
- VT_CALLBACKS_POST_LOAD = 100,
- VT_CALLBACKS_PRE_LOOP = 102,
- VT_CALLBACKS_POST_LOOP = 104
+ VT_FISH_SWARM = 22,
+ VT_FXINFOS = 24,
+ VT_NEXT_FX_FREE = 26,
+ VT_NEXT_FX_ACTIVE = 28,
+ VT_FIXED_CAMERAS = 30,
+ VT_SINKS = 32,
+ VT_STATIC_MESHES = 34,
+ VT_FLYBY_CAMERAS = 36,
+ VT_PARTICLES = 38,
+ VT_RATS = 40,
+ VT_SPIDERS = 42,
+ VT_SCARABS = 44,
+ VT_BATS = 46,
+ VT_FLIP_MAPS = 48,
+ VT_FLIP_STATS = 50,
+ VT_FLIP_EFFECT = 52,
+ VT_FLIP_TIMER = 54,
+ VT_FLIP_STATUS = 56,
+ VT_CURRENT_FOV = 58,
+ VT_LAST_INV_ITEM = 60,
+ VT_ACTION_QUEUE = 62,
+ VT_SOUNDTRACKS = 64,
+ VT_CD_FLAGS = 66,
+ VT_POSTPROCESS_MODE = 68,
+ VT_POSTPROCESS_STRENGTH = 70,
+ VT_POSTPROCESS_TINT = 72,
+ VT_ROPE = 74,
+ VT_PENDULUM = 76,
+ VT_ALTERNATE_PENDULUM = 78,
+ VT_VOLUMES = 80,
+ VT_GLOBAL_EVENT_SETS = 82,
+ VT_VOLUME_EVENT_SETS = 84,
+ VT_SCRIPT_VARS = 86,
+ VT_CALLBACKS_PRE_START = 88,
+ VT_CALLBACKS_POST_START = 90,
+ VT_CALLBACKS_PRE_END = 92,
+ VT_CALLBACKS_POST_END = 94,
+ VT_CALLBACKS_PRE_SAVE = 96,
+ VT_CALLBACKS_POST_SAVE = 98,
+ VT_CALLBACKS_PRE_LOAD = 100,
+ VT_CALLBACKS_POST_LOAD = 102,
+ VT_CALLBACKS_PRE_LOOP = 104,
+ VT_CALLBACKS_POST_LOOP = 106
};
const TEN::Save::SaveGameHeader *header() const {
return GetPointer(VT_HEADER);
@@ -7053,6 +7238,9 @@ struct SaveGame FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
const flatbuffers::Vector *room_items() const {
return GetPointer *>(VT_ROOM_ITEMS);
}
+ const flatbuffers::Vector> *fish_swarm() const {
+ return GetPointer> *>(VT_FISH_SWARM);
+ }
const flatbuffers::Vector> *fxinfos() const {
return GetPointer> *>(VT_FXINFOS);
}
@@ -7199,6 +7387,9 @@ struct SaveGame FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VerifyField(verifier, VT_NEXT_ITEM_ACTIVE) &&
VerifyOffset(verifier, VT_ROOM_ITEMS) &&
verifier.VerifyVector(room_items()) &&
+ VerifyOffset(verifier, VT_FISH_SWARM) &&
+ verifier.VerifyVector(fish_swarm()) &&
+ verifier.VerifyVectorOfTables(fish_swarm()) &&
VerifyOffset(verifier, VT_FXINFOS) &&
verifier.VerifyVector(fxinfos()) &&
verifier.VerifyVectorOfTables(fxinfos()) &&
@@ -7335,6 +7526,9 @@ struct SaveGameBuilder {
void add_room_items(flatbuffers::Offset> room_items) {
fbb_.AddOffset(SaveGame::VT_ROOM_ITEMS, room_items);
}
+ void add_fish_swarm(flatbuffers::Offset>> fish_swarm) {
+ fbb_.AddOffset(SaveGame::VT_FISH_SWARM, fish_swarm);
+ }
void add_fxinfos(flatbuffers::Offset>> fxinfos) {
fbb_.AddOffset(SaveGame::VT_FXINFOS, fxinfos);
}
@@ -7483,6 +7677,7 @@ inline flatbuffers::Offset CreateSaveGame(
int32_t next_item_free = 0,
int32_t next_item_active = 0,
flatbuffers::Offset> room_items = 0,
+ flatbuffers::Offset>> fish_swarm = 0,
flatbuffers::Offset>> fxinfos = 0,
int32_t next_fx_free = 0,
int32_t next_fx_active = 0,
@@ -7567,6 +7762,7 @@ inline flatbuffers::Offset CreateSaveGame(
builder_.add_next_fx_active(next_fx_active);
builder_.add_next_fx_free(next_fx_free);
builder_.add_fxinfos(fxinfos);
+ builder_.add_fish_swarm(fish_swarm);
builder_.add_room_items(room_items);
builder_.add_next_item_active(next_item_active);
builder_.add_next_item_free(next_item_free);
@@ -7596,6 +7792,7 @@ inline flatbuffers::Offset CreateSaveGameDirect(
int32_t next_item_free = 0,
int32_t next_item_active = 0,
const std::vector *room_items = nullptr,
+ const std::vector> *fish_swarm = nullptr,
const std::vector> *fxinfos = nullptr,
int32_t next_fx_free = 0,
int32_t next_fx_active = 0,
@@ -7641,6 +7838,7 @@ inline flatbuffers::Offset CreateSaveGameDirect(
auto rooms__ = rooms ? _fbb.CreateVector>(*rooms) : 0;
auto items__ = items ? _fbb.CreateVector>(*items) : 0;
auto room_items__ = room_items ? _fbb.CreateVector(*room_items) : 0;
+ auto fish_swarm__ = fish_swarm ? _fbb.CreateVector>(*fish_swarm) : 0;
auto fxinfos__ = fxinfos ? _fbb.CreateVector>(*fxinfos) : 0;
auto fixed_cameras__ = fixed_cameras ? _fbb.CreateVector>(*fixed_cameras) : 0;
auto sinks__ = sinks ? _fbb.CreateVector>(*sinks) : 0;
@@ -7680,6 +7878,7 @@ inline flatbuffers::Offset CreateSaveGameDirect(
next_item_free,
next_item_active,
room_items__,
+ fish_swarm__,
fxinfos__,
next_fx_free,
next_fx_active,
@@ -9387,6 +9586,65 @@ inline flatbuffers::Offset CreateVolume(flatbuffers::FlatBufferBuilder &
_queue);
}
+inline FishDataT *FishData::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+ auto _o = std::make_unique();
+ UnPackTo(_o.get(), _resolver);
+ return _o.release();
+}
+
+inline void FishData::UnPackTo(FishDataT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+ (void)_o;
+ (void)_resolver;
+ { auto _e = is_patrolling(); _o->is_patrolling = _e; }
+ { auto _e = is_lethal(); _o->is_lethal = _e; }
+ { auto _e = leader_item_number(); _o->leader_item_number = _e; }
+ { auto _e = life(); _o->life = _e; }
+ { auto _e = mesh_index(); _o->mesh_index = _e; }
+ { auto _e = orientation(); if (_e) _o->orientation = std::unique_ptr(new TEN::Save::EulerAngles(*_e)); }
+ { auto _e = position(); if (_e) _o->position = std::unique_ptr(new TEN::Save::Vector3(*_e)); }
+ { auto _e = position_target(); if (_e) _o->position_target = std::unique_ptr(new TEN::Save::Vector3(*_e)); }
+ { auto _e = room_number(); _o->room_number = _e; }
+ { auto _e = target_item_number(); _o->target_item_number = _e; }
+ { auto _e = undulation(); _o->undulation = _e; }
+ { auto _e = velocity(); _o->velocity = _e; }
+}
+
+inline flatbuffers::Offset FishData::Pack(flatbuffers::FlatBufferBuilder &_fbb, const FishDataT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+ return CreateFishData(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset CreateFishData(flatbuffers::FlatBufferBuilder &_fbb, const FishDataT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+ (void)_rehasher;
+ (void)_o;
+ struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const FishDataT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+ auto _is_patrolling = _o->is_patrolling;
+ auto _is_lethal = _o->is_lethal;
+ auto _leader_item_number = _o->leader_item_number;
+ auto _life = _o->life;
+ auto _mesh_index = _o->mesh_index;
+ auto _orientation = _o->orientation ? _o->orientation.get() : 0;
+ auto _position = _o->position ? _o->position.get() : 0;
+ auto _position_target = _o->position_target ? _o->position_target.get() : 0;
+ auto _room_number = _o->room_number;
+ auto _target_item_number = _o->target_item_number;
+ auto _undulation = _o->undulation;
+ auto _velocity = _o->velocity;
+ return TEN::Save::CreateFishData(
+ _fbb,
+ _is_patrolling,
+ _is_lethal,
+ _leader_item_number,
+ _life,
+ _mesh_index,
+ _orientation,
+ _position,
+ _position_target,
+ _room_number,
+ _target_item_number,
+ _undulation,
+ _velocity);
+}
+
inline ScriptTableT *ScriptTable::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
auto _o = std::make_unique();
UnPackTo(_o.get(), _resolver);
@@ -9785,6 +10043,7 @@ inline void SaveGame::UnPackTo(SaveGameT *_o, const flatbuffers::resolver_functi
{ auto _e = next_item_free(); _o->next_item_free = _e; }
{ auto _e = next_item_active(); _o->next_item_active = _e; }
{ auto _e = room_items(); if (_e) { _o->room_items.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->room_items[_i] = _e->Get(_i); } } }
+ { auto _e = fish_swarm(); if (_e) { _o->fish_swarm.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->fish_swarm[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } }
{ auto _e = fxinfos(); if (_e) { _o->fxinfos.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->fxinfos[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } }
{ auto _e = next_fx_free(); _o->next_fx_free = _e; }
{ auto _e = next_fx_active(); _o->next_fx_active = _e; }
@@ -9846,6 +10105,7 @@ inline flatbuffers::Offset CreateSaveGame(flatbuffers::FlatBufferBuild
auto _next_item_free = _o->next_item_free;
auto _next_item_active = _o->next_item_active;
auto _room_items = _fbb.CreateVector(_o->room_items);
+ auto _fish_swarm = _fbb.CreateVector> (_o->fish_swarm.size(), [](size_t i, _VectorArgs *__va) { return CreateFishData(*__va->__fbb, __va->__o->fish_swarm[i].get(), __va->__rehasher); }, &_va );
auto _fxinfos = _fbb.CreateVector> (_o->fxinfos.size(), [](size_t i, _VectorArgs *__va) { return CreateFXInfo(*__va->__fbb, __va->__o->fxinfos[i].get(), __va->__rehasher); }, &_va );
auto _next_fx_free = _o->next_fx_free;
auto _next_fx_active = _o->next_fx_active;
@@ -9899,6 +10159,7 @@ inline flatbuffers::Offset CreateSaveGame(flatbuffers::FlatBufferBuild
_next_item_free,
_next_item_active,
_room_items,
+ _fish_swarm,
_fxinfos,
_next_fx_free,
_next_fx_active,
diff --git a/TombEngine/Specific/savegame/schema/ten_savegame.fbs b/TombEngine/Specific/savegame/schema/ten_savegame.fbs
index 2d6a93de2..2c67b42ec 100644
--- a/TombEngine/Specific/savegame/schema/ten_savegame.fbs
+++ b/TombEngine/Specific/savegame/schema/ten_savegame.fbs
@@ -411,6 +411,21 @@ table Volume {
queue: [VolumeState];
}
+table FishData {
+ is_patrolling: bool;
+ is_lethal: bool;
+ leader_item_number: int32;
+ life: float;
+ mesh_index: int32;
+ orientation: EulerAngles;
+ position: Vector3;
+ position_target: Vector3;
+ room_number: int32;
+ target_item_number: int32;
+ undulation: float;
+ velocity: float;
+}
+
struct KeyValPair {
key: uint32;
val: uint32;
@@ -503,6 +518,7 @@ table SaveGame {
next_item_free: int32;
next_item_active: int32;
room_items: [int32];
+ fish_swarm: [FishData];
fxinfos: [FXInfo];
next_fx_free: int32;
next_fx_active: int32;
diff --git a/TombEngine/TombEngine.vcxproj b/TombEngine/TombEngine.vcxproj
index e4612b226..94bbf469b 100644
--- a/TombEngine/TombEngine.vcxproj
+++ b/TombEngine/TombEngine.vcxproj
@@ -526,6 +526,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
+
@@ -535,7 +536,6 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
-
@@ -563,7 +563,6 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
-
@@ -607,6 +606,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
+
@@ -1033,6 +1033,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
+
@@ -1040,7 +1041,6 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
-
@@ -1107,6 +1107,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
+
From 146c89b88866071630bb1b7c86b23dabb39f7651 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Tue, 16 Apr 2024 09:15:00 +0200
Subject: [PATCH 077/410] Added interpolation for. - splashed - ripples - blood
- drips - underwater dust - rain - snow - shockwaves - all effects based on
Particle class
---
TombEngine/Game/Setup.cpp | 4 +-
TombEngine/Game/effects/Blood.cpp | 2 +
TombEngine/Game/effects/Blood.h | 10 ++
TombEngine/Game/effects/Ripple.cpp | 2 +
TombEngine/Game/effects/Ripple.h | 11 ++
TombEngine/Game/effects/bubble.cpp | 2 +
TombEngine/Game/effects/bubble.h | 13 ++
TombEngine/Game/effects/chaffFX.cpp | 2 +-
TombEngine/Game/effects/drip.cpp | 2 +
TombEngine/Game/effects/drip.h | 15 ++
TombEngine/Game/effects/effects.cpp | 4 +
TombEngine/Game/effects/effects.h | 53 ++++++--
TombEngine/Game/effects/tomb4fx.cpp | 21 ++-
TombEngine/Game/effects/tomb4fx.h | 54 +++++++-
TombEngine/Game/effects/weather.cpp | 2 +
TombEngine/Game/effects/weather.h | 13 ++
TombEngine/Renderer/RendererDraw.cpp | 2 +-
TombEngine/Renderer/RendererDrawEffect.cpp | 151 ++++++++++++++++-----
18 files changed, 297 insertions(+), 66 deletions(-)
diff --git a/TombEngine/Game/Setup.cpp b/TombEngine/Game/Setup.cpp
index 20eaa6b14..a427dfe71 100644
--- a/TombEngine/Game/Setup.cpp
+++ b/TombEngine/Game/Setup.cpp
@@ -135,8 +135,8 @@ void InitializeGameFlags()
void InitializeSpecialEffects()
{
memset(&FireSparks, 0, MAX_SPARKS_FIRE * sizeof(FIRE_SPARKS));
- memset(&SmokeSparks, 0, MAX_SPARKS_SMOKE * sizeof(SmokeSparkInfo));
- memset(&Gunshells, 0, MAX_GUNSHELL * sizeof(GunshellInfo));
+ memset(&SmokeSparks, 0, MAX_SPARKS_SMOKE * sizeof(SMOKE_SPARKS));
+ memset(&Gunshells, 0, MAX_GUNSHELL * sizeof(GUNSHELL_STRUCT));
memset(&Blood, 0, MAX_SPARKS_BLOOD * sizeof(BLOOD_STRUCT));
memset(&Splashes, 0, MAX_SPLASHES * sizeof(SPLASH_STRUCT));
memset(&ShockWaves, 0, MAX_SHOCKWAVE * sizeof(SHOCKWAVE_STRUCT));
diff --git a/TombEngine/Game/effects/Blood.cpp b/TombEngine/Game/effects/Blood.cpp
index 9c46f2653..1d215db83 100644
--- a/TombEngine/Game/effects/Blood.cpp
+++ b/TombEngine/Game/effects/Blood.cpp
@@ -58,6 +58,8 @@ namespace TEN::Effects::Blood
if (uwBlood.Life <= 0.0f)
continue;
+ uwBlood.StoreInterpolationData();
+
// Update size.
if (uwBlood.Size < UW_BLOOD_SIZE_MAX)
uwBlood.Size += 4.0f;
diff --git a/TombEngine/Game/effects/Blood.h b/TombEngine/Game/effects/Blood.h
index 820f269d0..37939810b 100644
--- a/TombEngine/Game/effects/Blood.h
+++ b/TombEngine/Game/effects/Blood.h
@@ -19,6 +19,16 @@ namespace TEN::Effects::Blood
Vector4 OldColor = Vector4::Zero;
float OldSize = 0.0f;
float OldOpacity = 0.0f;
+ float OldLife = 0.0f;
+
+ void StoreInterpolationData()
+ {
+ OldPosition = Position;
+ OldColor = Color;
+ OldSize = Size;
+ OldOpacity = Opacity;
+ OldLife = Life;
+ }
};
extern std::vector UnderwaterBloodParticles;
diff --git a/TombEngine/Game/effects/Ripple.cpp b/TombEngine/Game/effects/Ripple.cpp
index 982c15177..e266ef127 100644
--- a/TombEngine/Game/effects/Ripple.cpp
+++ b/TombEngine/Game/effects/Ripple.cpp
@@ -59,6 +59,8 @@ namespace TEN::Effects::Ripple
if (ripple.Life <= 0.0f)
continue;
+ ripple.StoreInterpolationData();
+
// Update size.
if (ripple.Size < RIPPLE_SIZE_MAX)
ripple.Size += (ripple.Flags & ((int)RippleFlags::SlowFade | (int)RippleFlags::OnGround)) ? SIZE_STEP_SMALL : SIZE_STEP_LARGE;
diff --git a/TombEngine/Game/effects/Ripple.h b/TombEngine/Game/effects/Ripple.h
index ad1688c2b..031301911 100644
--- a/TombEngine/Game/effects/Ripple.h
+++ b/TombEngine/Game/effects/Ripple.h
@@ -23,6 +23,17 @@ namespace TEN::Effects::Ripple
float Size = 0.0f;
float FadeDuration = 0.0f;
int Flags = 0;
+
+ Vector3 OldPosition;
+ Vector4 OldColor;
+ float OldSize;
+
+ void StoreInterpolationData()
+ {
+ OldPosition = Position;
+ OldColor = Color;
+ OldSize = Size;
+ }
};
extern std::vector Ripples;
diff --git a/TombEngine/Game/effects/bubble.cpp b/TombEngine/Game/effects/bubble.cpp
index 58f10ccf4..9dedf6592 100644
--- a/TombEngine/Game/effects/bubble.cpp
+++ b/TombEngine/Game/effects/bubble.cpp
@@ -147,6 +147,8 @@ namespace TEN::Effects::Bubble
if (bubble.Life <= 0.0f)
continue;
+ bubble.StoreInterpolationData();
+
// Update room number. TODO: Should use GetCollision(), but calling it for each bubble is very inefficient.
auto roomVector = RoomVector(bubble.RoomNumber, int(bubble.Position.y - bubble.Gravity));
int roomNumber = GetRoomVector(roomVector, Vector3i(bubble.Position.x, bubble.Position.y - bubble.Gravity, bubble.Position.z)).RoomNumber;
diff --git a/TombEngine/Game/effects/bubble.h b/TombEngine/Game/effects/bubble.h
index 4825b89cf..e410842a9 100644
--- a/TombEngine/Game/effects/bubble.h
+++ b/TombEngine/Game/effects/bubble.h
@@ -30,6 +30,19 @@ namespace TEN::Effects::Bubble
float Gravity = 0.0f;
float OscillationPeriod = 0.0f;
float OscillationVelocity = 0.0f;
+
+ Vector3 OldPosition = Vector3::Zero;
+ Vector4 OldColor = Vector4::Zero;
+ Vector2 OldSize = Vector2::Zero;
+ float OldLife = 0.0f;
+
+ void StoreInterpolationData()
+ {
+ OldPosition = Position;
+ OldColor = Color;
+ OldSize = Size;
+ OldLife = Life;
+ }
};
extern std::vector Bubbles;
diff --git a/TombEngine/Game/effects/chaffFX.cpp b/TombEngine/Game/effects/chaffFX.cpp
index 4b4674204..f3e511a89 100644
--- a/TombEngine/Game/effects/chaffFX.cpp
+++ b/TombEngine/Game/effects/chaffFX.cpp
@@ -98,7 +98,7 @@ void TriggerChaffSparkles(const Vector3i& pos, const Vector3i& vel, const Color&
void TriggerChaffSmoke(const Vector3i& pos, const Vector3i& vel, int speed, bool isMoving, bool wind)
{
- SmokeSparkInfo* smoke;
+ SMOKE_SPARKS* smoke;
int rnd = 0;
BYTE trans, size;
diff --git a/TombEngine/Game/effects/drip.cpp b/TombEngine/Game/effects/drip.cpp
index 01609b5f0..4c08fc73f 100644
--- a/TombEngine/Game/effects/drip.cpp
+++ b/TombEngine/Game/effects/drip.cpp
@@ -105,6 +105,8 @@ namespace TEN::Effects::Drip
if (drip.Life <= 0.0f)
continue;
+ drip.StoreInterpolationData();
+
// Update velocity.
drip.Velocity.y += drip.Gravity;
if (TestEnvironment(ENV_FLAG_WIND, drip.RoomNumber))
diff --git a/TombEngine/Game/effects/drip.h b/TombEngine/Game/effects/drip.h
index 52f13d39c..bb6946ab1 100644
--- a/TombEngine/Game/effects/drip.h
+++ b/TombEngine/Game/effects/drip.h
@@ -15,6 +15,21 @@ namespace TEN::Effects::Drip
float Life = 0.0f;
float LifeMax = 0.0f;
float Gravity = 0.0f;
+
+ Vector3 OldPosition = Vector3::Zero;
+ Vector4 OldColor = Vector4::Zero;
+ Vector2 OldSize = Vector2::Zero;
+ float OldLife = 0.0f;
+ Vector3 OldVelocity = Vector3::Zero;
+
+ void StoreInterpolationData()
+ {
+ OldPosition = Position;
+ OldColor = Color;
+ OldSize = Size;
+ OldLife = Life;
+ OldVelocity = Velocity;
+ }
};
extern std::vector Drips;
diff --git a/TombEngine/Game/effects/effects.cpp b/TombEngine/Game/effects/effects.cpp
index e1e04d1ab..8743543a6 100644
--- a/TombEngine/Game/effects/effects.cpp
+++ b/TombEngine/Game/effects/effects.cpp
@@ -195,6 +195,8 @@ void UpdateSparks()
if (spark->on)
{
+ spark->StoreInterpolationData();
+
spark->life--;
if (!spark->life)
@@ -1046,6 +1048,8 @@ void UpdateSplashes()
if (splash.isActive)
{
+ splash.StoreInterpolationData();
+
splash.life--;
if (splash.life <= 0)
splash.isActive = false;
diff --git a/TombEngine/Game/effects/effects.h b/TombEngine/Game/effects/effects.h
index 2b77640a0..ba45f28c4 100644
--- a/TombEngine/Game/effects/effects.h
+++ b/TombEngine/Game/effects/effects.h
@@ -110,17 +110,6 @@ struct SPLASH_SETUP
int room;
};
-struct RIPPLE_STRUCT
-{
- int x;
- int y;
- int z;
- char flags;
- unsigned char life;
- unsigned char size;
- unsigned char init;
-};
-
struct Particle
{
int x;
@@ -160,6 +149,27 @@ struct Particle
int fxObj;
int roomNumber;
unsigned char nodeNumber; // ParticleNodeOffsetIDs enum.
+
+ int oldX;
+ int oldY;
+ int oldZ;
+ short oldRotAng;
+ byte oldR;
+ byte oldG;
+ byte oldB;
+ byte oldScalar;
+
+ void StoreInterpolationData()
+ {
+ oldX = x;
+ oldY = y;
+ oldZ = z;
+ oldRotAng = rotAng;
+ oldR = r;
+ oldG = g;
+ oldB = b;
+ oldScalar = scalar;
+ }
};
struct SPLASH_STRUCT
@@ -181,6 +191,27 @@ struct SPLASH_STRUCT
unsigned short life;
bool isRipple;
bool isActive;
+
+ float oldX;
+ float oldY;
+ float oldZ;
+ float oldInnerRad;
+ float oldOuterRad;
+ float oldHeight;
+ unsigned short oldLife;
+ float oldHeightSpeed;
+
+ void StoreInterpolationData()
+ {
+ oldX = x;
+ oldY = y;
+ oldZ = z;
+ oldInnerRad = innerRad;
+ oldOuterRad = outerRad;
+ oldHeight = height;
+ oldLife = life;
+ oldHeightSpeed = heightSpeed;
+ }
};
struct ParticleDynamic
diff --git a/TombEngine/Game/effects/tomb4fx.cpp b/TombEngine/Game/effects/tomb4fx.cpp
index 886a240c4..daaf05c94 100644
--- a/TombEngine/Game/effects/tomb4fx.cpp
+++ b/TombEngine/Game/effects/tomb4fx.cpp
@@ -47,8 +47,8 @@ int NextBlood = 0;
int NextGunShell = 0;
FIRE_SPARKS FireSparks[MAX_SPARKS_FIRE];
-SmokeSparkInfo SmokeSparks[MAX_SPARKS_SMOKE];
-GunshellInfo Gunshells[MAX_GUNSHELL];
+SMOKE_SPARKS SmokeSparks[MAX_SPARKS_SMOKE];
+GUNSHELL_STRUCT Gunshells[MAX_GUNSHELL];
BLOOD_STRUCT Blood[MAX_SPARKS_BLOOD];
SHOCKWAVE_STRUCT ShockWaves[MAX_SHOCKWAVE];
FIRE_LIST Fires[MAX_FIRE_LIST];
@@ -492,7 +492,7 @@ void UpdateFireSparks()
int GetFreeSmokeSpark()
{
- SmokeSparkInfo* spark = &SmokeSparks[NextSmokeSpark];
+ SMOKE_SPARKS* spark = &SmokeSparks[NextSmokeSpark];
int sparkNum = NextSmokeSpark;
short minLife = 4095;
short minIndex = 0;
@@ -532,7 +532,7 @@ void UpdateSmoke()
{
for (int i = 0; i < MAX_SPARKS_SMOKE; i++)
{
- SmokeSparkInfo* spark = &SmokeSparks[i];
+ SMOKE_SPARKS* spark = &SmokeSparks[i];
if (spark->on)
{
@@ -652,7 +652,7 @@ void TriggerGunSmoke(int x, int y, int z, short xv, short yv, short zv, byte ini
void TriggerShatterSmoke(int x, int y, int z)
{
- SmokeSparkInfo* spark = &SmokeSparks[GetFreeSmokeSpark()];
+ SMOKE_SPARKS* spark = &SmokeSparks[GetFreeSmokeSpark()];
spark->on = true;
spark->sShade = 0;
@@ -786,12 +786,7 @@ void UpdateBlood()
continue;
}
- blood->oldX = blood->x;
- blood->oldY = blood->y;
- blood->oldZ = blood->z;
- blood->oldRotAng = blood->rotAng;
- blood->oldSize = blood->size;
- blood->oldShade = blood->shade;
+ blood->StoreInterpolationData();
if (blood->sLife - blood->life >= blood->colFadeSpeed)
{
@@ -843,7 +838,7 @@ int GetFreeGunshell()
while (true)
{
- GunshellInfo* gs = &Gunshells[NextGunShell];
+ GUNSHELL_STRUCT* gs = &Gunshells[NextGunShell];
if (!gs->counter)
break;
@@ -1394,6 +1389,8 @@ void UpdateShockwaves()
if (shockwave.life <= 0)
continue;
+ shockwave.StoreInterpolationData();
+
shockwave.life--;
// Spawn light.
diff --git a/TombEngine/Game/effects/tomb4fx.h b/TombEngine/Game/effects/tomb4fx.h
index da63cb1cc..b75aad25d 100644
--- a/TombEngine/Game/effects/tomb4fx.h
+++ b/TombEngine/Game/effects/tomb4fx.h
@@ -25,7 +25,7 @@ enum BodyPartFlags
BODY_NO_SHATTER_EFFECT = (1 << 13), // Remove shatter effect upon despawn.
};
-struct SmokeSparkInfo
+struct SMOKE_SPARKS
{
Vector3i position;
Vector3i velocity;
@@ -95,9 +95,24 @@ struct SHOCKWAVE_STRUCT
bool fadeIn = false;
bool HasLight = false;
+
+ short oldInnerRad;
+ short oldOuterRad;
+ byte oldR;
+ byte oldG;
+ byte oldB;
+
+ void StoreInterpolationData()
+ {
+ oldInnerRad = innerRad;
+ oldOuterRad = outerRad;
+ oldR = r;
+ oldG = g;
+ oldB = b;
+ }
};
-struct GunshellInfo
+struct GUNSHELL_STRUCT
{
Pose pos;
short fallspeed;
@@ -130,6 +145,23 @@ struct DRIP_STRUCT
short roomNumber;
byte outside;
byte pad;
+
+ int oldX;
+ int oldY;
+ int oldZ;
+ byte oldR;
+ byte oldG;
+ byte oldB;
+
+ void StoreInterpolationData()
+ {
+ oldX = x;
+ oldY = y;
+ oldZ = z;
+ oldR = r;
+ oldG = g;
+ oldB = b;
+ }
};
struct FIRE_LIST
@@ -224,8 +256,18 @@ struct BLOOD_STRUCT
int oldY;
int oldZ;
short oldRotAng;
- unsigned char oldShade;
- unsigned char oldSize;
+ byte oldShade;
+ byte oldSize;
+
+ void StoreInterpolationData()
+ {
+ oldX = x;
+ oldY = y;
+ oldZ = z;
+ oldRotAng = rotAng;
+ oldShade = shade;
+ oldSize = size;
+ }
};
enum class ShockwaveStyle
@@ -260,8 +302,8 @@ constexpr auto MAX_GUNSHELL = 24;
constexpr auto MAX_SHOCKWAVE = 16;
extern FIRE_SPARKS FireSparks[MAX_SPARKS_FIRE];
-extern SmokeSparkInfo SmokeSparks[MAX_SPARKS_SMOKE];
-extern GunshellInfo Gunshells[MAX_GUNSHELL];
+extern SMOKE_SPARKS SmokeSparks[MAX_SPARKS_SMOKE];
+extern GUNSHELL_STRUCT Gunshells[MAX_GUNSHELL];
extern BLOOD_STRUCT Blood[MAX_SPARKS_BLOOD];
extern SHOCKWAVE_STRUCT ShockWaves[MAX_SHOCKWAVE];
extern FIRE_LIST Fires[MAX_FIRE_LIST];
diff --git a/TombEngine/Game/effects/weather.cpp b/TombEngine/Game/effects/weather.cpp
index a532d3b00..b4d99a50c 100644
--- a/TombEngine/Game/effects/weather.cpp
+++ b/TombEngine/Game/effects/weather.cpp
@@ -225,6 +225,8 @@ namespace TEN::Effects::Environment
{
for (auto& p : Particles)
{
+ p.StoreInterpolationData();
+
p.Life -= 2;
// Disable particle if it is dead. It will be cleaned on next call of
diff --git a/TombEngine/Game/effects/weather.h b/TombEngine/Game/effects/weather.h
index e96f27d76..214cd1ff5 100644
--- a/TombEngine/Game/effects/weather.h
+++ b/TombEngine/Game/effects/weather.h
@@ -22,6 +22,19 @@ namespace TEN::Effects::Environment
bool Stopped = false;
float Transparency() const;
+
+ Vector3 OldPosition = Vector3::Zero;
+ Vector3 OldVelocity = Vector3::Zero;
+ float OldSize = 0.0f;
+ float OldLife = 0.0f;
+
+ void StoreInterpolationData()
+ {
+ OldPosition = Position;
+ OldVelocity = Velocity;
+ OldSize = Size;
+ OldLife = Life;
+ }
};
class EnvironmentController
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index b5f99e81c..17b9aea3f 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -39,7 +39,7 @@ using namespace TEN::Entities::Generic;
using namespace TEN::Hud;
using namespace TEN::Renderer::Structures;
-extern GunshellInfo Gunshells[MAX_GUNSHELL];
+extern GUNSHELL_STRUCT Gunshells[MAX_GUNSHELL];
namespace TEN::Renderer
{
diff --git a/TombEngine/Renderer/RendererDrawEffect.cpp b/TombEngine/Renderer/RendererDrawEffect.cpp
index 2e353c16d..f8e99036a 100644
--- a/TombEngine/Renderer/RendererDrawEffect.cpp
+++ b/TombEngine/Renderer/RendererDrawEffect.cpp
@@ -48,7 +48,7 @@ using namespace TEN::Traps::TR5;
extern BLOOD_STRUCT Blood[MAX_SPARKS_BLOOD];
extern FIRE_SPARKS FireSparks[MAX_SPARKS_FIRE];
-extern SmokeSparkInfo SmokeSparks[MAX_SPARKS_SMOKE];
+extern SMOKE_SPARKS SmokeSparks[MAX_SPARKS_SMOKE];
extern SHOCKWAVE_STRUCT ShockWaves[MAX_SHOCKWAVE];
extern FIRE_LIST Fires[MAX_FIRE_LIST];
extern Particle Particles[MAX_PARTICLES];
@@ -277,7 +277,7 @@ namespace TEN::Renderer
{
for (int i = 0; i < 32; i++)
{
- SmokeSparkInfo* spark = &SmokeSparks[i];
+ SMOKE_SPARKS* spark = &SmokeSparks[i];
if (spark->on)
{
@@ -495,8 +495,19 @@ namespace TEN::Renderer
}
}
- float innerRadius = splash.innerRad;
- float outerRadius = splash.outerRad;
+ byte oldColor = (splash.oldLife >= 32 ? 128 : (byte)((splash.oldLife / 32.0f) * 128));
+
+ if (!splash.isRipple)
+ {
+ if (splash.oldHeightSpeed < 0 && splash.oldHeight < 1024)
+ {
+ float multiplier = splash.oldHeight / 1024.0f;
+ oldColor = (float)oldColor * multiplier;
+ }
+ }
+
+ color = (byte)Lerp(oldColor, color, _interpolationFactor);
+
float xInner;
float zInner;
float xOuter;
@@ -508,6 +519,9 @@ namespace TEN::Renderer
float yInner = splash.y;
float yOuter = splash.y - splash.height;
+ float innerRadius = Lerp(splash.oldInnerRad, splash.innerRad, _interpolationFactor);
+ float outerRadius = Lerp(splash.oldOuterRad, splash.outerRad, _interpolationFactor);
+
for (int i = 0; i < NUM_POINTS; i++)
{
xInner = innerRadius * sin(alpha * i * PI / 180);
@@ -527,12 +541,19 @@ namespace TEN::Renderer
x2Outer += splash.x;
z2Outer = outerRadius * cos(alpha * j * PI / 180);
z2Outer += splash.z;
+
AddQuad(&_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + splash.spriteSequenceStart + (int)splash.animationPhase],
- Vector3(xOuter, yOuter, zOuter),
- Vector3(x2Outer, yOuter, z2Outer),
- Vector3(x2Inner, yInner, z2Inner),
- Vector3(xInner, yInner, zInner), Vector4(color / 255.0f, color / 255.0f, color / 255.0f, 1.0f),
- 0, 1, { 0, 0 }, BlendMode::Additive, false, view);
+ Vector3(xOuter, yOuter, zOuter),
+ Vector3(x2Outer, yOuter, z2Outer),
+ Vector3(x2Inner, yInner, z2Inner),
+ Vector3(xInner, yInner, zInner),
+ Vector4(color / 255.0f, color / 255.0f, color / 255.0f, 1.0f),
+ 0,
+ 1,
+ { 0, 0 },
+ BlendMode::Additive,
+ false,
+ view);
}
}
}
@@ -552,8 +573,14 @@ namespace TEN::Renderer
AddSpriteBillboard(
&_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + bubble.SpriteIndex],
- bubble.Position,
- bubble.Color, 0.0f, 1.0f, bubble.Size / 2, BlendMode::Additive, true, view);
+ Vector3::Lerp(bubble.OldPosition, bubble.Position, _interpolationFactor),
+ Vector4::Lerp(bubble.OldColor, bubble.Color, _interpolationFactor),
+ 0.0f,
+ 1.0f,
+ Vector2::Lerp(bubble.OldSize, bubble.Size, _interpolationFactor) / 2,
+ BlendMode::Additive,
+ true,
+ view);
}
}
@@ -573,10 +600,20 @@ namespace TEN::Renderer
auto axis = drip.Velocity;
drip.Velocity.Normalize(axis);
+ auto oldAxis = drip.OldVelocity;
+ drip.OldVelocity.Normalize(oldAxis);
+
AddSpriteBillboardConstrained(
&_sprites[Objects[ID_DRIP_SPRITE].meshIndex],
- drip.Position,
- drip.Color, 0.0f, 1.0f, drip.Size, BlendMode::Additive, -axis, false, view);
+ Vector3::Lerp(drip.OldPosition, drip.Position, _interpolationFactor),
+ Vector4::Lerp(drip.OldColor, drip.Color, _interpolationFactor),
+ 0.0f,
+ 1.0f,
+ Vector2::Lerp(drip.OldSize, drip.Size, _interpolationFactor),
+ BlendMode::Additive,
+ -Vector3::Lerp(oldAxis, axis, _interpolationFactor),
+ false,
+ view);
}
}
@@ -594,10 +631,21 @@ namespace TEN::Renderer
auto color = ripple.Color;
color.w = opacity;
+ float oldOpacity = ripple.OldColor.w * ((ripple.Flags & (int)RippleFlags::LowOpacity) ? 0.5f : 1.0f);
+ auto oldColor = ripple.OldColor;
+ oldColor.w = oldOpacity;
+
AddSpriteBillboardConstrainedLookAt(
&_sprites[ripple.SpriteIndex],
- ripple.Position,
- color, 0.0f, 1.0f, Vector2(ripple.Size * 2), BlendMode::Additive, ripple.Normal, true, view);
+ Vector3::Lerp(ripple.OldPosition, ripple.Position, _interpolationFactor),
+ Vector4::Lerp(oldColor, color, _interpolationFactor),
+ 0.0f,
+ 1.0f,
+ Vector2(Lerp(ripple.OldSize, ripple.Size, _interpolationFactor) * 2),
+ BlendMode::Additive,
+ ripple.Normal,
+ true,
+ view);
}
}
@@ -622,10 +670,30 @@ namespace TEN::Renderer
color.z = (int)std::clamp((int)color.z, 0, UCHAR_MAX);
color /= UCHAR_MAX;
+ auto oldColor = Vector4::Zero;
+ if (uwBlood.Init)
+ oldColor = Vector4(uwBlood.Init / 2, 0, uwBlood.Init / 16, UCHAR_MAX);
+ else
+ oldColor = Vector4(uwBlood.OldLife / 2, 0, uwBlood.OldLife / 16, UCHAR_MAX);
+
+ oldColor.x = (int)std::clamp((int)oldColor.x, 0, UCHAR_MAX);
+ oldColor.y = (int)std::clamp((int)oldColor.y, 0, UCHAR_MAX);
+ oldColor.z = (int)std::clamp((int)oldColor.z, 0, UCHAR_MAX);
+ oldColor /= UCHAR_MAX;
+
AddSpriteBillboard(
&_sprites[uwBlood.SpriteIndex],
- uwBlood.Position,
- color, 0.0f, 1.0f, Vector2(uwBlood.Size, uwBlood.Size) * 2, BlendMode::Additive, true, view);
+ Vector3::Lerp(uwBlood.OldPosition, uwBlood.Position, _interpolationFactor),
+ Vector4::Lerp(oldColor, color, _interpolationFactor),
+ 0.0f,
+ 1.0f,
+ Vector2(
+ Lerp(uwBlood.OldSize, uwBlood.Size, _interpolationFactor),
+ Lerp(uwBlood.OldSize, uwBlood.Size, _interpolationFactor)
+ ) * 2,
+ BlendMode::Additive,
+ true,
+ view);
}
}
@@ -659,6 +727,9 @@ namespace TEN::Renderer
auto pos = Vector3(shockwave->x, shockwave->y, shockwave->z);
+ float innerRadius = Lerp(shockwave->oldInnerRad, shockwave->innerRad, _interpolationFactor);
+ float outerRadius = Lerp(shockwave->oldOuterRad, shockwave->outerRad, _interpolationFactor);
+
// Inner circle
if (shockwave->style == (int)ShockwaveStyle::Normal)
{
@@ -675,10 +746,10 @@ namespace TEN::Renderer
angle -= PI / 4.0f;
}
- float x1 = (shockwave->innerRad * c);
- float z1 = (shockwave->innerRad * s);
- float x4 = (shockwave->outerRad * c);
- float z4 = (shockwave->outerRad * s);
+ float x1 = (innerRadius * c);
+ float z1 = (innerRadius * s);
+ float x4 = (innerRadius * c);
+ float z4 = (innerRadius * s);
auto p1 = Vector3(x1, 0, z1);
auto p4 = Vector3(x4, 0, z4);
@@ -736,11 +807,11 @@ namespace TEN::Renderer
c = cos(angle);
s = sin(angle);
- float x2 = (shockwave->innerRad * c);
- float z2 = (shockwave->innerRad * s);
+ float x2 = (innerRadius * c);
+ float z2 = (innerRadius * s);
- float x3 = (shockwave->outerRad * c);
- float z3 = (shockwave->outerRad * s);
+ float x3 = (outerRadius * c);
+ float z3 = (outerRadius * s);
auto p2 = Vector3(x2, 0, z2);
auto p3 = Vector3(x3, 0, z3);
@@ -856,10 +927,14 @@ namespace TEN::Renderer
AddSpriteBillboard(
&_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_UNDERWATERDUST],
- p.Position,
+ Vector3::Lerp(p.OldPosition, p.Position, _interpolationFactor),
Vector4(1.0f, 1.0f, 1.0f, p.Transparency()),
- 0.0f, 1.0f, Vector2(p.Size),
- BlendMode::Additive, true, view);
+ 0.0f,
+ 1.0f,
+ Vector2(Lerp(p.OldSize, p.Size, _interpolationFactor)),
+ BlendMode::Additive,
+ true,
+ view);
break;
@@ -870,10 +945,14 @@ namespace TEN::Renderer
AddSpriteBillboard(
&_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_UNDERWATERDUST],
- p.Position,
+ Vector3::Lerp(p.OldPosition, p.Position, _interpolationFactor),
Vector4(1.0f, 1.0f, 1.0f, p.Transparency()),
- 0.0f, 1.0f, Vector2(p.Size),
- BlendMode::Additive, true, view);
+ 0.0f,
+ 1.0f,
+ Vector2(Lerp(p.OldSize, p.Size, _interpolationFactor)),
+ BlendMode::Additive,
+ true,
+ view);
break;
@@ -887,9 +966,15 @@ namespace TEN::Renderer
AddSpriteBillboardConstrained(
&_sprites[Objects[ID_DRIP_SPRITE].meshIndex],
- p.Position,
+ Vector3::Lerp(p.OldPosition, p.Position, _interpolationFactor),
Vector4(0.8f, 1.0f, 1.0f, p.Transparency()),
- 0.0f, 1.0f, Vector2(RAIN_WIDTH, p.Size), BlendMode::Additive, -v, true, view);
+ 0.0f,
+ 1.0f,
+ Vector2(RAIN_WIDTH, Lerp(p.OldSize, p.Size, _interpolationFactor)),
+ BlendMode::Additive,
+ -v,
+ true,
+ view);
break;
}
From d37eb6a69be8433069a474d21ec2ba9a488559f5 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Tue, 16 Apr 2024 09:18:56 +0200
Subject: [PATCH 078/410] Fixed bug with last merge
---
TombEngine/Renderer/Structures/RendererItem.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/TombEngine/Renderer/Structures/RendererItem.h b/TombEngine/Renderer/Structures/RendererItem.h
index a913a9f94..31f2a4204 100644
--- a/TombEngine/Renderer/Structures/RendererItem.h
+++ b/TombEngine/Renderer/Structures/RendererItem.h
@@ -34,8 +34,8 @@ namespace TEN::Renderer::Structures
Matrix InterpolatedScale;
Matrix InterpolatedAnimationTransforms[MAX_BONES];
- int RoomNumber = NO_ROOM;
- int PrevRoomNumber = NO_ROOM;
+ int RoomNumber = NO_VALUE;
+ int PrevRoomNumber = NO_VALUE;
Vector4 Color;
Vector4 AmbientLight;
From c11eab5f587a06eda44ed8abe792972a5469eccf Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Wed, 17 Apr 2024 05:31:19 +0200
Subject: [PATCH 079/410] Hairs interpolation
---
TombEngine/Game/effects/hair.cpp | 5 +++++
TombEngine/Game/effects/hair.h | 9 +++++++++
TombEngine/Renderer/RendererLara.cpp | 6 +++++-
3 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/TombEngine/Game/effects/hair.cpp b/TombEngine/Game/effects/hair.cpp
index 4a27ba83a..3ffc2215a 100644
--- a/TombEngine/Game/effects/hair.cpp
+++ b/TombEngine/Game/effects/hair.cpp
@@ -23,6 +23,11 @@ namespace TEN::Effects::Hair
void HairUnit::Update(const ItemInfo& item, int hairUnitIndex)
{
+ for (int i = 0; i < Segments.size(); i++)
+ {
+ Segments[i].StoreInterpolationData();
+ }
+
const auto& player = GetLaraInfo(item);
bool isYoung = (g_GameFlow->GetLevel(CurrentLevel)->GetLaraType() == LaraType::Young);
diff --git a/TombEngine/Game/effects/hair.h b/TombEngine/Game/effects/hair.h
index 8e0a842b6..dde5d3b3c 100644
--- a/TombEngine/Game/effects/hair.h
+++ b/TombEngine/Game/effects/hair.h
@@ -15,6 +15,15 @@ namespace TEN::Effects::Hair
Vector3 Position = Vector3::Zero;
Vector3 Velocity = Vector3::Zero;
Quaternion Orientation = Quaternion::Identity;
+
+ Vector3 OldPosition = Vector3::Zero;
+ Quaternion OldOrientation = Quaternion::Identity;
+
+ void StoreInterpolationData()
+ {
+ OldPosition = Position;
+ OldOrientation = Orientation;
+ }
};
public:
diff --git a/TombEngine/Renderer/RendererLara.cpp b/TombEngine/Renderer/RendererLara.cpp
index b294e5735..b36f8113f 100644
--- a/TombEngine/Renderer/RendererLara.cpp
+++ b/TombEngine/Renderer/RendererLara.cpp
@@ -350,7 +350,11 @@ void Renderer::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, Render
for (int i = 0; i < unit.Segments.size(); i++)
{
const auto& segment = unit.Segments[i];
- auto worldMatrix = Matrix::CreateFromQuaternion(segment.Orientation) * Matrix::CreateTranslation(segment.Position);
+ auto worldMatrix =
+ Matrix::CreateFromQuaternion(
+ Quaternion::Lerp(segment.OldOrientation, segment.Orientation, _interpolationFactor)) *
+ Matrix::CreateTranslation(
+ Vector3::Lerp(segment.OldPosition, segment.Position, _interpolationFactor));
_stItem.BonesMatrices[i + 1] = worldMatrix;
_stItem.BoneLightModes[i] = (int)LightMode::Dynamic;
From ff32cca745b02189fc5ff8e096b7e694b15d665d Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Thu, 18 Apr 2024 05:52:20 +0200
Subject: [PATCH 080/410] Shadow maps interpolation
---
TombEngine/Game/effects/Electricity.cpp | 4 +
TombEngine/Game/effects/Electricity.h | 58 +++++++++++--
TombEngine/Game/effects/explosion.cpp | 2 +
TombEngine/Game/effects/explosion.h | 69 ++++++++-------
TombEngine/Game/effects/simple_particle.cpp | 2 +
TombEngine/Game/effects/simple_particle.h | 14 +++-
TombEngine/Game/items.cpp | 5 ++
TombEngine/Game/items.h | 6 ++
TombEngine/Renderer/RendererDraw.cpp | 6 +-
TombEngine/Renderer/RendererDrawEffect.cpp | 93 +++++++++++++++++----
10 files changed, 201 insertions(+), 58 deletions(-)
diff --git a/TombEngine/Game/effects/Electricity.cpp b/TombEngine/Game/effects/Electricity.cpp
index 2c169717c..7e64d4cb4 100644
--- a/TombEngine/Game/effects/Electricity.cpp
+++ b/TombEngine/Game/effects/Electricity.cpp
@@ -175,6 +175,8 @@ namespace TEN::Effects::Electricity
for (auto& laser : HelicalLasers)
{
+ laser.StoreInterpolationData();
+
// Set to despawn.
laser.Life -= 1.0f;
if (laser.Life <= 0.0f)
@@ -213,6 +215,8 @@ namespace TEN::Effects::Electricity
if (arc.life <= 0.0f)
continue;
+ arc.StoreInterpolationData();
+
// If/when this behaviour is changed, modify AddLightningArc accordingly.
arc.life -= 2.0f;
if (arc.life > 0.0f)
diff --git a/TombEngine/Game/effects/Electricity.h b/TombEngine/Game/effects/Electricity.h
index 45ea1ecbd..0aa4fa764 100644
--- a/TombEngine/Game/effects/Electricity.h
+++ b/TombEngine/Game/effects/Electricity.h
@@ -39,24 +39,66 @@ namespace TEN::Effects::Electricity
int rotation;
int type;
int flags;
+
+ Vector3 oldPos1;
+ Vector3 oldPos2;
+ Vector3 oldPos3;
+ Vector3 oldPos4;
+ byte oldR;
+ byte oldG;
+ byte oldB;
+ float oldLife;
+
+ void StoreInterpolationData()
+ {
+ oldPos1 = pos1;
+ oldPos2 = pos2;
+ oldPos3 = pos3;
+ oldPos4 = pos4;
+ oldR = r;
+ oldG = g;
+ oldB = b;
+ oldLife = life;
+ }
};
struct HelicalLaser
{
unsigned int NumSegments = 0;
- Vector3 Origin = Vector3::Zero;
- Vector3 Target = Vector3::Zero;
+ Vector3 Origin = Vector3::Zero;
+ Vector3 Target = Vector3::Zero;
short Orientation2D = 0;
Vector3 LightPosition = Vector3::Zero; // TODO: Use light cone instead?
- Vector4 Color = Vector4::Zero;
+ Vector4 Color = Vector4::Zero;
- float Life = 0.0f;
- float Radius = 0.0f;
- float Length = 0.0f;
+ float Life = 0.0f;
+ float Radius = 0.0f;
+ float Length = 0.0f;
float LengthEnd = 0.0f;
- float Opacity = 0.0f;
- short Rotation = 0;
+ float Opacity = 0.0f;
+ short Rotation = 0;
+
+ Vector3 OldOrigin = Vector3::Zero;
+ Vector3 OldTarget = Vector3::Zero;
+ float OldLife = 0.0f;
+ float OldRadius = 0.0f;
+ float OldLength = 0.0f;
+ float OldOpacity = 0.0f;
+ Vector4 OldColor = Vector4::Zero;
+ short OldOrientation2D = 0;
+
+ void StoreInterpolationData()
+ {
+ OldOrigin = Origin;
+ OldTarget = Target;
+ OldLife = Life;
+ OldRadius = Radius;
+ OldLength = Length;
+ OldOpacity = Opacity;
+ OldColor = Color;
+ OldOrientation2D = Orientation2D;
+ }
};
extern std::vector ElectricityArcs;
diff --git a/TombEngine/Game/effects/explosion.cpp b/TombEngine/Game/effects/explosion.cpp
index 592e21580..d64dd8e42 100644
--- a/TombEngine/Game/effects/explosion.cpp
+++ b/TombEngine/Game/effects/explosion.cpp
@@ -49,6 +49,8 @@ namespace TEN::Effects::Explosion
if (!e.active)
continue;
+ e.StoreInterpolationData();
+
e.age++;
if (e.age > e.life)
{
diff --git a/TombEngine/Game/effects/explosion.h b/TombEngine/Game/effects/explosion.h
index 4c6ff9348..bc822573f 100644
--- a/TombEngine/Game/effects/explosion.h
+++ b/TombEngine/Game/effects/explosion.h
@@ -1,28 +1,41 @@
-#pragma once
-#include
-#include
-#include
-
-namespace TEN::Effects::Explosion
-{
- struct ExplosionParticle
- {
- Vector3 pos;
- Vector3 vel;
- Vector4 tint;
- float size;
- float rotation;
- float angularVel;
- float age;
- float life;
- int room;
- int sprite;
- bool active;
- };
- extern std::array explosionParticles;
-
- void TriggerExplosion(const Vector3& pos, float size, bool triggerSparks, bool triggerSmoke, bool triggerShockwave, int room);
- void UpdateExplosionParticles();
- ExplosionParticle& getFreeExplosionParticle();
- void SpawnExplosionParticle(const Vector3& pos);
-}
+#pragma once
+#include
+#include
+#include
+
+namespace TEN::Effects::Explosion
+{
+ struct ExplosionParticle
+ {
+ Vector3 pos;
+ Vector3 vel;
+ Vector4 tint;
+ float size;
+ float rotation;
+ float angularVel;
+ float age;
+ float life;
+ int room;
+ int sprite;
+ bool active;
+
+ Vector3 oldPos;
+ Vector4 oldTint;
+ float oldSize;
+ float oldRotation;
+
+ void StoreInterpolationData()
+ {
+ oldPos = pos;
+ oldTint = tint;
+ oldSize = size;
+ oldRotation = rotation;
+ }
+ };
+ extern std::array explosionParticles;
+
+ void TriggerExplosion(const Vector3& pos, float size, bool triggerSparks, bool triggerSmoke, bool triggerShockwave, int room);
+ void UpdateExplosionParticles();
+ ExplosionParticle& getFreeExplosionParticle();
+ void SpawnExplosionParticle(const Vector3& pos);
+}
diff --git a/TombEngine/Game/effects/simple_particle.cpp b/TombEngine/Game/effects/simple_particle.cpp
index 0165512ac..867f0da63 100644
--- a/TombEngine/Game/effects/simple_particle.cpp
+++ b/TombEngine/Game/effects/simple_particle.cpp
@@ -73,6 +73,8 @@ namespace TEN::Effects
if (!p.active)
continue;
+ p.StoreInterpolationData();
+
p.age+= p.ageRate;
if (p.life < p.age)
p.active = false;
diff --git a/TombEngine/Game/effects/simple_particle.h b/TombEngine/Game/effects/simple_particle.h
index cd32afa42..592c23154 100644
--- a/TombEngine/Game/effects/simple_particle.h
+++ b/TombEngine/Game/effects/simple_particle.h
@@ -1,14 +1,17 @@
#pragma once
#include "Objects\objectslist.h"
+#include
enum class BlendMode;
struct ItemInfo;
namespace TEN::Effects
{
+ using namespace DirectX::SimpleMath;
+
struct SimpleParticle
{
- DirectX::SimpleMath::Vector3 worldPosition;
+ Vector3 worldPosition;
float size;
float age;
float ageRate;
@@ -18,6 +21,15 @@ namespace TEN::Effects
GAME_OBJECT_ID sequence;
bool active;
BlendMode blendMode;
+
+ Vector3 oldWorldPosition;
+ float oldSize;
+
+ void StoreInterpolationData()
+ {
+ oldWorldPosition = worldPosition;
+ oldSize = size;
+ }
};
extern std::array simpleParticles;
diff --git a/TombEngine/Game/items.cpp b/TombEngine/Game/items.cpp
index 29a4cf9bc..590de6614 100644
--- a/TombEngine/Game/items.cpp
+++ b/TombEngine/Game/items.cpp
@@ -745,6 +745,11 @@ int FindItem(ItemInfo* item)
void UpdateAllItems()
{
+ for (int i = 0; i < g_Level.Items.size(); i++)
+ {
+ g_Level.Items[i].StoreInterpolationData();
+ }
+
InItemControlLoop = true;
short itemNumber = NextItemActive;
diff --git a/TombEngine/Game/items.h b/TombEngine/Game/items.h
index cda9aafee..9e0faed69 100644
--- a/TombEngine/Game/items.h
+++ b/TombEngine/Game/items.h
@@ -122,6 +122,7 @@ struct ItemInfo
EntityEffectData Effect = {};
EntityModelData Model = {};
+ Pose OldPose = Pose::Zero;
Pose StartPose = Pose::Zero;
Pose Pose = Pose::Zero;
RoomVector Location = {}; // NOTE: Describes vertical position in room.
@@ -172,6 +173,11 @@ struct ItemInfo
bool IsLara() const;
bool IsCreature() const;
bool IsBridge() const;
+
+ void StoreInterpolationData()
+ {
+ OldPose = Pose;
+ }
};
bool TestState(int refState, const std::vector& stateList);
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index 979919fd7..5bd6c0abe 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -208,10 +208,10 @@ namespace TEN::Renderer
RendererObject& obj = GetRendererObject((GAME_OBJECT_ID)item->ObjectNumber);
- _stItem.World = item->World;
+ _stItem.World = item->InterpolatedWorld;
_stItem.Color = item->Color;
_stItem.AmbientLight = item->AmbientLight;
- memcpy(_stItem.BonesMatrices, item->AnimationTransforms, sizeof(Matrix) * MAX_BONES);
+ memcpy(_stItem.BonesMatrices, item->InterpolatedAnimationTransforms, sizeof(Matrix) * MAX_BONES);
for (int k = 0; k < MAX_BONES; k++)
_stItem.BoneLightModes[k] = (int)LightMode::Static;
@@ -2308,7 +2308,7 @@ namespace TEN::Renderer
RendererObject& moveableObj = *_moveableObjects[item->ObjectNumber];
// Bind item main properties
- _stItem.World = item->InterpolatedWorld; // item->World;
+ _stItem.World = item->InterpolatedWorld;
_stItem.Color = item->Color;
_stItem.AmbientLight = item->AmbientLight;
memcpy(_stItem.BonesMatrices, item->InterpolatedAnimationTransforms, sizeof(Matrix) * MAX_BONES);
diff --git a/TombEngine/Renderer/RendererDrawEffect.cpp b/TombEngine/Renderer/RendererDrawEffect.cpp
index f8e99036a..1839a5875 100644
--- a/TombEngine/Renderer/RendererDrawEffect.cpp
+++ b/TombEngine/Renderer/RendererDrawEffect.cpp
@@ -169,14 +169,16 @@ namespace TEN::Renderer
if (laser.Life <= 0.0f)
continue;
- auto color = laser.Color;
- color.w = laser.Opacity;
+ auto color = Vector4::Lerp(laser.OldColor, laser.Color, _interpolationFactor);
+ color.w = Lerp(laser.OldOpacity, laser.Opacity, _interpolationFactor);
- ElectricityKnots[0] = laser.Target;
- ElectricityKnots[1] = laser.Origin;
+ Vector3 laserTarget = Vector3::Lerp(laser.OldTarget, laser.Target, _interpolationFactor);
+
+ ElectricityKnots[0] = laserTarget;
+ ElectricityKnots[1] = Vector3::Lerp(laser.OldOrigin, laser.Origin, _interpolationFactor);
for (int j = 0; j < 2; j++)
- ElectricityKnots[j] -= laser.Target;
+ ElectricityKnots[j] -= laserTarget;
CalculateHelixSpline(laser, ElectricityKnots, ElectricityBuffer);
@@ -189,9 +191,9 @@ namespace TEN::Renderer
auto& interpPosArray = ElectricityBuffer;
for (int s = 0; s < laser.NumSegments ; s++)
{
- auto origin = laser.Target + interpPosArray[bufferIndex];
+ auto origin = laserTarget + interpPosArray[bufferIndex];
bufferIndex++;
- auto target = laser.Target + interpPosArray[bufferIndex];
+ auto target = laserTarget + interpPosArray[bufferIndex];
auto center = (origin + target) / 2;
auto direction = target - origin;
@@ -201,7 +203,13 @@ namespace TEN::Renderer
&_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LIGHTHING],
center,
color,
- PI_DIV_2, 1.0f, Vector2(5 * 8.0f, Vector3::Distance(origin, target)), BlendMode::Additive, direction, true, view);
+ PI_DIV_2,
+ 1.0f,
+ Vector2(5 * 8.0f, Vector3::Distance(origin, target)),
+ BlendMode::Additive,
+ direction,
+ true,
+ view);
}
}
}
@@ -220,12 +228,12 @@ namespace TEN::Renderer
if (arc.life <= 0)
continue;
- ElectricityKnots[0] = arc.pos1;
- ElectricityKnots[1] = arc.pos1;
- ElectricityKnots[2] = arc.pos2;
- ElectricityKnots[3] = arc.pos3;
- ElectricityKnots[4] = arc.pos4;
- ElectricityKnots[5] = arc.pos4;
+ ElectricityKnots[0] = Vector3::Lerp(arc.oldPos1, arc.pos1, _interpolationFactor);
+ ElectricityKnots[1] = Vector3::Lerp(arc.oldPos1, arc.pos1, _interpolationFactor);
+ ElectricityKnots[2] = Vector3::Lerp(arc.oldPos2, arc.pos2, _interpolationFactor);
+ ElectricityKnots[3] = Vector3::Lerp(arc.oldPos3, arc.pos3, _interpolationFactor);
+ ElectricityKnots[4] = Vector3::Lerp(arc.oldPos4, arc.pos4, _interpolationFactor);
+ ElectricityKnots[5] = Vector3::Lerp(arc.oldPos4, arc.pos4, _interpolationFactor);
for (int j = 0; j < ElectricityKnots.size(); j++)
ElectricityKnots[j] -= LaraItem->Pose.Position.ToVector3();
@@ -239,6 +247,7 @@ namespace TEN::Renderer
int bufferIndex = 0;
auto& interpPosArray = ElectricityBuffer;
+
for (int s = 0; s < ((arc.segments * 3) - 1); s++)
{
auto origin = (LaraItem->Pose.Position + interpPosArray[bufferIndex]).ToVector3();
@@ -263,11 +272,36 @@ namespace TEN::Renderer
b = (arc.life * arc.b) / 16;
}
+
+ byte oldR, oldG, oldB;
+ if (arc.oldLife >= 16)
+ {
+ oldR = arc.oldR;
+ oldG = arc.oldG;
+ oldB = arc.oldB;
+ }
+ else
+ {
+ oldR = (arc.oldLife * arc.oldR) / 16;
+ oldG = (arc.oldLife * arc.oldG) / 16;
+ oldB = (arc.oldLife * arc.oldB) / 16;
+ }
+
+ r = (byte)Lerp(oldR, r, _interpolationFactor);
+ g = (byte)Lerp(oldG, g, _interpolationFactor);
+ b = (byte)Lerp(oldB, b, _interpolationFactor);
+
AddSpriteBillboardConstrained(
&_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LIGHTHING],
center,
Vector4(r / 255.0f, g / 255.0f, b / 255.0f, 1.0f),
- PI_DIV_2, 1.0f, Vector2(arc.width * 8, Vector3::Distance(origin, target)), BlendMode::Additive, direction, true, view);
+ PI_DIV_2,
+ 1.0f,
+ Vector2(arc.width * 8, Vector3::Distance(origin, target)),
+ BlendMode::Additive,
+ direction,
+ true,
+ view);
}
}
}
@@ -1490,8 +1524,19 @@ namespace TEN::Renderer
if (!CheckIfSlotExists(ID_EXPLOSION_SPRITES, "Explosion particles rendering"))
return;
- AddSpriteBillboard(&_sprites[Objects[ID_EXPLOSION_SPRITES].meshIndex + e.sprite],
- e.pos, e.tint, e.rotation, 1.0f, { e.size, e.size }, BlendMode::Additive, true, view);
+ AddSpriteBillboard(
+ &_sprites[Objects[ID_EXPLOSION_SPRITES].meshIndex + e.sprite],
+ Vector3::Lerp(e.oldPos, e.pos, _interpolationFactor),
+ Vector4::Lerp(e.oldTint, e.tint, _interpolationFactor),
+ Lerp(e.oldRotation, e.rotation, _interpolationFactor),
+ 1.0f,
+ {
+ Lerp(e.oldSize, e.size, _interpolationFactor),
+ Lerp(e.oldSize, e.size, _interpolationFactor)
+ },
+ BlendMode::Additive,
+ true,
+ view);
}
}
@@ -1506,7 +1551,19 @@ namespace TEN::Renderer
if (!CheckIfSlotExists(s.sequence, "Particle rendering"))
continue;
- AddSpriteBillboard(&_sprites[Objects[s.sequence].meshIndex + s.sprite], s.worldPosition, Vector4(1, 1, 1, 1), 0, 1.0f, { s.size, s.size / 2 }, BlendMode::AlphaBlend, true, view);
+ AddSpriteBillboard(
+ &_sprites[Objects[s.sequence].meshIndex + s.sprite],
+ Vector3::Lerp(s.oldWorldPosition, s.worldPosition, _interpolationFactor),
+ Vector4(1.0f),
+ 0,
+ 1.0f,
+ {
+ Lerp(s.oldSize, s.size, _interpolationFactor),
+ Lerp(s.oldSize, s.size, _interpolationFactor) / 2
+ },
+ BlendMode::AlphaBlend,
+ true,
+ view);
}
}
}
From ce403506b54b9eb4babf18841e803d0e347eb836 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Thu, 18 Apr 2024 09:38:15 +0200
Subject: [PATCH 081/410] Lens flares prototype
---
TombEngine/Renderer/Renderer.h | 2 +
TombEngine/Renderer/RendererInit.cpp | 3 +-
TombEngine/Renderer/RendererPostProcess.cpp | 17 ++++-
TombEngine/Shaders/PostProcess.fx | 74 +++++++++++++++++++++
4 files changed, 93 insertions(+), 3 deletions(-)
diff --git a/TombEngine/Renderer/Renderer.h b/TombEngine/Renderer/Renderer.h
index 30c1386b0..9b0197193 100644
--- a/TombEngine/Renderer/Renderer.h
+++ b/TombEngine/Renderer/Renderer.h
@@ -355,6 +355,8 @@ namespace TEN::Renderer
ComPtr _psPostProcessNegative;
ComPtr _psPostProcessExclusion;
ComPtr _psPostProcessFinalPass;
+ ComPtr _psPostProcessLensFlare;
+
bool _doingFullscreenPass = false;
// SSAO
diff --git a/TombEngine/Renderer/RendererInit.cpp b/TombEngine/Renderer/RendererInit.cpp
index c6d339c5e..b918d6a4d 100644
--- a/TombEngine/Renderer/RendererInit.cpp
+++ b/TombEngine/Renderer/RendererInit.cpp
@@ -297,12 +297,13 @@ namespace TEN::Renderer
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};
Utils::throwIfFailed(_device->CreateInputLayout(postProcessInputLayoutItems, 3, blob->GetBufferPointer(), blob->GetBufferSize(), &_fullscreenTriangleInputLayout));
-
+
_psPostProcessCopy = Utils::compilePixelShader(_device.Get(), GetAssetPath(L"Shaders\\PostProcess.fx"), "PSCopy", "ps_5_0", nullptr, blob);
_psPostProcessMonochrome = Utils::compilePixelShader(_device.Get(), GetAssetPath(L"Shaders\\PostProcess.fx"), "PSMonochrome", "ps_5_0", nullptr, blob);
_psPostProcessNegative = Utils::compilePixelShader(_device.Get(), GetAssetPath(L"Shaders\\PostProcess.fx"), "PSNegative", "ps_5_0", nullptr, blob);
_psPostProcessExclusion = Utils::compilePixelShader(_device.Get(), GetAssetPath(L"Shaders\\PostProcess.fx"), "PSExclusion", "ps_5_0", nullptr, blob);
_psPostProcessFinalPass = Utils::compilePixelShader(_device.Get(), GetAssetPath(L"Shaders\\PostProcess.fx"), "PSFinalPass", "ps_5_0", nullptr, blob);
+ _psPostProcessLensFlare = Utils::compilePixelShader(_device.Get(), GetAssetPath(L"Shaders\\PostProcess.fx"), "PSLensFlare", "ps_5_0", nullptr, blob);
}
void Renderer::CreateSSAONoiseTexture()
diff --git a/TombEngine/Renderer/RendererPostProcess.cpp b/TombEngine/Renderer/RendererPostProcess.cpp
index 5742f01c6..300322794 100644
--- a/TombEngine/Renderer/RendererPostProcess.cpp
+++ b/TombEngine/Renderer/RendererPostProcess.cpp
@@ -72,9 +72,22 @@ namespace TEN::Renderer
BindRenderTargetAsTexture(TextureRegister::ColorMap, &_postProcessRenderTarget[currentRenderTarget], SamplerStateRegister::PointWrap);
DrawTriangles(3, 0);
- destinationRenderTarget = 0;
- currentRenderTarget = 1;
+ destinationRenderTarget = destinationRenderTarget == 1 ? 0 : 1;
+ currentRenderTarget = currentRenderTarget == 1 ? 0 : 1;
}
+
+ // Lens flare
+ {
+ _context->ClearRenderTargetView(_postProcessRenderTarget[destinationRenderTarget].RenderTargetView.Get(), clearColor);
+ _context->OMSetRenderTargets(1, _postProcessRenderTarget[destinationRenderTarget].RenderTargetView.GetAddressOf(), nullptr);
+
+ _context->PSSetShader(_psPostProcessLensFlare.Get(), nullptr, 0);
+ BindRenderTargetAsTexture(TextureRegister::ColorMap, &_postProcessRenderTarget[currentRenderTarget], SamplerStateRegister::PointWrap);
+ DrawTriangles(3, 0);
+
+ destinationRenderTarget = destinationRenderTarget == 1 ? 0 : 1;
+ currentRenderTarget = currentRenderTarget == 1 ? 0 : 1;
+ }
// Do the final pass
_context->PSSetShader(_psPostProcessFinalPass.Get(), nullptr, 0);
diff --git a/TombEngine/Shaders/PostProcess.fx b/TombEngine/Shaders/PostProcess.fx
index bc17733d0..193e9eadd 100644
--- a/TombEngine/Shaders/PostProcess.fx
+++ b/TombEngine/Shaders/PostProcess.fx
@@ -89,4 +89,78 @@ float4 PSFinalPass(PixelShaderInput input) : SV_TARGET
output.xyz = output.xyz * Tint;
return output;
+}
+
+float3 LensFlare(float2 uv, float2 pos)
+{
+ float intensity = 1.5;
+ float2 main = uv-pos;
+ float2 uvd = uv*(length(uv));
+
+ float dist=length(main); dist = pow(dist,.1);
+
+
+ float f1 = max(0.01-pow(length(uv+1.2*pos),1.9),.0)*7.0;
+
+ float f2 = max(1.0/(1.0+32.0*pow(length(uvd+0.8*pos),2.0)),.0)*00.1;
+ float f22 = max(1.0/(1.0+32.0*pow(length(uvd+0.85*pos),2.0)),.0)*00.08;
+ float f23 = max(1.0/(1.0+32.0*pow(length(uvd+0.9*pos),2.0)),.0)*00.06;
+
+ float2 uvx = lerp(uv,uvd,-0.5);
+
+ float f4 = max(0.01-pow(length(uvx+0.4*pos),2.4),.0)*6.0;
+ float f42 = max(0.01-pow(length(uvx+0.45*pos),2.4),.0)*5.0;
+ float f43 = max(0.01-pow(length(uvx+0.5*pos),2.4),.0)*3.0;
+
+ uvx = lerp(uv,uvd,-.4);
+
+ float f5 = max(0.01-pow(length(uvx+0.2*pos),5.5),.0)*2.0;
+ float f52 = max(0.01-pow(length(uvx+0.4*pos),5.5),.0)*2.0;
+ float f53 = max(0.01-pow(length(uvx+0.6*pos),5.5),.0)*2.0;
+
+ uvx = lerp(uv,uvd,-0.5);
+
+ float f6 = max(0.01-pow(length(uvx-0.3*pos),1.6),.0)*6.0;
+ float f62 = max(0.01-pow(length(uvx-0.325*pos),1.6),.0)*3.0;
+ float f63 = max(0.01-pow(length(uvx-0.35*pos),1.6),.0)*5.0;
+
+ float3 c = float3(0,0,0);
+
+ c.r+=f2+f4+f5+f6; c.g+=f22+f42+f52+f62; c.b+=f23+f43+f53+f63;
+ c = c*1.3 - float3(length(uvd)*.05,length(uvd)*.05,length(uvd)*.05);
+
+ return c * intensity;
+}
+
+float3 LensFlareColorCorrection(float3 color, float factor,float factor2) // color modifier
+{
+ float w = color.x+color.y+color.z;
+ return lerp(color,float3(w,w,w)*factor,w*factor2);
+}
+
+float4 PSLensFlare(PixelShaderInput input) : SV_Target
+{
+ float4 color = ColorTexture.Sample(ColorSampler, input.UV);
+
+ float4 position = input.PositionCopy;
+
+ position.xyz /= position.w;
+ position.xyz = position.xyz * 0.5f + 0.5f;
+ position.y = 1.0f - position.y;
+
+ float4 offset = float4(0,-5000,0, 1.0);
+ offset = mul(mul(offset, View), Projection);
+ offset.xyz /= offset.w;
+
+ //offset.xyz /= offset.w;
+ // offset.xyz = offset.xyz * 0.5f + 0.5f;
+ // offset.y = 1.0f - offset.y;
+
+ position = input.PositionCopy;
+
+
+ color.xyz += max(float3(0,0,0), float3(1.5,1.2,1.2)*float3(3,3,3)*LensFlare(position.xy, offset.xy));
+ //color.xyz = LensFlareColorCorrection(color,.5,.1);
+
+ return color; // float4(output, color.a);
}
\ No newline at end of file
From 4bbf52abf55d4388124cdd0b5d70b4d3a6fcfc48 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Thu, 18 Apr 2024 15:58:47 +0200
Subject: [PATCH 082/410] Polished the lens flare pixel shader
---
TombEngine/Shaders/PostProcess.fx | 84 ++++++++++++++++---------------
1 file changed, 44 insertions(+), 40 deletions(-)
diff --git a/TombEngine/Shaders/PostProcess.fx b/TombEngine/Shaders/PostProcess.fx
index 193e9eadd..2c090a27d 100644
--- a/TombEngine/Shaders/PostProcess.fx
+++ b/TombEngine/Shaders/PostProcess.fx
@@ -93,49 +93,52 @@ float4 PSFinalPass(PixelShaderInput input) : SV_TARGET
float3 LensFlare(float2 uv, float2 pos)
{
- float intensity = 1.5;
- float2 main = uv-pos;
- float2 uvd = uv*(length(uv));
-
- float dist=length(main); dist = pow(dist,.1);
-
-
- float f1 = max(0.01-pow(length(uv+1.2*pos),1.9),.0)*7.0;
+ float intensity = 1.5f;
+ float2 main = uv - pos;
+ float2 uvd = uv * (length(uv));
- float f2 = max(1.0/(1.0+32.0*pow(length(uvd+0.8*pos),2.0)),.0)*00.1;
- float f22 = max(1.0/(1.0+32.0*pow(length(uvd+0.85*pos),2.0)),.0)*00.08;
- float f23 = max(1.0/(1.0+32.0*pow(length(uvd+0.9*pos),2.0)),.0)*00.06;
-
- float2 uvx = lerp(uv,uvd,-0.5);
-
- float f4 = max(0.01-pow(length(uvx+0.4*pos),2.4),.0)*6.0;
- float f42 = max(0.01-pow(length(uvx+0.45*pos),2.4),.0)*5.0;
- float f43 = max(0.01-pow(length(uvx+0.5*pos),2.4),.0)*3.0;
-
- uvx = lerp(uv,uvd,-.4);
-
- float f5 = max(0.01-pow(length(uvx+0.2*pos),5.5),.0)*2.0;
- float f52 = max(0.01-pow(length(uvx+0.4*pos),5.5),.0)*2.0;
- float f53 = max(0.01-pow(length(uvx+0.6*pos),5.5),.0)*2.0;
-
- uvx = lerp(uv,uvd,-0.5);
-
- float f6 = max(0.01-pow(length(uvx-0.3*pos),1.6),.0)*6.0;
- float f62 = max(0.01-pow(length(uvx-0.325*pos),1.6),.0)*3.0;
- float f63 = max(0.01-pow(length(uvx-0.35*pos),1.6),.0)*5.0;
-
- float3 c = float3(0,0,0);
-
- c.r+=f2+f4+f5+f6; c.g+=f22+f42+f52+f62; c.b+=f23+f43+f53+f63;
- c = c*1.3 - float3(length(uvd)*.05,length(uvd)*.05,length(uvd)*.05);
+ float dist = length(main);
+ dist = pow(dist, 0.1f);
+
+ float f1 = max(0.01f - pow(length(uv + 1.2f * pos), 1.9f), 0.0f) * 7.0f;
+
+ float f2 = max(1.0f / (1.0f + 32.0f * pow(length(uvd + 0.8f * pos), 2.0f)), 0.0f) * 00.1f;
+ float f22 = max(1.0f / (1.0f + 32.0f * pow(length(uvd + 0.85f * pos), 2.0f)), 0.0f) * 00.08f;
+ float f23 = max(1.0f / (1.0f + 32.0f * pow(length(uvd + 0.9f * pos), 2.0f)), 0.0f) * 00.06f;
+
+ float2 uvx = lerp(uv, uvd, -0.5f);
+
+ float f4 = max(0.01f - pow(length(uvx + 0.4f * pos), 2.4f), 0.0f) * 6.0f;
+ float f42 = max(0.01f - pow(length(uvx + 0.45f * pos), 2.4f), 0.0f) * 5.0f;
+ float f43 = max(0.01f - pow(length(uvx + 0.5f * pos), 2.4f), 0.0f) * 3.0f;
+
+ uvx = lerp(uv, uvd, -0.4f);
+
+ float f5 = max(0.01f - pow(length(uvx + 0.2f * pos), 5.5f), 0.0f) * 2.0f;
+ float f52 = max(0.01f - pow(length(uvx + 0.4f * pos), 5.5f), 0.0f) * 2.0f;
+ float f53 = max(0.01f - pow(length(uvx + 0.6f * pos), 5.5f), 0.0f) * 2.0f;
+
+ uvx = lerp(uv, uvd, -0.5f);
+
+ float f6 = max(0.01f - pow(length(uvx - 0.3f * pos), 1.6f), 0.0f) * 6.0f;
+ float f62 = max(0.01f - pow(length(uvx - 0.325f * pos), 1.6f), 0.0f) * 3.0f;
+ float f63 = max(0.01f - pow(length(uvx - 0.35f * pos), 1.6f), 0.0f) * 5.0f;
+
+ float3 c = float3(0.0f, 0.0f, 0.0f);
+
+ c.r += f2 + f4 + f5 + f6;
+ c.g += f22 + f42 + f52 + f62;
+ c.b += f23 + f43 + f53 + f63;
+ c = c * 1.3f - float3(length(uvd) * 0.05f, length(uvd) * 0.05f, length(uvd) * 0.05f);
+
return c * intensity;
}
-float3 LensFlareColorCorrection(float3 color, float factor,float factor2) // color modifier
+float3 LensFlareColorCorrection(float3 color, float factor,float factor2)
{
- float w = color.x+color.y+color.z;
- return lerp(color,float3(w,w,w)*factor,w*factor2);
+ float w = color.x + color.y + color.z;
+ return lerp(color, float3(w, w, w) * factor, w * factor2);
}
float4 PSLensFlare(PixelShaderInput input) : SV_Target
@@ -159,8 +162,9 @@ float4 PSLensFlare(PixelShaderInput input) : SV_Target
position = input.PositionCopy;
- color.xyz += max(float3(0,0,0), float3(1.5,1.2,1.2)*float3(3,3,3)*LensFlare(position.xy, offset.xy));
- //color.xyz = LensFlareColorCorrection(color,.5,.1);
+ float3 lensFlareColor = max(float3(0.0f, 0.0f, 0.0f), float3(4.5f, 3.6f, 3.6f) * LensFlare(position.xy, offset.xy));
+ lensFlareColor = LensFlareColorCorrection(lensFlareColor, 0.5f, 0.1f);
+ color.xyz += lensFlareColor;
- return color; // float4(output, color.a);
+ return color;
}
\ No newline at end of file
From 7d66d49742fc3bb1d5d5ae6142d22c2a6050224f Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Thu, 18 Apr 2024 16:58:07 +0200
Subject: [PATCH 083/410] Lens flares set by code and not hardcoded in shader
---
.../ConstantBuffers/PostProcessBuffer.h | 10 +++++++
TombEngine/Renderer/RendererPostProcess.cpp | 7 ++++-
.../Renderer/Structures/RendererLensFlare.h | 14 ++++++++++
TombEngine/Shaders/CBPostProcess.hlsli | 10 +++++++
TombEngine/Shaders/PostProcess.fx | 27 ++++++++-----------
TombEngine/TombEngine.vcxproj | 1 +
6 files changed, 52 insertions(+), 17 deletions(-)
create mode 100644 TombEngine/Renderer/Structures/RendererLensFlare.h
diff --git a/TombEngine/Renderer/ConstantBuffers/PostProcessBuffer.h b/TombEngine/Renderer/ConstantBuffers/PostProcessBuffer.h
index e0fc6821f..bd86c56f4 100644
--- a/TombEngine/Renderer/ConstantBuffers/PostProcessBuffer.h
+++ b/TombEngine/Renderer/ConstantBuffers/PostProcessBuffer.h
@@ -4,6 +4,12 @@ namespace TEN::Renderer::ConstantBuffers
{
using namespace DirectX::SimpleMath;
+ struct alignas(16) ShaderLensFlare
+ {
+ Vector3 Position;
+ float Padding;
+ };
+
struct alignas(16) CPostProcessBuffer
{
float CinematicBarsHeight;
@@ -15,5 +21,9 @@ namespace TEN::Renderer::ConstantBuffers
Vector3 Tint;
//--
Vector4 SSAOKernel[64];
+ //--
+ ShaderLensFlare LensFlares[4];
+ //--
+ int NumLensFlares;
};
}
\ No newline at end of file
diff --git a/TombEngine/Renderer/RendererPostProcess.cpp b/TombEngine/Renderer/RendererPostProcess.cpp
index 300322794..99867f4b7 100644
--- a/TombEngine/Renderer/RendererPostProcess.cpp
+++ b/TombEngine/Renderer/RendererPostProcess.cpp
@@ -70,7 +70,7 @@ namespace TEN::Renderer
}
BindRenderTargetAsTexture(TextureRegister::ColorMap, &_postProcessRenderTarget[currentRenderTarget], SamplerStateRegister::PointWrap);
- DrawTriangles(3, 0);
+ DrawTriangles(3, 0);
destinationRenderTarget = destinationRenderTarget == 1 ? 0 : 1;
currentRenderTarget = currentRenderTarget == 1 ? 0 : 1;
@@ -82,6 +82,11 @@ namespace TEN::Renderer
_context->OMSetRenderTargets(1, _postProcessRenderTarget[destinationRenderTarget].RenderTargetView.GetAddressOf(), nullptr);
_context->PSSetShader(_psPostProcessLensFlare.Get(), nullptr, 0);
+
+ _stPostProcessBuffer.LensFlares[0].Position = Vector3(0, -10000, 0);
+ _stPostProcessBuffer.NumLensFlares = 1;
+ _cbPostProcessBuffer.UpdateData(_stPostProcessBuffer, _context.Get());
+
BindRenderTargetAsTexture(TextureRegister::ColorMap, &_postProcessRenderTarget[currentRenderTarget], SamplerStateRegister::PointWrap);
DrawTriangles(3, 0);
diff --git a/TombEngine/Renderer/Structures/RendererLensFlare.h b/TombEngine/Renderer/Structures/RendererLensFlare.h
new file mode 100644
index 000000000..0385700bb
--- /dev/null
+++ b/TombEngine/Renderer/Structures/RendererLensFlare.h
@@ -0,0 +1,14 @@
+#pragma once
+#include
+#include "Renderer/RendererEnums.h"
+
+namespace TEN::Renderer::Structures
+{
+ using namespace DirectX::SimpleMath;
+
+ struct RendererLensFlare
+ {
+ Vector3 Position;
+ float Padding;
+ };
+}
\ No newline at end of file
diff --git a/TombEngine/Shaders/CBPostProcess.hlsli b/TombEngine/Shaders/CBPostProcess.hlsli
index a4ab6cd8b..4d292c5aa 100644
--- a/TombEngine/Shaders/CBPostProcess.hlsli
+++ b/TombEngine/Shaders/CBPostProcess.hlsli
@@ -1,5 +1,11 @@
#include "./Math.hlsli"
+struct ShaderLensFlare
+{
+ float3 Position;
+ float Padding;
+};
+
cbuffer CBPostProcess : register(b7)
{
float CinematicBarsHeight;
@@ -11,4 +17,8 @@ cbuffer CBPostProcess : register(b7)
float3 Tint;
//--
float4 SSAOKernel[64];
+ //--
+ ShaderLensFlare LensFlares[4];
+ //--
+ int NumLensFlares;
};
\ No newline at end of file
diff --git a/TombEngine/Shaders/PostProcess.fx b/TombEngine/Shaders/PostProcess.fx
index 2c090a27d..1fa91fb39 100644
--- a/TombEngine/Shaders/PostProcess.fx
+++ b/TombEngine/Shaders/PostProcess.fx
@@ -146,25 +146,20 @@ float4 PSLensFlare(PixelShaderInput input) : SV_Target
float4 color = ColorTexture.Sample(ColorSampler, input.UV);
float4 position = input.PositionCopy;
+ float3 totalLensFlareColor = float3(0.0f, 0.0f, 0.0f);
- position.xyz /= position.w;
- position.xyz = position.xyz * 0.5f + 0.5f;
- position.y = 1.0f - position.y;
+ for (int i = 0; i < NumLensFlares; i++)
+ {
+ float4 lensFlarePosition = float4(LensFlares[i].Position, 1.0f);
+ lensFlarePosition = mul(mul(lensFlarePosition, View), Projection);
+ lensFlarePosition.xyz /= lensFlarePosition.w;
- float4 offset = float4(0,-5000,0, 1.0);
- offset = mul(mul(offset, View), Projection);
- offset.xyz /= offset.w;
+ float3 lensFlareColor = max(float3(0.0f, 0.0f, 0.0f), float3(4.5f, 3.6f, 3.6f) * LensFlare(position.xy, lensFlarePosition.xy));
+ lensFlareColor = LensFlareColorCorrection(lensFlareColor, 0.5f, 0.1f);
+ totalLensFlareColor += lensFlareColor;
+ }
- //offset.xyz /= offset.w;
- // offset.xyz = offset.xyz * 0.5f + 0.5f;
- // offset.y = 1.0f - offset.y;
+ color.xyz += totalLensFlareColor;
- position = input.PositionCopy;
-
-
- float3 lensFlareColor = max(float3(0.0f, 0.0f, 0.0f), float3(4.5f, 3.6f, 3.6f) * LensFlare(position.xy, offset.xy));
- lensFlareColor = LensFlareColorCorrection(lensFlareColor, 0.5f, 0.1f);
- color.xyz += lensFlareColor;
-
return color;
}
\ No newline at end of file
diff --git a/TombEngine/TombEngine.vcxproj b/TombEngine/TombEngine.vcxproj
index 32b5b12f6..2615d05d2 100644
--- a/TombEngine/TombEngine.vcxproj
+++ b/TombEngine/TombEngine.vcxproj
@@ -732,6 +732,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
+
From 374697f38b5be933f3ee6da9a958bb225957cbea Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Sat, 20 Apr 2024 05:41:01 +0200
Subject: [PATCH 084/410] WIP ID_LENS_FLARE objects
---
TombEngine/Objects/Effects/lens_flare.cpp | 28 +++++++++++++++++++++++
TombEngine/Objects/Effects/lens_flare.h | 20 ++++++++++++++++
TombEngine/TombEngine.vcxproj | 2 ++
3 files changed, 50 insertions(+)
create mode 100644 TombEngine/Objects/Effects/lens_flare.cpp
create mode 100644 TombEngine/Objects/Effects/lens_flare.h
diff --git a/TombEngine/Objects/Effects/lens_flare.cpp b/TombEngine/Objects/Effects/lens_flare.cpp
new file mode 100644
index 000000000..e03d3c448
--- /dev/null
+++ b/TombEngine/Objects/Effects/lens_flare.cpp
@@ -0,0 +1,28 @@
+#include "framework.h"
+#include "Objects/Effects/lens_flare.h"
+#include "Specific/level.h"
+
+namespace TEN::Entities::Effects
+{
+ std::vector LensFlares;
+
+ void LensFlareControl(short itemNumber)
+ {
+ auto* item = &g_Level.Items[itemNumber];
+
+ if (TriggerActive(item))
+ {
+ LensFlare lensFlare;
+
+ lensFlare.Position = item->Pose.Position.ToVector3();
+ lensFlare.RoomNumber = item->RoomNumber;
+
+ LensFlares.push_back(lensFlare);
+ }
+ }
+
+ void ClearLensFlares()
+ {
+ LensFlare.clear();
+ }
+}
\ No newline at end of file
diff --git a/TombEngine/Objects/Effects/lens_flare.h b/TombEngine/Objects/Effects/lens_flare.h
new file mode 100644
index 000000000..3acaab5b7
--- /dev/null
+++ b/TombEngine/Objects/Effects/lens_flare.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include
+#include
+
+namespace TEN::Entities::Effects
+{
+ using namespace DirectX::SimpleMath;
+
+ struct LensFlare
+ {
+ Vector3 Position;
+ short RoomNumber;
+ };
+
+ extern std::vector LensFlares;
+
+ void LensFlareControl(short itemNumber);
+ void ClearLensFlares();
+}
\ No newline at end of file
diff --git a/TombEngine/TombEngine.vcxproj b/TombEngine/TombEngine.vcxproj
index 2615d05d2..44ef99dbf 100644
--- a/TombEngine/TombEngine.vcxproj
+++ b/TombEngine/TombEngine.vcxproj
@@ -441,6 +441,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
+
@@ -950,6 +951,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
+
From 994dc69ce0ce62059827a265fef5d5d21db9e4f1 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Sat, 20 Apr 2024 06:30:00 +0200
Subject: [PATCH 085/410] Implemented ID_LENS_FARE objects
---
TombEngine/Game/control/control.cpp | 3 ++
TombEngine/Objects/Effects/effect_objects.cpp | 8 ++++
TombEngine/Objects/Effects/lens_flare.cpp | 2 +-
TombEngine/Objects/TR5/tr5_objects.cpp | 7 ----
TombEngine/Renderer/RenderView.cpp | 1 +
TombEngine/Renderer/RenderView.h | 2 +
TombEngine/Renderer/RendererFrame.cpp | 40 ++++++++++++++-----
TombEngine/Renderer/RendererPostProcess.cpp | 11 +++--
8 files changed, 53 insertions(+), 21 deletions(-)
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index 0f86ed4b4..b0a419461 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -60,6 +60,7 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
#include "Specific/winmain.h"
+#include "Objects/Effects/lens_flare.h"
using namespace std::chrono;
using namespace TEN::Effects;
@@ -87,6 +88,7 @@ using namespace TEN::Math;
using namespace TEN::Renderer;
using namespace TEN::Traps::TR5;
using namespace TEN::Entities::Creatures::TR3;
+using namespace TEN::Entities::Effects;
int GameTimer = 0;
int GlobalCounter = 0;
@@ -140,6 +142,7 @@ GameStatus ControlPhase(int numFrames)
ClearFires();
g_Renderer.ClearDynamicLights();
RegeneratePickups();
+ ClearLensFlares();
numFrames = std::clamp(numFrames, 0, 10);
diff --git a/TombEngine/Objects/Effects/effect_objects.cpp b/TombEngine/Objects/Effects/effect_objects.cpp
index 6014c7c5b..1449d8ed2 100644
--- a/TombEngine/Objects/Effects/effect_objects.cpp
+++ b/TombEngine/Objects/Effects/effect_objects.cpp
@@ -4,6 +4,7 @@
#include "Game/Setup.h"
#include "Objects/Effects/flame_emitters.h"
#include "Objects/Effects/enemy_missile.h"
+#include "Objects/Effects/lens_flare.h"
using namespace TEN::Entities::Effects;
@@ -54,4 +55,11 @@ void InitializeEffectsObjects()
obj->collision = nullptr;
obj->control = ControlEnemyMissile;
}
+
+ obj = &Objects[ID_LENS_FLARE];
+ if (obj->loaded)
+ {
+ obj->control = LensFlareControl;
+ }
+
}
\ No newline at end of file
diff --git a/TombEngine/Objects/Effects/lens_flare.cpp b/TombEngine/Objects/Effects/lens_flare.cpp
index e03d3c448..fb60940b5 100644
--- a/TombEngine/Objects/Effects/lens_flare.cpp
+++ b/TombEngine/Objects/Effects/lens_flare.cpp
@@ -23,6 +23,6 @@ namespace TEN::Entities::Effects
void ClearLensFlares()
{
- LensFlare.clear();
+ LensFlares.clear();
}
}
\ No newline at end of file
diff --git a/TombEngine/Objects/TR5/tr5_objects.cpp b/TombEngine/Objects/TR5/tr5_objects.cpp
index 686c9d28c..9a31f90c7 100644
--- a/TombEngine/Objects/TR5/tr5_objects.cpp
+++ b/TombEngine/Objects/TR5/tr5_objects.cpp
@@ -818,13 +818,6 @@ static void StartObject(ObjectInfo *obj)
obj->usingDrawAnimatingItem = false;
}
- obj = &Objects[ID_LENS_FLARE];
- if (obj->loaded)
- {
- //obj->drawRoutine = DrawLensFlare;
-
- }
-
obj = &Objects[ID_WATERFALLSS1];
if (obj->loaded)
{
diff --git a/TombEngine/Renderer/RenderView.cpp b/TombEngine/Renderer/RenderView.cpp
index 3c6d416b3..6558d062c 100644
--- a/TombEngine/Renderer/RenderView.cpp
+++ b/TombEngine/Renderer/RenderView.cpp
@@ -51,6 +51,7 @@ namespace TEN::Renderer
DisplaySpritesToDraw.clear();
SortedStaticsToDraw.clear();
FogBulbsToDraw.clear();
+ LensFlaresToDraw.clear();
}
RenderViewCamera::RenderViewCamera(CAMERA_INFO* cam, float roll, float fov, float n, float f, int w, int h)
diff --git a/TombEngine/Renderer/RenderView.h b/TombEngine/Renderer/RenderView.h
index 5260b7626..b028b4788 100644
--- a/TombEngine/Renderer/RenderView.h
+++ b/TombEngine/Renderer/RenderView.h
@@ -14,6 +14,7 @@
#include "Renderer/Structures/RendererRoom.h"
#include "Renderer/Structures/RendererSortableObject.h"
#include "Renderer/Structures/RendererSpriteToDraw.h"
+#include "Renderer/Structures/RendererLensFlare.h"
namespace TEN::Renderer
{
@@ -51,6 +52,7 @@ namespace TEN::Renderer
std::vector DisplaySpritesToDraw = {};
std::map> SortedStaticsToDraw = {};
std::vector TransparentObjectsToDraw = {};
+ std::vector LensFlaresToDraw = {};
RenderView(CAMERA_INFO* cam, float roll, float fov, float nearPlane, float farPlane, int w, int h);
RenderView(const Vector3& pos, const Vector3& dir, const Vector3& up, int w, int h, int room, float nearPlane, float farPlane, float fov);
diff --git a/TombEngine/Renderer/RendererFrame.cpp b/TombEngine/Renderer/RendererFrame.cpp
index e5389d24b..1b9956cc1 100644
--- a/TombEngine/Renderer/RendererFrame.cpp
+++ b/TombEngine/Renderer/RendererFrame.cpp
@@ -13,8 +13,10 @@
#include "Math/Math.h"
#include "Specific/level.h"
#include "Renderer/RenderView.h"
+#include "Objects/Effects/lens_flare.h"
using namespace TEN::Math;
+using namespace TEN::Entities::Effects;
namespace TEN::Renderer
{
@@ -27,10 +29,10 @@ namespace TEN::Renderer
_visitedRoomsStack.clear();
for (int i = 0; i < g_Level.Rooms.size(); i++)
- {
+ {
auto& room = _rooms[i];
-
- room.ItemsToDraw.clear();
+
+ room.ItemsToDraw.clear();
room.EffectsToDraw.clear();
room.StaticsToDraw.clear();
room.LightsToDraw.clear();
@@ -47,7 +49,7 @@ namespace TEN::Renderer
GetVisibleRooms(NO_VALUE, renderView.Camera.RoomNumber, VIEW_PORT, false, 0, onlyRooms, renderView);
- _invalidateCache = false;
+ _invalidateCache = false;
// Prepare real DX scissor test rectangle.
for (auto* roomPtr : renderView.RoomsToDraw)
@@ -56,17 +58,17 @@ namespace TEN::Renderer
roomPtr->ClipBounds.Bottom = (1.0f - roomPtr->ViewPort.y) * _screenHeight * 0.5f;
roomPtr->ClipBounds.Right = (roomPtr->ViewPort.z + 1.0f) * _screenWidth * 0.5f;
roomPtr->ClipBounds.Top = (1.0f - roomPtr->ViewPort.w) * _screenHeight * 0.5f;
- }
+ }
// Collect fog bulbs.
std::vector tempFogBulbs;
tempFogBulbs.reserve(MAX_FOG_BULBS_DRAW);
- for (auto& room : _rooms)
+ for (auto& room : _rooms)
{
if (!g_Level.Rooms[room.RoomNumber].Active())
continue;
-
+
for (const auto& light : room.Lights)
{
if (light.Type != LightType::FogBulb)
@@ -76,7 +78,7 @@ namespace TEN::Renderer
if (renderView.Camera.Frustum.SphereInFrustum(light.Position, light.Out * 1.2f))
{
RendererFogBulb bulb;
-
+
bulb.Position = light.Position;
bulb.Density = light.Intensity;
bulb.Color = light.Color;
@@ -88,7 +90,7 @@ namespace TEN::Renderer
}
}
}
-
+
// Sort fog bulbs.
std::sort(
tempFogBulbs.begin(),
@@ -100,6 +102,26 @@ namespace TEN::Renderer
for (int i = 0; i < std::min(MAX_FOG_BULBS_DRAW, (int)tempFogBulbs.size()); i++)
renderView.FogBulbsToDraw.push_back(tempFogBulbs[i]);
+
+ // Collect lens flares
+ for (auto lensFlare : LensFlares)
+ {
+ if (Vector3::Distance(lensFlare.Position, renderView.Camera.WorldPosition) < BLOCK(32))
+ {
+ Vector3 lensFlareToCamera = lensFlare.Position - renderView.Camera.WorldPosition;
+ Vector3 cameraDirection = renderView.Camera.WorldDirection;
+
+ lensFlareToCamera.Normalize();
+ cameraDirection.Normalize();
+
+ if (lensFlareToCamera.Dot(cameraDirection) >= 0.0f)
+ {
+ RendererLensFlare lensFlareToDraw;
+ lensFlareToDraw.Position = lensFlare.Position;
+ renderView.LensFlaresToDraw.push_back(lensFlareToDraw);
+ }
+ }
+ }
}
bool Renderer::CheckPortal(short parentRoomNumber, RendererDoor* door, Vector4 viewPort, Vector4* clipPort, RenderView& renderView)
diff --git a/TombEngine/Renderer/RendererPostProcess.cpp b/TombEngine/Renderer/RendererPostProcess.cpp
index 99867f4b7..c53787082 100644
--- a/TombEngine/Renderer/RendererPostProcess.cpp
+++ b/TombEngine/Renderer/RendererPostProcess.cpp
@@ -83,16 +83,19 @@ namespace TEN::Renderer
_context->PSSetShader(_psPostProcessLensFlare.Get(), nullptr, 0);
- _stPostProcessBuffer.LensFlares[0].Position = Vector3(0, -10000, 0);
- _stPostProcessBuffer.NumLensFlares = 1;
- _cbPostProcessBuffer.UpdateData(_stPostProcessBuffer, _context.Get());
+ for (int i = 0; i < view.LensFlaresToDraw.size(); i++)
+ {
+ _stPostProcessBuffer.LensFlares[i].Position = view.LensFlaresToDraw[i].Position;
+ }
+ _stPostProcessBuffer.NumLensFlares = (int)view.LensFlaresToDraw.size();
+ _cbPostProcessBuffer.UpdateData(_stPostProcessBuffer, _context.Get());
BindRenderTargetAsTexture(TextureRegister::ColorMap, &_postProcessRenderTarget[currentRenderTarget], SamplerStateRegister::PointWrap);
DrawTriangles(3, 0);
destinationRenderTarget = destinationRenderTarget == 1 ? 0 : 1;
currentRenderTarget = currentRenderTarget == 1 ? 0 : 1;
- }
+ }
// Do the final pass
_context->PSSetShader(_psPostProcessFinalPass.Get(), nullptr, 0);
From e73bb7b92b7740e68af43b40b00712134540bece Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Sat, 20 Apr 2024 06:44:12 +0200
Subject: [PATCH 086/410] Increased max lens flares to 8; Choose the nearest 8
ones; Make the code in post process optional only if some lens flares are
available; Max distance of lens flare 20 blocks and they must be in the same
room of camera;
---
.../ConstantBuffers/PostProcessBuffer.h | 3 ++-
TombEngine/Renderer/RendererEnums.h | 1 +
TombEngine/Renderer/RendererFrame.cpp | 22 ++++++++++++++++---
TombEngine/Renderer/RendererPostProcess.cpp | 13 ++++++-----
.../Renderer/Structures/RendererLensFlare.h | 2 +-
TombEngine/Shaders/CBPostProcess.hlsli | 2 +-
6 files changed, 31 insertions(+), 12 deletions(-)
diff --git a/TombEngine/Renderer/ConstantBuffers/PostProcessBuffer.h b/TombEngine/Renderer/ConstantBuffers/PostProcessBuffer.h
index bd86c56f4..130136463 100644
--- a/TombEngine/Renderer/ConstantBuffers/PostProcessBuffer.h
+++ b/TombEngine/Renderer/ConstantBuffers/PostProcessBuffer.h
@@ -1,4 +1,5 @@
#include
+#include "Renderer/RendererEnums.h"
namespace TEN::Renderer::ConstantBuffers
{
@@ -22,7 +23,7 @@ namespace TEN::Renderer::ConstantBuffers
//--
Vector4 SSAOKernel[64];
//--
- ShaderLensFlare LensFlares[4];
+ ShaderLensFlare LensFlares[MAX_LENS_FLARES_DRAW];
//--
int NumLensFlares;
};
diff --git a/TombEngine/Renderer/RendererEnums.h b/TombEngine/Renderer/RendererEnums.h
index 5d46489ce..69fa97d1e 100644
--- a/TombEngine/Renderer/RendererEnums.h
+++ b/TombEngine/Renderer/RendererEnums.h
@@ -64,6 +64,7 @@ constexpr auto MAX_ITEMS_DRAW = 128;
constexpr auto MAX_LIGHTS_DRAW = 48;
constexpr auto MAX_FOG_BULBS_DRAW = 32;
constexpr auto MAX_SPRITES_DRAW = 512;
+constexpr auto MAX_LENS_FLARES_DRAW = 8;
constexpr auto ROOM_AMBIENT_MAP_SIZE = 32;
constexpr auto MAX_ROOM_AMBIENT_MAPS = 10;
diff --git a/TombEngine/Renderer/RendererFrame.cpp b/TombEngine/Renderer/RendererFrame.cpp
index 1b9956cc1..7169c1785 100644
--- a/TombEngine/Renderer/RendererFrame.cpp
+++ b/TombEngine/Renderer/RendererFrame.cpp
@@ -91,7 +91,6 @@ namespace TEN::Renderer
}
}
- // Sort fog bulbs.
std::sort(
tempFogBulbs.begin(),
tempFogBulbs.end(),
@@ -104,9 +103,14 @@ namespace TEN::Renderer
renderView.FogBulbsToDraw.push_back(tempFogBulbs[i]);
// Collect lens flares
+ std::vector tempLensFlares;
+ tempLensFlares.reserve(MAX_LENS_FLARES_DRAW);
+
for (auto lensFlare : LensFlares)
{
- if (Vector3::Distance(lensFlare.Position, renderView.Camera.WorldPosition) < BLOCK(32))
+ float distance = Vector3::Distance(lensFlare.Position, renderView.Camera.WorldPosition);
+
+ if (lensFlare.RoomNumber == Camera.pos.RoomNumber && distance < BLOCK(20))
{
Vector3 lensFlareToCamera = lensFlare.Position - renderView.Camera.WorldPosition;
Vector3 cameraDirection = renderView.Camera.WorldDirection;
@@ -118,10 +122,22 @@ namespace TEN::Renderer
{
RendererLensFlare lensFlareToDraw;
lensFlareToDraw.Position = lensFlare.Position;
- renderView.LensFlaresToDraw.push_back(lensFlareToDraw);
+ lensFlareToDraw.Distance = distance;
+ tempLensFlares.push_back(lensFlareToDraw);
}
}
}
+
+ std::sort(
+ tempLensFlares.begin(),
+ tempLensFlares.end(),
+ [](const RendererLensFlare& lensFlare0, const RendererLensFlare& lensFlare1)
+ {
+ return lensFlare0.Distance < lensFlare1.Distance;
+ });
+
+ for (int i = 0; i < std::min(MAX_LENS_FLARES_DRAW, (int)tempLensFlares.size()); i++)
+ renderView.LensFlaresToDraw.push_back(tempLensFlares[i]);
}
bool Renderer::CheckPortal(short parentRoomNumber, RendererDoor* door, Vector4 viewPort, Vector4* clipPort, RenderView& renderView)
diff --git a/TombEngine/Renderer/RendererPostProcess.cpp b/TombEngine/Renderer/RendererPostProcess.cpp
index c53787082..3393dfacc 100644
--- a/TombEngine/Renderer/RendererPostProcess.cpp
+++ b/TombEngine/Renderer/RendererPostProcess.cpp
@@ -50,7 +50,7 @@ namespace TEN::Renderer
{
_context->ClearRenderTargetView(_postProcessRenderTarget[destinationRenderTarget].RenderTargetView.Get(), clearColor);
_context->OMSetRenderTargets(1, _postProcessRenderTarget[destinationRenderTarget].RenderTargetView.GetAddressOf(), nullptr);
-
+
switch (_postProcessMode)
{
case PostProcessMode::Monochrome:
@@ -64,19 +64,20 @@ namespace TEN::Renderer
case PostProcessMode::Exclusion:
_context->PSSetShader(_psPostProcessExclusion.Get(), nullptr, 0);
break;
-
+
default:
return;
}
BindRenderTargetAsTexture(TextureRegister::ColorMap, &_postProcessRenderTarget[currentRenderTarget], SamplerStateRegister::PointWrap);
- DrawTriangles(3, 0);
+ DrawTriangles(3, 0);
destinationRenderTarget = destinationRenderTarget == 1 ? 0 : 1;
currentRenderTarget = currentRenderTarget == 1 ? 0 : 1;
- }
-
- // Lens flare
+ }
+
+ // Lens flares
+ if (view.LensFlaresToDraw.size() > 0)
{
_context->ClearRenderTargetView(_postProcessRenderTarget[destinationRenderTarget].RenderTargetView.Get(), clearColor);
_context->OMSetRenderTargets(1, _postProcessRenderTarget[destinationRenderTarget].RenderTargetView.GetAddressOf(), nullptr);
diff --git a/TombEngine/Renderer/Structures/RendererLensFlare.h b/TombEngine/Renderer/Structures/RendererLensFlare.h
index 0385700bb..4acb56fcd 100644
--- a/TombEngine/Renderer/Structures/RendererLensFlare.h
+++ b/TombEngine/Renderer/Structures/RendererLensFlare.h
@@ -9,6 +9,6 @@ namespace TEN::Renderer::Structures
struct RendererLensFlare
{
Vector3 Position;
- float Padding;
+ float Distance;
};
}
\ No newline at end of file
diff --git a/TombEngine/Shaders/CBPostProcess.hlsli b/TombEngine/Shaders/CBPostProcess.hlsli
index 4d292c5aa..dfe6f2514 100644
--- a/TombEngine/Shaders/CBPostProcess.hlsli
+++ b/TombEngine/Shaders/CBPostProcess.hlsli
@@ -18,7 +18,7 @@ cbuffer CBPostProcess : register(b7)
//--
float4 SSAOKernel[64];
//--
- ShaderLensFlare LensFlares[4];
+ ShaderLensFlare LensFlares[8];
//--
int NumLensFlares;
};
\ No newline at end of file
From a7dcba12cefcd4a0e3fd800e1a8f9adf55aa403e Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Sun, 21 Apr 2024 19:39:05 +0200
Subject: [PATCH 087/410] Fix directional flame emitters
---
TombEngine/Game/effects/effects.cpp | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/TombEngine/Game/effects/effects.cpp b/TombEngine/Game/effects/effects.cpp
index fd825b073..4cdc79ac4 100644
--- a/TombEngine/Game/effects/effects.cpp
+++ b/TombEngine/Game/effects/effects.cpp
@@ -939,14 +939,17 @@ void TriggerSuperJetFlame(ItemInfo* item, int yvel, int deadly)
float xAngle = item->Pose.Orientation.x;
float yAngle = item->Pose.Orientation.y;
+
+ Vector3 dir;
+ dir.x = phd_cos(xAngle) * phd_sin(yAngle);
+ dir.y = phd_sin(xAngle);
+ dir.z = phd_cos(xAngle) * phd_cos(yAngle);
- float xDir = phd_cos(yAngle) * phd_cos(xAngle);
- float zDir = phd_sin(yAngle) * phd_cos(xAngle);
- float yDir = phd_sin(xAngle);
+ dir.Normalize();
- sptr->xVel += xDir * (size - (size >> 2));
- sptr->yVel += yDir * (size - (size >> 2));
- sptr->zVel += zDir * (size - (size >> 2));
+ sptr->xVel += dir.x * (size - (size >> 2));
+ sptr->yVel -= dir.y * (size - (size >> 2));
+ sptr->zVel += dir.z * (size - (size >> 2));
}
}
From 29ebdf452fa42d53add505e9b0d4ccf800f46ab2 Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Mon, 22 Apr 2024 20:58:46 +0200
Subject: [PATCH 088/410] Update effects.cpp
---
TombEngine/Game/effects/effects.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/TombEngine/Game/effects/effects.cpp b/TombEngine/Game/effects/effects.cpp
index 4cdc79ac4..1a67640be 100644
--- a/TombEngine/Game/effects/effects.cpp
+++ b/TombEngine/Game/effects/effects.cpp
@@ -937,7 +937,7 @@ void TriggerSuperJetFlame(ItemInfo* item, int yvel, int deadly)
sptr->xVel = (GetRandomControl() & 0xFF) - 128;
sptr->zVel = (GetRandomControl() & 0xFF) - 128;
- float xAngle = item->Pose.Orientation.x;
+ float xAngle = item->Pose.Orientation.x + ANGLE(180); // Nullmesh is rotated 180 degrees in editor
float yAngle = item->Pose.Orientation.y;
Vector3 dir;
From c55b25239372709d18d14ce707b3f4f2eee391df Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Tue, 23 Apr 2024 20:40:51 +0200
Subject: [PATCH 089/410] Global lens flare; Starry night simulation;
---
TombEngine/Game/control/control.cpp | 1 +
TombEngine/Game/effects/weather.cpp | 124 ++++++++++++
TombEngine/Game/effects/weather.h | 37 ++++
TombEngine/Objects/Effects/lens_flare.cpp | 86 +++++++-
TombEngine/Objects/Effects/lens_flare.h | 3 +
TombEngine/Objects/objectslist.h | 6 +-
TombEngine/Renderer/Renderer.h | 2 +
TombEngine/Renderer/RendererDraw.cpp | 190 +++++++++++++++++-
TombEngine/Renderer/RendererFrame.cpp | 41 ++--
.../Renderer/Structures/RendererLensFlare.h | 2 +
TombEngine/Renderer/Structures/RendererStar.h | 17 ++
TombEngine/TombEngine.vcxproj | 1 +
12 files changed, 486 insertions(+), 24 deletions(-)
create mode 100644 TombEngine/Renderer/Structures/RendererStar.h
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index b0a419461..d3fa54462 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -243,6 +243,7 @@ GameStatus ControlPhase(int numFrames)
UpdateBeetleSwarm();
UpdateLocusts();
UpdateUnderwaterBloodParticles();
+ SetupGlobalLensFlare(180.0f, 30.0f);
// Update HUD.
g_Hud.Update(*LaraItem);
diff --git a/TombEngine/Game/effects/weather.cpp b/TombEngine/Game/effects/weather.cpp
index 16f24c5b0..b5b4667ad 100644
--- a/TombEngine/Game/effects/weather.cpp
+++ b/TombEngine/Game/effects/weather.cpp
@@ -39,6 +39,12 @@ namespace TEN::Effects::Environment
constexpr auto DUST_LIFE = 40;
constexpr auto DUST_SPAWN_RADIUS = (10 * 1024);
+ constexpr auto METEOR_PARTICLES_MAX_COUNT = 10;
+ constexpr auto METEOR_PARTICLES_MAX_LIFE = 150;
+ constexpr auto METEOR_PARTICLES_SPEED = 32.0f;
+ constexpr auto METEOR_PARTICLES_SPAWN_DENSITY = 4;
+ constexpr auto METEOR_PARTICLES_FADE_TIME = 30;
+
EnvironmentController Weather;
float WeatherParticle::Transparency() const
@@ -72,8 +78,11 @@ namespace TEN::Effects::Environment
UpdateWind(level);
UpdateFlash(level);
UpdateWeather(level);
+ UpdateStarfield(level);
+
SpawnWeatherParticles(level);
SpawnDustParticles(level);
+ SpawnMeteorParticles(level);
}
void EnvironmentController::Clear()
@@ -93,6 +102,10 @@ namespace TEN::Effects::Environment
// Clear weather
Particles.clear();
+
+ // Clear starfield
+ ResetStarField = true;
+ Meteors.clear();
}
void EnvironmentController::Flash(int r, int g, int b, float speed)
@@ -221,6 +234,74 @@ namespace TEN::Effects::Environment
FlashColorBase = Vector3::Zero;
}
+ void EnvironmentController::UpdateStarfield(ScriptInterfaceLevel* level)
+ {
+ if (ResetStarField)
+ {
+ Stars.clear();
+ Stars.reserve(StarsCount);
+
+ for (int i = 0; i < StarsCount; i++)
+ {
+ Vector3 starDirection = Random::GenerateDirectionInCone(-Vector3::UnitY, 70.0f);
+ starDirection.Normalize();
+
+ StarParticle star;
+ star.Direction = starDirection;
+ star.Color = Vector3(
+ Random::GenerateFloat(0.6f, 1.0f),
+ Random::GenerateFloat(0.6f, 1.0f),
+ Random::GenerateFloat(0.6f, 1.0f)
+ );
+ star.Scale = Random::GenerateFloat(0.5f, 1.5f);
+
+ float cosine = Vector3::UnitY.Dot(starDirection);
+ float maxCosine = cos(DEG_TO_RAD(50));
+ float minCosine = cos(DEG_TO_RAD(70));
+
+ if (cosine >= minCosine && cosine <= maxCosine)
+ {
+ star.Extinction = (cosine - minCosine) / (maxCosine - minCosine);
+ }
+ else
+ {
+ star.Extinction = 1.0f;
+ }
+
+ Stars.push_back(star);
+ }
+
+ ResetStarField = false;
+ }
+
+ for (auto& s : Stars)
+ {
+ s.Blinking = Random::GenerateFloat(0.5f, 1.0f);
+ }
+
+ for (auto& m : Meteors)
+ {
+ //p.StoreInterpolationData();
+
+ m.Life--;
+
+ if (m.Life <= 0)
+ {
+ m.Active = false;
+ continue;
+ }
+
+ if (m.Life <= METEOR_PARTICLES_FADE_TIME)
+ m.Fade = m.Life / (float)METEOR_PARTICLES_FADE_TIME;
+ else if (m.Life >= METEOR_PARTICLES_MAX_LIFE - METEOR_PARTICLES_FADE_TIME)
+ m.Fade = (METEOR_PARTICLES_MAX_LIFE - m.Life) / (float)METEOR_PARTICLES_FADE_TIME;
+ else
+ m.Fade = 1.0f;
+
+ m.Position += m.Direction * METEOR_PARTICLES_SPEED;
+ }
+ }
+
void EnvironmentController::UpdateWeather(ScriptInterfaceLevel* level)
{
for (auto& p : Particles)
@@ -519,4 +600,47 @@ namespace TEN::Effects::Environment
}
}
}
+
+ void EnvironmentController::SpawnMeteorParticles(ScriptInterfaceLevel* level)
+ {
+ // Clean up dead particles
+ if (Meteors.size() > 0)
+ Meteors.erase(std::remove_if(Meteors.begin(), Meteors.end(), [](const MeteorParticle& part) { return !part.Active; }), Meteors.end());
+
+ //if (level->GetWeatherType() == WeatherType::None || level->GetWeatherStrength() == 0.0f)
+ // return;
+
+ int newParticlesCount = 0;
+ int density = METEOR_PARTICLES_SPAWN_DENSITY;
+
+ if (density > 0.0f /* && level->GetWeatherType() != WeatherType::None */)
+ {
+ while (Meteors.size() < METEOR_PARTICLES_MAX_COUNT)
+ {
+ if (newParticlesCount > density)
+ break;
+
+ newParticlesCount++;
+
+ auto part = MeteorParticle();
+
+ part.Active = true;
+ part.Life = METEOR_PARTICLES_MAX_LIFE;
+ part.StartPosition = part.Position = Random::GenerateDirectionInCone(-Vector3::UnitY, 40.0f) * BLOCK(1.5f);
+ part.Fade = 0.0f;
+ part.Color = Vector3(
+ Random::GenerateFloat(0.6f, 1.0f),
+ Random::GenerateFloat(0.6f, 1.0f),
+ Random::GenerateFloat(0.6f, 1.0f)
+ );
+
+ Vector2 horizontalDirection = Random::GenerateDirection2D();
+ part.Direction = Random::GenerateDirectionInCone(Vector3(horizontalDirection.x, 0, horizontalDirection.y), 10.0f);
+ if (part.Direction.y < 0.0f)
+ part.Direction.y = -part.Direction.y;
+
+ Meteors.push_back(part);
+ }
+ }
+ }
}
diff --git a/TombEngine/Game/effects/weather.h b/TombEngine/Game/effects/weather.h
index 214cd1ff5..0efc267b7 100644
--- a/TombEngine/Game/effects/weather.h
+++ b/TombEngine/Game/effects/weather.h
@@ -2,9 +2,33 @@
#include
#include "Scripting/Include/ScriptInterfaceLevel.h"
#include "Math/Math.h"
+#include "Objects/Effects/lens_flare.h"
+
+using namespace TEN::Entities::Effects;
namespace TEN::Effects::Environment
{
+ struct StarParticle
+ {
+ Vector3 Position = Vector3::Zero;
+ Vector3 Direction = Vector3::Zero;
+ Vector3 Color = Vector3::Zero;
+ float Extinction = 1.0f;
+ float Scale = 1.0f;
+ float Blinking = 1.0f;
+ };
+
+ struct MeteorParticle
+ {
+ Vector3 Position = Vector3::Zero;
+ Vector3 Direction = Vector3::Zero;
+ Vector3 StartPosition = Vector3::Zero;
+ Vector3 Color = Vector3::Zero;
+ float Life;
+ bool Active;
+ float Fade;
+ };
+
struct WeatherParticle
{
WeatherType Type = WeatherType::None;
@@ -52,6 +76,8 @@ namespace TEN::Effects::Environment
void Clear();
const std::vector& GetParticles() const { return Particles; }
+ const std::vector& GetStars() const { return Stars; }
+ const std::vector& GetMeteors() { return Meteors; }
private:
// Weather
@@ -80,6 +106,16 @@ namespace TEN::Effects::Environment
byte StormSkyColor = 1;
byte StormSkyColor2 = 1;
+ // Starfield
+ int StarsCount = 3000;
+ std::vector Stars;
+ std::vector Meteors;
+ bool ResetStarField = true;
+
+ // Lens flare
+ LensFlare GlobalLensFlare;
+
+ void UpdateStarfield(ScriptInterfaceLevel* level);
void UpdateSky(ScriptInterfaceLevel* level);
void UpdateStorm(ScriptInterfaceLevel* level);
void UpdateWind(ScriptInterfaceLevel* level);
@@ -89,6 +125,7 @@ namespace TEN::Effects::Environment
void SpawnDustParticles(ScriptInterfaceLevel* level);
void SpawnWeatherParticles(ScriptInterfaceLevel* level);
+ void SpawnMeteorParticles(ScriptInterfaceLevel* level);
};
extern EnvironmentController Weather;
diff --git a/TombEngine/Objects/Effects/lens_flare.cpp b/TombEngine/Objects/Effects/lens_flare.cpp
index fb60940b5..fd06249b8 100644
--- a/TombEngine/Objects/Effects/lens_flare.cpp
+++ b/TombEngine/Objects/Effects/lens_flare.cpp
@@ -1,6 +1,8 @@
#include "framework.h"
#include "Objects/Effects/lens_flare.h"
#include "Specific/level.h"
+#include "Game/camera.h"
+#include "Game/control/los.h"
namespace TEN::Entities::Effects
{
@@ -12,12 +14,7 @@ namespace TEN::Entities::Effects
if (TriggerActive(item))
{
- LensFlare lensFlare;
-
- lensFlare.Position = item->Pose.Position.ToVector3();
- lensFlare.RoomNumber = item->RoomNumber;
-
- LensFlares.push_back(lensFlare);
+ SetupLensFlare(item->Pose.Position.ToVector3(), item->RoomNumber, false);
}
}
@@ -25,4 +22,81 @@ namespace TEN::Entities::Effects
{
LensFlares.clear();
}
+
+ void SetupGlobalLensFlare(float yaw, float pitch)
+ {
+ Vector3 position = Camera.pos.ToVector3();
+ Matrix rotation = Matrix::CreateFromYawPitchRoll(DEG_TO_RAD(yaw), DEG_TO_RAD(pitch), 0);
+ position += Vector3::Transform(Vector3(0, 0, BLOCK(256)), rotation);
+ SetupLensFlare(position, NO_VALUE, true);
+ }
+
+ void SetupLensFlare(Vector3 position, short roomNumber, bool sun)
+ {
+ Vector3 lensFlarePosition;
+
+ if (sun)
+ {
+ if (g_Level.Rooms[Camera.pos.RoomNumber].flags & ENV_FLAG_NO_LENSFLARE)
+ {
+ return;
+ }
+
+ lensFlarePosition = position;
+ Vector3 delta = (lensFlarePosition - Camera.pos.ToVector3()) / 16.0f;
+ while (abs(delta.x) > BLOCK(200) || abs(delta.y) > BLOCK(200) || abs(delta.z) > BLOCK(200))
+ {
+ lensFlarePosition -= delta;
+ }
+
+ delta = (lensFlarePosition - Camera.pos.ToVector3()) / 16.0f;
+ while (abs(delta.x) > BLOCK(32) || abs(delta.y) > BLOCK(32) || abs(delta.z) > BLOCK(32))
+ {
+ lensFlarePosition -= delta;
+ }
+
+ delta = (lensFlarePosition - Camera.pos.ToVector3()) / 16.0f;
+ for (int i = 0; i < 16; i++)
+ {
+ short foundRoomNumber = IsRoomOutside(lensFlarePosition.x, lensFlarePosition.y, lensFlarePosition.z);
+ if (foundRoomNumber != NO_VALUE)
+ {
+ roomNumber = foundRoomNumber;
+ break;
+ }
+ lensFlarePosition -= delta;
+ }
+ }
+ else
+ {
+ if (Vector3::Distance(position, Camera.pos.ToVector3()) > BLOCK(32))
+ {
+ return;
+ }
+ lensFlarePosition = position;
+ }
+
+ bool flareVisible = false;
+
+ if (roomNumber != NO_VALUE)
+ {
+ if (g_Level.Rooms[roomNumber].flags & ENV_FLAG_NOT_NEAR_OUTSIDE || !sun)
+ {
+ GameVector source = { Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.pos.RoomNumber };
+ GameVector destination = { (int)lensFlarePosition.x, (int)lensFlarePosition.y, (int)lensFlarePosition.z, roomNumber };
+ flareVisible = LOS(&source, &destination);
+ }
+ }
+
+ if (!flareVisible && !sun)
+ {
+ return;
+ }
+
+ LensFlare lensFlare;
+ lensFlare.Position = position;
+ lensFlare.RoomNumber = roomNumber;
+ lensFlare.Sun = sun;
+ LensFlares.push_back(lensFlare);
+ }
}
\ No newline at end of file
diff --git a/TombEngine/Objects/Effects/lens_flare.h b/TombEngine/Objects/Effects/lens_flare.h
index 3acaab5b7..0f0901338 100644
--- a/TombEngine/Objects/Effects/lens_flare.h
+++ b/TombEngine/Objects/Effects/lens_flare.h
@@ -11,10 +11,13 @@ namespace TEN::Entities::Effects
{
Vector3 Position;
short RoomNumber;
+ bool Sun;
};
extern std::vector LensFlares;
void LensFlareControl(short itemNumber);
void ClearLensFlares();
+ void SetupLensFlare(Vector3 position, short roomNumber, bool global);
+ void SetupGlobalLensFlare(float yaw, float pitch);
}
\ No newline at end of file
diff --git a/TombEngine/Objects/objectslist.h b/TombEngine/Objects/objectslist.h
index f8f04a841..73f48b3b1 100644
--- a/TombEngine/Objects/objectslist.h
+++ b/TombEngine/Objects/objectslist.h
@@ -50,5 +50,9 @@ template std::enable_if_t _sortedPolygonsVertexBuffer;
IndexBuffer _sortedPolygonsIndexBuffer;
+ // Used for variable framerate
float _interpolationFactor = 0.0f;
// Private functions
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index 5bd6c0abe..2b04a3126 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -31,6 +31,7 @@
#include "Specific/level.h"
#include "Specific/winmain.h"
#include "Renderer/Structures/RendererSortableObject.h"
+#include "Game/effects/weather.h"
using namespace std::chrono;
using namespace TEN::Effects::Hair;
@@ -38,6 +39,7 @@ using namespace TEN::Entities::Creatures::TR3;
using namespace TEN::Entities::Generic;
using namespace TEN::Hud;
using namespace TEN::Renderer::Structures;
+using namespace TEN::Effects::Environment;
extern GUNSHELL_STRUCT Gunshells[MAX_GUNSHELL];
@@ -2819,19 +2821,151 @@ namespace TEN::Renderer
_context->ClearDepthStencilView(depthTarget, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0);
+ int starsCount = (int)Weather.GetStars().size();
+ if (starsCount > 0)
+ {
+ SetDepthState(DepthState::Read);
+ SetBlendMode(BlendMode::Additive);
+ SetCullMode(CullMode::None);
+
+ _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+
+ _context->VSSetShader(_vsInstancedSprites.Get(), nullptr, 0);
+ _context->PSSetShader(_psInstancedSprites.Get(), nullptr, 0);
+
+ // Set up vertex buffer and parameters.
+ UINT stride = sizeof(Vertex);
+ UINT offset = 0;
+ _context->IASetVertexBuffers(0, 1, _quadVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
+
+ BindTexture(TextureRegister::ColorMap, _sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LENSFLARE3].Texture, SamplerStateRegister::LinearClamp);
+
+ int drawnStars = 0;
+ while (drawnStars < starsCount)
+ {
+ int starsToDraw = (starsCount - drawnStars) > 100 ? 100 : (starsCount - drawnStars);
+ int i = 0;
+
+ for (int i = 0; i < starsToDraw; i++)
+ {
+ auto& s = Weather.GetStars()[drawnStars + i];
+
+ RendererSpriteToDraw rDrawSprite;
+ rDrawSprite.Sprite = &_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LENSFLARE3];
+
+ constexpr auto STAR_SIZE = 2;
+
+ rDrawSprite.Type = SpriteType::Billboard;
+ rDrawSprite.pos = renderView.Camera.WorldPosition + s.Direction * BLOCK(1);
+ rDrawSprite.Rotation = 0;
+ rDrawSprite.Scale = 1;
+ rDrawSprite.Width = STAR_SIZE * s.Scale;
+ rDrawSprite.Height = STAR_SIZE * s.Scale;
+
+ _stInstancedSpriteBuffer.Sprites[i].World = GetWorldMatrixForSprite(&rDrawSprite, renderView);
+ _stInstancedSpriteBuffer.Sprites[i].Color = Vector4(
+ s.Color.x,
+ s.Color.y,
+ s.Color.z,
+ s.Blinking * s.Extinction);
+ _stInstancedSpriteBuffer.Sprites[i].IsBillboard = 1;
+ _stInstancedSpriteBuffer.Sprites[i].IsSoftParticle = 0;
+
+ // NOTE: Strange packing due to particular HLSL 16 byte alignment requirements.
+ _stInstancedSpriteBuffer.Sprites[i].UV[0].x = rDrawSprite.Sprite->UV[0].x;
+ _stInstancedSpriteBuffer.Sprites[i].UV[0].y = rDrawSprite.Sprite->UV[1].x;
+ _stInstancedSpriteBuffer.Sprites[i].UV[0].z = rDrawSprite.Sprite->UV[2].x;
+ _stInstancedSpriteBuffer.Sprites[i].UV[0].w = rDrawSprite.Sprite->UV[3].x;
+ _stInstancedSpriteBuffer.Sprites[i].UV[1].x = rDrawSprite.Sprite->UV[0].y;
+ _stInstancedSpriteBuffer.Sprites[i].UV[1].y = rDrawSprite.Sprite->UV[1].y;
+ _stInstancedSpriteBuffer.Sprites[i].UV[1].z = rDrawSprite.Sprite->UV[2].y;
+ _stInstancedSpriteBuffer.Sprites[i].UV[1].w = rDrawSprite.Sprite->UV[3].y;
+ }
+
+ _cbInstancedSpriteBuffer.UpdateData(_stInstancedSpriteBuffer, _context.Get());
+
+ // Draw sprites with instancing.
+ DrawInstancedTriangles(4, starsToDraw, 0);
+
+ drawnStars += starsToDraw;
+ }
+
+ // Draw meteor
+ if (Weather.GetMeteors().size() > 0)
+ {
+ RendererSpriteToDraw rDrawSprite;
+ rDrawSprite.Sprite = &_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LENSFLARE3];
+ BindTexture(TextureRegister::ColorMap, rDrawSprite.Sprite->Texture, SamplerStateRegister::LinearClamp);
+
+ int meteorsCount = 0;
+
+ for (int i = 0; i < Weather.GetMeteors().size(); i++)
+ {
+ MeteorParticle meteor = Weather.GetMeteors()[i];
+
+ if (meteor.Active == false)
+ continue;
+
+ rDrawSprite.Type = SpriteType::CustomBillboard;
+ rDrawSprite.pos = renderView.Camera.WorldPosition + meteor.Position;
+ rDrawSprite.Rotation = 0;
+ rDrawSprite.Scale = 1;
+ rDrawSprite.Width = 2;
+ rDrawSprite.Height = 192;
+ rDrawSprite.ConstrainAxis = meteor.Direction;
+
+ _stInstancedSpriteBuffer.Sprites[meteorsCount].World = GetWorldMatrixForSprite(&rDrawSprite, renderView);
+ _stInstancedSpriteBuffer.Sprites[meteorsCount].Color = Vector4(
+ meteor.Color.x,
+ meteor.Color.y,
+ meteor.Color.z,
+ meteor.Fade
+ );
+ _stInstancedSpriteBuffer.Sprites[meteorsCount].IsBillboard = 1;
+ _stInstancedSpriteBuffer.Sprites[i].IsSoftParticle = 0;
+
+ // NOTE: Strange packing due to particular HLSL 16 byte alignment requirements.
+ _stInstancedSpriteBuffer.Sprites[meteorsCount].UV[0].x = rDrawSprite.Sprite->UV[0].x;
+ _stInstancedSpriteBuffer.Sprites[meteorsCount].UV[0].y = rDrawSprite.Sprite->UV[1].x;
+ _stInstancedSpriteBuffer.Sprites[meteorsCount].UV[0].z = rDrawSprite.Sprite->UV[2].x;
+ _stInstancedSpriteBuffer.Sprites[meteorsCount].UV[0].w = rDrawSprite.Sprite->UV[3].x;
+ _stInstancedSpriteBuffer.Sprites[meteorsCount].UV[1].x = rDrawSprite.Sprite->UV[0].y;
+ _stInstancedSpriteBuffer.Sprites[meteorsCount].UV[1].y = rDrawSprite.Sprite->UV[1].y;
+ _stInstancedSpriteBuffer.Sprites[meteorsCount].UV[1].z = rDrawSprite.Sprite->UV[2].y;
+ _stInstancedSpriteBuffer.Sprites[meteorsCount].UV[1].w = rDrawSprite.Sprite->UV[3].y;
+
+ meteorsCount++;
+ }
+
+ _cbInstancedSpriteBuffer.UpdateData(_stInstancedSpriteBuffer, _context.Get());
+
+ // Draw sprites with instancing.
+ DrawInstancedTriangles(4, meteorsCount, 0);
+ }
+
+ _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+ }
+
// Draw horizon.
if (_moveableObjects[ID_HORIZON].has_value())
{
+ SetDepthState(DepthState::None);
+ SetBlendMode(BlendMode::Opaque);
+ SetCullMode(CullMode::CounterClockwise);
+
_context->IASetVertexBuffers(0, 1, _moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
_context->IASetIndexBuffer(_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
+ _context->VSSetShader(_vsSky.Get(), nullptr, 0);
+ _context->PSSetShader(_psSky.Get(), nullptr, 0);
+
auto& moveableObj = *_moveableObjects[ID_HORIZON];
_stStatic.World = Matrix::CreateTranslation(renderView.Camera.WorldPosition);
_stStatic.Color = Vector4::One;
_stStatic.ApplyFogBulbs = 1;
_cbStatic.UpdateData(_stStatic, _context.Get());
-
+
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
{
auto* meshPtr = moveableObj.ObjectMeshes[k];
@@ -2858,6 +2992,60 @@ namespace TEN::Renderer
}
}
+ // Eventually draw the sun sprite
+ if (renderView.LensFlaresToDraw.size() > 0 && renderView.LensFlaresToDraw[0].Sun)
+ {
+ SetDepthState(DepthState::Read);
+ SetBlendMode(BlendMode::Additive);
+ SetCullMode(CullMode::None);
+
+ _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+
+ _context->VSSetShader(_vsInstancedSprites.Get(), nullptr, 0);
+ _context->PSSetShader(_psInstancedSprites.Get(), nullptr, 0);
+
+ // Set up vertex buffer and parameters.
+ UINT stride = sizeof(Vertex);
+ UINT offset = 0;
+ _context->IASetVertexBuffers(0, 1, _quadVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
+
+ RendererSpriteToDraw rDrawSprite;
+ rDrawSprite.Sprite = &_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LENSFLARE3];
+
+ constexpr auto SUN_SIZE = 64;
+
+ rDrawSprite.Type = SpriteType::Billboard;
+ rDrawSprite.pos = renderView.Camera.WorldPosition + renderView.LensFlaresToDraw[0].Direction * BLOCK(1);
+ rDrawSprite.Rotation = 0;
+ rDrawSprite.Scale = 1;
+ rDrawSprite.Width = SUN_SIZE;
+ rDrawSprite.Height = SUN_SIZE;
+
+ _stInstancedSpriteBuffer.Sprites[0].World = GetWorldMatrixForSprite(&rDrawSprite, renderView);
+ _stInstancedSpriteBuffer.Sprites[0].Color = Vector4::One;
+ _stInstancedSpriteBuffer.Sprites[0].IsBillboard = 1;
+ _stInstancedSpriteBuffer.Sprites[0].IsSoftParticle = 0;
+
+ // NOTE: Strange packing due to particular HLSL 16 byte alignment requirements.
+ _stInstancedSpriteBuffer.Sprites[0].UV[0].x = rDrawSprite.Sprite->UV[0].x;
+ _stInstancedSpriteBuffer.Sprites[0].UV[0].y = rDrawSprite.Sprite->UV[1].x;
+ _stInstancedSpriteBuffer.Sprites[0].UV[0].z = rDrawSprite.Sprite->UV[2].x;
+ _stInstancedSpriteBuffer.Sprites[0].UV[0].w = rDrawSprite.Sprite->UV[3].x;
+ _stInstancedSpriteBuffer.Sprites[0].UV[1].x = rDrawSprite.Sprite->UV[0].y;
+ _stInstancedSpriteBuffer.Sprites[0].UV[1].y = rDrawSprite.Sprite->UV[1].y;
+ _stInstancedSpriteBuffer.Sprites[0].UV[1].z = rDrawSprite.Sprite->UV[2].y;
+ _stInstancedSpriteBuffer.Sprites[0].UV[1].w = rDrawSprite.Sprite->UV[3].y;
+
+ BindTexture(TextureRegister::ColorMap, rDrawSprite.Sprite->Texture, SamplerStateRegister::LinearClamp);
+
+ _cbInstancedSpriteBuffer.UpdateData(_stInstancedSpriteBuffer, _context.Get());
+
+ // Draw sprites with instancing.
+ DrawInstancedTriangles(4, 1, 0);
+
+ _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+ }
+
// Clear just the Z-buffer to start drawing on top of horizon.
_context->ClearDepthStencilView(depthTarget, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
}
diff --git a/TombEngine/Renderer/RendererFrame.cpp b/TombEngine/Renderer/RendererFrame.cpp
index 7169c1785..041d11aad 100644
--- a/TombEngine/Renderer/RendererFrame.cpp
+++ b/TombEngine/Renderer/RendererFrame.cpp
@@ -108,23 +108,25 @@ namespace TEN::Renderer
for (auto lensFlare : LensFlares)
{
- float distance = Vector3::Distance(lensFlare.Position, renderView.Camera.WorldPosition);
-
- if (lensFlare.RoomNumber == Camera.pos.RoomNumber && distance < BLOCK(20))
+ Vector3 lensFlareToCamera = lensFlare.Position - renderView.Camera.WorldPosition;
+ float distance = 0.0f;
+ if (!lensFlare.Sun)
{
- Vector3 lensFlareToCamera = lensFlare.Position - renderView.Camera.WorldPosition;
- Vector3 cameraDirection = renderView.Camera.WorldDirection;
+ distance = lensFlareToCamera.Length();
+ }
+ lensFlareToCamera.Normalize();
+
+ Vector3 cameraDirection = renderView.Camera.WorldDirection;
+ cameraDirection.Normalize();
- lensFlareToCamera.Normalize();
- cameraDirection.Normalize();
-
- if (lensFlareToCamera.Dot(cameraDirection) >= 0.0f)
- {
- RendererLensFlare lensFlareToDraw;
- lensFlareToDraw.Position = lensFlare.Position;
- lensFlareToDraw.Distance = distance;
- tempLensFlares.push_back(lensFlareToDraw);
- }
+ if (lensFlareToCamera.Dot(cameraDirection) >= 0.0f)
+ {
+ RendererLensFlare lensFlareToDraw;
+ lensFlareToDraw.Position = lensFlare.Position;
+ lensFlareToDraw.Distance = distance;
+ lensFlareToDraw.Direction = lensFlareToCamera;
+ lensFlareToDraw.Sun = lensFlare.Sun;
+ tempLensFlares.push_back(lensFlareToDraw);
}
}
@@ -133,11 +135,18 @@ namespace TEN::Renderer
tempLensFlares.end(),
[](const RendererLensFlare& lensFlare0, const RendererLensFlare& lensFlare1)
{
- return lensFlare0.Distance < lensFlare1.Distance;
+ if (lensFlare0.Sun && !lensFlare1.Sun)
+ return true;
+ else if (!lensFlare0.Sun && lensFlare1.Sun)
+ return false;
+ else
+ return lensFlare0.Distance < lensFlare1.Distance;
});
for (int i = 0; i < std::min(MAX_LENS_FLARES_DRAW, (int)tempLensFlares.size()); i++)
+ {
renderView.LensFlaresToDraw.push_back(tempLensFlares[i]);
+ }
}
bool Renderer::CheckPortal(short parentRoomNumber, RendererDoor* door, Vector4 viewPort, Vector4* clipPort, RenderView& renderView)
diff --git a/TombEngine/Renderer/Structures/RendererLensFlare.h b/TombEngine/Renderer/Structures/RendererLensFlare.h
index 4acb56fcd..2fc8b74ae 100644
--- a/TombEngine/Renderer/Structures/RendererLensFlare.h
+++ b/TombEngine/Renderer/Structures/RendererLensFlare.h
@@ -9,6 +9,8 @@ namespace TEN::Renderer::Structures
struct RendererLensFlare
{
Vector3 Position;
+ Vector3 Direction;
float Distance;
+ bool Sun;
};
}
\ No newline at end of file
diff --git a/TombEngine/Renderer/Structures/RendererStar.h b/TombEngine/Renderer/Structures/RendererStar.h
new file mode 100644
index 000000000..d0bb916f9
--- /dev/null
+++ b/TombEngine/Renderer/Structures/RendererStar.h
@@ -0,0 +1,17 @@
+#pragma once
+#include
+#include "Renderer/RendererEnums.h"
+
+namespace TEN::Renderer::Structures
+{
+ using namespace DirectX::SimpleMath;
+
+ struct RendererStar
+ {
+ Vector3 Direction;
+ Vector3 Color;
+ float Blinking;
+ float Scale;
+ float Extinction;
+ };
+}
\ No newline at end of file
diff --git a/TombEngine/TombEngine.vcxproj b/TombEngine/TombEngine.vcxproj
index 44ef99dbf..6464b9af8 100644
--- a/TombEngine/TombEngine.vcxproj
+++ b/TombEngine/TombEngine.vcxproj
@@ -750,6 +750,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
+
From c241af1c70b55ebc2a839efc8da731075b32ca5c Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Tue, 23 Apr 2024 20:59:43 +0200
Subject: [PATCH 090/410] Meteors interpolation
---
TombEngine/Game/effects/weather.cpp | 2 ++
TombEngine/Game/effects/weather.h | 9 +++++++++
TombEngine/Renderer/RendererDraw.cpp | 6 ++++--
3 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/TombEngine/Game/effects/weather.cpp b/TombEngine/Game/effects/weather.cpp
index b5b4667ad..f6269b983 100644
--- a/TombEngine/Game/effects/weather.cpp
+++ b/TombEngine/Game/effects/weather.cpp
@@ -291,6 +291,8 @@ namespace TEN::Effects::Environment
continue;
}
+ m.StoreInterpolationData();
+
if (m.Life <= METEOR_PARTICLES_FADE_TIME)
m.Fade = m.Life / (float)METEOR_PARTICLES_FADE_TIME;
else if (m.Life >= METEOR_PARTICLES_MAX_LIFE - METEOR_PARTICLES_FADE_TIME)
diff --git a/TombEngine/Game/effects/weather.h b/TombEngine/Game/effects/weather.h
index 0efc267b7..43daf02d9 100644
--- a/TombEngine/Game/effects/weather.h
+++ b/TombEngine/Game/effects/weather.h
@@ -27,6 +27,15 @@ namespace TEN::Effects::Environment
float Life;
bool Active;
float Fade;
+
+ Vector3 OldPosition = Vector3::Zero;
+ float OldFade = 0.0f;
+
+ void StoreInterpolationData()
+ {
+ OldPosition = Position;
+ OldFade = Fade;
+ }
};
struct WeatherParticle
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index 2b04a3126..30a4e11bb 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -2907,7 +2907,9 @@ namespace TEN::Renderer
continue;
rDrawSprite.Type = SpriteType::CustomBillboard;
- rDrawSprite.pos = renderView.Camera.WorldPosition + meteor.Position;
+ rDrawSprite.pos =
+ renderView.Camera.WorldPosition +
+ Vector3::Lerp(meteor.OldPosition, meteor.Position, _interpolationFactor);
rDrawSprite.Rotation = 0;
rDrawSprite.Scale = 1;
rDrawSprite.Width = 2;
@@ -2919,7 +2921,7 @@ namespace TEN::Renderer
meteor.Color.x,
meteor.Color.y,
meteor.Color.z,
- meteor.Fade
+ Lerp(meteor.OldFade, meteor.Fade, _interpolationFactor)
);
_stInstancedSpriteBuffer.Sprites[meteorsCount].IsBillboard = 1;
_stInstancedSpriteBuffer.Sprites[i].IsSoftParticle = 0;
From c13bd9ab19e90f173ddbd3a61a90c05b06d95220 Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Wed, 24 Apr 2024 00:21:00 +0200
Subject: [PATCH 091/410] Fixed original issue with classic switch off trigger
wrongly activating some trigger actions
---
Documentation/Changes.txt | 6 +++
TombEngine/Game/control/trigger.cpp | 74 ++++++++++++++++-------------
TombEngine/Game/control/trigger.h | 2 +-
3 files changed, 48 insertions(+), 34 deletions(-)
diff --git a/Documentation/Changes.txt b/Documentation/Changes.txt
index 09efb1cbc..d15337e7d 100644
--- a/Documentation/Changes.txt
+++ b/Documentation/Changes.txt
@@ -1,3 +1,9 @@
+Version 1.5
+===========
+
+* Fixed original issue with classic switch off trigger wrongly activating some trigger actions.
+
+
Version 1.4
===========
diff --git a/TombEngine/Game/control/trigger.cpp b/TombEngine/Game/control/trigger.cpp
index 5b03b8f2a..fa24bc70f 100644
--- a/TombEngine/Game/control/trigger.cpp
+++ b/TombEngine/Game/control/trigger.cpp
@@ -114,7 +114,7 @@ int GetSwitchTrigger(ItemInfo* item, short* itemNumbersPtr, int attatchedToSwitc
return k;
}
-int SwitchTrigger(short itemNumber, short timer)
+bool SwitchTrigger(short itemNumber, short timer)
{
auto& item = g_Level.Items[itemNumber];
const auto& player = Lara;
@@ -127,7 +127,7 @@ int SwitchTrigger(short itemNumber, short timer)
item.Status = ITEM_ACTIVE;
item.ItemFlags[1] = false;
- return 1;
+ return true;
}
if (item.ObjectNumber >= ID_PUZZLE_HOLE1 && item.ObjectNumber <= ID_PUZZLE_HOLE16 &&
@@ -137,13 +137,13 @@ int SwitchTrigger(short itemNumber, short timer)
item.Status = ITEM_DEACTIVATED;
item.ItemFlags[1] = false;
- return 1;
+ return true;
}
if ((item.ObjectNumber >= ID_PUZZLE_DONE1 && item.ObjectNumber <= ID_PUZZLE_DONE16) ||
(item.ObjectNumber >= ID_PUZZLE_HOLE1 && item.ObjectNumber <= ID_PUZZLE_HOLE16))
{
- return 0;
+ return false;
}
// Handle reusable receptacles.
@@ -156,7 +156,7 @@ int SwitchTrigger(short itemNumber, short timer)
item.Status = ITEM_ACTIVE;
item.ItemFlags[5] = (int)ReusableReceptacleState::Done;
item.ItemFlags[1] = false;
- return 1;
+ return true;
}
if (item.ObjectNumber >= ID_KEY_HOLE1 && item.ObjectNumber <= ID_KEY_HOLE16 &&
@@ -167,11 +167,11 @@ int SwitchTrigger(short itemNumber, short timer)
item.Status = ITEM_DEACTIVATED;
item.ItemFlags[5] = (int)ReusableReceptacleState::Empty;
item.ItemFlags[1] = false;
- return 1;
+ return true;
}
if (item.ObjectNumber >= ID_KEY_HOLE1 && item.ObjectNumber <= ID_KEY_HOLE16)
- return 0;
+ return false;
// Handle switches.
if (item.Status == ITEM_DEACTIVATED)
@@ -186,7 +186,7 @@ int SwitchTrigger(short itemNumber, short timer)
if (timer != 1)
item.Timer = FPS * timer;
- return 1;
+ return true;
}
if (item.TriggerFlags >= 0 || item.Animation.ActiveState != SWITCH_OFF)
@@ -197,12 +197,12 @@ int SwitchTrigger(short itemNumber, short timer)
if (!item.ItemFlags[0] == 0)
item.Flags |= ONESHOT;
- return 1;
+ return true;
}
else
{
item.Status = ITEM_ACTIVE;
- return 1;
+ return true;
}
}
else if (item.Status != ITEM_NOT_ACTIVE)
@@ -211,13 +211,14 @@ int SwitchTrigger(short itemNumber, short timer)
item.Animation.AnimNumber == GetAnimIndex(item, 2) &&
item.Animation.FrameNumber == GetFrameIndex(&item, 0))
{
- return 1;
+ return true;
}
- return ((item.Flags & ONESHOT) >> 8);
+ if (item.Flags & ONESHOT)
+ return true;
}
- return 0;
+ return false;
}
int KeyTrigger(short itemNumber)
@@ -398,15 +399,11 @@ void Trigger(short const value, short const flags)
void TestTriggers(int x, int y, int z, FloorInfo* floor, Activator activator, bool heavy, int heavyFlags)
{
- int flip = -1;
- int flipAvailable = 0;
- int newEffect = -1;
- int switchOff = 0;
- //int switchFlag = 0;
- short objectNumber = 0;
+ bool switchOff = false;
+ bool flipAvailable = false;
+ int flip = NO_VALUE;
+ int newEffect = NO_VALUE;
int keyResult = 0;
- short cameraFlags = 0;
- short cameraTimer = 0;
int spotCamIndex = 0;
auto data = GetTriggerIndex(floor, x, y, z);
@@ -466,13 +463,7 @@ void TestTriggers(int x, int y, int z, FloorInfo* floor, Activator activator, bo
if (!SwitchTrigger(value, timer))
return;
- objectNumber = g_Level.Items[value].ObjectNumber;
- //This disables the antitrigger of the Valve switch (ocb 5). I don't know the purpose of this in TR4.
- //if (objectNumber >= ID_SWITCH_TYPE1 && objectNumber <= ID_SWITCH_TYPE6 && g_Level.Items[value].TriggerFlags == 5)
- //switchFlag = 1;
-
- switchOff = (g_Level.Items[value].Animation.ActiveState == 1);
-
+ switchOff = (triggerType == TRIGGER_TYPES::SWITCH && timer && g_Level.Items[value].Animation.ActiveState == 1);
break;
case TRIGGER_TYPES::MONKEY:
@@ -571,8 +562,8 @@ void TestTriggers(int x, int y, int z, FloorInfo* floor, Activator activator, bo
if (keyResult >= 2 ||
(triggerType == TRIGGER_TYPES::ANTIPAD ||
- triggerType == TRIGGER_TYPES::ANTITRIGGER ||
- triggerType == TRIGGER_TYPES::HEAVYANTITRIGGER) &&
+ triggerType == TRIGGER_TYPES::ANTITRIGGER ||
+ triggerType == TRIGGER_TYPES::HEAVYANTITRIGGER) &&
item->Flags & ATONESHOT)
break;
@@ -656,7 +647,7 @@ void TestTriggers(int x, int y, int z, FloorInfo* floor, Activator activator, bo
if (triggerType == TRIGGER_TYPES::COMBAT)
break;
- if (triggerType == TRIGGER_TYPES::SWITCH && timer && switchOff)
+ if (switchOff)
break;
if (Camera.number != Camera.last || triggerType == TRIGGER_TYPES::SWITCH)
@@ -674,6 +665,9 @@ void TestTriggers(int x, int y, int z, FloorInfo* floor, Activator activator, bo
if (keyResult == 1)
break;
+ if (switchOff)
+ break;
+
if (triggerType == TRIGGER_TYPES::ANTIPAD ||
triggerType == TRIGGER_TYPES::ANTITRIGGER ||
triggerType == TRIGGER_TYPES::HEAVYANTITRIGGER)
@@ -748,16 +742,25 @@ void TestTriggers(int x, int y, int z, FloorInfo* floor, Activator activator, bo
break;
case TO_FLIPEFFECT:
+ if (switchOff)
+ break;
+
TriggerTimer = timer;
newEffect = value;
break;
case TO_FINISH:
+ if (switchOff)
+ break;
+
NextLevel = value ? value : (CurrentLevel + 1);
RequiredStartPos = timer;
break;
case TO_CD:
+ if (switchOff)
+ break;
+
PlaySoundTrack(value, flags);
break;
@@ -766,6 +769,9 @@ void TestTriggers(int x, int y, int z, FloorInfo* floor, Activator activator, bo
break;
case TO_SECRET:
+ if (switchOff)
+ break;
+
if (!(SaveGame::Statistics.Level.Secrets & (1 << value)))
{
PlaySecretTrack();
@@ -777,6 +783,8 @@ void TestTriggers(int x, int y, int z, FloorInfo* floor, Activator activator, bo
case TO_VOLUMEEVENT:
case TO_GLOBALEVENT:
trigger = *(data++);
+
+ if (!switchOff)
{
auto& list = targetType == TO_VOLUMEEVENT ? g_Level.VolumeEventSets : g_Level.GlobalEventSets;
@@ -815,10 +823,10 @@ void TestTriggers(int x, int y, int z, FloorInfo* floor, Activator activator, bo
if (cameraItem && (Camera.type == CameraType::Fixed || Camera.type == CameraType::Heavy))
Camera.item = cameraItem;
- if (flip != -1)
+ if (flip != NO_VALUE)
DoFlipMap(flip);
- if (newEffect != -1 && (flip || !flipAvailable))
+ if (newEffect != NO_VALUE && (flip || !flipAvailable))
FlipEffect = newEffect;
}
diff --git a/TombEngine/Game/control/trigger.h b/TombEngine/Game/control/trigger.h
index fb60974fa..f1b3e2668 100644
--- a/TombEngine/Game/control/trigger.h
+++ b/TombEngine/Game/control/trigger.h
@@ -63,7 +63,7 @@ extern int KeyTriggerActive;
bool GetKeyTrigger(ItemInfo* item);
int GetSwitchTrigger(ItemInfo* item, short* itemNumbersPtr, int attatchedToSwitch);
-int SwitchTrigger(short itemNumber, short timer);
+bool SwitchTrigger(short itemNumber, short timer);
int KeyTrigger(short itemNumber);
bool PickupTrigger(short itemNumber);
void RefreshCamera(short type, short* data);
From 46d19878165fb598bbb8529b4637ce2adfa97711 Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Wed, 24 Apr 2024 00:30:02 +0200
Subject: [PATCH 092/410] Implement lua API functions to get last chosen
inventory item
---
TombEngine/Game/Lara/lara.cpp | 6 ----
TombEngine/Game/control/control.cpp | 3 ++
TombEngine/Game/gui.cpp | 9 +++++
TombEngine/Game/gui.h | 1 +
.../Scripting/Internal/ReservedScriptNames.h | 3 ++
.../TEN/Inventory/InventoryHandler.cpp | 35 +++++++++++++++++++
6 files changed, 51 insertions(+), 6 deletions(-)
diff --git a/TombEngine/Game/Lara/lara.cpp b/TombEngine/Game/Lara/lara.cpp
index 447f10052..07a251277 100644
--- a/TombEngine/Game/Lara/lara.cpp
+++ b/TombEngine/Game/Lara/lara.cpp
@@ -634,12 +634,6 @@ void UpdateLara(ItemInfo* item, bool isTitle)
if (isTitle)
ActionMap = actionMap;
- if (g_Gui.GetInventoryItemChosen() != NO_VALUE)
- {
- g_Gui.SetInventoryItemChosen(NO_VALUE);
- SayNo();
- }
-
// Update player animations.
g_Renderer.UpdateLaraAnimations(true);
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index 4b71e240b..4502e5a59 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -162,6 +162,9 @@ GameStatus ControlPhase(int numFrames)
g_GameScript->OnLoop(DELTA_TIME, false); // TODO: Don't use DELTA_TIME constant with variable framerate
HandleAllGlobalEvents(EventType::Loop, (Activator)LaraItem->Index);
+ // Clear last selected item in inventory (need to be after on loop event handling, so they can detect that).
+ g_Gui.CancelInventorySelection();
+
// Control lock is processed after handling scripts, because builder may want to
// process input externally, while still locking Lara from input.
if (!isTitle && Lara.Control.IsLocked)
diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp
index 06635e097..e1e74e083 100644
--- a/TombEngine/Game/gui.cpp
+++ b/TombEngine/Game/gui.cpp
@@ -3427,6 +3427,15 @@ namespace TEN::Gui
}
}
+ void GuiController::CancelInventorySelection()
+ {
+ if (GetInventoryItemChosen() != NO_VALUE)
+ {
+ SetInventoryItemChosen(NO_VALUE);
+ SayNo();
+ }
+ }
+
void GuiController::DrawCompass(ItemInfo* item)
{
constexpr auto POS_2D = Vector2(130.0f, 450.0f);
diff --git a/TombEngine/Game/gui.h b/TombEngine/Game/gui.h
index 2bdf145bb..f456889bd 100644
--- a/TombEngine/Game/gui.h
+++ b/TombEngine/Game/gui.h
@@ -180,6 +180,7 @@ namespace TEN::Gui
void DrawAmmoSelector();
bool PerformWaterskinCombine(ItemInfo* item, bool flag);
void DrawCompass(ItemInfo* item);
+ void CancelInventorySelection();
// Getters
const InventoryRing& GetRing(RingTypes ringType);
diff --git a/TombEngine/Scripting/Internal/ReservedScriptNames.h b/TombEngine/Scripting/Internal/ReservedScriptNames.h
index e8821218c..181e94953 100644
--- a/TombEngine/Scripting/Internal/ReservedScriptNames.h
+++ b/TombEngine/Scripting/Internal/ReservedScriptNames.h
@@ -259,6 +259,9 @@ static constexpr char ScriptReserved_GiveInvItem[] = "GiveItem";
static constexpr char ScriptReserved_TakeInvItem[] = "TakeItem";
static constexpr char ScriptReserved_GetInvItemCount[] = "GetItemCount";
static constexpr char ScriptReserved_SetInvItemCount[] = "SetItemCount";
+static constexpr char ScriptReserved_GetChosenItem[] = "GetChosenItem";
+static constexpr char ScriptReserved_SetChosenItem[] = "SetChosenItem";
+static constexpr char ScriptReserved_ClearChosenItem[] = "ClearChosenItem";
static constexpr char ScriptReserved_GetMoveableByName[] = "GetMoveableByName";
static constexpr char ScriptReserved_GetStaticByName[] = "GetStaticByName";
static constexpr char ScriptReserved_GetMoveablesBySlot[] = "GetMoveablesBySlot";
diff --git a/TombEngine/Scripting/Internal/TEN/Inventory/InventoryHandler.cpp b/TombEngine/Scripting/Internal/TEN/Inventory/InventoryHandler.cpp
index 1eb1414ba..a570cebfd 100644
--- a/TombEngine/Scripting/Internal/TEN/Inventory/InventoryHandler.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Inventory/InventoryHandler.cpp
@@ -1,12 +1,14 @@
#include "framework.h"
#include "Scripting/Internal/TEN/Inventory/InventoryHandler.h"
+#include "Game/gui.h"
#include "Game/Hud/Hud.h"
#include "Game/Lara/lara.h"
#include "Game/pickup/pickup.h"
#include "Scripting/Internal/ReservedScriptNames.h"
using namespace TEN::Hud;
+using namespace TEN::Gui;
/***
Inventory manipulation
@@ -59,6 +61,36 @@ namespace TEN::Scripting::InventoryHandler
SetInventoryCount(objectID, count);
}
+ /// Get last selected item in the player's inventory.
+ // This value will be valid only for a single frame after exiting inventory, after which Lara says "No".
+ // Therefore, this function must be preferably used either in OnLoop events or callbacks.
+ // If you have used this function and you want to avoid "No" sound, you should use ClearChosenItem function.
+ //@function GetChosenItem
+ //@treturn Objects.ObjID Last selected item in the inventory.
+ static GAME_OBJECT_ID GetChosenItem()
+ {
+ return (GAME_OBJECT_ID)g_Gui.GetInventoryItemChosen();
+ }
+
+ /// Set last selected item in the player's inventory.
+ // You will be able to select only objects which already exist in inventory.
+ // Will only be valid for the next frame. If not processed by the game, Lara will say "No".
+ //@function SetChosenItem
+ //@tparam Objects.ObjID objectID Object ID of the item to select from inventory.
+ static void SetChosenItem(GAME_OBJECT_ID objectID)
+ {
+ if (g_Gui.IsObjectInInventory(objectID))
+ g_Gui.SetInventoryItemChosen(objectID);
+ }
+
+ /// Clear last selected item in the player's inventory.
+ // This function is needed to avoid Lara saying "No" after selecting particular item in inventory.
+ //@function ClearChosenItem
+ static void ClearChosenItem()
+ {
+ g_Gui.SetInventoryItemChosen(GAME_OBJECT_ID::ID_NO_OBJECT);
+ }
+
void Register(sol::state* state, sol::table& parent)
{
auto tableInventory = sol::table{ state->lua_state(), sol::create };
@@ -68,5 +100,8 @@ namespace TEN::Scripting::InventoryHandler
tableInventory.set_function(ScriptReserved_TakeInvItem, &TakeItem);
tableInventory.set_function(ScriptReserved_GetInvItemCount, &GetItemCount);
tableInventory.set_function(ScriptReserved_SetInvItemCount, &SetItemCount);
+ tableInventory.set_function(ScriptReserved_SetChosenItem, &SetChosenItem);
+ tableInventory.set_function(ScriptReserved_GetChosenItem, &GetChosenItem);
+ tableInventory.set_function(ScriptReserved_ClearChosenItem, &ClearChosenItem);
}
}
From 809d54d8115d9d9ce265da2ed0d1f8f84f62423c Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Wed, 24 Apr 2024 00:32:32 +0200
Subject: [PATCH 093/410] Update docs
---
Documentation/Changes.txt | 2 +
Documentation/doc/1 modules/Inventory.html | 76 ++++++++++++++++++++++
2 files changed, 78 insertions(+)
diff --git a/Documentation/Changes.txt b/Documentation/Changes.txt
index d15337e7d..542f6fb9a 100644
--- a/Documentation/Changes.txt
+++ b/Documentation/Changes.txt
@@ -3,6 +3,8 @@ Version 1.5
* Fixed original issue with classic switch off trigger wrongly activating some trigger actions.
+Lua API changes:
+* Added Inventory.GetChosenItem(), Inventory.SetChosenItem() and Inventory.ClearChosenItem() functions.
Version 1.4
===========
diff --git a/Documentation/doc/1 modules/Inventory.html b/Documentation/doc/1 modules/Inventory.html
index e5fd825ec..f0df17c5b 100644
--- a/Documentation/doc/1 modules/Inventory.html
+++ b/Documentation/doc/1 modules/Inventory.html
@@ -124,6 +124,18 @@
SetItemCount(objectID, count)
Set the amount of an item in the player's inventory.
+
+ GetChosenItem()
+ Get last selected item in the player's inventory.
+
+
+ SetChosenItem(objectID)
+ Set last selected item in the player's inventory.
+
+
+ ClearChosenItem()
+ Clear last selected item in the player's inventory.
+
@@ -245,6 +257,70 @@
+
+
+
+ GetChosenItem()
+
+
+ Get last selected item in the player's inventory.
+ This value will be valid only for a single frame after exiting inventory, after which Lara says "No".
+ Therefore, this function must be preferably used either in OnLoop events or callbacks.
+ If you have used this function and you want to avoid "No" sound, you should use ClearChosenItem function.
+
+
+
+
+ Returns:
+
+
+ ObjID
+ Last selected item in the inventory.
+
+
+
+
+
+
+
+
+ SetChosenItem(objectID)
+
+
+ Set last selected item in the player's inventory.
+ You will be able to select only objects which already exist in inventory.
+ Will only be valid for the next frame. If not processed by the game, Lara will say "No".
+
+
+
+ Parameters:
+
+ objectID
+ ObjID
+ Object ID of the item to select from inventory.
+
+
+
+
+
+
+
+
+
+
+ ClearChosenItem()
+
+
+ Clear last selected item in the player's inventory.
+ This function is needed to avoid Lara saying "No" after selecting particular item in inventory.
+
+
+
+
+
+
+
+
From 30a72eb71b4f8ac3cc109ebd6514f0ccd1f276f2 Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Wed, 24 Apr 2024 00:42:00 +0200
Subject: [PATCH 094/410] Filter out code bits for legacy soundtrack mask
---
TombEngine/Game/control/trigger.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/TombEngine/Game/control/trigger.cpp b/TombEngine/Game/control/trigger.cpp
index fa24bc70f..740cb4088 100644
--- a/TombEngine/Game/control/trigger.cpp
+++ b/TombEngine/Game/control/trigger.cpp
@@ -761,7 +761,7 @@ void TestTriggers(int x, int y, int z, FloorInfo* floor, Activator activator, bo
if (switchOff)
break;
- PlaySoundTrack(value, flags);
+ PlaySoundTrack(value, flags & CODE_BITS);
break;
case TO_CUTSCENE:
From 9dc4f9e24e50f6f43cb7e120fe24cc6ad3d75029 Mon Sep 17 00:00:00 2001
From: Adngel <60930991+Adngel@users.noreply.github.com>
Date: Wed, 24 Apr 2024 07:25:22 +0200
Subject: [PATCH 095/410] Adngel small fixes (#1355)
* Update tr2_worker_shotgun.cpp
Added enumerators for Animations and States.
* Fix Worker Shotgun walking attack
Now the enemy can hurt Lara with every shooting he does while walking.
* Fix skidoo driver lack of AI
* Update tr2_worker_shotgun.cpp
Use TestProbability()
---------
Co-authored-by: Sezz
---
TombEngine/Objects/TR2/Entity/tr2_skidman.cpp | 3 +
.../Objects/TR2/Entity/tr2_worker_shotgun.cpp | 105 ++++++++++++------
2 files changed, 72 insertions(+), 36 deletions(-)
diff --git a/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp b/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp
index 4b573f7b5..17c95d586 100644
--- a/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp
+++ b/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp
@@ -131,6 +131,9 @@ namespace TEN::Entities::Creatures::TR2
int skidooItemNumber = (short)riderItem.ItemFlags[0];
auto* skidooItem = &g_Level.Items[skidooItemNumber];
+ if (!CreatureActive(skidooItemNumber))
+ return;
+
if (!skidooItem->Data)
{
EnableEntityAI(skidooItemNumber, true);
diff --git a/TombEngine/Objects/TR2/Entity/tr2_worker_shotgun.cpp b/TombEngine/Objects/TR2/Entity/tr2_worker_shotgun.cpp
index 0d365e113..7694f559e 100644
--- a/TombEngine/Objects/TR2/Entity/tr2_worker_shotgun.cpp
+++ b/TombEngine/Objects/TR2/Entity/tr2_worker_shotgun.cpp
@@ -5,29 +5,61 @@
#include "Game/control/box.h"
#include "Game/control/control.h"
#include "Game/effects/effects.h"
-#include "Game/items.h"
#include "Game/itemdata/creature_info.h"
+#include "Game/items.h"
#include "Game/misc.h"
#include "Game/people.h"
#include "Game/Setup.h"
+#include "Math/Math.h"
#include "Specific/level.h"
+using namespace TEN::Math;
+
namespace TEN::Entities::Creatures::TR2
{
constexpr auto WORKER_SHOTGUN_NUM_SHOTS = 6;
const auto WorkerShotgunBite = CreatureBiteInfo(Vector3(0, 350, 40), 9);
- // TODO
enum ShotgunWorkerState
{
-
+ // No state 0.
+ WORKER_SHOTGUN_STATE_WALK = 1,
+ WORKER_SHOTGUN_STATE_IDLE = 2,
+ WORKER_SHOTGUN_STATE_REST = 3,
+ WORKER_SHOTGUN_STATE_STANDING_ATTACK = 4,
+ WORKER_SHOTGUN_STATE_RUN = 5,
+ WORKER_SHOTGUN_STATE_WALKING_ATTACK = 6,
+ WORKER_SHOTGUN_STATE_DEATH = 7,
+ WORKER_SHOTGUN_STATE_STANDING_ATTACK_AIM = 8,
+ WORKER_SHOTGUN_STATE_KNEEL_ATTACK_AIM = 9,
+ WORKER_SHOTGUN_STATE_KNEEL_ATTACK = 10
};
- // TODO
enum ShotgunWorkerAnim
{
-
+ WORKER_SHOTGUN_ANIM_WALK = 0,
+ WORKER_SHOTGUN_ANIM_STANDING_ATTACK_AIM = 1,
+ WORKER_SHOTGUN_ANIM_STANDING_ATTACK_SHOOT = 2,
+ WORKER_SHOTGUN_ANIM_STANDING_ATTACK_STOP = 3,
+ WORKER_SHOTGUN_ANIM_WALK_TO_IDLE = 4,
+ WORKER_SHOTGUN_ANIM_IDLE = 5,
+ WORKER_SHOTGUN_ANIM_IDLE_TO_WALK = 6,
+ WORKER_SHOTGUN_ANIM_WALKING_ATTACK_AIM = 7,
+ WORKER_SHOTGUN_ANIM_WALKING_ATTACK_SHOOT = 8,
+ WORKER_SHOTGUN_ANIM_REST_TO_IDLE = 9,
+ WORKER_SHOTGUN_ANIM_REST = 10,
+ WORKER_SHOTGUN_ANIM_REST_TO_STANDING_ATTACK = 11,
+ WORKER_SHOTGUN_ANIM_IDLE_TO_REST = 12,
+ WORKER_SHOTGUN_ANIM_STANDING_ATTACK_TO_IDLE = 13,
+ WORKER_SHOTGUN_ANIM_WALK_TO_RUN = 14,
+ WORKER_SHOTGUN_ANIM_RUN_TO_WALK = 15,
+ WORKER_SHOTGUN_ANIM_IDLE_TO_RUN = 16,
+ WORKER_SHOTGUN_ANIM_RUN = 17,
+ WORKER_SHOTGUN_ANIM_DEATH = 18,
+ WORKER_SHOTGUN_ANIM_KNEEL_ATTACK_AIM = 19,
+ WORKER_SHOTGUN_ANIM_KNEEL_ATTACK_SHOOT = 20,
+ WORKER_SHOTGUN_ANIM_KNEEL_ATTACK_STOP = 21
};
static void ShootWorkerShotgun(ItemInfo& item, AI_INFO& ai, const CreatureBiteInfo& bite, short headingAngle, int damage)
@@ -62,8 +94,8 @@ namespace TEN::Entities::Creatures::TR2
if (item->HitPoints <= 0)
{
- if (item->Animation.ActiveState != 7)
- SetAnimation(item, 18);
+ if (item->Animation.ActiveState != WORKER_SHOTGUN_STATE_DEATH)
+ SetAnimation(item, WORKER_SHOTGUN_ANIM_DEATH);
}
else
{
@@ -77,7 +109,7 @@ namespace TEN::Entities::Creatures::TR2
switch (item->Animation.ActiveState)
{
- case 2:
+ case WORKER_SHOTGUN_STATE_IDLE:
creature->MaxTurn = 0;
creature->Flags = 0;
@@ -89,38 +121,38 @@ namespace TEN::Entities::Creatures::TR2
if (creature->Mood == MoodType::Escape)
{
- item->Animation.TargetState = 5;
+ item->Animation.TargetState = WORKER_SHOTGUN_STATE_RUN;
}
else if (Targetable(item, &ai))
{
if (ai.distance < SQUARE(BLOCK(3)) || ai.zoneNumber != ai.enemyZone)
{
- item->Animation.TargetState = (GetRandomControl() >= 0x4000) ? 9 : 8;
+ item->Animation.TargetState = Random::TestProbability(1 / 2.0f) ? WORKER_SHOTGUN_STATE_KNEEL_ATTACK_AIM : WORKER_SHOTGUN_STATE_STANDING_ATTACK_AIM;
}
else
{
- item->Animation.TargetState = 1;
+ item->Animation.TargetState = WORKER_SHOTGUN_STATE_WALK;
}
}
else if (creature->Mood == MoodType::Attack || !ai.ahead)
{
if (ai.distance <= SQUARE(BLOCK(2)))
{
- item->Animation.TargetState = 1;
+ item->Animation.TargetState = WORKER_SHOTGUN_STATE_WALK;
}
else
{
- item->Animation.TargetState = 5;
+ item->Animation.TargetState = WORKER_SHOTGUN_STATE_RUN;
}
}
else
{
- item->Animation.TargetState = 3;
+ item->Animation.TargetState = WORKER_SHOTGUN_STATE_REST;
}
break;
- case 3:
+ case WORKER_SHOTGUN_STATE_REST:
if (ai.ahead)
{
extraHeadRot.x = ai.xAngle;
@@ -129,16 +161,16 @@ namespace TEN::Entities::Creatures::TR2
if (Targetable(item, &ai))
{
- item->Animation.TargetState = 4;
+ item->Animation.TargetState = WORKER_SHOTGUN_STATE_STANDING_ATTACK;
}
else if (creature->Mood == MoodType::Attack || !ai.ahead)
{
- item->Animation.TargetState = 2;
+ item->Animation.TargetState = WORKER_SHOTGUN_STATE_IDLE;
}
break;
- case 1:
+ case WORKER_SHOTGUN_STATE_WALK:
creature->MaxTurn = ANGLE(3.0f);
if (ai.ahead)
@@ -149,32 +181,33 @@ namespace TEN::Entities::Creatures::TR2
if (creature->Mood == MoodType::Escape)
{
- item->Animation.TargetState = 5;
+ item->Animation.TargetState = WORKER_SHOTGUN_STATE_RUN;
}
else if (Targetable(item, &ai))
{
if (ai.distance < SQUARE(BLOCK(3)) || ai.zoneNumber != ai.enemyZone)
{
- item->Animation.TargetState = 2;
+ item->Animation.TargetState = WORKER_SHOTGUN_STATE_IDLE;
}
else
{
- item->Animation.TargetState = 6;
+ item->Animation.TargetState = WORKER_SHOTGUN_STATE_WALKING_ATTACK;
+ creature->Flags = 0;
}
}
else if (creature->Mood == MoodType::Attack || !ai.ahead)
{
if (ai.distance > SQUARE(BLOCK(2)))
- item->Animation.TargetState = 5;
+ item->Animation.TargetState = WORKER_SHOTGUN_STATE_RUN;
}
else
{
- item->Animation.TargetState = 2;
+ item->Animation.TargetState = WORKER_SHOTGUN_STATE_IDLE;
}
break;
- case 5:
+ case WORKER_SHOTGUN_STATE_RUN:
creature->MaxTurn = ANGLE(5.0f);
tiltAngle = headingAngle / 2;
@@ -188,18 +221,18 @@ namespace TEN::Entities::Creatures::TR2
{
if (Targetable(item, &ai))
{
- item->Animation.TargetState = 1;
+ item->Animation.TargetState = WORKER_SHOTGUN_STATE_WALK;
}
else if (creature->Mood == MoodType::Bored || creature->Mood == MoodType::Stalk)
{
- item->Animation.TargetState = 1;
+ item->Animation.TargetState = WORKER_SHOTGUN_STATE_WALK;
}
}
break;
- case 8:
- case 9:
+ case WORKER_SHOTGUN_STATE_STANDING_ATTACK_AIM:
+ case WORKER_SHOTGUN_STATE_KNEEL_ATTACK_AIM:
creature->Flags = 0;
if (ai.ahead)
@@ -210,20 +243,20 @@ namespace TEN::Entities::Creatures::TR2
if (Targetable(item, &ai))
{
- if (item->Animation.ActiveState == 8)
+ if (item->Animation.ActiveState == WORKER_SHOTGUN_STATE_STANDING_ATTACK_AIM)
{
- item->Animation.TargetState = 4;
+ item->Animation.TargetState = WORKER_SHOTGUN_STATE_STANDING_ATTACK;
}
else
{
- item->Animation.TargetState = 10;
+ item->Animation.TargetState = WORKER_SHOTGUN_STATE_KNEEL_ATTACK;
}
}
break;
- case 4:
- case 10:
+ case WORKER_SHOTGUN_STATE_STANDING_ATTACK:
+ case WORKER_SHOTGUN_STATE_KNEEL_ATTACK:
if (ai.ahead)
{
extraTorsoRot.x = ai.xAngle;
@@ -238,15 +271,15 @@ namespace TEN::Entities::Creatures::TR2
creature->Flags = 1;
}
- if (item->Animation.ActiveState == 4 && item->Animation.TargetState != 2 &&
+ if (item->Animation.ActiveState == WORKER_SHOTGUN_STATE_STANDING_ATTACK && item->Animation.TargetState != WORKER_SHOTGUN_STATE_IDLE &&
(creature->Mood == MoodType::Escape || ai.distance > SQUARE(BLOCK(3)) || !Targetable(item, &ai)))
{
- item->Animation.TargetState = 2;
+ item->Animation.TargetState = WORKER_SHOTGUN_STATE_IDLE;
}
break;
- case 6:
+ case WORKER_SHOTGUN_STATE_WALKING_ATTACK:
if (ai.ahead)
{
extraTorsoRot.x = ai.xAngle;
From 15bd3d52172f1991c24407a6fbd298c948b8e022 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Thu, 25 Apr 2024 19:38:39 +1000
Subject: [PATCH 096/410] Add bridge check to player move test over death
sectors
---
TombEngine/Game/Lara/PlayerContext.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/TombEngine/Game/Lara/PlayerContext.cpp b/TombEngine/Game/Lara/PlayerContext.cpp
index b9944df22..6bf992c6e 100644
--- a/TombEngine/Game/Lara/PlayerContext.cpp
+++ b/TombEngine/Game/Lara/PlayerContext.cpp
@@ -190,7 +190,7 @@ namespace TEN::Entities::Player
}
// 3) Check for death floor (if applicable).
- if (setup.TestDeathFloor && pointColl.Block->Flags.Death)
+ if (setup.TestDeathFloor && pointColl.Block->Flags.Death && pointColl.Position.Bridge == NO_VALUE)
return false;
// LOS setup at upper floor bound.
From 546034ecc133658a3759a18473b21501381f8d00 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Fri, 26 Apr 2024 15:49:27 +1000
Subject: [PATCH 097/410] Apply PR comments
---
TombEngine/Game/collision/Point.cpp | 52 +++++++++----------
TombEngine/Game/collision/Point.h | 6 +--
.../Object/Pushable/PushableCollision.cpp | 4 --
3 files changed, 29 insertions(+), 33 deletions(-)
diff --git a/TombEngine/Game/collision/Point.cpp b/TombEngine/Game/collision/Point.cpp
index 19312969d..51701b4ab 100644
--- a/TombEngine/Game/collision/Point.cpp
+++ b/TombEngine/Game/collision/Point.cpp
@@ -34,56 +34,56 @@ namespace TEN::Collision::Point
FloorInfo& PointCollisionData::GetSector()
{
- if (_sectorPtr != nullptr)
- return *_sectorPtr;
+ if (_sector != nullptr)
+ return *_sector;
- // Set current sector pointer.
+ // Set current sector.
short probeRoomNumber = _roomNumber;
- _sectorPtr = GetFloor(_position.x, _position.y, _position.z, &probeRoomNumber);
+ _sector = GetFloor(_position.x, _position.y, _position.z, &probeRoomNumber);
- return *_sectorPtr;
+ return *_sector;
}
FloorInfo& PointCollisionData::GetBottomSector()
{
- if (_bottomSectorPtr != nullptr)
- return *_bottomSectorPtr;
+ if (_bottomSector != nullptr)
+ return *_bottomSector;
- // Set bottom sector pointer.
- auto* bottomSectorPtr = &GetSector();
- auto roomNumberBelow = bottomSectorPtr->GetNextRoomNumber(_position, true);
+ // Set bottom sector.
+ auto* bottomSector = &GetSector();
+ auto roomNumberBelow = bottomSector->GetNextRoomNumber(_position, true);
while (roomNumberBelow.has_value())
{
- int roomNumber = roomNumberBelow.value_or(bottomSectorPtr->RoomNumber);
+ int roomNumber = roomNumberBelow.value_or(bottomSector->RoomNumber);
auto& room = g_Level.Rooms[roomNumber];
- bottomSectorPtr = Room::GetSector(&room, _position.x - room.x, _position.z - room.z);
- roomNumberBelow = bottomSectorPtr->GetNextRoomNumber(_position, true);
+ bottomSector = Room::GetSector(&room, _position.x - room.x, _position.z - room.z);
+ roomNumberBelow = bottomSector->GetNextRoomNumber(_position, true);
}
- _bottomSectorPtr = bottomSectorPtr;
+ _bottomSector = bottomSector;
- return *_bottomSectorPtr;
+ return *_bottomSector;
}
FloorInfo& PointCollisionData::GetTopSector()
{
- if (_topSectorPtr != nullptr)
- return *_topSectorPtr;
+ if (_topSector != nullptr)
+ return *_topSector;
- // Set top sector pointer.
- auto* topSectorPtr = &GetSector();
- auto roomNumberAbove = topSectorPtr->GetNextRoomNumber(_position, false);
+ // Set top sector.
+ auto* topSector = &GetSector();
+ auto roomNumberAbove = topSector->GetNextRoomNumber(_position, false);
while (roomNumberAbove.has_value())
{
- int roomNumber = roomNumberAbove.value_or(topSectorPtr->RoomNumber);
+ int roomNumber = roomNumberAbove.value_or(topSector->RoomNumber);
auto& room = g_Level.Rooms[roomNumber];
- topSectorPtr = Room::GetSector(&room, _position.x - room.x, _position.z - room.z);
- roomNumberAbove = topSectorPtr->GetNextRoomNumber(_position, false);
+ topSector = Room::GetSector(&room, _position.x - room.x, _position.z - room.z);
+ roomNumberAbove = topSector->GetNextRoomNumber(_position, false);
}
- _topSectorPtr = topSectorPtr;
+ _topSector = topSector;
- return *_topSectorPtr;
+ return *_topSector;
}
int PointCollisionData::GetFloorHeight()
@@ -340,7 +340,7 @@ namespace TEN::Collision::Point
PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber)
{
// HACK: Ensure room number is correct if position extends to another room.
- // Accounts for some calls to this function which directly pass offset position instead of using dedicated overloads to probe.
+ // Accounts for some calls to this function which directly pass offset position instead of using dedicated probe overloads.
GetFloor(pos.x, pos.y, pos.z, (short*)&roomNumber);
return PointCollisionData(pos, roomNumber);
diff --git a/TombEngine/Game/collision/Point.h b/TombEngine/Game/collision/Point.h
index 318082c42..cf8150b60 100644
--- a/TombEngine/Game/collision/Point.h
+++ b/TombEngine/Game/collision/Point.h
@@ -17,9 +17,9 @@ namespace TEN::Collision::Point
Vector3i _position = Vector3i::Zero;
int _roomNumber = 0;
- FloorInfo* _sectorPtr = nullptr;
- FloorInfo* _bottomSectorPtr = nullptr;
- FloorInfo* _topSectorPtr = nullptr;
+ FloorInfo* _sector = nullptr;
+ FloorInfo* _bottomSector = nullptr;
+ FloorInfo* _topSector = nullptr;
std::optional _floorHeight = std::nullopt;
std::optional _ceilingHeight = std::nullopt;
diff --git a/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp b/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
index 52c681f52..39ac6d5e7 100644
--- a/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
+++ b/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
@@ -37,10 +37,6 @@ namespace TEN::Entities::Generic
pointColl = GetPointCollision(pushableItem);
AddPushableBridge(pushableItem);
}
- else
- {
- pointColl = GetPointCollision(pushableItem);
- }
// 1) Check for wall.
if (pointColl.GetSector().IsWall(pushableItem.Pose.Position.x, pushableItem.Pose.Position.z))
From bcd689b8ba7afe653d044273b76ef91a6ca9f5b8 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Fri, 26 Apr 2024 15:53:02 +1000
Subject: [PATCH 098/410] Update collide_room.cpp
---
TombEngine/Game/collision/collide_room.cpp | 176 ++++++++++-----------
1 file changed, 88 insertions(+), 88 deletions(-)
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index 438c8fa7c..52ac15f32 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -823,11 +823,11 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance)
// Get front floor block
auto room = GetRoomVector(item->Location, Vector3i(ffpX, y, ffpZ)).RoomNumber;
- auto sectorPtr = &GetPointCollision(Vector3i(ffpX, y, ffpZ), room).GetSector();
+ auto sector = &GetPointCollision(Vector3i(ffpX, y, ffpZ), room).GetSector();
// Get front floor surface heights
- auto floorHeight = GetSurfaceHeight(RoomVector(sectorPtr->RoomNumber, y), ffpX, ffpZ, true).value_or(NO_HEIGHT);
- auto ceilingHeight = GetSurfaceHeight(RoomVector(sectorPtr->RoomNumber, y), ffpX, ffpZ, false).value_or(NO_HEIGHT);
+ auto floorHeight = GetSurfaceHeight(RoomVector(sector->RoomNumber, y), ffpX, ffpZ, true).value_or(NO_HEIGHT);
+ auto ceilingHeight = GetSurfaceHeight(RoomVector(sector->RoomNumber, y), ffpX, ffpZ, false).value_or(NO_HEIGHT);
// If probe landed inside wall (i.e. both floor/ceiling heights are NO_HEIGHT), make a fake
// ledge for algorithm to further succeed.
@@ -840,7 +840,7 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance)
int height = useCeilingLedge ? ceilingHeight : floorHeight;
// Determine if there is a bridge in front.
- auto bridge = sectorPtr->GetInsideBridgeItemNumber(Vector3i(ffpX, height, ffpZ), true, y == height);
+ auto bridge = sector->GetInsideBridgeItemNumber(Vector3i(ffpX, height, ffpZ), true, y == height);
// Determine floor probe offset.
// This must be slightly in front of own coll radius so no bridge misfires occur.
@@ -853,7 +853,7 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance)
// Get true room number and block, based on derived height
room = GetRoomVector(item->Location, Vector3i(fpX, height, fpZ)).RoomNumber;
- sectorPtr = &GetPointCollision(Vector3i(fpX, height, fpZ), room).GetSector();
+ sector = &GetPointCollision(Vector3i(fpX, height, fpZ), room).GetSector();
// We don't need actual corner heights to build planes, so just use normalized value here.
auto fY = height - 1;
@@ -911,7 +911,7 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance)
else
{
// Determine if we should use floor or ceiling split angle based on early tests.
- auto splitAngle = (useCeilingLedge ? TO_RAD(sectorPtr->CeilingSurface.SplitAngle) : TO_RAD(sectorPtr->FloorSurface.SplitAngle));
+ auto splitAngle = (useCeilingLedge ? TO_RAD(sector->CeilingSurface.SplitAngle) : TO_RAD(sector->FloorSurface.SplitAngle));
// Get horizontal block corner coordinates.
auto fX = floor(eX / BLOCK(1)) * BLOCK(1) - 1;
@@ -939,7 +939,7 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance)
};
// If split angle exists, take split plane into account too.
- auto useSplitAngle = (useCeilingLedge ? sectorPtr->IsSurfaceSplit(false) : sectorPtr->IsSurfaceSplit(true));
+ auto useSplitAngle = (useCeilingLedge ? sector->IsSurfaceSplit(false) : sector->IsSurfaceSplit(true));
// Find closest block edge plane.
for (int i = 0; i < (useSplitAngle ? 5 : 4); i++)
@@ -966,7 +966,7 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance)
if (i == 4)
{
- auto usedSectorPlane = useCeilingLedge ? sectorPtr->GetSurfaceTriangleID(eX, eZ, false) : sectorPtr->GetSurfaceTriangleID(eX, eZ, true);
+ auto usedSectorPlane = useCeilingLedge ? sector->GetSurfaceTriangleID(eX, eZ, false) : sector->GetSurfaceTriangleID(eX, eZ, true);
result[p] = FROM_RAD(splitAngle) + ANGLE(usedSectorPlane * 180.0f) + ANGLE(90.0f);
}
else
@@ -1085,31 +1085,31 @@ int GetDistanceToFloor(int itemNumber, bool precise)
int GetWaterSurface(int x, int y, int z, short roomNumber)
{
- auto* roomPtr = &g_Level.Rooms[roomNumber];
- auto* sectorPtr = GetSector(roomPtr, x - roomPtr->x, z - roomPtr->z);
+ auto* room = &g_Level.Rooms[roomNumber];
+ auto* sector = GetSector(room, x - room->x, z - room->z);
- if (TestEnvironment(ENV_FLAG_WATER, roomPtr))
+ if (TestEnvironment(ENV_FLAG_WATER, room))
{
- while (sectorPtr->GetNextRoomNumber(Vector3i(x, y, z), false).value_or(NO_ROOM) != NO_ROOM)
+ while (sector->GetNextRoomNumber(Vector3i(x, y, z), false).value_or(NO_VALUE) != NO_VALUE)
{
- roomPtr = &g_Level.Rooms[sectorPtr->GetNextRoomNumber(Vector3i(x, y, z), false).value_or(sectorPtr->RoomNumber)];
- if (!TestEnvironment(ENV_FLAG_WATER, roomPtr))
- return (sectorPtr->GetSurfaceHeight(x, z, false));
+ room = &g_Level.Rooms[sector->GetNextRoomNumber(Vector3i(x, y, z), false).value_or(sector->RoomNumber)];
+ if (!TestEnvironment(ENV_FLAG_WATER, room))
+ return (sector->GetSurfaceHeight(x, z, false));
- sectorPtr = GetSector(roomPtr, x - roomPtr->x, z - roomPtr->z);
+ sector = GetSector(room, x - room->x, z - room->z);
}
return NO_HEIGHT;
}
else
{
- while (sectorPtr->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(NO_ROOM) != NO_ROOM)
+ while (sector->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(NO_VALUE) != NO_VALUE)
{
- roomPtr = &g_Level.Rooms[sectorPtr->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(sectorPtr->RoomNumber)];
- if (TestEnvironment(ENV_FLAG_WATER, roomPtr))
- return (sectorPtr->GetSurfaceHeight(x, z, true));
+ room = &g_Level.Rooms[sector->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(sector->RoomNumber)];
+ if (TestEnvironment(ENV_FLAG_WATER, room))
+ return (sector->GetSurfaceHeight(x, z, true));
- sectorPtr = GetSector(roomPtr, x - roomPtr->x, z - roomPtr->z);
+ sector = GetSector(room, x - room->x, z - room->z);
}
}
@@ -1123,14 +1123,14 @@ int GetWaterSurface(ItemInfo* item)
int GetWaterDepth(int x, int y, int z, short roomNumber)
{
- FloorInfo* sectorPtr = nullptr;
- auto* roomPtr = &g_Level.Rooms[roomNumber];
+ FloorInfo* sector = nullptr;
+ auto* room = &g_Level.Rooms[roomNumber];
- int adjoiningRoomNumber = NO_ROOM;
+ int adjoiningRoomNumber = NO_VALUE;
do
{
- int xFloor = (x - roomPtr->x) / BLOCK(1);
- int zFloor = (z - roomPtr->z) / BLOCK(1);
+ int xFloor = (x - room->x) / BLOCK(1);
+ int zFloor = (z - room->z) / BLOCK(1);
if (zFloor <= 0)
{
@@ -1139,77 +1139,77 @@ int GetWaterDepth(int x, int y, int z, short roomNumber)
{
xFloor = 1;
}
- else if (xFloor > (roomPtr->xSize - 2))
+ else if (xFloor > (room->xSize - 2))
{
- xFloor = roomPtr->xSize - 2;
+ xFloor = room->xSize - 2;
}
}
- else if (zFloor >= (roomPtr->zSize - 1))
+ else if (zFloor >= (room->zSize - 1))
{
- zFloor = roomPtr->zSize - 1;
+ zFloor = room->zSize - 1;
if (xFloor < 1)
{
xFloor = 1;
}
- else if (xFloor > (roomPtr->xSize - 2))
+ else if (xFloor > (room->xSize - 2))
{
- xFloor = roomPtr->xSize - 2;
+ xFloor = room->xSize - 2;
}
}
else if (xFloor < 0)
{
xFloor = 0;
}
- else if (xFloor >= roomPtr->xSize)
+ else if (xFloor >= room->xSize)
{
- xFloor = roomPtr->xSize - 1;
+ xFloor = room->xSize - 1;
}
- sectorPtr = &roomPtr->floor[zFloor + (xFloor * roomPtr->zSize)];
- adjoiningRoomNumber = sectorPtr->SidePortalRoomNumber;
- if (adjoiningRoomNumber != NO_ROOM)
+ sector = &room->floor[zFloor + (xFloor * room->zSize)];
+ adjoiningRoomNumber = sector->SidePortalRoomNumber;
+ if (adjoiningRoomNumber != NO_VALUE)
{
roomNumber = adjoiningRoomNumber;
- roomPtr = &g_Level.Rooms[adjoiningRoomNumber];
+ room = &g_Level.Rooms[adjoiningRoomNumber];
}
}
- while (adjoiningRoomNumber != NO_ROOM);
+ while (adjoiningRoomNumber != NO_VALUE);
- if (TestEnvironment(ENV_FLAG_WATER, roomPtr) ||
- TestEnvironment(ENV_FLAG_SWAMP, roomPtr))
+ if (TestEnvironment(ENV_FLAG_WATER, room) ||
+ TestEnvironment(ENV_FLAG_SWAMP, room))
{
- while (sectorPtr->GetNextRoomNumber(Vector3i(x, y, z), false).value_or(NO_ROOM) != NO_ROOM)
+ while (sector->GetNextRoomNumber(Vector3i(x, y, z), false).value_or(NO_VALUE) != NO_VALUE)
{
- roomPtr = &g_Level.Rooms[sectorPtr->GetNextRoomNumber(Vector3i(x, y, z), false).value_or(sectorPtr->RoomNumber)];
+ room = &g_Level.Rooms[sector->GetNextRoomNumber(Vector3i(x, y, z), false).value_or(sector->RoomNumber)];
- if (!TestEnvironment(ENV_FLAG_WATER, roomPtr) &&
- !TestEnvironment(ENV_FLAG_SWAMP, roomPtr))
+ if (!TestEnvironment(ENV_FLAG_WATER, room) &&
+ !TestEnvironment(ENV_FLAG_SWAMP, room))
{
- int waterHeight = sectorPtr->GetSurfaceHeight(x, z, false);
- int floorHeight = GetPointCollision(Vector3i(x, y, z), sectorPtr->RoomNumber).GetBottomSector().GetSurfaceHeight(x, z, true);
+ int waterHeight = sector->GetSurfaceHeight(x, z, false);
+ int floorHeight = GetPointCollision(Vector3i(x, y, z), sector->RoomNumber).GetBottomSector().GetSurfaceHeight(x, z, true);
return (floorHeight - waterHeight);
}
- sectorPtr = GetSector(roomPtr, x - roomPtr->x, z - roomPtr->z);
+ sector = GetSector(room, x - room->x, z - room->z);
}
return DEEP_WATER;
}
else
{
- while (sectorPtr->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(NO_ROOM) != NO_ROOM)
+ while (sector->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(NO_VALUE) != NO_VALUE)
{
- roomPtr = &g_Level.Rooms[sectorPtr->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(sectorPtr->RoomNumber)];
+ room = &g_Level.Rooms[sector->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(sector->RoomNumber)];
- if (TestEnvironment(ENV_FLAG_WATER, roomPtr) ||
- TestEnvironment(ENV_FLAG_SWAMP, roomPtr))
+ if (TestEnvironment(ENV_FLAG_WATER, room) ||
+ TestEnvironment(ENV_FLAG_SWAMP, room))
{
- int waterHeight = sectorPtr->GetSurfaceHeight(x, z, true);
- sectorPtr = GetFloor(x, y, z, &roomNumber);
- return (GetFloorHeight(sectorPtr, x, y, z) - waterHeight);
+ int waterHeight = sector->GetSurfaceHeight(x, z, true);
+ sector = GetFloor(x, y, z, &roomNumber);
+ return (GetFloorHeight(sector, x, y, z) - waterHeight);
}
- sectorPtr = GetSector(roomPtr, x - roomPtr->x, z - roomPtr->z);
+ sector = GetSector(room, x - room->x, z - room->z);
}
return NO_HEIGHT;
@@ -1223,14 +1223,14 @@ int GetWaterDepth(ItemInfo* item)
int GetWaterHeight(int x, int y, int z, short roomNumber)
{
- FloorInfo* sectorPtr = nullptr;
- auto* roomPtr = &g_Level.Rooms[roomNumber];
+ FloorInfo* sector = nullptr;
+ auto* room = &g_Level.Rooms[roomNumber];
- int adjoiningRoomNumber = NO_ROOM;
+ int adjoiningRoomNumber = NO_VALUE;
do
{
- int xBlock = (x - roomPtr->x) / BLOCK(1);
- int zBlock = (z - roomPtr->z) / BLOCK(1);
+ int xBlock = (x - room->x) / BLOCK(1);
+ int zBlock = (z - room->z) / BLOCK(1);
if (zBlock <= 0)
{
@@ -1239,52 +1239,52 @@ int GetWaterHeight(int x, int y, int z, short roomNumber)
{
xBlock = 1;
}
- else if (xBlock > (roomPtr->xSize - 2))
+ else if (xBlock > (room->xSize - 2))
{
- xBlock = roomPtr->xSize - 2;
+ xBlock = room->xSize - 2;
}
}
- else if (zBlock >= (roomPtr->zSize - 1))
+ else if (zBlock >= (room->zSize - 1))
{
- zBlock = roomPtr->zSize - 1;
+ zBlock = room->zSize - 1;
if (xBlock < 1)
{
xBlock = 1;
}
- else if (xBlock > (roomPtr->xSize - 2))
+ else if (xBlock > (room->xSize - 2))
{
- xBlock = roomPtr->xSize - 2;
+ xBlock = room->xSize - 2;
}
}
else if (xBlock < 0)
{
xBlock = 0;
}
- else if (xBlock >= roomPtr->xSize)
+ else if (xBlock >= room->xSize)
{
- xBlock = roomPtr->xSize - 1;
+ xBlock = room->xSize - 1;
}
- sectorPtr = &roomPtr->floor[zBlock + (xBlock * roomPtr->zSize)];
- adjoiningRoomNumber = sectorPtr->SidePortalRoomNumber;
+ sector = &room->floor[zBlock + (xBlock * room->zSize)];
+ adjoiningRoomNumber = sector->SidePortalRoomNumber;
- if (adjoiningRoomNumber != NO_ROOM)
+ if (adjoiningRoomNumber != NO_VALUE)
{
roomNumber = adjoiningRoomNumber;
- roomPtr = &g_Level.Rooms[adjoiningRoomNumber];
+ room = &g_Level.Rooms[adjoiningRoomNumber];
}
}
- while (adjoiningRoomNumber != NO_ROOM);
+ while (adjoiningRoomNumber != NO_VALUE);
- if (sectorPtr->IsWall(x, z))
+ if (sector->IsWall(x, z))
return NO_HEIGHT;
- if (TestEnvironment(ENV_FLAG_WATER, roomPtr) ||
- TestEnvironment(ENV_FLAG_SWAMP, roomPtr))
+ if (TestEnvironment(ENV_FLAG_WATER, room) ||
+ TestEnvironment(ENV_FLAG_SWAMP, room))
{
- while (sectorPtr->GetNextRoomNumber(Vector3i(x, y, z), false).value_or(NO_ROOM) != NO_ROOM)
+ while (sector->GetNextRoomNumber(Vector3i(x, y, z), false).value_or(NO_VALUE) != NO_VALUE)
{
- auto* room = &g_Level.Rooms[sectorPtr->GetNextRoomNumber(Vector3i(x, y, z), false).value_or(sectorPtr->RoomNumber)];
+ auto* room = &g_Level.Rooms[sector->GetNextRoomNumber(Vector3i(x, y, z), false).value_or(sector->RoomNumber)];
if (!TestEnvironment(ENV_FLAG_WATER, room) &&
!TestEnvironment(ENV_FLAG_SWAMP, room))
@@ -1292,27 +1292,27 @@ int GetWaterHeight(int x, int y, int z, short roomNumber)
break;
}
- sectorPtr = GetSector(room, x - room->x, z - room->z);
+ sector = GetSector(room, x - room->x, z - room->z);
}
- return GetPointCollision(Vector3i(x, y, z), sectorPtr->RoomNumber).GetSector().GetSurfaceHeight(Vector3i(x, y, z), false);
+ return GetPointCollision(Vector3i(x, y, z), sector->RoomNumber).GetSector().GetSurfaceHeight(Vector3i(x, y, z), false);
}
- else if (sectorPtr->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(NO_ROOM) != NO_ROOM)
+ else if (sector->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(NO_VALUE) != NO_VALUE)
{
- while (sectorPtr->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(NO_ROOM) != NO_ROOM)
+ while (sector->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(NO_VALUE) != NO_VALUE)
{
- auto* roomPtr2 = &g_Level.Rooms[sectorPtr->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(sectorPtr->RoomNumber)];
+ auto* room2 = &g_Level.Rooms[sector->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(sector->RoomNumber)];
- if (TestEnvironment(ENV_FLAG_WATER, roomPtr2) ||
- TestEnvironment(ENV_FLAG_SWAMP, roomPtr2))
+ if (TestEnvironment(ENV_FLAG_WATER, room2) ||
+ TestEnvironment(ENV_FLAG_SWAMP, room2))
{
break;
}
- sectorPtr = GetSector(roomPtr2, x - roomPtr2->x, z - roomPtr2->z);
+ sector = GetSector(room2, x - room2->x, z - room2->z);
}
- return GetPointCollision(Vector3i(x, y, z), sectorPtr->RoomNumber).GetSector().GetSurfaceHeight(Vector3i(x, y, z), true);
+ return GetPointCollision(Vector3i(x, y, z), sector->RoomNumber).GetSector().GetSurfaceHeight(Vector3i(x, y, z), true);
}
return NO_HEIGHT;
From b73b31784c9eaee23691b64db219fcf5399a0835 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Fri, 26 Apr 2024 16:30:44 +1000
Subject: [PATCH 099/410] Add TODOs
---
TombEngine/Game/collision/Point.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/TombEngine/Game/collision/Point.cpp b/TombEngine/Game/collision/Point.cpp
index 51701b4ab..7c8b12c59 100644
--- a/TombEngine/Game/collision/Point.cpp
+++ b/TombEngine/Game/collision/Point.cpp
@@ -177,7 +177,7 @@ namespace TEN::Collision::Point
if (_waterSurfaceHeight.has_value())
return *_waterSurfaceHeight;
- // Set water surface height.
+ // Set water surface height. TODO: Calculate here.
_waterSurfaceHeight = GetWaterSurface(_position.x, _position.y, _position.z, _roomNumber);
return *_waterSurfaceHeight;
@@ -188,7 +188,7 @@ namespace TEN::Collision::Point
if (_waterBottomHeight.has_value())
return *_waterBottomHeight;
- // Set water bottom height.
+ // Set water bottom height. TODO: Calculate here.
_waterBottomHeight = GetWaterDepth(_position.x, _position.y, _position.z, _roomNumber);
return *_waterBottomHeight;
@@ -199,7 +199,7 @@ namespace TEN::Collision::Point
if (_waterTopHeight.has_value())
return *_waterTopHeight;
- // Set water top height.
+ // Set water top height. TODO: Calculate here.
_waterTopHeight = GetWaterHeight(_position.x, _position.y, _position.z, _roomNumber);
return *_waterTopHeight;
From ad8215830191637e1d4048d3ca9e55f4e078ce48 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Fri, 26 Apr 2024 17:51:53 +1000
Subject: [PATCH 100/410] Illegal slope -> steep slope
---
TombEngine/Game/Lara/PlayerContext.cpp | 12 ++++++------
TombEngine/Game/Lara/lara_overhang.cpp | 2 +-
TombEngine/Game/Lara/lara_tests.cpp | 4 ++--
TombEngine/Game/collision/Point.cpp | 16 ++++++++--------
TombEngine/Game/collision/Point.h | 4 ++--
TombEngine/Game/collision/collide_room.cpp | 4 ++--
TombEngine/Game/collision/collide_room.h | 4 ++--
TombEngine/Game/collision/floordata.cpp | 2 +-
TombEngine/Game/collision/floordata.h | 8 ++++----
TombEngine/Game/misc.cpp | 2 +-
TombEngine/Game/pickup/pickup.cpp | 4 ++--
.../Object/Pushable/PushableCollision.cpp | 2 +-
TombEngine/Objects/TR2/Vehicles/skidoo.cpp | 2 +-
TombEngine/Objects/TR2/Vehicles/speedboat.cpp | 2 +-
TombEngine/Objects/TR3/Vehicles/minecart.cpp | 2 +-
TombEngine/Objects/TR3/Vehicles/quad_bike.cpp | 2 +-
TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp | 2 +-
TombEngine/Objects/TR4/Vehicles/jeep.cpp | 2 +-
TombEngine/Objects/TR4/Vehicles/motorbike.cpp | 2 +-
TombEngine/Specific/level.cpp | 8 ++++----
20 files changed, 43 insertions(+), 43 deletions(-)
diff --git a/TombEngine/Game/Lara/PlayerContext.cpp b/TombEngine/Game/Lara/PlayerContext.cpp
index 0bffbec87..8d71d80a7 100644
--- a/TombEngine/Game/Lara/PlayerContext.cpp
+++ b/TombEngine/Game/Lara/PlayerContext.cpp
@@ -179,14 +179,14 @@ namespace TEN::Entities::Player
// 1) Check for illegal slope below floor (if applicable).
if (setup.TestIllegalFloorBelow &&
- (pointColl.IsIllegalFloor() && abs(aspectAngleDelta) <= SLOPE_ASPECT_ANGLE_DELTA_MAX))
+ (pointColl.IsSteepFloor() && abs(aspectAngleDelta) <= SLOPE_ASPECT_ANGLE_DELTA_MAX))
{
return false;
}
// 1) Check for illegal slope above floor (if applicable).
if (setup.TestIllegalFloorAbove &&
- (pointColl.IsIllegalFloor() && abs(aspectAngleDelta) >= SLOPE_ASPECT_ANGLE_DELTA_MAX))
+ (pointColl.IsSteepFloor() && abs(aspectAngleDelta) >= SLOPE_ASPECT_ANGLE_DELTA_MAX))
{
return false;
}
@@ -407,7 +407,7 @@ namespace TEN::Entities::Player
// 2) Assess point collision.
if (abs(relFloorHeight) <= ABS_FLOOR_BOUND && // Floor height is within upper/lower floor bounds.
- pointColl.IsIllegalFloor()) // Floor is a slippery slope.
+ pointColl.IsSteepFloor()) // Floor is a slippery slope.
{
return true;
}
@@ -543,7 +543,7 @@ namespace TEN::Entities::Player
// Assess point collision.
if (floorHeightDelta > FLOOR_BOUND || // Avoid floor height delta beyond crawl stepup threshold.
floorToCeilHeight <= FLOOR_TO_CEIL_HEIGHT_MAX || // Avoid narrow spaces.
- pointColl1.IsIllegalFloor()) // Avoid slippery floor slopes.
+ pointColl1.IsSteepFloor()) // Avoid slippery floor slopes.
{
return false;
}
@@ -609,7 +609,7 @@ namespace TEN::Entities::Player
auto pointColl = GetPointCollision(item);
// 2) Test for slippery ceiling slope and check if overhang climb is disabled.
- if (pointColl.IsIllegalCeiling() && !g_GameFlow->HasOverhangClimb())
+ if (pointColl.IsSteepCeiling() && !g_GameFlow->HasOverhangClimb())
return true;
// 3) Assess point collision.
@@ -667,7 +667,7 @@ namespace TEN::Entities::Player
return false;
// 2) Test for illegal ceiling.
- if (pointColl.IsIllegalCeiling())
+ if (pointColl.IsSteepCeiling())
return false;
int vPos = item.Pose.Position.y;
diff --git a/TombEngine/Game/Lara/lara_overhang.cpp b/TombEngine/Game/Lara/lara_overhang.cpp
index 72cc86ad0..12f04361e 100644
--- a/TombEngine/Game/Lara/lara_overhang.cpp
+++ b/TombEngine/Game/Lara/lara_overhang.cpp
@@ -972,7 +972,7 @@ bool LadderMonkeyExtra(ItemInfo* item, CollisionInfo* coll)
{
auto probe = GetPointCollision(*item);
- if (probe.IsIllegalCeiling())
+ if (probe.IsSteepCeiling())
return false;
if (probe.GetBottomSector().Flags.Monkeyswing && (item->Pose.Position.y - coll->Setup.Height - CLICK(0.5f) <= probe.GetCeilingHeight()))
diff --git a/TombEngine/Game/Lara/lara_tests.cpp b/TombEngine/Game/Lara/lara_tests.cpp
index 4612b0217..9d24bc0ea 100644
--- a/TombEngine/Game/Lara/lara_tests.cpp
+++ b/TombEngine/Game/Lara/lara_tests.cpp
@@ -881,7 +881,7 @@ bool TestPlayerWaterStepOut(ItemInfo* item, CollisionInfo* coll)
int vPos = item->Pose.Position.y;
if (coll->CollisionType == CollisionType::Front ||
- pointColl.IsIllegalFloor() ||
+ pointColl.IsSteepFloor() ||
(pointColl.GetFloorHeight() - vPos) <= 0)
{
return false;
@@ -1602,7 +1602,7 @@ CrawlVaultTestResult TestLaraCrawlVaultTolerance(ItemInfo* item, CollisionInfo*
auto probeB = GetPointCollision(*item, item->Pose.Orientation.y, testSetup.DestDist, -LARA_HEIGHT_CRAWL); // Approximate destination.
auto probeMiddle = GetPointCollision(*item);
- bool isSlope = testSetup.CheckSlope ? probeB.IsIllegalFloor() : false;
+ bool isSlope = testSetup.CheckSlope ? probeB.IsSteepFloor() : false;
bool isDeath = testSetup.CheckDeath ? probeB.GetSector().Flags.Death : false;
// Discard walls.
diff --git a/TombEngine/Game/collision/Point.cpp b/TombEngine/Game/collision/Point.cpp
index 7c8b12c59..8790423a3 100644
--- a/TombEngine/Game/collision/Point.cpp
+++ b/TombEngine/Game/collision/Point.cpp
@@ -211,24 +211,24 @@ namespace TEN::Collision::Point
GetFloorHeight() <= GetCeilingHeight());
}
- bool PointCollisionData::IsIllegalFloor()
+ bool PointCollisionData::IsSteepFloor()
{
short slopeAngle = Geometry::GetSurfaceSlopeAngle(GetFloorNormal());
- short illegalSlopeAngle = (GetFloorBridgeItemNumber() != NO_VALUE) ?
- DEFAULT_ILLEGAL_FLOOR_SLOPE_ANGLE :
+ short steepSlopeAngle = (GetFloorBridgeItemNumber() != NO_VALUE) ?
+ DEFAULT_STEEP_FLOOR_SLOPE_ANGLE :
GetBottomSector().GetSurfaceIllegalSlopeAngle(_position.x, _position.z, true);
- return (abs(slopeAngle) >= illegalSlopeAngle);
+ return (abs(slopeAngle) >= steepSlopeAngle);
}
- bool PointCollisionData::IsIllegalCeiling()
+ bool PointCollisionData::IsSteepCeiling()
{
short slopeAngle = Geometry::GetSurfaceSlopeAngle(GetCeilingNormal(), -Vector3::UnitY);
- short illegalSlopeAngle = (GetCeilingBridgeItemNumber() != NO_VALUE) ?
- DEFAULT_ILLEGAL_CEILING_SLOPE_ANGLE :
+ short steepSlopeAngle = (GetCeilingBridgeItemNumber() != NO_VALUE) ?
+ DEFAULT_STEEP_CEILING_SLOPE_ANGLE :
GetTopSector().GetSurfaceIllegalSlopeAngle(_position.x, _position.z, false);
- return (abs(slopeAngle) >= illegalSlopeAngle);
+ return (abs(slopeAngle) >= steepSlopeAngle);
}
bool PointCollisionData::IsDiagonalFloorStep()
diff --git a/TombEngine/Game/collision/Point.h b/TombEngine/Game/collision/Point.h
index cf8150b60..9f1651f10 100644
--- a/TombEngine/Game/collision/Point.h
+++ b/TombEngine/Game/collision/Point.h
@@ -57,8 +57,8 @@ namespace TEN::Collision::Point
// Inquirers
bool IsWall();
- bool IsIllegalFloor();
- bool IsIllegalCeiling();
+ bool IsSteepFloor();
+ bool IsSteepCeiling();
bool IsDiagonalFloorStep();
bool IsDiagonalCeilingStep();
bool IsDiagonalFloorSplit();
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index 52ac15f32..3ca9517cd 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -128,8 +128,8 @@ static CollisionPositionData GetCollisionPosition(PointCollisionData& pointColl)
collPos.Ceiling = pointColl.GetCeilingHeight();
collPos.Bridge = pointColl.GetFloorBridgeItemNumber();
collPos.SplitAngle = pointColl.GetBottomSector().FloorSurface.SplitAngle;
- collPos.FloorSlope = pointColl.IsIllegalFloor();
- collPos.CeilingSlope = pointColl.IsIllegalCeiling();
+ collPos.FloorSlope = pointColl.IsSteepFloor();
+ collPos.CeilingSlope = pointColl.IsSteepCeiling();
collPos.DiagonalStep = pointColl.IsDiagonalFloorStep();
return collPos;
diff --git a/TombEngine/Game/collision/collide_room.h b/TombEngine/Game/collision/collide_room.h
index 52a215687..1dc1c5ef2 100644
--- a/TombEngine/Game/collision/collide_room.h
+++ b/TombEngine/Game/collision/collide_room.h
@@ -16,8 +16,8 @@ constexpr auto NO_LOWER_BOUND = -NO_HEIGHT; // Used by coll->Setup.LowerFloorBou
constexpr auto NO_UPPER_BOUND = NO_HEIGHT; // Used by coll->Setup.UpperFloorBound.
constexpr auto COLLISION_CHECK_DISTANCE = BLOCK(8);
-constexpr auto DEFAULT_ILLEGAL_FLOOR_SLOPE_ANGLE = ANGLE(36.0f);
-constexpr auto DEFAULT_ILLEGAL_CEILING_SLOPE_ANGLE = ANGLE(45.0f);
+constexpr auto DEFAULT_STEEP_FLOOR_SLOPE_ANGLE = ANGLE(36.0f);
+constexpr auto DEFAULT_STEEP_CEILING_SLOPE_ANGLE = ANGLE(45.0f);
enum class CollisionType
{
diff --git a/TombEngine/Game/collision/floordata.cpp b/TombEngine/Game/collision/floordata.cpp
index 470df2dc7..a15e2d8fe 100644
--- a/TombEngine/Game/collision/floordata.cpp
+++ b/TombEngine/Game/collision/floordata.cpp
@@ -62,7 +62,7 @@ Vector3 FloorInfo::GetSurfaceNormal(int x, int z, bool isFloor) const
short FloorInfo::GetSurfaceIllegalSlopeAngle(int x, int z, bool isFloor) const
{
const auto& tri = GetSurfaceTriangle(x, z, isFloor);
- return tri.IllegalSlopeAngle;
+ return tri.SteepSlopeAngle;
}
MaterialType FloorInfo::GetSurfaceMaterial(int x, int z, bool isFloor) const
diff --git a/TombEngine/Game/collision/floordata.h b/TombEngine/Game/collision/floordata.h
index 16662eeca..891e130f5 100644
--- a/TombEngine/Game/collision/floordata.h
+++ b/TombEngine/Game/collision/floordata.h
@@ -74,10 +74,10 @@ public:
struct SectorSurfaceTriangleData
{
- Plane Plane = {};
- int PortalRoomNumber = 0;
- short IllegalSlopeAngle = 0;
- MaterialType Material = MaterialType::Stone;
+ Plane Plane = {};
+ int PortalRoomNumber = 0;
+ short SteepSlopeAngle = 0;
+ MaterialType Material = MaterialType::Stone;
};
struct SectorSurfaceData
diff --git a/TombEngine/Game/misc.cpp b/TombEngine/Game/misc.cpp
index 3f5af7186..b9d789402 100644
--- a/TombEngine/Game/misc.cpp
+++ b/TombEngine/Game/misc.cpp
@@ -55,7 +55,7 @@ bool IsNextSectorValid(const ItemInfo& item, const Vector3& dir, float dist)
return false;
// Test for slippery slope.
- if (pointColl.IsIllegalFloor())
+ if (pointColl.IsSteepFloor())
return false;
// Flat floor.
diff --git a/TombEngine/Game/pickup/pickup.cpp b/TombEngine/Game/pickup/pickup.cpp
index 86d2fee4b..0dff72dda 100644
--- a/TombEngine/Game/pickup/pickup.cpp
+++ b/TombEngine/Game/pickup/pickup.cpp
@@ -860,7 +860,7 @@ void DropPickups(ItemInfo* item)
auto collPoint = GetPointCollision(candidatePos, item->RoomNumber);
// If position is inside a wall or on a slope, don't use it.
- if (collPoint.GetFloorHeight() == NO_HEIGHT || collPoint.IsIllegalFloor())
+ if (collPoint.GetFloorHeight() == NO_HEIGHT || collPoint.IsSteepFloor())
continue;
// Remember floor position for a tested point.
@@ -872,7 +872,7 @@ void DropPickups(ItemInfo* item)
collPoint = GetPointCollision(candidatePos, item->RoomNumber);
// If position is inside a wall or on a slope, don't use it.
- if (collPoint.GetFloorHeight() == NO_HEIGHT || collPoint.IsIllegalFloor())
+ if (collPoint.GetFloorHeight() == NO_HEIGHT || collPoint.IsSteepFloor())
continue;
// If position is not in the same room, don't use it.
diff --git a/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp b/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
index 39ac6d5e7..733ae4c86 100644
--- a/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
+++ b/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
@@ -86,7 +86,7 @@ namespace TEN::Entities::Generic
}
// 3) Check for slippery floor slope.
- if (pointColl.IsIllegalFloor())
+ if (pointColl.IsSteepFloor())
return false;
// 4) Check for diagonal floor step.
diff --git a/TombEngine/Objects/TR2/Vehicles/skidoo.cpp b/TombEngine/Objects/TR2/Vehicles/skidoo.cpp
index 47ec2fa3c..0032ae11b 100644
--- a/TombEngine/Objects/TR2/Vehicles/skidoo.cpp
+++ b/TombEngine/Objects/TR2/Vehicles/skidoo.cpp
@@ -189,7 +189,7 @@ namespace TEN::Entities::Vehicles
auto probe = GetPointCollision(*skidooItem, angle, -SKIDOO_DISMOUNT_DISTANCE);
- if ((probe.IsIllegalFloor() || probe.GetFloorHeight() == NO_HEIGHT) ||
+ if ((probe.IsSteepFloor() || probe.GetFloorHeight() == NO_HEIGHT) ||
abs(probe.GetFloorHeight() - skidooItem->Pose.Position.y) > CLICK(2) ||
((probe.GetCeilingHeight() - skidooItem->Pose.Position.y) > -LARA_HEIGHT ||
(probe.GetFloorHeight() - probe.GetCeilingHeight()) < LARA_HEIGHT))
diff --git a/TombEngine/Objects/TR2/Vehicles/speedboat.cpp b/TombEngine/Objects/TR2/Vehicles/speedboat.cpp
index 037c06ab8..f0914c1b7 100644
--- a/TombEngine/Objects/TR2/Vehicles/speedboat.cpp
+++ b/TombEngine/Objects/TR2/Vehicles/speedboat.cpp
@@ -244,7 +244,7 @@ namespace TEN::Entities::Vehicles
if ((probe.GetFloorHeight() - speedboatItem->Pose.Position.y) < -CLICK(2))
return false;
- if (probe.IsIllegalFloor() ||
+ if (probe.IsSteepFloor() ||
probe.GetFloorHeight() == NO_HEIGHT)
{
return false;
diff --git a/TombEngine/Objects/TR3/Vehicles/minecart.cpp b/TombEngine/Objects/TR3/Vehicles/minecart.cpp
index 21215c3f9..75de38a5e 100644
--- a/TombEngine/Objects/TR3/Vehicles/minecart.cpp
+++ b/TombEngine/Objects/TR3/Vehicles/minecart.cpp
@@ -264,7 +264,7 @@ namespace TEN::Entities::Vehicles
auto probe = GetPointCollision(*minecartItem, angle, -MINECART_DISMOUNT_DISTANCE);
- if (probe.IsIllegalFloor() || probe.GetFloorHeight() == NO_HEIGHT)
+ if (probe.IsSteepFloor() || probe.GetFloorHeight() == NO_HEIGHT)
return false;
if (abs(probe.GetFloorHeight() - minecartItem->Pose.Position.y) > CLICK(2))
diff --git a/TombEngine/Objects/TR3/Vehicles/quad_bike.cpp b/TombEngine/Objects/TR3/Vehicles/quad_bike.cpp
index 6dc3a4f5f..c8ae399b1 100644
--- a/TombEngine/Objects/TR3/Vehicles/quad_bike.cpp
+++ b/TombEngine/Objects/TR3/Vehicles/quad_bike.cpp
@@ -240,7 +240,7 @@ namespace TEN::Entities::Vehicles
auto pointColl = GetPointCollision(Vector3i(x, y, z), quadBikeItem->RoomNumber);
- if (pointColl.IsIllegalFloor() ||
+ if (pointColl.IsSteepFloor() ||
pointColl.GetFloorHeight() == NO_HEIGHT)
{
return false;
diff --git a/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp b/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp
index 4466ff811..ef36e34c7 100644
--- a/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp
+++ b/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp
@@ -611,7 +611,7 @@ namespace TEN::Entities::Vehicles
if ((pointColl.GetFloorHeight() - sBoatItem->Pose.Position.y) < -512)
return false;
- if (pointColl.IsIllegalFloor() || pointColl.GetFloorHeight() == NO_HEIGHT)
+ if (pointColl.IsSteepFloor() || pointColl.GetFloorHeight() == NO_HEIGHT)
return false;
if ((pointColl.GetCeilingHeight() - sBoatItem->Pose.Position.y) > -LARA_HEIGHT ||
diff --git a/TombEngine/Objects/TR4/Vehicles/jeep.cpp b/TombEngine/Objects/TR4/Vehicles/jeep.cpp
index 169e254e6..70258a975 100644
--- a/TombEngine/Objects/TR4/Vehicles/jeep.cpp
+++ b/TombEngine/Objects/TR4/Vehicles/jeep.cpp
@@ -376,7 +376,7 @@ namespace TEN::Entities::Vehicles
auto probe = GetPointCollision(Vector3i(x, y, z), jeepItem->RoomNumber);
- if (probe.IsIllegalFloor() || probe.GetFloorHeight() == NO_HEIGHT)
+ if (probe.IsSteepFloor() || probe.GetFloorHeight() == NO_HEIGHT)
return false;
if (abs(probe.GetFloorHeight() - jeepItem->Pose.Position.y) > BLOCK(1 / 2.0f))
diff --git a/TombEngine/Objects/TR4/Vehicles/motorbike.cpp b/TombEngine/Objects/TR4/Vehicles/motorbike.cpp
index 985ab5360..8ccee05d0 100644
--- a/TombEngine/Objects/TR4/Vehicles/motorbike.cpp
+++ b/TombEngine/Objects/TR4/Vehicles/motorbike.cpp
@@ -749,7 +749,7 @@ namespace TEN::Entities::Vehicles
short angle = motorbikeItem->Pose.Orientation.y + ANGLE(90.0f);
auto collResult = GetPointCollision(*motorbikeItem, angle, MOTORBIKE_RADIUS);
- if (collResult.IsIllegalFloor() || collResult.GetFloorHeight() == NO_HEIGHT) // Was previously set to -NO_HEIGHT by TokyoSU -- Lwmte 23.08.21
+ if (collResult.IsSteepFloor() || collResult.GetFloorHeight() == NO_HEIGHT) // Was previously set to -NO_HEIGHT by TokyoSU -- Lwmte 23.08.21
return false;
if (abs(collResult.GetFloorHeight() - motorbikeItem->Pose.Position.y) > CLICK(1))
diff --git a/TombEngine/Specific/level.cpp b/TombEngine/Specific/level.cpp
index 6e5941fe8..d3e4e1fbc 100644
--- a/TombEngine/Specific/level.cpp
+++ b/TombEngine/Specific/level.cpp
@@ -790,16 +790,16 @@ void ReadRooms()
sector.Stopper = (bool)ReadInt32();
sector.FloorSurface.SplitAngle = FROM_RAD(ReadFloat());
- sector.FloorSurface.Triangles[0].IllegalSlopeAngle = ILLEGAL_FLOOR_SLOPE_ANGLE;
- sector.FloorSurface.Triangles[1].IllegalSlopeAngle = ILLEGAL_FLOOR_SLOPE_ANGLE;
+ sector.FloorSurface.Triangles[0].SteepSlopeAngle = ILLEGAL_FLOOR_SLOPE_ANGLE;
+ sector.FloorSurface.Triangles[1].SteepSlopeAngle = ILLEGAL_FLOOR_SLOPE_ANGLE;
sector.FloorSurface.Triangles[0].PortalRoomNumber = ReadInt32();
sector.FloorSurface.Triangles[1].PortalRoomNumber = ReadInt32();
sector.FloorSurface.Triangles[0].Plane = ConvertFakePlaneToPlane(ReadVector3(), true);
sector.FloorSurface.Triangles[1].Plane = ConvertFakePlaneToPlane(ReadVector3(), true);
sector.CeilingSurface.SplitAngle = FROM_RAD(ReadFloat());
- sector.CeilingSurface.Triangles[0].IllegalSlopeAngle = ILLEGAL_CEILING_SLOPE_ANGLE;
- sector.CeilingSurface.Triangles[1].IllegalSlopeAngle = ILLEGAL_CEILING_SLOPE_ANGLE;
+ sector.CeilingSurface.Triangles[0].SteepSlopeAngle = ILLEGAL_CEILING_SLOPE_ANGLE;
+ sector.CeilingSurface.Triangles[1].SteepSlopeAngle = ILLEGAL_CEILING_SLOPE_ANGLE;
sector.CeilingSurface.Triangles[0].PortalRoomNumber = ReadInt32();
sector.CeilingSurface.Triangles[1].PortalRoomNumber = ReadInt32();
sector.CeilingSurface.Triangles[0].Plane = ConvertFakePlaneToPlane(ReadVector3(), false);
From 29a5fc74113eebab067430d220a85c403974351a Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Fri, 26 Apr 2024 12:43:10 +0300
Subject: [PATCH 101/410] UseItem event (#1357)
* Implement UseItem event, refactor item usage a bit
* Decopypaste medipack hotkey usage code
* Prevent small and large medipacks from being used simultaneously; tidy up UseItem()
---------
Co-authored-by: Sezz
---
Documentation/doc/1 modules/Inventory.html | 40 +-
Documentation/doc/1 modules/Logic.html | 3 +-
TombEngine/Game/Lara/lara_helpers.cpp | 55 +--
TombEngine/Game/control/event.h | 1 +
TombEngine/Game/control/volume.cpp | 6 +-
TombEngine/Game/control/volume.h | 2 +-
TombEngine/Game/gui.cpp | 408 ++++++++----------
TombEngine/Game/gui.h | 4 +-
.../Scripting/Include/ScriptInterfaceGame.h | 3 +-
.../Scripting/Internal/ReservedScriptNames.h | 42 +-
.../TEN/Inventory/InventoryHandler.cpp | 34 +-
.../Internal/TEN/Logic/LogicHandler.cpp | 12 +-
.../Internal/TEN/Logic/LogicHandler.h | 2 +
13 files changed, 281 insertions(+), 331 deletions(-)
diff --git a/Documentation/doc/1 modules/Inventory.html b/Documentation/doc/1 modules/Inventory.html
index f0df17c5b..3d0cf51a8 100644
--- a/Documentation/doc/1 modules/Inventory.html
+++ b/Documentation/doc/1 modules/Inventory.html
@@ -125,16 +125,16 @@
Set the amount of an item in the player's inventory.
- GetChosenItem()
- Get last selected item in the player's inventory.
+ GetUsedItem()
+ Get last item used in the player's inventory.
- SetChosenItem(objectID)
- Set last selected item in the player's inventory.
+ SetUsedItem(objectID)
+ Set last item used in the player's inventory.
- ClearChosenItem()
- Clear last selected item in the player's inventory.
+ ClearUsedItem()
+ Clear last item used in the player's inventory.
@@ -259,14 +259,13 @@
-
- GetChosenItem()
+
+ GetUsedItem()
- Get last selected item in the player's inventory.
+ Get last item used in the player's inventory.
This value will be valid only for a single frame after exiting inventory, after which Lara says "No".
- Therefore, this function must be preferably used either in OnLoop events or callbacks.
- If you have used this function and you want to avoid "No" sound, you should use ClearChosenItem function.
+ Therefore, this function must be preferably used either in OnLoop or OnUseItem events.
@@ -275,7 +274,7 @@
ObjID
- Last selected item in the inventory.
+ Last item used in the inventory.
@@ -283,12 +282,12 @@
-
- SetChosenItem(objectID)
+
+ SetUsedItem(objectID)
- Set last selected item in the player's inventory.
- You will be able to select only objects which already exist in inventory.
+ Set last item used in the player's inventory.
+ You will be able to specify only objects which already exist in the inventory.
Will only be valid for the next frame. If not processed by the game, Lara will say "No".
@@ -307,12 +306,13 @@
-
- ClearChosenItem()
+
+ ClearUsedItem()
- Clear last selected item in the player's inventory.
- This function is needed to avoid Lara saying "No" after selecting particular item in inventory.
+ Clear last item used in the player's inventory.
+ When this function is used in OnUseItem level function, it allows to override existing item functionality.
+ For items without existing functionality, this function is needed to avoid Lara saying "No" after using it.
diff --git a/Documentation/doc/1 modules/Logic.html b/Documentation/doc/1 modules/Logic.html
index e190f3c99..3bf36c12d 100644
--- a/Documentation/doc/1 modules/Logic.html
+++ b/Documentation/doc/1 modules/Logic.html
@@ -263,7 +263,8 @@ LOAD
SAVE
START
END
-LOOP
+LOOP
+USEITEM
Parameters:
diff --git a/TombEngine/Game/Lara/lara_helpers.cpp b/TombEngine/Game/Lara/lara_helpers.cpp
index 80ea111fc..3b137afe9 100644
--- a/TombEngine/Game/Lara/lara_helpers.cpp
+++ b/TombEngine/Game/Lara/lara_helpers.cpp
@@ -276,49 +276,6 @@ void HandlePlayerStatusEffects(ItemInfo& item, WaterStatus waterStatus, PlayerWa
}
}
-static void UsePlayerMedipack(ItemInfo& item)
-{
- auto& player = GetLaraInfo(item);
-
- // Can't use medipack; return early.
- if (item.HitPoints <= 0 ||
- (item.HitPoints >= LARA_HEALTH_MAX && player.Status.Poison == 0))
- {
- return;
- }
-
- bool hasUsedMedipack = false;
-
- if (IsClicked(In::SmallMedipack) &&
- player.Inventory.TotalSmallMedipacks != 0)
- {
- hasUsedMedipack = true;
-
- item.HitPoints += LARA_HEALTH_MAX / 2;
- if (item.HitPoints > LARA_HEALTH_MAX)
- item.HitPoints = LARA_HEALTH_MAX;
-
- if (player.Inventory.TotalSmallMedipacks != -1)
- player.Inventory.TotalSmallMedipacks--;
- }
- else if (IsClicked(In::LargeMedipack) &&
- player.Inventory.TotalLargeMedipacks != 0)
- {
- hasUsedMedipack = true;
- item.HitPoints = LARA_HEALTH_MAX;
-
- if (player.Inventory.TotalLargeMedipacks != -1)
- player.Inventory.TotalLargeMedipacks--;
- }
-
- if (hasUsedMedipack)
- {
- player.Status.Poison = 0;
- SaveGame::Statistics.Game.HealthUsed++;
- SoundEffect(SFX_TR4_MENU_MEDI, nullptr, SoundEnvironment::Always);
- }
-}
-
static std::optional GetPlayerScrolledWeaponType(const ItemInfo& item, LaraWeaponType currentWeaponType, bool getPrev)
{
static const auto SCROLL_WEAPON_TYPES = std::vector
@@ -376,8 +333,14 @@ void HandlePlayerQuickActions(ItemInfo& item)
auto& player = GetLaraInfo(item);
// Handle medipacks.
- if (IsClicked(In::SmallMedipack) || IsClicked(In::LargeMedipack))
- UsePlayerMedipack(item);
+ if (IsClicked(In::SmallMedipack))
+ {
+ g_Gui.UseItem(item, GAME_OBJECT_ID::ID_SMALLMEDI_ITEM);
+ }
+ else if (IsClicked(In::LargeMedipack))
+ {
+ g_Gui.UseItem(item, GAME_OBJECT_ID::ID_BIGMEDI_ITEM);
+ }
// Handle weapon scroll request.
if (IsClicked(In::PreviousWeapon) || IsClicked(In::NextWeapon))
@@ -419,7 +382,7 @@ void HandlePlayerQuickActions(ItemInfo& item)
// TODO: 10th possible weapon, probably grapple gun.
/*if (IsClicked(In::Weapon10) && player.Weapons[(int)LaraWeaponType::].Present)
- player.Control.Weapon.RequestGunType = LaraWeaponType::;*/
+ player.Control.Weapon.RequestGunType = LaraWeaponType::;*/
}
bool CanPlayerLookAround(const ItemInfo& item)
diff --git a/TombEngine/Game/control/event.h b/TombEngine/Game/control/event.h
index 771b60112..2b712efec 100644
--- a/TombEngine/Game/control/event.h
+++ b/TombEngine/Game/control/event.h
@@ -41,6 +41,7 @@ namespace TEN::Control::Volumes
Save,
Start,
End,
+ UseItem,
Count
};
diff --git a/TombEngine/Game/control/volume.cpp b/TombEngine/Game/control/volume.cpp
index a15f4ad2a..80984208a 100644
--- a/TombEngine/Game/control/volume.cpp
+++ b/TombEngine/Game/control/volume.cpp
@@ -89,14 +89,16 @@ namespace TEN::Control::Volumes
return nullptr;
}
- void HandleEvent(Event& event, Activator& activator)
+ bool HandleEvent(Event& event, Activator& activator)
{
if (event.Function.empty() || event.CallCounter == 0 || event.CallCounter < NO_CALL_COUNTER)
- return;
+ return false;
g_GameScript->ExecuteFunction(event.Function, activator, event.Data);
if (event.CallCounter != NO_CALL_COUNTER)
event.CallCounter--;
+
+ return true;
}
bool HandleEvent(const std::string& name, EventType eventType, Activator activator)
diff --git a/TombEngine/Game/control/volume.h b/TombEngine/Game/control/volume.h
index 9d9fc6a84..28694aef8 100644
--- a/TombEngine/Game/control/volume.h
+++ b/TombEngine/Game/control/volume.h
@@ -43,7 +43,7 @@ namespace TEN::Control::Volumes
void TestVolumes(short roomNumber, MESH_INFO* mesh);
void TestVolumes(CAMERA_INFO* camera);
- void HandleEvent(Event& event, Activator& activator);
+ bool HandleEvent(Event& event, Activator& activator);
bool HandleEvent(const std::string& name, EventType eventType, Activator activator);
void HandleAllGlobalEvents(EventType type, Activator& activator);
bool SetEventState(const std::string& name, EventType eventType, bool enabled);
diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp
index e1e74e083..2e2bf148d 100644
--- a/TombEngine/Game/gui.cpp
+++ b/TombEngine/Game/gui.cpp
@@ -6,6 +6,7 @@
#include "Game/animation.h"
#include "Game/camera.h"
#include "Game/control/control.h"
+#include "Game/control/volume.h"
#include "Game/items.h"
#include "Game/Lara/lara.h"
#include "Game/Lara/lara_fire.h"
@@ -1876,7 +1877,7 @@ namespace TEN::Gui
AlterFOV(ANGLE(DEFAULT_FOV), false);
lara->Inventory.IsBusy = false;
InventoryItemChosen = NO_VALUE;
- UseItem = false;
+ ItemUsed = false;
if (lara->Weapons[(int)LaraWeaponType::Shotgun].Ammo[0].HasInfinite())
{
@@ -2030,16 +2031,16 @@ namespace TEN::Gui
}
}
- void GuiController::UseCurrentItem(ItemInfo* item)
+ void GuiController::UseItem(ItemInfo& item, int objectNumber)
{
- const std::vector CrouchStates =
+ const auto CROUCH_STATES = std::vector
{
LS_CROUCH_IDLE,
LS_CROUCH_TURN_LEFT,
LS_CROUCH_TURN_RIGHT,
LS_CROUCH_TURN_180
};
- const std::vector CrawlStates =
+ const auto CRAWL_STATES = std::vector
{
LS_CRAWL_IDLE,
LS_CRAWL_FORWARD,
@@ -2050,265 +2051,232 @@ namespace TEN::Gui
LS_CRAWL_TO_HANG
};
- auto* lara = GetLaraInfo(item);
+ auto& player = GetLaraInfo(item);
- int prevOpticRange = lara->Control.Look.OpticRange;
- short inventoryObject = Rings[(int)RingTypes::Inventory].CurrentObjectList[Rings[(int)RingTypes::Inventory].CurrentObjectInList].InventoryItem;
- short gameObject = InventoryObjectTable[inventoryObject].ObjectNumber;
+ short prevOpticRange = player.Control.Look.OpticRange;
+ player.Control.Look.OpticRange = 0;
+ player.Inventory.OldBusy = false;
+ item.MeshBits = ALL_JOINT_BITS;
- item->MeshBits = ALL_JOINT_BITS;
- lara->Control.Look.OpticRange = 0;
- lara->Inventory.OldBusy = false;
+ InventoryItemChosen = objectNumber;
- if (lara->Control.WaterStatus == WaterStatus::Dry ||
- lara->Control.WaterStatus == WaterStatus::Wade)
+ // Use item event handling.
+ g_GameScript->OnUseItem((GAME_OBJECT_ID)InventoryItemChosen);
+ HandleAllGlobalEvents(EventType::UseItem, (Activator)item.Index);
+
+ // Quickly discard further processing if chosen item was reset in script.
+ if (InventoryItemChosen == NO_VALUE)
+ return;
+
+ if (InventoryItemChosen == ID_PISTOLS_ITEM ||
+ InventoryItemChosen == ID_UZI_ITEM ||
+ InventoryItemChosen == ID_REVOLVER_ITEM)
{
- if (gameObject == ID_PISTOLS_ITEM)
+ if (player.Control.WaterStatus != WaterStatus::Dry &&
+ player.Control.WaterStatus != WaterStatus::Wade)
{
- lara->Control.Weapon.RequestGunType = LaraWeaponType::Pistol;
-
- if (lara->Control.HandStatus != HandStatus::Free)
- return;
-
- if (lara->Control.Weapon.GunType == LaraWeaponType::Pistol)
- lara->Control.HandStatus = HandStatus::WeaponDraw;
-
return;
}
- if (gameObject == ID_UZI_ITEM)
+ switch (InventoryItemChosen)
{
- lara->Control.Weapon.RequestGunType = LaraWeaponType::Uzi;
+ case ID_PISTOLS_ITEM:
+ player.Control.Weapon.RequestGunType = LaraWeaponType::Pistol;
+ break;
- if (lara->Control.HandStatus != HandStatus::Free)
+ case ID_UZI_ITEM:
+ player.Control.Weapon.RequestGunType = LaraWeaponType::Uzi;
+ break;
+
+ case ID_REVOLVER_ITEM:
+ player.Control.Weapon.RequestGunType = LaraWeaponType::Revolver;
+ break;
+
+ default:
return;
-
- if (lara->Control.Weapon.GunType == LaraWeaponType::Uzi)
- lara->Control.HandStatus = HandStatus::WeaponDraw;
-
- return;
}
+
+ if (player.Control.HandStatus == HandStatus::Free &&
+ player.Control.Weapon.GunType == player.Control.Weapon.RequestGunType)
+ {
+ player.Control.HandStatus = HandStatus::WeaponDraw;
+ }
+
+ InventoryItemChosen = NO_VALUE;
+ return;
}
- if (gameObject != ID_SHOTGUN_ITEM &&
- gameObject != ID_REVOLVER_ITEM &&
- gameObject != ID_HK_ITEM &&
- gameObject != ID_CROSSBOW_ITEM &&
- gameObject != ID_GRENADE_GUN_ITEM &&
- gameObject != ID_ROCKET_LAUNCHER_ITEM &&
- gameObject != ID_HARPOON_ITEM)
+ if (InventoryItemChosen == ID_SHOTGUN_ITEM ||
+ InventoryItemChosen == ID_HK_ITEM ||
+ InventoryItemChosen == ID_CROSSBOW_ITEM ||
+ InventoryItemChosen == ID_GRENADE_GUN_ITEM ||
+ InventoryItemChosen == ID_ROCKET_LAUNCHER_ITEM ||
+ InventoryItemChosen == ID_HARPOON_ITEM)
{
- if (gameObject == ID_FLARE_INV_ITEM)
+ if (InventoryItemChosen != ID_HARPOON_ITEM &&
+ player.Control.WaterStatus != WaterStatus::Dry &&
+ player.Control.WaterStatus != WaterStatus::Wade)
{
- if (lara->Control.HandStatus == HandStatus::Free)
- {
- if (!TestState(item->Animation.ActiveState, CrawlStates))
- {
- if (lara->Control.Weapon.GunType != LaraWeaponType::Flare)
- {
- // HACK.
- ClearAllActions();
- ActionMap[(int)In::Flare].Update(1.0f);
-
- HandleWeapon(*item);
- ClearAllActions();
- }
-
- return;
- }
- }
-
- SayNo();
return;
}
- switch (inventoryObject)
+ if (TestState(item.Animation.ActiveState, CROUCH_STATES) ||
+ TestState(item.Animation.ActiveState, CRAWL_STATES))
{
- case INV_OBJECT_BINOCULARS:
- if (((item->Animation.ActiveState == LS_IDLE && item->Animation.AnimNumber == LA_STAND_IDLE) ||
- (lara->Control.IsLow && !IsHeld(In::Crouch))) &&
- !UseSpotCam && !TrackCameraInit)
- {
- lara->Control.Look.OpticRange = 128;
- lara->Control.Look.IsUsingBinoculars = true;
- lara->Inventory.OldBusy = true;
-
- // TODO: To prevent Lara from crouching or performing other actions, the inherent state of
- // LA_BINOCULARS_IDLE must be changed to LS_IDLE. @Sezz 2022.05.19
- //SetAnimation(item, LA_BINOCULARS_IDLE);
-
- if (lara->Control.HandStatus != HandStatus::Free)
- lara->Control.HandStatus = HandStatus::WeaponUndraw;
- }
-
- if (prevOpticRange)
- {
- lara->Control.Look.OpticRange = prevOpticRange;
- }
- else
- {
- BinocularOldCamera = Camera.oldType;
- }
-
- return;
-
- case INV_OBJECT_SMALL_MEDIPACK:
-
- if ((item->HitPoints <= 0 || item->HitPoints >= LARA_HEALTH_MAX) &&
- lara->Status.Poison == 0)
- {
- SayNo();
- return;
- }
-
- if (lara->Inventory.TotalSmallMedipacks != 0)
- {
- if (lara->Inventory.TotalSmallMedipacks != -1)
- lara->Inventory.TotalSmallMedipacks--;
-
- lara->Status.Poison = 0;
- item->HitPoints += LARA_HEALTH_MAX / 2;
-
- if (item->HitPoints > LARA_HEALTH_MAX)
- item->HitPoints = LARA_HEALTH_MAX;
-
- SoundEffect(SFX_TR4_MENU_MEDI, nullptr, SoundEnvironment::Always);
- SaveGame::Statistics.Game.HealthUsed++;
- }
- else
- SayNo();
-
- return;
-
- case INV_OBJECT_LARGE_MEDIPACK:
-
- if ((item->HitPoints <= 0 || item->HitPoints >= LARA_HEALTH_MAX) &&
- lara->Status.Poison == 0)
- {
- SayNo();
- return;
- }
-
- if (lara->Inventory.TotalLargeMedipacks != 0)
- {
- if (lara->Inventory.TotalLargeMedipacks != -1)
- lara->Inventory.TotalLargeMedipacks--;
-
- lara->Status.Poison = 0;
- item->HitPoints = LARA_HEALTH_MAX;
-
- SoundEffect(SFX_TR4_MENU_MEDI, nullptr, SoundEnvironment::Always);
- SaveGame::Statistics.Game.HealthUsed++;
- }
- else
- SayNo();
-
- return;
-
- default:
- InventoryItemChosen = gameObject;
return;
}
+ switch (InventoryItemChosen)
+ {
+ case ID_SHOTGUN_ITEM:
+ player.Control.Weapon.RequestGunType = LaraWeaponType::Shotgun;
+ break;
+
+ case ID_REVOLVER_ITEM:
+ player.Control.Weapon.RequestGunType = LaraWeaponType::Revolver;
+ break;
+
+ case ID_HK_ITEM:
+ player.Control.Weapon.RequestGunType = LaraWeaponType::HK;
+ break;
+
+ case ID_CROSSBOW_ITEM:
+ player.Control.Weapon.RequestGunType = LaraWeaponType::Crossbow;
+ break;
+
+ case ID_GRENADE_GUN_ITEM:
+ player.Control.Weapon.RequestGunType = LaraWeaponType::GrenadeLauncher;
+ break;
+
+ case ID_HARPOON_ITEM:
+ player.Control.Weapon.RequestGunType = LaraWeaponType::HarpoonGun;
+ break;
+
+ case ID_ROCKET_LAUNCHER_ITEM:
+ player.Control.Weapon.RequestGunType = LaraWeaponType::RocketLauncher;
+ break;
+
+ default:
+ return;
+ }
+
+ if (player.Control.HandStatus == HandStatus::Free &&
+ player.Control.Weapon.GunType == player.Control.Weapon.RequestGunType)
+ {
+ player.Control.HandStatus = HandStatus::WeaponDraw;
+ }
+
+ InventoryItemChosen = NO_VALUE;
return;
}
- if (lara->Control.HandStatus == HandStatus::Busy)
+ switch (InventoryItemChosen)
{
- SayNo();
- return;
- }
-
- if (TestState(item->Animation.ActiveState, CrouchStates) ||
- TestState(item->Animation.ActiveState, CrawlStates))
- {
- SayNo();
- return;
- }
-
- if (gameObject == ID_SHOTGUN_ITEM)
- {
- lara->Control.Weapon.RequestGunType = LaraWeaponType::Shotgun;
-
- if (lara->Control.HandStatus != HandStatus::Free)
+ case ID_FLARE_INV_ITEM:
+ if (player.Control.HandStatus != HandStatus::Free)
return;
- if (lara->Control.Weapon.GunType == LaraWeaponType::Shotgun)
- lara->Control.HandStatus = HandStatus::WeaponDraw;
+ if (!TestState(item.Animation.ActiveState, CRAWL_STATES))
+ {
+ if (player.Control.Weapon.GunType != LaraWeaponType::Flare)
+ {
+ // HACK.
+ ClearAllActions();
+ ActionMap[(int)In::Flare].Update(1.0f);
+ HandleWeapon(item);
+ ClearAllActions();
+ }
+ }
+
+ InventoryItemChosen = NO_VALUE;
return;
- }
- if (gameObject == ID_REVOLVER_ITEM)
- {
- lara->Control.Weapon.RequestGunType = LaraWeaponType::Revolver;
+ case ID_BINOCULARS_ITEM:
+ if (((item.Animation.ActiveState == LS_IDLE && item.Animation.AnimNumber == LA_STAND_IDLE) ||
+ (player.Control.IsLow && !IsHeld(In::Crouch))) &&
+ !UseSpotCam && !TrackCameraInit)
+ {
+ player.Control.Look.OpticRange = ANGLE(0.7f);
+ player.Control.Look.IsUsingBinoculars = true;
+ player.Inventory.OldBusy = true;
- if (lara->Control.HandStatus != HandStatus::Free)
- return;
+ // TODO: To prevent Lara from crouching or performing other actions, the inherent state of
+ // LA_BINOCULARS_IDLE must be changed to LS_IDLE. @Sezz 2022.05.19
+ //SetAnimation(item, LA_BINOCULARS_IDLE);
- if (lara->Control.Weapon.GunType == LaraWeaponType::Revolver)
- lara->Control.HandStatus = HandStatus::WeaponDraw;
+ if (player.Control.HandStatus != HandStatus::Free)
+ player.Control.HandStatus = HandStatus::WeaponUndraw;
+ }
+ if (prevOpticRange != ANGLE(0.0f))
+ {
+ player.Control.Look.OpticRange = prevOpticRange;
+ }
+ else
+ {
+ BinocularOldCamera = Camera.oldType;
+ }
+
+ InventoryItemChosen = NO_VALUE;
return;
- }
- else if (gameObject == ID_HK_ITEM)
- {
- lara->Control.Weapon.RequestGunType = LaraWeaponType::HK;
- if (lara->Control.HandStatus != HandStatus::Free)
+ case ID_SMALLMEDI_ITEM:
+ if ((item.HitPoints <= 0 || item.HitPoints >= LARA_HEALTH_MAX) &&
+ player.Status.Poison == 0)
+ {
return;
+ }
- if (lara->Control.Weapon.GunType == LaraWeaponType::HK)
- lara->Control.HandStatus = HandStatus::WeaponDraw;
+ if (player.Inventory.TotalSmallMedipacks != 0)
+ {
+ if (player.Inventory.TotalSmallMedipacks != NO_VALUE)
+ player.Inventory.TotalSmallMedipacks--;
+ player.Status.Poison = 0;
+ item.HitPoints += LARA_HEALTH_MAX / 2;
+
+ if (item.HitPoints > LARA_HEALTH_MAX)
+ item.HitPoints = LARA_HEALTH_MAX;
+
+ SoundEffect(SFX_TR4_MENU_MEDI, nullptr, SoundEnvironment::Always);
+ SaveGame::Statistics.Game.HealthUsed++;
+ }
+ else
+ {
+ return;
+ }
+
+ InventoryItemChosen = NO_VALUE;
return;
- }
- else if (gameObject == ID_CROSSBOW_ITEM)
- {
- lara->Control.Weapon.RequestGunType = LaraWeaponType::Crossbow;
- if (lara->Control.HandStatus != HandStatus::Free)
+ case ID_BIGMEDI_ITEM:
+ if ((item.HitPoints <= 0 || item.HitPoints >= LARA_HEALTH_MAX) &&
+ player.Status.Poison == 0)
+ {
return;
+ }
- if (lara->Control.Weapon.GunType == LaraWeaponType::Crossbow)
- lara->Control.HandStatus = HandStatus::WeaponDraw;
+ if (player.Inventory.TotalLargeMedipacks != 0)
+ {
+ if (player.Inventory.TotalLargeMedipacks != NO_VALUE)
+ player.Inventory.TotalLargeMedipacks--;
+ player.Status.Poison = 0;
+ item.HitPoints = LARA_HEALTH_MAX;
+
+ SoundEffect(SFX_TR4_MENU_MEDI, nullptr, SoundEnvironment::Always);
+ SaveGame::Statistics.Game.HealthUsed++;
+ }
+ else
+ {
+ return;
+ }
+
+ InventoryItemChosen = NO_VALUE;
return;
- }
- else if (gameObject == ID_GRENADE_GUN_ITEM)
- {
- lara->Control.Weapon.RequestGunType = LaraWeaponType::GrenadeLauncher;
-
- if (lara->Control.HandStatus != HandStatus::Free)
- return;
-
- if (lara->Control.Weapon.GunType == LaraWeaponType::GrenadeLauncher)
- lara->Control.HandStatus = HandStatus::WeaponDraw;
-
- return;
- }
- else if (gameObject == ID_HARPOON_ITEM)
- {
- lara->Control.Weapon.RequestGunType = LaraWeaponType::HarpoonGun;
-
- if (lara->Control.HandStatus != HandStatus::Free)
- return;
-
- if (lara->Control.Weapon.GunType == LaraWeaponType::HarpoonGun)
- lara->Control.HandStatus = HandStatus::WeaponDraw;
-
- return;
- }
- else if (gameObject == ID_ROCKET_LAUNCHER_ITEM)
- {
- lara->Control.Weapon.RequestGunType = LaraWeaponType::RocketLauncher;
-
- if (lara->Control.HandStatus != HandStatus::Free)
- return;
-
- if (lara->Control.Weapon.GunType == LaraWeaponType::RocketLauncher)
- lara->Control.HandStatus = HandStatus::WeaponDraw;
+ default:
return;
}
}
@@ -2654,7 +2622,7 @@ namespace TEN::Gui
case MenuType::Equip:
case MenuType::Use:
MenuActive = false;
- UseItem = true;
+ ItemUsed = true;
break;
case MenuType::Diary:
@@ -3382,7 +3350,7 @@ namespace TEN::Gui
break;
}
- if (UseItem && NoAction())
+ if (ItemUsed && NoAction())
exitLoop = true;
SetEnterInventory(NO_VALUE);
@@ -3393,8 +3361,8 @@ namespace TEN::Gui
LastInvItem = Rings[(int)RingTypes::Inventory].CurrentObjectList[Rings[(int)RingTypes::Inventory].CurrentObjectInList].InventoryItem;
UpdateWeaponStatus(item);
- if (UseItem)
- UseCurrentItem(item);
+ if (ItemUsed)
+ UseItem(*item, InventoryObjectTable[LastInvItem].ObjectNumber);
AlterFOV(LastFOV);
ResumeAllSounds(SoundPauseMode::Inventory);
diff --git a/TombEngine/Game/gui.h b/TombEngine/Game/gui.h
index f456889bd..bf4a4baea 100644
--- a/TombEngine/Game/gui.h
+++ b/TombEngine/Game/gui.h
@@ -139,7 +139,7 @@ namespace TEN::Gui
// Inventory variables
short CombineObject1;
short CombineObject2;
- bool UseItem;
+ bool ItemUsed;
char SeperateTypeFlag;
char CombineTypeFlag;
InventoryRing Rings[2];
@@ -181,6 +181,7 @@ namespace TEN::Gui
bool PerformWaterskinCombine(ItemInfo* item, bool flag);
void DrawCompass(ItemInfo* item);
void CancelInventorySelection();
+ void UseItem(ItemInfo& item, int objectNumber);
// Getters
const InventoryRing& GetRing(RingTypes ringType);
@@ -221,7 +222,6 @@ namespace TEN::Gui
void SeparateObject(ItemInfo* item, int objectNumber);
void InsertObjectIntoList(int objectNumber);
void InsertObjectIntoList_v2(int objectNumber);
- void UseCurrentItem(ItemInfo* item);
void SpinBack(EulerAngles& orient);
void UpdateWeaponStatus(ItemInfo* item);
void DoStatisticsMode();
diff --git a/TombEngine/Scripting/Include/ScriptInterfaceGame.h b/TombEngine/Scripting/Include/ScriptInterfaceGame.h
index 7be1be9ec..81958aaaf 100644
--- a/TombEngine/Scripting/Include/ScriptInterfaceGame.h
+++ b/TombEngine/Scripting/Include/ScriptInterfaceGame.h
@@ -57,8 +57,9 @@ public:
virtual void OnLoop(float deltaTime, bool postLoop) = 0;
virtual void OnSave() = 0;
virtual void OnEnd(GameStatus reason) = 0;
- virtual void ShortenTENCalls() = 0;
+ virtual void OnUseItem(GAME_OBJECT_ID objectNumber) = 0;
+ virtual void ShortenTENCalls() = 0;
virtual void FreeLevelScripts() = 0;
virtual void ResetScripts(bool clearGameVars) = 0;
virtual void ExecuteScriptFile(const std::string& luaFileName) = 0;
diff --git a/TombEngine/Scripting/Internal/ReservedScriptNames.h b/TombEngine/Scripting/Internal/ReservedScriptNames.h
index 181e94953..8d0e58181 100644
--- a/TombEngine/Scripting/Internal/ReservedScriptNames.h
+++ b/TombEngine/Scripting/Internal/ReservedScriptNames.h
@@ -53,14 +53,6 @@ static constexpr char ScriptReserved_DisplayStringSetScale[] = "SetScale";
static constexpr char ScriptReserved_DisplayStringSetColor[] = "SetColor";
static constexpr char ScriptReserved_DisplaySpriteDraw[] = "Draw";
-// Built-in LevelFuncs
-static constexpr char ScriptReserved_OnStart[] = "OnStart";
-static constexpr char ScriptReserved_OnLoad[] = "OnLoad";
-static constexpr char ScriptReserved_OnLoop[] = "OnLoop";
-static constexpr char ScriptReserved_OnControlPhase[] = "OnControlPhase"; // DEPRECATED
-static constexpr char ScriptReserved_OnSave[] = "OnSave";
-static constexpr char ScriptReserved_OnEnd[] = "OnEnd";
-
static constexpr char ScriptReserved_EndReasonExitToTitle[] = "EXITTOTITLE";
static constexpr char ScriptReserved_EndReasonLevelComplete[] = "LEVELCOMPLETE";
static constexpr char ScriptReserved_EndReasonLoadGame[] = "LOADGAME";
@@ -81,15 +73,25 @@ static constexpr char ScriptReserved_PostLoop[] = "POSTLOOP";
static constexpr char ScriptReserved_PreControlPhase[] = "PRECONTROLPHASE";
static constexpr char ScriptReserved_PostControlPhase[] = "POSTCONTROLPHASE";
-// Event types
-static constexpr char ScriptReserved_EventOnEnter[] = "ENTER";
-static constexpr char ScriptReserved_EventOnInside[] = "INSIDE";
-static constexpr char ScriptReserved_EventOnLeave[] = "LEAVE";
-static constexpr char ScriptReserved_EventOnLoad[] = "LOAD";
-static constexpr char ScriptReserved_EventOnSave[] = "SAVE";
-static constexpr char ScriptReserved_EventOnStart[] = "START";
-static constexpr char ScriptReserved_EventOnEnd[] = "END";
-static constexpr char ScriptReserved_EventOnLoop[] = "LOOP";
+// Built-in LevelFuncs
+static constexpr char ScriptReserved_OnStart[] = "OnStart";
+static constexpr char ScriptReserved_OnLoad[] = "OnLoad";
+static constexpr char ScriptReserved_OnLoop[] = "OnLoop";
+static constexpr char ScriptReserved_OnControlPhase[] = "OnControlPhase"; // DEPRECATED
+static constexpr char ScriptReserved_OnSave[] = "OnSave";
+static constexpr char ScriptReserved_OnEnd[] = "OnEnd";
+static constexpr char ScriptReserved_OnUseItem[] = "OnUseItem";
+
+// Event types (volume events + global events)
+static constexpr char ScriptReserved_EventOnEnter[] = "ENTER";
+static constexpr char ScriptReserved_EventOnInside[] = "INSIDE";
+static constexpr char ScriptReserved_EventOnLeave[] = "LEAVE";
+static constexpr char ScriptReserved_EventOnStart[] = "START";
+static constexpr char ScriptReserved_EventOnLoad[] = "LOAD";
+static constexpr char ScriptReserved_EventOnLoop[] = "LOOP";
+static constexpr char ScriptReserved_EventOnSave[] = "SAVE";
+static constexpr char ScriptReserved_EventOnEnd[] = "END";
+static constexpr char ScriptReserved_EventOnUseItem[] = "USEITEM";
// Member functions
static constexpr char ScriptReserved_New[] = "New";
@@ -259,9 +261,9 @@ static constexpr char ScriptReserved_GiveInvItem[] = "GiveItem";
static constexpr char ScriptReserved_TakeInvItem[] = "TakeItem";
static constexpr char ScriptReserved_GetInvItemCount[] = "GetItemCount";
static constexpr char ScriptReserved_SetInvItemCount[] = "SetItemCount";
-static constexpr char ScriptReserved_GetChosenItem[] = "GetChosenItem";
-static constexpr char ScriptReserved_SetChosenItem[] = "SetChosenItem";
-static constexpr char ScriptReserved_ClearChosenItem[] = "ClearChosenItem";
+static constexpr char ScriptReserved_GetUsedItem[] = "GetUsedItem";
+static constexpr char ScriptReserved_SetUsedItem[] = "SetUsedItem";
+static constexpr char ScriptReserved_ClearUsedItem[] = "ClearUsedItem";
static constexpr char ScriptReserved_GetMoveableByName[] = "GetMoveableByName";
static constexpr char ScriptReserved_GetStaticByName[] = "GetStaticByName";
static constexpr char ScriptReserved_GetMoveablesBySlot[] = "GetMoveablesBySlot";
diff --git a/TombEngine/Scripting/Internal/TEN/Inventory/InventoryHandler.cpp b/TombEngine/Scripting/Internal/TEN/Inventory/InventoryHandler.cpp
index a570cebfd..8cce6990e 100644
--- a/TombEngine/Scripting/Internal/TEN/Inventory/InventoryHandler.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Inventory/InventoryHandler.cpp
@@ -61,32 +61,32 @@ namespace TEN::Scripting::InventoryHandler
SetInventoryCount(objectID, count);
}
- /// Get last selected item in the player's inventory.
+ /// Get last item used in the player's inventory.
// This value will be valid only for a single frame after exiting inventory, after which Lara says "No".
- // Therefore, this function must be preferably used either in OnLoop events or callbacks.
- // If you have used this function and you want to avoid "No" sound, you should use ClearChosenItem function.
- //@function GetChosenItem
- //@treturn Objects.ObjID Last selected item in the inventory.
- static GAME_OBJECT_ID GetChosenItem()
+ // Therefore, this function must be preferably used either in OnLoop or OnUseItem events.
+ //@function GetUsedItem
+ //@treturn Objects.ObjID Last item used in the inventory.
+ static GAME_OBJECT_ID GetUsedItem()
{
return (GAME_OBJECT_ID)g_Gui.GetInventoryItemChosen();
}
- /// Set last selected item in the player's inventory.
- // You will be able to select only objects which already exist in inventory.
+ /// Set last item used in the player's inventory.
+ // You will be able to specify only objects which already exist in the inventory.
// Will only be valid for the next frame. If not processed by the game, Lara will say "No".
- //@function SetChosenItem
+ //@function SetUsedItem
//@tparam Objects.ObjID objectID Object ID of the item to select from inventory.
- static void SetChosenItem(GAME_OBJECT_ID objectID)
+ static void SetUsedItem(GAME_OBJECT_ID objectID)
{
if (g_Gui.IsObjectInInventory(objectID))
g_Gui.SetInventoryItemChosen(objectID);
}
- /// Clear last selected item in the player's inventory.
- // This function is needed to avoid Lara saying "No" after selecting particular item in inventory.
- //@function ClearChosenItem
- static void ClearChosenItem()
+ /// Clear last item used in the player's inventory.
+ // When this function is used in OnUseItem level function, it allows to override existing item functionality.
+ // For items without existing functionality, this function is needed to avoid Lara saying "No" after using it.
+ //@function ClearUsedItem
+ static void ClearUsedItem()
{
g_Gui.SetInventoryItemChosen(GAME_OBJECT_ID::ID_NO_OBJECT);
}
@@ -100,8 +100,8 @@ namespace TEN::Scripting::InventoryHandler
tableInventory.set_function(ScriptReserved_TakeInvItem, &TakeItem);
tableInventory.set_function(ScriptReserved_GetInvItemCount, &GetItemCount);
tableInventory.set_function(ScriptReserved_SetInvItemCount, &SetItemCount);
- tableInventory.set_function(ScriptReserved_SetChosenItem, &SetChosenItem);
- tableInventory.set_function(ScriptReserved_GetChosenItem, &GetChosenItem);
- tableInventory.set_function(ScriptReserved_ClearChosenItem, &ClearChosenItem);
+ tableInventory.set_function(ScriptReserved_SetUsedItem, &SetUsedItem);
+ tableInventory.set_function(ScriptReserved_GetUsedItem, &GetUsedItem);
+ tableInventory.set_function(ScriptReserved_ClearUsedItem, &ClearUsedItem);
}
}
diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp
index cef0ba8b2..9b96d12d7 100644
--- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp
@@ -65,7 +65,8 @@ static const std::unordered_map EVENT_TYPES
{ ScriptReserved_EventOnLoad, EventType::Load },
{ ScriptReserved_EventOnSave, EventType::Save },
{ ScriptReserved_EventOnStart, EventType::Start },
- { ScriptReserved_EventOnEnd, EventType::End }
+ { ScriptReserved_EventOnEnd, EventType::End },
+ { ScriptReserved_EventOnUseItem, EventType::UseItem }
};
enum class LevelEndReason
@@ -293,6 +294,7 @@ Possible event type values:
START
END
LOOP
+ USEITEM
@function HandleEvent
@tparam string name Name of the event set to find.
@@ -457,6 +459,7 @@ void LogicHandler::FreeLevelScripts()
m_onLoop = sol::nil;
m_onSave = sol::nil;
m_onEnd = sol::nil;
+ m_onUseItem = sol::nil;
m_handler.GetState()->collect_garbage();
}
@@ -999,6 +1002,12 @@ void LogicHandler::OnEnd(GameStatus reason)
CallLevelFuncByName(name, endReason);
}
+void LogicHandler::OnUseItem(GAME_OBJECT_ID objectNumber)
+{
+ if (m_onUseItem.valid())
+ CallLevelFunc(m_onUseItem, objectNumber);
+}
+
/*** Special tables
TombEngine uses the following tables for specific things.
@@ -1142,4 +1151,5 @@ void LogicHandler::InitCallbacks()
assignCB(m_onLoop, ScriptReserved_OnLoop);
assignCB(m_onSave, ScriptReserved_OnSave);
assignCB(m_onEnd, ScriptReserved_OnEnd);
+ assignCB(m_onUseItem, ScriptReserved_OnUseItem);
}
diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h
index 1e1b485f9..c1f4f2108 100644
--- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h
+++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h
@@ -56,6 +56,7 @@ private:
sol::protected_function m_onLoop{};
sol::protected_function m_onSave{};
sol::protected_function m_onEnd{};
+ sol::protected_function m_onUseItem{};
std::unordered_set m_callbacksPreSave;
std::unordered_set m_callbacksPostSave;
@@ -170,4 +171,5 @@ public:
void OnLoop(float deltaTime, bool postLoop) override;
void OnSave() override;
void OnEnd(GameStatus reason) override;
+ void OnUseItem(GAME_OBJECT_ID item) override;
};
From 571f87f35f5e9ec7520359679b81ca14226cdeaa Mon Sep 17 00:00:00 2001
From: Kubsy <80340234+Jakub768@users.noreply.github.com>
Date: Fri, 26 Apr 2024 10:45:40 +0100
Subject: [PATCH 102/410] Update Changes.txt
---
Documentation/Changes.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/Changes.txt b/Documentation/Changes.txt
index 542f6fb9a..b92da2a99 100644
--- a/Documentation/Changes.txt
+++ b/Documentation/Changes.txt
@@ -4,7 +4,7 @@ Version 1.5
* Fixed original issue with classic switch off trigger wrongly activating some trigger actions.
Lua API changes:
-* Added Inventory.GetChosenItem(), Inventory.SetChosenItem() and Inventory.ClearChosenItem() functions.
+* Added Inventory.GetUsedItem(), Inventory.SetUsedItem() and Inventory.ClearUsedItem() functions.
Version 1.4
===========
From 05376122b03020151ee3e43bb5dcbd4c94395b74 Mon Sep 17 00:00:00 2001
From: Jakub
Date: Fri, 26 Apr 2024 10:52:01 +0100
Subject: [PATCH 103/410] fix compile error
---
TombEngine/Game/collision/collide_item.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/TombEngine/Game/collision/collide_item.cpp b/TombEngine/Game/collision/collide_item.cpp
index b879bd0a4..8698d01df 100644
--- a/TombEngine/Game/collision/collide_item.cpp
+++ b/TombEngine/Game/collision/collide_item.cpp
@@ -1291,7 +1291,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
{
int bs = 0;
- if (pointColl.IsIllegalFloor() && prevPointColl.GetFloorHeight() < pointColl.GetFloorHeight())
+ if (pointColl.IsSteepFloor() && prevPointColl.GetFloorHeight() < pointColl.GetFloorHeight())
{
int yAngle = (long)((unsigned short)item->Pose.Orientation.y);
@@ -1360,7 +1360,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
item->Pose.Position.z = z;
}
// Hit a steep slope?
- else if (pointColl.IsIllegalFloor())
+ else if (pointColl.IsSteepFloor())
{
// Need to know which direction the slope is.
From 1d2f3dc64da671df785ca6c90f17d4f9707df216 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sat, 27 Apr 2024 00:01:08 +1000
Subject: [PATCH 104/410] Rename struct member
---
TombEngine/Game/Lara/PlayerContextData.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/TombEngine/Game/Lara/PlayerContextData.h b/TombEngine/Game/Lara/PlayerContextData.h
index 8e3b315e2..c5fca5052 100644
--- a/TombEngine/Game/Lara/PlayerContextData.h
+++ b/TombEngine/Game/Lara/PlayerContextData.h
@@ -8,9 +8,9 @@ namespace TEN::Entities::Player
int LowerFloorBound = 0;
int UpperFloorBound = 0;
- bool TestIllegalFloorBelow = true;
- bool TestIllegalFloorAbove = true;
- bool TestDeathFloor = true;
+ bool TestSteepFloorBelow = true;
+ bool TestSteepFloorAbove = true;
+ bool TestDeathFloor = true;
};
struct MonkeySwingMovementSetupData
From 4d59cb6d0379937576b08d6d51b3b3e7dfd8b278 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sat, 27 Apr 2024 00:24:09 +1000
Subject: [PATCH 105/410] Fix water ripple, splash sound, vehicle bugs
---
TombEngine/Game/Lara/PlayerContext.cpp | 4 ++--
TombEngine/Game/Lara/lara_helpers.cpp | 14 ++++----------
TombEngine/Game/collision/Point.cpp | 2 +-
3 files changed, 7 insertions(+), 13 deletions(-)
diff --git a/TombEngine/Game/Lara/PlayerContext.cpp b/TombEngine/Game/Lara/PlayerContext.cpp
index 8d71d80a7..99ac6a5b9 100644
--- a/TombEngine/Game/Lara/PlayerContext.cpp
+++ b/TombEngine/Game/Lara/PlayerContext.cpp
@@ -178,14 +178,14 @@ namespace TEN::Entities::Player
short aspectAngleDelta = Geometry::GetShortestAngle(setup.HeadingAngle, aspectAngle);
// 1) Check for illegal slope below floor (if applicable).
- if (setup.TestIllegalFloorBelow &&
+ if (setup.TestSteepFloorBelow &&
(pointColl.IsSteepFloor() && abs(aspectAngleDelta) <= SLOPE_ASPECT_ANGLE_DELTA_MAX))
{
return false;
}
// 1) Check for illegal slope above floor (if applicable).
- if (setup.TestIllegalFloorAbove &&
+ if (setup.TestSteepFloorAbove &&
(pointColl.IsSteepFloor() && abs(aspectAngleDelta) >= SLOPE_ASPECT_ANGLE_DELTA_MAX))
{
return false;
diff --git a/TombEngine/Game/Lara/lara_helpers.cpp b/TombEngine/Game/Lara/lara_helpers.cpp
index d38ee2e44..ae37d3d7a 100644
--- a/TombEngine/Game/Lara/lara_helpers.cpp
+++ b/TombEngine/Game/Lara/lara_helpers.cpp
@@ -1252,20 +1252,14 @@ LaraInfo*& GetLaraInfo(ItemInfo* item)
PlayerWaterData GetPlayerWaterData(ItemInfo& item)
{
- bool isWater = TestEnvironment(ENV_FLAG_WATER, &item);
- bool isSwamp = TestEnvironment(ENV_FLAG_SWAMP, &item);
- bool isCold = TestEnvironment(ENV_FLAG_COLD, &item);
-
- int waterDepth = GetWaterDepth(&item);
- int waterHeight = GetWaterHeight(&item);
-
auto pointColl = GetPointCollision(item);
- int heightFromWater = (waterHeight == NO_HEIGHT) ? NO_HEIGHT : (std::min(item.Pose.Position.y, pointColl.GetFloorHeight()) - waterHeight);
+ int heightFromWater = (pointColl.GetWaterTopHeight() == NO_HEIGHT) ?
+ NO_HEIGHT : (std::min(item.Pose.Position.y, pointColl.GetFloorHeight()) - pointColl.GetWaterTopHeight());
return PlayerWaterData
{
- isWater, isSwamp, isCold,
- waterDepth, waterHeight, heightFromWater
+ TestEnvironment(ENV_FLAG_WATER, &item), TestEnvironment(ENV_FLAG_SWAMP, &item), TestEnvironment(ENV_FLAG_COLD, &item),
+ pointColl.GetWaterBottomHeight(), pointColl.GetWaterTopHeight(), heightFromWater
};
}
diff --git a/TombEngine/Game/collision/Point.cpp b/TombEngine/Game/collision/Point.cpp
index 8790423a3..45f1b3fc2 100644
--- a/TombEngine/Game/collision/Point.cpp
+++ b/TombEngine/Game/collision/Point.cpp
@@ -372,7 +372,7 @@ namespace TEN::Collision::Point
PointCollisionData GetPointCollision(const ItemInfo& item)
{
- return PointCollisionData(item.Pose.Position, item.RoomNumber);
+ return GetPointCollision(item.Pose.Position, item.RoomNumber);
}
PointCollisionData GetPointCollision(const ItemInfo& item, const Vector3& dir, float dist)
From abb77ced54e7a137a02bfb1b35856c89a6e25335 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sat, 27 Apr 2024 01:25:16 +1000
Subject: [PATCH 106/410] Remove pointless const
---
TombEngine/Game/collision/collide_room.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index 3ca9517cd..aa90ae3ec 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -1051,7 +1051,7 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance)
FloorInfo* GetFloor(int x, int y, int z, short* roomNumber)
{
- const auto location = GetRoomVector(RoomVector(*roomNumber, y), Vector3i(x, y, z));
+ auto location = GetRoomVector(RoomVector(*roomNumber, y), Vector3i(x, y, z));
*roomNumber = location.RoomNumber;
return &GetFloor(*roomNumber, x, z);
}
From 1e38baf8fc79011c3aade6451a378f7be54f6317 Mon Sep 17 00:00:00 2001
From: Joey Quint
Date: Fri, 26 Apr 2024 18:48:54 +0200
Subject: [PATCH 107/410] Fix incorrect diving animation when swandiving from a
high place
---
TombEngine/Game/Lara/lara.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/TombEngine/Game/Lara/lara.cpp b/TombEngine/Game/Lara/lara.cpp
index 07a251277..e4b47469b 100644
--- a/TombEngine/Game/Lara/lara.cpp
+++ b/TombEngine/Game/Lara/lara.cpp
@@ -152,7 +152,7 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
}
else if (item->Animation.ActiveState == LS_FREEFALL_DIVE)
{
- SetAnimation(item, LA_SWANDIVE_DIVE);
+ SetAnimation(item, LA_SWANDIVE_FREEFALL_DIVE);
item->Animation.Velocity.y /= 2;
item->Pose.Orientation.x = ANGLE(-85.0f);
player.Control.HandStatus = HandStatus::Free;
From dbfaf6c7fd93dcada48976617f341e5bdc5a6361 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sat, 27 Apr 2024 04:13:18 +1000
Subject: [PATCH 108/410] Update water functions
---
TombEngine/Game/collision/collide_room.cpp | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index aa90ae3ec..137d8d62e 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -1090,7 +1090,7 @@ int GetWaterSurface(int x, int y, int z, short roomNumber)
if (TestEnvironment(ENV_FLAG_WATER, room))
{
- while (sector->GetNextRoomNumber(Vector3i(x, y, z), false).value_or(NO_VALUE) != NO_VALUE)
+ while (sector->GetNextRoomNumber(Vector3i(x, y, z), false).has_value())
{
room = &g_Level.Rooms[sector->GetNextRoomNumber(Vector3i(x, y, z), false).value_or(sector->RoomNumber)];
if (!TestEnvironment(ENV_FLAG_WATER, room))
@@ -1103,7 +1103,7 @@ int GetWaterSurface(int x, int y, int z, short roomNumber)
}
else
{
- while (sector->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(NO_VALUE) != NO_VALUE)
+ while (sector->GetNextRoomNumber(Vector3i(x, y, z), true).has_value())
{
room = &g_Level.Rooms[sector->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(sector->RoomNumber)];
if (TestEnvironment(ENV_FLAG_WATER, room))
@@ -1282,7 +1282,7 @@ int GetWaterHeight(int x, int y, int z, short roomNumber)
if (TestEnvironment(ENV_FLAG_WATER, room) ||
TestEnvironment(ENV_FLAG_SWAMP, room))
{
- while (sector->GetNextRoomNumber(Vector3i(x, y, z), false).value_or(NO_VALUE) != NO_VALUE)
+ while (sector->GetNextRoomNumber(Vector3i(x, y, z), false).has_value())
{
auto* room = &g_Level.Rooms[sector->GetNextRoomNumber(Vector3i(x, y, z), false).value_or(sector->RoomNumber)];
@@ -1295,11 +1295,11 @@ int GetWaterHeight(int x, int y, int z, short roomNumber)
sector = GetSector(room, x - room->x, z - room->z);
}
- return GetPointCollision(Vector3i(x, y, z), sector->RoomNumber).GetSector().GetSurfaceHeight(Vector3i(x, y, z), false);
+ return sector->GetSurfaceHeight(Vector3i(x, y, z), false);
}
- else if (sector->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(NO_VALUE) != NO_VALUE)
+ else if (sector->GetNextRoomNumber(Vector3i(x, y, z), true).has_value())
{
- while (sector->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(NO_VALUE) != NO_VALUE)
+ while (sector->GetNextRoomNumber(Vector3i(x, y, z), true).has_value())
{
auto* room2 = &g_Level.Rooms[sector->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(sector->RoomNumber)];
@@ -1312,7 +1312,7 @@ int GetWaterHeight(int x, int y, int z, short roomNumber)
sector = GetSector(room2, x - room2->x, z - room2->z);
}
- return GetPointCollision(Vector3i(x, y, z), sector->RoomNumber).GetSector().GetSurfaceHeight(Vector3i(x, y, z), true);
+ return sector->GetSurfaceHeight(Vector3i(x, y, z), true);
}
return NO_HEIGHT;
From 9df06e0a635bae59a0dc13d46d311cfd094a6b30 Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Sat, 27 Apr 2024 11:00:18 +0200
Subject: [PATCH 109/410] Update Changes.txt
---
Documentation/Changes.txt | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/Changes.txt b/Documentation/Changes.txt
index b92da2a99..035d60ef2 100644
--- a/Documentation/Changes.txt
+++ b/Documentation/Changes.txt
@@ -2,6 +2,8 @@ Version 1.5
===========
* Fixed original issue with classic switch off trigger wrongly activating some trigger actions.
+* Fixed incorrect diving animation when swandiving from a high place.
+* Fixed AI for skidoo driver and worker with shotgun TR2 enemies.
Lua API changes:
* Added Inventory.GetUsedItem(), Inventory.SetUsedItem() and Inventory.ClearUsedItem() functions.
From 7f9f5c619a46aabf4ebaaabf411aa724d1b9b6cc Mon Sep 17 00:00:00 2001
From: Nemoel-Tomo
Date: Sat, 27 Apr 2024 20:48:39 +0200
Subject: [PATCH 110/410] Bugfix: ember emitter, cleaner and squishy block (get
valid sector) (#1358)
* bugfix, ember emitter, cleaner and squishy
* formatting
* Update misc.cpp
---------
Co-authored-by: Sezz
---
TombEngine/Game/misc.cpp | 33 +++++++++++++++----
TombEngine/Game/misc.h | 2 +-
TombEngine/Objects/Effects/EmberEmitter.cpp | 7 ++--
.../Objects/TR3/Trap/ElectricCleaner.cpp | 6 ++--
TombEngine/Objects/TR4/Trap/SquishyBlock.cpp | 2 +-
5 files changed, 37 insertions(+), 13 deletions(-)
diff --git a/TombEngine/Game/misc.cpp b/TombEngine/Game/misc.cpp
index 878281da8..ab9345203 100644
--- a/TombEngine/Game/misc.cpp
+++ b/TombEngine/Game/misc.cpp
@@ -40,7 +40,7 @@ void TargetNearestEntity(ItemInfo* item, CreatureInfo* creature)
}
}
-bool IsNextSectorValid(const ItemInfo& item, const Vector3& dir, float dist)
+bool IsNextSectorValid(const ItemInfo& item, const Vector3& dir, float dist, bool canFloat)
{
auto projectedPos = Geometry::TranslatePoint(item.Pose.Position, dir, dist);
auto pointColl = GetCollision(item.Pose.Position, item.RoomNumber, dir, dist);
@@ -59,16 +59,29 @@ bool IsNextSectorValid(const ItemInfo& item, const Vector3& dir, float dist)
{
// Test for step.
int relFloorHeight = abs(pointColl.Position.Floor - item.Pose.Position.y);
- if (relFloorHeight >= CLICK(1) && item.Pose.Position.y >= pointColl.Position.Floor)
+
+ if (relFloorHeight >= CLICK(1) && item.Pose.Position.y >= pointColl.Position.Floor && canFloat)
+ {
return false;
+ }
+ else if (relFloorHeight >= CLICK(1) && !canFloat)
+ {
+ return false;
+ }
}
// Sloped floor.
else
{
// Half block.
int relFloorHeight = abs(pointColl.Position.Floor - item.Pose.Position.y);
- if (relFloorHeight > CLICK(1))
+ if (relFloorHeight > CLICK(1) && canFloat)
+ {
return false;
+ }
+ else if (relFloorHeight > CLICK(2) && !canFloat)
+ {
+ return false;
+ }
short slopeAngle = ANGLE(0.0f);
if (pointColl.FloorTilt.x > 0)
@@ -104,8 +117,16 @@ bool IsNextSectorValid(const ItemInfo& item, const Vector3& dir, float dist)
// Test ceiling height.
int relCeilHeight = abs(pointColl.Position.Ceiling - pointColl.Position.Floor);
- if (relCeilHeight <= height)
- return false;
+ if (canFloat)
+ {
+ if (relCeilHeight <= height)
+ return false;
+ }
+ else
+ {
+ if (relCeilHeight < BLOCK(1))
+ return false;
+ }
// Check for blocked grey box.
if (g_Level.Boxes[pointColl.Block->Box].flags & BLOCKABLE)
@@ -123,4 +144,4 @@ bool IsNextSectorValid(const ItemInfo& item, const Vector3& dir, float dist)
return false;
return true;
-}
\ No newline at end of file
+}
diff --git a/TombEngine/Game/misc.h b/TombEngine/Game/misc.h
index ef00bf1fd..d3e4b6e65 100644
--- a/TombEngine/Game/misc.h
+++ b/TombEngine/Game/misc.h
@@ -19,4 +19,4 @@ enum LaraMeshMask
CreatureInfo* GetCreatureInfo(ItemInfo* item);
void TargetNearestEntity(ItemInfo* item, CreatureInfo* creature);
-bool IsNextSectorValid(const ItemInfo& item, const Vector3& dir, float dist);
+bool IsNextSectorValid(const ItemInfo& item, const Vector3& dir, float dist, bool canFloat);
diff --git a/TombEngine/Objects/Effects/EmberEmitter.cpp b/TombEngine/Objects/Effects/EmberEmitter.cpp
index 096ade6e1..4aef9f6de 100644
--- a/TombEngine/Objects/Effects/EmberEmitter.cpp
+++ b/TombEngine/Objects/Effects/EmberEmitter.cpp
@@ -27,10 +27,13 @@ namespace TEN::Effects::EmberEmitter
if (item.TriggerFlags < 0)
{
+ if (item.TriggerFlags > -11)
+ item.TriggerFlags = -11;
+
if (!item.ItemFlags[2])
{
- int div = abs(item.TriggerFlags) % 10 << 10;
- int mod = abs(item.TriggerFlags) / 10 << 10;
+ int div = (abs(item.TriggerFlags) % 10) << 10;
+ int mod = (abs(item.TriggerFlags) / 10) << 10;
// TODO: Use Random::GenerateInt()
item.ItemFlags[0] = GetRandomControl() % div;
diff --git a/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp b/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp
index 84343ccc5..ba40d9323 100644
--- a/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp
+++ b/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp
@@ -72,13 +72,13 @@ namespace TEN::Entities::Traps
static Vector3 GetElectricCleanerMovementDirection(const ItemInfo& item, const Vector3& dir0, const Vector3& dir1, const Vector3& dir2)
{
- if (IsNextSectorValid(item, dir0, BLOCK(1)))
+ if (IsNextSectorValid(item, dir0, BLOCK(1), false))
return dir0;
- if (IsNextSectorValid(item, dir1, BLOCK(1)))
+ if (IsNextSectorValid(item, dir1, BLOCK(1), false))
return dir1;
- if (IsNextSectorValid(item, dir2, BLOCK(1)))
+ if (IsNextSectorValid(item, dir2, BLOCK(1), false))
return dir2;
return Vector3::Zero;
diff --git a/TombEngine/Objects/TR4/Trap/SquishyBlock.cpp b/TombEngine/Objects/TR4/Trap/SquishyBlock.cpp
index 3423d3890..ddab6f7bc 100644
--- a/TombEngine/Objects/TR4/Trap/SquishyBlock.cpp
+++ b/TombEngine/Objects/TR4/Trap/SquishyBlock.cpp
@@ -99,7 +99,7 @@ namespace TEN::Entities::Traps
if (pointColl.RoomNumber != item.RoomNumber)
ItemNewRoom(itemNumber, pointColl.RoomNumber);
- if (!IsNextSectorValid(item, forwardDir, BLOCK(0.5f)))
+ if (!IsNextSectorValid(item, forwardDir, BLOCK(0.5f), true))
{
switch (headingAngle)
{
From 1d30d43aac46df2208676ec88932b211d80c2f4e Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Sun, 28 Apr 2024 06:31:59 +0200
Subject: [PATCH 111/410] Added color to lens flare; Added LUA api for
starfield and lens flare;
---
Documentation/doc/1 modules/Effects.html | 2 +
Documentation/doc/1 modules/Flow.html | 2 +
Documentation/doc/1 modules/Input.html | 2 +
Documentation/doc/1 modules/Inventory.html | 2 +
Documentation/doc/1 modules/Logic.html | 2 +
Documentation/doc/1 modules/Objects.html | 2 +
Documentation/doc/1 modules/Sound.html | 2 +
Documentation/doc/1 modules/Strings.html | 2 +
Documentation/doc/1 modules/Util.html | 2 +
Documentation/doc/1 modules/View.html | 2 +
.../doc/2 classes/Flow.Animations.html | 2 +
Documentation/doc/2 classes/Flow.Fog.html | 2 +
.../doc/2 classes/Flow.InventoryItem.html | 2 +
.../doc/2 classes/Flow.LensFlare.html | 223 +++++++++++++
Documentation/doc/2 classes/Flow.Level.html | 40 +++
Documentation/doc/2 classes/Flow.Mirror.html | 2 +
.../doc/2 classes/Flow.Settings.html | 2 +
.../doc/2 classes/Flow.SkyLayer.html | 15 +-
.../doc/2 classes/Flow.Starfield.html | 303 ++++++++++++++++++
.../doc/2 classes/Objects.AIObject.html | 2 +
.../doc/2 classes/Objects.Camera.html | 2 +
.../doc/2 classes/Objects.LaraObject.html | 2 +
.../doc/2 classes/Objects.Moveable.html | 2 +
Documentation/doc/2 classes/Objects.Room.html | 2 +
Documentation/doc/2 classes/Objects.Sink.html | 2 +
.../doc/2 classes/Objects.SoundSource.html | 2 +
.../doc/2 classes/Objects.Static.html | 2 +
.../doc/2 classes/Objects.Volume.html | 2 +
.../doc/2 classes/Strings.DisplayString.html | 2 +
.../doc/2 classes/View.DisplaySprite.html | 2 +
.../doc/3 primitive classes/Color.html | 2 +
.../doc/3 primitive classes/Rotation.html | 2 +
.../doc/3 primitive classes/Vec2.html | 2 +
.../doc/3 primitive classes/Vec3.html | 2 +
.../doc/4 enums/Effects.BlendID.html | 2 +
.../doc/4 enums/Effects.EffectID.html | 2 +
.../doc/4 enums/Flow.GameStatus.html | 2 +
Documentation/doc/4 enums/Input.ActionID.html | 2 +
.../doc/4 enums/Objects.AmmoType.html | 2 +
.../doc/4 enums/Objects.MoveableStatus.html | 2 +
Documentation/doc/4 enums/Objects.ObjID.html | 2 +
.../doc/4 enums/Objects.RoomFlagID.html | 2 +
.../doc/4 enums/Objects.RoomReverb.html | 2 +
.../doc/4 enums/Sound.SoundTrackType.html | 2 +
Documentation/doc/4 enums/Util.LogLevel.html | 2 +
Documentation/doc/4 enums/View.AlignMode.html | 2 +
.../doc/4 enums/View.CameraType.html | 2 +
.../doc/4 enums/View.PostProcessMode.html | 2 +
Documentation/doc/4 enums/View.ScaleMode.html | 2 +
.../5 lua utility modules/EventSequence.html | 2 +
.../doc/5 lua utility modules/Timer.html | 2 +
Documentation/doc/index.html | 10 +
TombEngine/Game/control/control.cpp | 10 +-
TombEngine/Game/effects/weather.cpp | 92 +++---
TombEngine/Game/effects/weather.h | 28 +-
TombEngine/Objects/Effects/lens_flare.cpp | 31 +-
TombEngine/Objects/Effects/lens_flare.h | 8 +-
.../ConstantBuffers/PostProcessBuffer.h | 5 +-
TombEngine/Renderer/RendererDraw.cpp | 17 +-
TombEngine/Renderer/RendererFrame.cpp | 12 +-
TombEngine/Renderer/RendererPostProcess.cpp | 1 +
.../Renderer/Structures/RendererLensFlare.h | 4 +-
.../Scripting/Include/ScriptInterfaceLevel.h | 10 +
.../Internal/TEN/Flow/FlowHandler.cpp | 4 +-
.../Internal/TEN/Flow/LensFlare/LensFlare.cpp | 85 +++++
.../Internal/TEN/Flow/LensFlare/LensFlare.h | 34 ++
.../Internal/TEN/Flow/Level/FlowLevel.cpp | 58 ++++
.../Internal/TEN/Flow/Level/FlowLevel.h | 17 +-
.../Internal/TEN/Flow/SkyLayer/SkyLayer.cpp | 116 +++----
.../Internal/TEN/Flow/Starfield/Starfield.cpp | 127 ++++++++
.../Internal/TEN/Flow/Starfield/Starfield.h | 36 +++
TombEngine/Shaders/CBPostProcess.hlsli | 5 +-
TombEngine/Shaders/PostProcess.fx | 11 +-
TombEngine/TombEngine.vcxproj | 6 +-
74 files changed, 1246 insertions(+), 156 deletions(-)
create mode 100644 Documentation/doc/2 classes/Flow.LensFlare.html
create mode 100644 Documentation/doc/2 classes/Flow.Starfield.html
create mode 100644 TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.cpp
create mode 100644 TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.h
create mode 100644 TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.cpp
create mode 100644 TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.h
diff --git a/Documentation/doc/1 modules/Effects.html b/Documentation/doc/1 modules/Effects.html
index c9aaf46b4..fbdd34565 100644
--- a/Documentation/doc/1 modules/Effects.html
+++ b/Documentation/doc/1 modules/Effects.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/1 modules/Flow.html b/Documentation/doc/1 modules/Flow.html
index 46af015e4..79f548b42 100644
--- a/Documentation/doc/1 modules/Flow.html
+++ b/Documentation/doc/1 modules/Flow.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/1 modules/Input.html b/Documentation/doc/1 modules/Input.html
index 61d495f1c..245afbb73 100644
--- a/Documentation/doc/1 modules/Input.html
+++ b/Documentation/doc/1 modules/Input.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/1 modules/Inventory.html b/Documentation/doc/1 modules/Inventory.html
index e5fd825ec..026463dc8 100644
--- a/Documentation/doc/1 modules/Inventory.html
+++ b/Documentation/doc/1 modules/Inventory.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/1 modules/Logic.html b/Documentation/doc/1 modules/Logic.html
index e190f3c99..5a4e0f59f 100644
--- a/Documentation/doc/1 modules/Logic.html
+++ b/Documentation/doc/1 modules/Logic.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/1 modules/Objects.html b/Documentation/doc/1 modules/Objects.html
index 2cb40e8e6..e2254f3e5 100644
--- a/Documentation/doc/1 modules/Objects.html
+++ b/Documentation/doc/1 modules/Objects.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/1 modules/Sound.html b/Documentation/doc/1 modules/Sound.html
index 109ac6e89..ef08ef33e 100644
--- a/Documentation/doc/1 modules/Sound.html
+++ b/Documentation/doc/1 modules/Sound.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/1 modules/Strings.html b/Documentation/doc/1 modules/Strings.html
index 63f90605b..32c538451 100644
--- a/Documentation/doc/1 modules/Strings.html
+++ b/Documentation/doc/1 modules/Strings.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/1 modules/Util.html b/Documentation/doc/1 modules/Util.html
index d9f5352d1..967e94298 100644
--- a/Documentation/doc/1 modules/Util.html
+++ b/Documentation/doc/1 modules/Util.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/1 modules/View.html b/Documentation/doc/1 modules/View.html
index 34b89cba7..fb8ac12f0 100644
--- a/Documentation/doc/1 modules/View.html
+++ b/Documentation/doc/1 modules/View.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/2 classes/Flow.Animations.html b/Documentation/doc/2 classes/Flow.Animations.html
index fa6b9a829..138c78dee 100644
--- a/Documentation/doc/2 classes/Flow.Animations.html
+++ b/Documentation/doc/2 classes/Flow.Animations.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/2 classes/Flow.Fog.html b/Documentation/doc/2 classes/Flow.Fog.html
index a55a11544..e90cb08d9 100644
--- a/Documentation/doc/2 classes/Flow.Fog.html
+++ b/Documentation/doc/2 classes/Flow.Fog.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/2 classes/Flow.InventoryItem.html b/Documentation/doc/2 classes/Flow.InventoryItem.html
index ccfe68f21..d8eba55a3 100644
--- a/Documentation/doc/2 classes/Flow.InventoryItem.html
+++ b/Documentation/doc/2 classes/Flow.InventoryItem.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/2 classes/Flow.LensFlare.html b/Documentation/doc/2 classes/Flow.LensFlare.html
new file mode 100644
index 000000000..8ae3ca788
--- /dev/null
+++ b/Documentation/doc/2 classes/Flow.LensFlare.html
@@ -0,0 +1,223 @@
+
+
+
+
+ TombEngine 1.4 Lua API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
TombEngine
+
+
+
+
1 Modules
+
+
2 Classes
+
+
3 Primitive Classes
+
+
4 Enums
+
+
5 Lua utility modules
+
+
+
+
+
+
+
Class Flow.LensFlare
+
LensFlare
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ lensFlareColor
+
+
+ (Color ) RGB lens flare color
+
+
+
+
+
+
+
+
+
+
+
+ lensFlarePosition
+
+
+
+(Vec2 ) Lens flare orientation.
+
+ This is the position of the lens flare in the sky. The X value is the horizontal position, and the Y value is the vertical position. Angles must be specified in degrees.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ LensFlare(yawPitchInDegrees, color)
+
+
+
+
+
+
+
+
+ Parameters:
+
+ yawPitchInDegrees
+ Vec2
+ Position of the lens flare (yaw and pitch) in degrees
+
+ color
+ Color
+ RGB color
+
+
+
+ Returns:
+
+
+ LensFlare
+ A lens flare object.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Documentation/doc/2 classes/Flow.Level.html b/Documentation/doc/2 classes/Flow.Level.html
index 6c505e3e8..a3309e70d 100644
--- a/Documentation/doc/2 classes/Flow.Level.html
+++ b/Documentation/doc/2 classes/Flow.Level.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
@@ -135,6 +137,14 @@
(Flow.SkyLayer ) Secondary sky layer
+ starfield
+ (Flow.Starfield ) Starfield
+
+
+ lensFlare
+ (Flow.LensFlare ) Global lens flare
+
+
fog
(Flow.Fog ) omni fog RGB color and distance.
@@ -307,6 +317,36 @@
+
+
+
+ starfield
+
+
+ (Flow.Starfield ) Starfield
+
+
+
+
+
+
+
+
+
+
+
+ lensFlare
+
+
+ (Flow.LensFlare ) Global lens flare
+
+
+
+
+
+
+
+
diff --git a/Documentation/doc/2 classes/Flow.Mirror.html b/Documentation/doc/2 classes/Flow.Mirror.html
index a391b693d..26e8fbfb4 100644
--- a/Documentation/doc/2 classes/Flow.Mirror.html
+++ b/Documentation/doc/2 classes/Flow.Mirror.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/2 classes/Flow.Settings.html b/Documentation/doc/2 classes/Flow.Settings.html
index a5f64f145..a29324f2e 100644
--- a/Documentation/doc/2 classes/Flow.Settings.html
+++ b/Documentation/doc/2 classes/Flow.Settings.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/2 classes/Flow.SkyLayer.html b/Documentation/doc/2 classes/Flow.SkyLayer.html
index 6ec6adcf9..f3863417a 100644
--- a/Documentation/doc/2 classes/Flow.SkyLayer.html
+++ b/Documentation/doc/2 classes/Flow.SkyLayer.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
@@ -154,13 +156,14 @@
(int) cloud speed.
-Values can be between [-32768, 32767], with positive numbers resulting in a sky that scrolls from
-west to east, and negative numbers resulting in one that travels east to west.
-
-Please note that speeds outside of the range of about [-1000, 1000] will cause the
-sky to scroll so fast that it will no longer appear as a coherent stream of clouds.
-Less is more. City of The Dead, for example, uses a speed value of 16.
+
Values can be between [-32768, 32767], with positive numbers resulting in a sky that scrolls from
+ west to east, and negative numbers resulting in one that travels east to west.
+ Please note that speeds outside of the range of about [-1000, 1000] will cause the
+ sky to scroll so fast that it will no longer appear as a coherent stream of clouds.
+ Less is more. City of The Dead, for example, uses a speed value of 16.
+
+
diff --git a/Documentation/doc/2 classes/Flow.Starfield.html b/Documentation/doc/2 classes/Flow.Starfield.html
new file mode 100644
index 000000000..9b75c5427
--- /dev/null
+++ b/Documentation/doc/2 classes/Flow.Starfield.html
@@ -0,0 +1,303 @@
+
+
+
+
+ TombEngine 1.4 Lua API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
TombEngine
+
+
+
+
1 Modules
+
+
2 Classes
+
+
3 Primitive Classes
+
+
4 Enums
+
+
5 Lua utility modules
+
+
+
+
+
+
+
Class Flow.Starfield
+
Starfield
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ starsCount
+
+
+
+(int) Stars count.
+
+ Values can be between [0, 6000], 0 resulting in no stars being rendered, and 6000 resulting in the maximum number of stars being rendered.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ meteorsCount
+
+
+
+(int) Meteors count.
+
+ Values can be between [0, 100], 0 resulting in no meteors being rendered, and 100 resulting in the maximum number of meteors being rendered.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ meteorsSpawnDensity
+
+
+ (int) Meteors spawn density.
+
+
+
+
+
+
+
+
+
+
+
+ meteorsSpeed
+
+
+ (float) Meteors speed.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Starfield(starsCount)
+
+
+
+
+
+
+
+
+ Parameters:
+
+ starsCount
+ int
+ Stars count
+
+
+
+ Returns:
+
+
+ Starfield
+ A starfield object with only stars enabled.
+
+
+
+
+
+
+
+
+ Starfield(starsCount, meteorsCount)
+
+
+
+
+
+
+
+
+ Parameters:
+
+ starsCount
+ int
+ Stars count
+
+ meteorsCount
+ int
+ Stars count
+
+
+
+ Returns:
+
+
+ Starfield
+ A starfield object with boths stars and meteors enabled.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Documentation/doc/2 classes/Objects.AIObject.html b/Documentation/doc/2 classes/Objects.AIObject.html
index a8816eb21..8b8095d28 100644
--- a/Documentation/doc/2 classes/Objects.AIObject.html
+++ b/Documentation/doc/2 classes/Objects.AIObject.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/2 classes/Objects.Camera.html b/Documentation/doc/2 classes/Objects.Camera.html
index 297e7cb13..5729dcefa 100644
--- a/Documentation/doc/2 classes/Objects.Camera.html
+++ b/Documentation/doc/2 classes/Objects.Camera.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/2 classes/Objects.LaraObject.html b/Documentation/doc/2 classes/Objects.LaraObject.html
index 56ae5ea19..eaf8bc408 100644
--- a/Documentation/doc/2 classes/Objects.LaraObject.html
+++ b/Documentation/doc/2 classes/Objects.LaraObject.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/2 classes/Objects.Moveable.html b/Documentation/doc/2 classes/Objects.Moveable.html
index 00671976d..b0ecc0d54 100644
--- a/Documentation/doc/2 classes/Objects.Moveable.html
+++ b/Documentation/doc/2 classes/Objects.Moveable.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/2 classes/Objects.Room.html b/Documentation/doc/2 classes/Objects.Room.html
index d49f8c93b..c4e632774 100644
--- a/Documentation/doc/2 classes/Objects.Room.html
+++ b/Documentation/doc/2 classes/Objects.Room.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/2 classes/Objects.Sink.html b/Documentation/doc/2 classes/Objects.Sink.html
index ca807b417..f88a0f3f6 100644
--- a/Documentation/doc/2 classes/Objects.Sink.html
+++ b/Documentation/doc/2 classes/Objects.Sink.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/2 classes/Objects.SoundSource.html b/Documentation/doc/2 classes/Objects.SoundSource.html
index 24e4f3b7d..6221a947d 100644
--- a/Documentation/doc/2 classes/Objects.SoundSource.html
+++ b/Documentation/doc/2 classes/Objects.SoundSource.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/2 classes/Objects.Static.html b/Documentation/doc/2 classes/Objects.Static.html
index c91209d0e..9b23623cc 100644
--- a/Documentation/doc/2 classes/Objects.Static.html
+++ b/Documentation/doc/2 classes/Objects.Static.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/2 classes/Objects.Volume.html b/Documentation/doc/2 classes/Objects.Volume.html
index a23618fc7..575b2cbbf 100644
--- a/Documentation/doc/2 classes/Objects.Volume.html
+++ b/Documentation/doc/2 classes/Objects.Volume.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/2 classes/Strings.DisplayString.html b/Documentation/doc/2 classes/Strings.DisplayString.html
index eff4085fd..9a7d4ae31 100644
--- a/Documentation/doc/2 classes/Strings.DisplayString.html
+++ b/Documentation/doc/2 classes/Strings.DisplayString.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/2 classes/View.DisplaySprite.html b/Documentation/doc/2 classes/View.DisplaySprite.html
index 4edcad83e..f17aabb51 100644
--- a/Documentation/doc/2 classes/View.DisplaySprite.html
+++ b/Documentation/doc/2 classes/View.DisplaySprite.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/3 primitive classes/Color.html b/Documentation/doc/3 primitive classes/Color.html
index 58efaffe6..fe9932009 100644
--- a/Documentation/doc/3 primitive classes/Color.html
+++ b/Documentation/doc/3 primitive classes/Color.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/3 primitive classes/Rotation.html b/Documentation/doc/3 primitive classes/Rotation.html
index d3f49a53a..81269805f 100644
--- a/Documentation/doc/3 primitive classes/Rotation.html
+++ b/Documentation/doc/3 primitive classes/Rotation.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/3 primitive classes/Vec2.html b/Documentation/doc/3 primitive classes/Vec2.html
index 30cb5546b..1968ad094 100644
--- a/Documentation/doc/3 primitive classes/Vec2.html
+++ b/Documentation/doc/3 primitive classes/Vec2.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/3 primitive classes/Vec3.html b/Documentation/doc/3 primitive classes/Vec3.html
index d5c81d100..ce6afe46f 100644
--- a/Documentation/doc/3 primitive classes/Vec3.html
+++ b/Documentation/doc/3 primitive classes/Vec3.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/4 enums/Effects.BlendID.html b/Documentation/doc/4 enums/Effects.BlendID.html
index cbc48754f..176648f3d 100644
--- a/Documentation/doc/4 enums/Effects.BlendID.html
+++ b/Documentation/doc/4 enums/Effects.BlendID.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/4 enums/Effects.EffectID.html b/Documentation/doc/4 enums/Effects.EffectID.html
index 585cd7cfa..a4f375d07 100644
--- a/Documentation/doc/4 enums/Effects.EffectID.html
+++ b/Documentation/doc/4 enums/Effects.EffectID.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/4 enums/Flow.GameStatus.html b/Documentation/doc/4 enums/Flow.GameStatus.html
index d7b9af20a..913f32956 100644
--- a/Documentation/doc/4 enums/Flow.GameStatus.html
+++ b/Documentation/doc/4 enums/Flow.GameStatus.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/4 enums/Input.ActionID.html b/Documentation/doc/4 enums/Input.ActionID.html
index 960659276..f6baf89fd 100644
--- a/Documentation/doc/4 enums/Input.ActionID.html
+++ b/Documentation/doc/4 enums/Input.ActionID.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/4 enums/Objects.AmmoType.html b/Documentation/doc/4 enums/Objects.AmmoType.html
index c21a2221d..1d0acd788 100644
--- a/Documentation/doc/4 enums/Objects.AmmoType.html
+++ b/Documentation/doc/4 enums/Objects.AmmoType.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/4 enums/Objects.MoveableStatus.html b/Documentation/doc/4 enums/Objects.MoveableStatus.html
index 2407fc1f4..d72b97b7a 100644
--- a/Documentation/doc/4 enums/Objects.MoveableStatus.html
+++ b/Documentation/doc/4 enums/Objects.MoveableStatus.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/4 enums/Objects.ObjID.html b/Documentation/doc/4 enums/Objects.ObjID.html
index 9372f1014..450b7e795 100644
--- a/Documentation/doc/4 enums/Objects.ObjID.html
+++ b/Documentation/doc/4 enums/Objects.ObjID.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/4 enums/Objects.RoomFlagID.html b/Documentation/doc/4 enums/Objects.RoomFlagID.html
index bdac34926..99800c4a7 100644
--- a/Documentation/doc/4 enums/Objects.RoomFlagID.html
+++ b/Documentation/doc/4 enums/Objects.RoomFlagID.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/4 enums/Objects.RoomReverb.html b/Documentation/doc/4 enums/Objects.RoomReverb.html
index 839bad41c..2602f78a7 100644
--- a/Documentation/doc/4 enums/Objects.RoomReverb.html
+++ b/Documentation/doc/4 enums/Objects.RoomReverb.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/4 enums/Sound.SoundTrackType.html b/Documentation/doc/4 enums/Sound.SoundTrackType.html
index 64c9e8ba1..a940321bc 100644
--- a/Documentation/doc/4 enums/Sound.SoundTrackType.html
+++ b/Documentation/doc/4 enums/Sound.SoundTrackType.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/4 enums/Util.LogLevel.html b/Documentation/doc/4 enums/Util.LogLevel.html
index 78844e1a5..6b21b58ee 100644
--- a/Documentation/doc/4 enums/Util.LogLevel.html
+++ b/Documentation/doc/4 enums/Util.LogLevel.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/4 enums/View.AlignMode.html b/Documentation/doc/4 enums/View.AlignMode.html
index 92542e66b..568016c03 100644
--- a/Documentation/doc/4 enums/View.AlignMode.html
+++ b/Documentation/doc/4 enums/View.AlignMode.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/4 enums/View.CameraType.html b/Documentation/doc/4 enums/View.CameraType.html
index d2b629311..ffd8a8402 100644
--- a/Documentation/doc/4 enums/View.CameraType.html
+++ b/Documentation/doc/4 enums/View.CameraType.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/4 enums/View.PostProcessMode.html b/Documentation/doc/4 enums/View.PostProcessMode.html
index 9caf7b0be..37ddb7709 100644
--- a/Documentation/doc/4 enums/View.PostProcessMode.html
+++ b/Documentation/doc/4 enums/View.PostProcessMode.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/4 enums/View.ScaleMode.html b/Documentation/doc/4 enums/View.ScaleMode.html
index 192589739..1460c4610 100644
--- a/Documentation/doc/4 enums/View.ScaleMode.html
+++ b/Documentation/doc/4 enums/View.ScaleMode.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/5 lua utility modules/EventSequence.html b/Documentation/doc/5 lua utility modules/EventSequence.html
index 93464f9ff..c1f7495c3 100644
--- a/Documentation/doc/5 lua utility modules/EventSequence.html
+++ b/Documentation/doc/5 lua utility modules/EventSequence.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/5 lua utility modules/Timer.html b/Documentation/doc/5 lua utility modules/Timer.html
index 1a3645b43..542dce9e2 100644
--- a/Documentation/doc/5 lua utility modules/Timer.html
+++ b/Documentation/doc/5 lua utility modules/Timer.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
diff --git a/Documentation/doc/index.html b/Documentation/doc/index.html
index 77f425919..6ae912f78 100644
--- a/Documentation/doc/index.html
+++ b/Documentation/doc/index.html
@@ -49,10 +49,12 @@
Flow.Animations
Flow.Fog
Flow.InventoryItem
+ Flow.LensFlare
Flow.Level
Flow.Mirror
Flow.Settings
Flow.SkyLayer
+ Flow.Starfield
Objects.AIObject
Objects.Camera
Objects.LaraObject
@@ -183,6 +185,10 @@ local door = GetMoveableByName("door_type4_14")
Flow.InventoryItem
Represents the properties of an object as it appears in the inventory.
+
+ Flow.LensFlare
+ LensFlare
+
Flow.Level
Stores level metadata.
@@ -199,6 +205,10 @@ local door = GetMoveableByName("door_type4_14")
Flow.SkyLayer
Describes a layer of moving clouds.
+
+ Flow.Starfield
+ Starfield
+
Objects.AIObject
AI object
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index d3fa54462..e7c064dc9 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -243,8 +243,16 @@ GameStatus ControlPhase(int numFrames)
UpdateBeetleSwarm();
UpdateLocusts();
UpdateUnderwaterBloodParticles();
- SetupGlobalLensFlare(180.0f, 30.0f);
+ if (g_GameFlow->GetLevel(CurrentLevel)->GetLensFlareEnabled())
+ {
+ SetupGlobalLensFlare(
+ g_GameFlow->GetLevel(CurrentLevel)->GetLensFlarePosition(),
+ g_GameFlow->GetLevel(CurrentLevel)->GetLensFlareColor(),
+ g_GameFlow->GetLevel(CurrentLevel)->GetLensFlareSpriteID()
+ );
+ }
+
// Update HUD.
g_Hud.Update(*LaraItem);
UpdateFadeScreenAndCinematicBars();
diff --git a/TombEngine/Game/effects/weather.cpp b/TombEngine/Game/effects/weather.cpp
index f6269b983..f1379adf3 100644
--- a/TombEngine/Game/effects/weather.cpp
+++ b/TombEngine/Game/effects/weather.cpp
@@ -18,33 +18,6 @@ using namespace TEN::Math::Random;
namespace TEN::Effects::Environment
{
- constexpr auto WEATHER_PARTICLES_SPAWN_DENSITY = 32;
- constexpr auto WEATHER_PARTICLES_MAX_COUNT = 2048;
- constexpr auto WEATHER_PARTICLES_MAX_COLL_CHECK_DELAY = 5.0f;
-
- constexpr auto MAX_DUST_SIZE = 25.0f;
- constexpr auto MAX_SNOW_SIZE = 32.0f;
- constexpr auto MAX_RAIN_SIZE = 128.0f;
-
- constexpr auto WEATHER_PARTICLE_HORIZONTAL_SPEED = 8.0f;
- constexpr auto MAX_SNOW_SPEED = 128.0f;
- constexpr auto MAX_RAIN_SPEED = 256.0f;
- constexpr auto MAX_DUST_SPEED = 1.0f;
-
- constexpr auto WEATHER_PARTICLES_TRANSPARENCY = 0.8f;
- constexpr auto WEATHER_PARTICLES_NEAR_DEATH_LIFE_VALUE = 20.0f;
- constexpr auto WEATHER_PARTICLES_NEAR_DEATH_MELT_FACTOR = 1.0f - (1.0f / (WEATHER_PARTICLES_NEAR_DEATH_LIFE_VALUE * 2));
-
- constexpr auto DUST_SPAWN_DENSITY = 300;
- constexpr auto DUST_LIFE = 40;
- constexpr auto DUST_SPAWN_RADIUS = (10 * 1024);
-
- constexpr auto METEOR_PARTICLES_MAX_COUNT = 10;
- constexpr auto METEOR_PARTICLES_MAX_LIFE = 150;
- constexpr auto METEOR_PARTICLES_SPEED = 32.0f;
- constexpr auto METEOR_PARTICLES_SPAWN_DENSITY = 4;
- constexpr auto METEOR_PARTICLES_FADE_TIME = 30;
-
EnvironmentController Weather;
float WeatherParticle::Transparency() const
@@ -236,12 +209,17 @@ namespace TEN::Effects::Environment
void EnvironmentController::UpdateStarfield(ScriptInterfaceLevel* level)
{
+ if (!level->GetStarfieldEnabled())
+ return;
+
if (ResetStarField)
{
- Stars.clear();
- Stars.reserve(StarsCount);
+ int starsCount = level->GetStarfieldStarsCount();
- for (int i = 0; i < StarsCount; i++)
+ Stars.clear();
+ Stars.reserve(starsCount);
+
+ for (int i = 0; i < starsCount; i++)
{
Vector3 starDirection = Random::GenerateDirectionInCone(-Vector3::UnitY, 70.0f);
starDirection.Normalize();
@@ -279,29 +257,30 @@ namespace TEN::Effects::Environment
s.Blinking = Random::GenerateFloat(0.5f, 1.0f);
}
- for (auto& m : Meteors)
+ if (level->GetStarfieldMeteorsEnabled())
{
- //p.StoreInterpolationData();
-
- m.Life--;
-
- if (m.Life <= 0)
+ for (auto& m : Meteors)
{
- m.Active = false;
- continue;
+ m.Life--;
+
+ if (m.Life <= 0)
+ {
+ m.Active = false;
+ continue;
+ }
+
+ m.StoreInterpolationData();
+
+ if (m.Life <= METEOR_PARTICLES_FADE_TIME)
+ m.Fade = m.Life / (float)METEOR_PARTICLES_FADE_TIME;
+ else if (m.Life >= METEOR_PARTICLES_MAX_LIFE - METEOR_PARTICLES_FADE_TIME)
+ m.Fade = (METEOR_PARTICLES_MAX_LIFE - m.Life) / (float)METEOR_PARTICLES_FADE_TIME;
+ else
+ m.Fade = 1.0f;
+
+ m.Position += m.Direction * level->GetStarfieldMeteorsSpeed();
}
-
- m.StoreInterpolationData();
-
- if (m.Life <= METEOR_PARTICLES_FADE_TIME)
- m.Fade = m.Life / (float)METEOR_PARTICLES_FADE_TIME;
- else if (m.Life >= METEOR_PARTICLES_MAX_LIFE - METEOR_PARTICLES_FADE_TIME)
- m.Fade = (METEOR_PARTICLES_MAX_LIFE - m.Life) / (float)METEOR_PARTICLES_FADE_TIME;
- else
- m.Fade = 1.0f;
-
- m.Position += m.Direction * METEOR_PARTICLES_SPEED;
- }
+ }
}
void EnvironmentController::UpdateWeather(ScriptInterfaceLevel* level)
@@ -609,15 +588,16 @@ namespace TEN::Effects::Environment
if (Meteors.size() > 0)
Meteors.erase(std::remove_if(Meteors.begin(), Meteors.end(), [](const MeteorParticle& part) { return !part.Active; }), Meteors.end());
- //if (level->GetWeatherType() == WeatherType::None || level->GetWeatherStrength() == 0.0f)
- // return;
+ if (!level->GetStarfieldMeteorsEnabled())
+ return;
int newParticlesCount = 0;
- int density = METEOR_PARTICLES_SPAWN_DENSITY;
+ int density = level->GetStarfieldMeteorsSpawnDensity();
+ int meteorsCount = level->GetStarfieldMeteorsCount();
- if (density > 0.0f /* && level->GetWeatherType() != WeatherType::None */)
- {
- while (Meteors.size() < METEOR_PARTICLES_MAX_COUNT)
+ if (density > 0)
+ {
+ while (Meteors.size() < meteorsCount)
{
if (newParticlesCount > density)
break;
diff --git a/TombEngine/Game/effects/weather.h b/TombEngine/Game/effects/weather.h
index 43daf02d9..07ac92765 100644
--- a/TombEngine/Game/effects/weather.h
+++ b/TombEngine/Game/effects/weather.h
@@ -8,6 +8,33 @@ using namespace TEN::Entities::Effects;
namespace TEN::Effects::Environment
{
+ constexpr auto WEATHER_PARTICLES_SPAWN_DENSITY = 32;
+ constexpr auto WEATHER_PARTICLES_MAX_COUNT = 2048;
+ constexpr auto WEATHER_PARTICLES_MAX_COLL_CHECK_DELAY = 5.0f;
+
+ constexpr auto MAX_DUST_SIZE = 25.0f;
+ constexpr auto MAX_SNOW_SIZE = 32.0f;
+ constexpr auto MAX_RAIN_SIZE = 128.0f;
+
+ constexpr auto WEATHER_PARTICLE_HORIZONTAL_SPEED = 8.0f;
+ constexpr auto MAX_SNOW_SPEED = 128.0f;
+ constexpr auto MAX_RAIN_SPEED = 256.0f;
+ constexpr auto MAX_DUST_SPEED = 1.0f;
+
+ constexpr auto WEATHER_PARTICLES_TRANSPARENCY = 0.8f;
+ constexpr auto WEATHER_PARTICLES_NEAR_DEATH_LIFE_VALUE = 20.0f;
+ constexpr auto WEATHER_PARTICLES_NEAR_DEATH_MELT_FACTOR = 1.0f - (1.0f / (WEATHER_PARTICLES_NEAR_DEATH_LIFE_VALUE * 2));
+
+ constexpr auto DUST_SPAWN_DENSITY = 300;
+ constexpr auto DUST_LIFE = 40;
+ constexpr auto DUST_SPAWN_RADIUS = (10 * 1024);
+
+ constexpr auto METEOR_PARTICLES_MAX_COUNT = 10;
+ constexpr auto METEOR_PARTICLES_MAX_LIFE = 150;
+ constexpr auto METEOR_PARTICLES_SPEED = 32.0f;
+ constexpr auto METEOR_PARTICLES_SPAWN_DENSITY = 4;
+ constexpr auto METEOR_PARTICLES_FADE_TIME = 30;
+
struct StarParticle
{
Vector3 Position = Vector3::Zero;
@@ -116,7 +143,6 @@ namespace TEN::Effects::Environment
byte StormSkyColor2 = 1;
// Starfield
- int StarsCount = 3000;
std::vector Stars;
std::vector Meteors;
bool ResetStarField = true;
diff --git a/TombEngine/Objects/Effects/lens_flare.cpp b/TombEngine/Objects/Effects/lens_flare.cpp
index fd06249b8..2d585bae7 100644
--- a/TombEngine/Objects/Effects/lens_flare.cpp
+++ b/TombEngine/Objects/Effects/lens_flare.cpp
@@ -14,7 +14,12 @@ namespace TEN::Entities::Effects
if (TriggerActive(item))
{
- SetupLensFlare(item->Pose.Position.ToVector3(), item->RoomNumber, false);
+ SetupLensFlare(
+ item->Pose.Position.ToVector3(),
+ Vector3::One,
+ item->RoomNumber,
+ false,
+ SPR_LENSFLARE3);
}
}
@@ -23,19 +28,23 @@ namespace TEN::Entities::Effects
LensFlares.clear();
}
- void SetupGlobalLensFlare(float yaw, float pitch)
+ void SetupGlobalLensFlare(Vector2 yawAndPitchInDegrees, Vector3 color, int spriteIndex)
{
Vector3 position = Camera.pos.ToVector3();
- Matrix rotation = Matrix::CreateFromYawPitchRoll(DEG_TO_RAD(yaw), DEG_TO_RAD(pitch), 0);
+ Matrix rotation = Matrix::CreateFromYawPitchRoll(
+ DEG_TO_RAD(yawAndPitchInDegrees.x),
+ DEG_TO_RAD(yawAndPitchInDegrees.y),
+ 0
+ );
position += Vector3::Transform(Vector3(0, 0, BLOCK(256)), rotation);
- SetupLensFlare(position, NO_VALUE, true);
+ SetupLensFlare(position, color, NO_VALUE, true, spriteIndex);
}
- void SetupLensFlare(Vector3 position, short roomNumber, bool sun)
+ void SetupLensFlare(Vector3 position, Vector3 color, short roomNumber, bool global, int spriteIndex)
{
Vector3 lensFlarePosition;
- if (sun)
+ if (global)
{
if (g_Level.Rooms[Camera.pos.RoomNumber].flags & ENV_FLAG_NO_LENSFLARE)
{
@@ -80,7 +89,7 @@ namespace TEN::Entities::Effects
if (roomNumber != NO_VALUE)
{
- if (g_Level.Rooms[roomNumber].flags & ENV_FLAG_NOT_NEAR_OUTSIDE || !sun)
+ if (g_Level.Rooms[roomNumber].flags & ENV_FLAG_NOT_NEAR_OUTSIDE || !global)
{
GameVector source = { Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.pos.RoomNumber };
GameVector destination = { (int)lensFlarePosition.x, (int)lensFlarePosition.y, (int)lensFlarePosition.z, roomNumber };
@@ -88,15 +97,19 @@ namespace TEN::Entities::Effects
}
}
- if (!flareVisible && !sun)
+ if (!flareVisible && !global)
{
return;
}
LensFlare lensFlare;
+
lensFlare.Position = position;
lensFlare.RoomNumber = roomNumber;
- lensFlare.Sun = sun;
+ lensFlare.Global = global;
+ lensFlare.Color = color;
+ lensFlare.SpriteIndex = spriteIndex;
+
LensFlares.push_back(lensFlare);
}
}
\ No newline at end of file
diff --git a/TombEngine/Objects/Effects/lens_flare.h b/TombEngine/Objects/Effects/lens_flare.h
index 0f0901338..553866f4f 100644
--- a/TombEngine/Objects/Effects/lens_flare.h
+++ b/TombEngine/Objects/Effects/lens_flare.h
@@ -10,14 +10,16 @@ namespace TEN::Entities::Effects
struct LensFlare
{
Vector3 Position;
+ Vector3 Color;
short RoomNumber;
- bool Sun;
+ bool Global;
+ int SpriteIndex;
};
extern std::vector LensFlares;
void LensFlareControl(short itemNumber);
void ClearLensFlares();
- void SetupLensFlare(Vector3 position, short roomNumber, bool global);
- void SetupGlobalLensFlare(float yaw, float pitch);
+ void SetupLensFlare(Vector3 position, Vector3 color, short roomNumber, bool global, int spriteIndex);
+ void SetupGlobalLensFlare(Vector2 yawAndPitchInDegrees, Vector3 color, int spriteIndex);
}
\ No newline at end of file
diff --git a/TombEngine/Renderer/ConstantBuffers/PostProcessBuffer.h b/TombEngine/Renderer/ConstantBuffers/PostProcessBuffer.h
index 130136463..40658395b 100644
--- a/TombEngine/Renderer/ConstantBuffers/PostProcessBuffer.h
+++ b/TombEngine/Renderer/ConstantBuffers/PostProcessBuffer.h
@@ -8,7 +8,10 @@ namespace TEN::Renderer::ConstantBuffers
struct alignas(16) ShaderLensFlare
{
Vector3 Position;
- float Padding;
+ float Padding1;
+ //--
+ Vector3 Color;
+ float Padding2;
};
struct alignas(16) CPostProcessBuffer
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index 30a4e11bb..6c110c6cc 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -2821,8 +2821,7 @@ namespace TEN::Renderer
_context->ClearDepthStencilView(depthTarget, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0);
- int starsCount = (int)Weather.GetStars().size();
- if (starsCount > 0)
+ if (Weather.GetStars().size() > 0)
{
SetDepthState(DepthState::Read);
SetBlendMode(BlendMode::Additive);
@@ -2841,6 +2840,8 @@ namespace TEN::Renderer
BindTexture(TextureRegister::ColorMap, _sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LENSFLARE3].Texture, SamplerStateRegister::LinearClamp);
int drawnStars = 0;
+ int starsCount = (int)Weather.GetStars().size();
+
while (drawnStars < starsCount)
{
int starsToDraw = (starsCount - drawnStars) > 100 ? 100 : (starsCount - drawnStars);
@@ -2851,7 +2852,7 @@ namespace TEN::Renderer
auto& s = Weather.GetStars()[drawnStars + i];
RendererSpriteToDraw rDrawSprite;
- rDrawSprite.Sprite = &_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LENSFLARE3];
+ rDrawSprite.Sprite = &_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LENSFLARE3];
constexpr auto STAR_SIZE = 2;
@@ -2890,7 +2891,7 @@ namespace TEN::Renderer
drawnStars += starsToDraw;
}
- // Draw meteor
+ // Draw meteors
if (Weather.GetMeteors().size() > 0)
{
RendererSpriteToDraw rDrawSprite;
@@ -2907,8 +2908,8 @@ namespace TEN::Renderer
continue;
rDrawSprite.Type = SpriteType::CustomBillboard;
- rDrawSprite.pos =
- renderView.Camera.WorldPosition +
+ rDrawSprite.pos =
+ renderView.Camera.WorldPosition +
Vector3::Lerp(meteor.OldPosition, meteor.Position, _interpolationFactor);
rDrawSprite.Rotation = 0;
rDrawSprite.Scale = 1;
@@ -2995,7 +2996,7 @@ namespace TEN::Renderer
}
// Eventually draw the sun sprite
- if (renderView.LensFlaresToDraw.size() > 0 && renderView.LensFlaresToDraw[0].Sun)
+ if (renderView.LensFlaresToDraw.size() > 0 && renderView.LensFlaresToDraw[0].Global)
{
SetDepthState(DepthState::Read);
SetBlendMode(BlendMode::Additive);
@@ -3012,7 +3013,7 @@ namespace TEN::Renderer
_context->IASetVertexBuffers(0, 1, _quadVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
RendererSpriteToDraw rDrawSprite;
- rDrawSprite.Sprite = &_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LENSFLARE3];
+ rDrawSprite.Sprite = &_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + renderView.LensFlaresToDraw[0].SpriteIndex];
constexpr auto SUN_SIZE = 64;
diff --git a/TombEngine/Renderer/RendererFrame.cpp b/TombEngine/Renderer/RendererFrame.cpp
index 041d11aad..e552f5772 100644
--- a/TombEngine/Renderer/RendererFrame.cpp
+++ b/TombEngine/Renderer/RendererFrame.cpp
@@ -110,7 +110,7 @@ namespace TEN::Renderer
{
Vector3 lensFlareToCamera = lensFlare.Position - renderView.Camera.WorldPosition;
float distance = 0.0f;
- if (!lensFlare.Sun)
+ if (!lensFlare.Global)
{
distance = lensFlareToCamera.Length();
}
@@ -122,10 +122,14 @@ namespace TEN::Renderer
if (lensFlareToCamera.Dot(cameraDirection) >= 0.0f)
{
RendererLensFlare lensFlareToDraw;
+
lensFlareToDraw.Position = lensFlare.Position;
lensFlareToDraw.Distance = distance;
+ lensFlareToDraw.Color = lensFlare.Color;
+ lensFlareToDraw.SpriteIndex = lensFlare.SpriteIndex;
lensFlareToDraw.Direction = lensFlareToCamera;
- lensFlareToDraw.Sun = lensFlare.Sun;
+ lensFlareToDraw.Global = lensFlare.Global;
+
tempLensFlares.push_back(lensFlareToDraw);
}
}
@@ -135,9 +139,9 @@ namespace TEN::Renderer
tempLensFlares.end(),
[](const RendererLensFlare& lensFlare0, const RendererLensFlare& lensFlare1)
{
- if (lensFlare0.Sun && !lensFlare1.Sun)
+ if (lensFlare0.Global && !lensFlare1.Global)
return true;
- else if (!lensFlare0.Sun && lensFlare1.Sun)
+ else if (!lensFlare0.Global && lensFlare1.Global)
return false;
else
return lensFlare0.Distance < lensFlare1.Distance;
diff --git a/TombEngine/Renderer/RendererPostProcess.cpp b/TombEngine/Renderer/RendererPostProcess.cpp
index 3393dfacc..d34e05187 100644
--- a/TombEngine/Renderer/RendererPostProcess.cpp
+++ b/TombEngine/Renderer/RendererPostProcess.cpp
@@ -87,6 +87,7 @@ namespace TEN::Renderer
for (int i = 0; i < view.LensFlaresToDraw.size(); i++)
{
_stPostProcessBuffer.LensFlares[i].Position = view.LensFlaresToDraw[i].Position;
+ _stPostProcessBuffer.LensFlares[i].Color = view.LensFlaresToDraw[i].Color;
}
_stPostProcessBuffer.NumLensFlares = (int)view.LensFlaresToDraw.size();
_cbPostProcessBuffer.UpdateData(_stPostProcessBuffer, _context.Get());
diff --git a/TombEngine/Renderer/Structures/RendererLensFlare.h b/TombEngine/Renderer/Structures/RendererLensFlare.h
index 2fc8b74ae..1c88d8fb3 100644
--- a/TombEngine/Renderer/Structures/RendererLensFlare.h
+++ b/TombEngine/Renderer/Structures/RendererLensFlare.h
@@ -9,8 +9,10 @@ namespace TEN::Renderer::Structures
struct RendererLensFlare
{
Vector3 Position;
+ Vector3 Color;
Vector3 Direction;
float Distance;
- bool Sun;
+ bool Global;
+ int SpriteIndex;
};
}
\ No newline at end of file
diff --git a/TombEngine/Scripting/Include/ScriptInterfaceLevel.h b/TombEngine/Scripting/Include/ScriptInterfaceLevel.h
index 072bee854..1302d22d7 100644
--- a/TombEngine/Scripting/Include/ScriptInterfaceLevel.h
+++ b/TombEngine/Scripting/Include/ScriptInterfaceLevel.h
@@ -48,4 +48,14 @@ public:
virtual int GetSecrets() const = 0;
virtual std::string GetAmbientTrack() const = 0;
virtual bool GetResetHubEnabled() const = 0;
+ virtual bool GetLensFlareEnabled() const = 0;
+ virtual Vector2 GetLensFlarePosition() const = 0;
+ virtual RGBAColor8Byte GetLensFlareColor() const = 0;
+ virtual int GetLensFlareSpriteID() const = 0;
+ virtual bool GetStarfieldEnabled() const = 0;
+ virtual bool GetStarfieldMeteorsEnabled() const = 0;
+ virtual int GetStarfieldStarsCount() const = 0;
+ virtual int GetStarfieldMeteorsCount() const = 0;
+ virtual int GetStarfieldMeteorsSpawnDensity() const = 0;
+ virtual float GetStarfieldMeteorsSpeed() const = 0;
};
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp
index 5240789f8..455fb73cf 100644
--- a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp
@@ -264,7 +264,9 @@ Specify which translations in the strings table correspond to which languages.
Animations::Register(tableFlow);
Settings::Register(tableFlow);
Fog::Register(tableFlow);
-
+ LensFlare::Register(tableFlow);
+ Starfield::Register(tableFlow);
+
m_handler.MakeReadOnlyTable(tableFlow, ScriptReserved_WeatherType, WEATHER_TYPES);
m_handler.MakeReadOnlyTable(tableFlow, ScriptReserved_LaraType, PLAYER_TYPES);
m_handler.MakeReadOnlyTable(tableFlow, ScriptReserved_RotationAxis, ROTATION_AXES);
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.cpp b/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.cpp
new file mode 100644
index 000000000..690e1a214
--- /dev/null
+++ b/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.cpp
@@ -0,0 +1,85 @@
+#include "framework.h"
+#include "LensFlare.h"
+#include
+
+/***
+LensFlare
+
+@tenclass Flow.LensFlare
+@pragma nostrip
+*/
+
+void LensFlare::Register(sol::table& parent)
+{
+ using ctors = sol::constructors;
+ parent.new_usertype("LensFlare",
+ ctors(),
+ sol::call_constructor, ctors(),
+
+ /// (@{Color}) RGB lens flare color
+ //@mem lensFlareColor
+ "color", sol::property(&LensFlare::GetColor, &LensFlare::SetColor),
+
+ /*** (@{Vec2}) Lens flare orientation.
+
+ This is the position of the lens flare in the sky. The X value is the horizontal position, and the Y value is the vertical position. Angles must be specified in degrees.
+
+ @mem lensFlarePosition*/
+ "position", sol::property(&LensFlare::GetPosition, &LensFlare::SetPosition)
+ );
+}
+
+/***
+@tparam Vec2 yawPitchInDegrees Position of the lens flare (yaw and pitch) in degrees
+@tparam Color color RGB color
+@treturn LensFlare A lens flare object.
+@function LensFlare
+*/
+LensFlare::LensFlare(Vec2 const& yawPitchInDegrees, ScriptColor const& col)
+{
+ SetColor(col);
+ SetPosition(yawPitchInDegrees);
+ Enabled = true;
+}
+
+void LensFlare::SetColor(ScriptColor const& col)
+{
+ R = col.GetR();
+ G = col.GetG();
+ B = col.GetB();
+}
+
+
+ScriptColor LensFlare::GetColor() const
+{
+ return ScriptColor{ R, G, B };
+}
+
+void LensFlare::SetPosition(Vec2 const& yawPitchInDegrees)
+{
+ Yaw = yawPitchInDegrees.x;
+ Pitch = yawPitchInDegrees.y;
+}
+
+
+Vec2 LensFlare::GetPosition() const
+{
+ return Vec2{ Yaw, Pitch };
+}
+
+bool LensFlare::GetEnabled() const
+{
+ return Enabled;
+}
+
+void LensFlare::SetSunSpriteID(int const& spriteIndex)
+{
+ assertion(spriteIndex >= 0 && spriteIndex < g_Level.Sprites.size(), "Sprite Index must be in a valid range");
+
+ SunSpriteID = spriteIndex;
+}
+
+int LensFlare::GetSunSpriteID() const
+{
+ return SunSpriteID;
+}
\ No newline at end of file
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.h b/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.h
new file mode 100644
index 000000000..d14f4c7b6
--- /dev/null
+++ b/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include "Scripting/Internal/TEN/Color/Color.h"
+#include "Scripting/Internal/TEN/Vec2/Vec2.h"
+#include "Objects/objectslist.h"
+
+namespace sol { class state; }
+
+struct LensFlare
+{
+ bool Enabled;
+ int SunSpriteID = SPR_LENSFLARE3; // Index into sprites
+ byte R;
+ byte G;
+ byte B;
+ float Yaw;
+ float Pitch;
+
+ LensFlare() = default;
+ LensFlare(Vec2 const& yawPitchInDegrees, ScriptColor const& col);
+
+ void SetColor(ScriptColor const& color);
+ ScriptColor GetColor() const;
+
+ void SetPosition(Vec2 const& yawPitchInDegrees);
+ Vec2 GetPosition() const;
+
+ void SetSunSpriteID(int const& spriteIndex);
+ int GetSunSpriteID() const;
+
+ bool GetEnabled() const;
+
+ static void Register(sol::table&);
+};
\ No newline at end of file
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp b/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp
index 55067e76a..919174fdd 100644
--- a/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp
@@ -52,6 +52,14 @@ void Level::Register(sol::table& parent)
//@mem layer2
"layer2", &Level::Layer2,
+/// (@{Flow.Starfield}) Starfield
+//@mem starfield
+ "starfield", & Level::Starfield,
+
+/// (@{Flow.LensFlare}) Global lens flare
+//@mem lensFlare
+ "lensFlare", & Level::LensFlare,
+
/// (@{Flow.Fog}) omni fog RGB color and distance.
// As seen in TR4's Desert Railroad.
// If not provided, distance fog will be black.
@@ -277,3 +285,53 @@ std::string Level::GetAmbientTrack() const
{
return AmbientTrack;
}
+
+bool Level::GetLensFlareEnabled() const
+{
+ return LensFlare.GetEnabled();
+}
+
+Vector2 Level::GetLensFlarePosition() const
+{
+ return LensFlare.GetPosition();
+}
+
+RGBAColor8Byte Level::GetLensFlareColor() const
+{
+ return LensFlare.GetColor();
+}
+
+int Level::GetLensFlareSpriteID() const
+{
+ return LensFlare.GetSunSpriteID();
+}
+
+bool Level::GetStarfieldEnabled() const
+{
+ return Starfield.GetEnabled();
+}
+
+bool Level::GetStarfieldMeteorsEnabled() const
+{
+ return Starfield.GetMeteorsEnabled();
+}
+
+int Level::GetStarfieldStarsCount() const
+{
+ return Starfield.GetStarsCount();
+}
+
+int Level::GetStarfieldMeteorsCount() const
+{
+ return Starfield.GetMeteorsCount();
+}
+
+int Level::GetStarfieldMeteorsSpawnDensity() const
+{
+ return Starfield.GetMeteorsSpawnDensity();
+}
+
+float Level::GetStarfieldMeteorsSpeed() const
+{
+ return Starfield.GetMeteorsSpeed();
+}
\ No newline at end of file
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.h b/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.h
index e3d632e80..0460e6a9b 100644
--- a/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.h
+++ b/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.h
@@ -1,6 +1,8 @@
#pragma once
#include
#include "Scripting/Internal/TEN/Flow/SkyLayer/SkyLayer.h"
+#include "Scripting/Internal/TEN/Flow/LensFlare/LensFlare.h"
+#include "Scripting/Internal/TEN/Flow/Starfield/Starfield.h"
#include "Scripting/Internal/TEN/Flow/Mirror/Mirror.h"
#include "Scripting/Internal/TEN/Flow/Fog/Fog.h"
#include "Scripting/Include/ScriptInterfaceLevel.h"
@@ -31,7 +33,10 @@ struct Level : public ScriptInterfaceLevel
Mirror Mirror = {};
int LevelFarView = 0;
std::string AmbientTrack = {};
-
+
+ LensFlare LensFlare = {};
+ Starfield Starfield = {};
+
WeatherType Weather = WeatherType::None;
float WeatherStrength = 1.0f;
bool Storm = false;
@@ -62,4 +67,14 @@ struct Level : public ScriptInterfaceLevel
int GetSecrets() const override;
std::string GetAmbientTrack() const override;
bool GetResetHubEnabled() const override;
+ bool GetLensFlareEnabled() const override;
+ Vector2 GetLensFlarePosition() const override;
+ RGBAColor8Byte GetLensFlareColor() const override;
+ int GetLensFlareSpriteID() const override;
+ bool GetStarfieldEnabled() const override;
+ bool GetStarfieldMeteorsEnabled() const override;
+ int GetStarfieldStarsCount() const override;
+ int GetStarfieldMeteorsCount() const override;
+ int GetStarfieldMeteorsSpawnDensity() const override;
+ float GetStarfieldMeteorsSpeed() const override;
};
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/SkyLayer/SkyLayer.cpp b/TombEngine/Scripting/Internal/TEN/Flow/SkyLayer/SkyLayer.cpp
index 5e9586a5f..e37d1dbeb 100644
--- a/TombEngine/Scripting/Internal/TEN/Flow/SkyLayer/SkyLayer.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Flow/SkyLayer/SkyLayer.cpp
@@ -1,58 +1,58 @@
-#include "framework.h"
-#include "SkyLayer.h"
-
-/*** Describes a layer of moving clouds.
-As seen in TR4's City of the Dead.
-
-@tenclass Flow.SkyLayer
-@pragma nostrip
-*/
-
-void SkyLayer::Register(sol::table & parent)
-{
- using ctors = sol::constructors;
- parent.new_usertype("SkyLayer",
- ctors(),
- sol::call_constructor, ctors(),
-
-/// (@{Color}) RGB sky color
-//@mem color
- "color", sol::property(&SkyLayer::GetColor, &SkyLayer::SetColor),
-
-/*** (int) cloud speed.
-
-Values can be between [-32768, 32767], with positive numbers resulting in a sky that scrolls from
-west to east, and negative numbers resulting in one that travels east to west.
-
-Please note that speeds outside of the range of about [-1000, 1000] will cause the
-sky to scroll so fast that it will no longer appear as a coherent stream of clouds.
-Less is more. City of The Dead, for example, uses a speed value of 16.
-
-@mem speed*/
- "speed", &SkyLayer::CloudSpeed
- );
-}
-
-/***
-@tparam Color color RGB color
-@tparam int speed cloud speed
-@treturn SkyLayer A SkyLayer object.
-@function SkyLayer
-*/
-SkyLayer::SkyLayer(ScriptColor const& col, short speed)
-{
- SetColor(col);
- CloudSpeed = speed;
- Enabled = true;
-}
-
-void SkyLayer::SetColor(ScriptColor const & col)
-{
- R = col.GetR();
- G = col.GetG();
- B = col.GetB();
-}
-
-ScriptColor SkyLayer::GetColor() const {
- return ScriptColor{ R, G, B };
-}
+#include "framework.h"
+#include "SkyLayer.h"
+
+/*** Describes a layer of moving clouds.
+As seen in TR4's City of the Dead.
+
+@tenclass Flow.SkyLayer
+@pragma nostrip
+*/
+
+void SkyLayer::Register(sol::table & parent)
+{
+ using ctors = sol::constructors;
+ parent.new_usertype("SkyLayer",
+ ctors(),
+ sol::call_constructor, ctors(),
+
+ /// (@{Color}) RGB sky color
+ //@mem color
+ "color", sol::property(&SkyLayer::GetColor, &SkyLayer::SetColor),
+
+ /*** (int) cloud speed.
+
+ Values can be between [-32768, 32767], with positive numbers resulting in a sky that scrolls from
+ west to east, and negative numbers resulting in one that travels east to west.
+
+ Please note that speeds outside of the range of about [-1000, 1000] will cause the
+ sky to scroll so fast that it will no longer appear as a coherent stream of clouds.
+ Less is more. City of The Dead, for example, uses a speed value of 16.
+
+ @mem speed*/
+ "speed", &SkyLayer::CloudSpeed
+ );
+}
+
+/***
+@tparam Color color RGB color
+@tparam int speed cloud speed
+@treturn SkyLayer A SkyLayer object.
+@function SkyLayer
+*/
+SkyLayer::SkyLayer(ScriptColor const& col, short speed)
+{
+ SetColor(col);
+ CloudSpeed = speed;
+ Enabled = true;
+}
+
+void SkyLayer::SetColor(ScriptColor const & col)
+{
+ R = col.GetR();
+ G = col.GetG();
+ B = col.GetB();
+}
+
+ScriptColor SkyLayer::GetColor() const {
+ return ScriptColor{ R, G, B };
+}
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.cpp b/TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.cpp
new file mode 100644
index 000000000..56f957300
--- /dev/null
+++ b/TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.cpp
@@ -0,0 +1,127 @@
+#include "framework.h"
+#include "Starfield.h"
+#include "Specific/level.h"
+#include "Game/effects/weather.h"
+
+using namespace TEN::Effects::Environment;
+
+/***
+Starfield
+
+@tenclass Flow.Starfield
+@pragma nostrip
+*/
+
+void Starfield::Register(sol::table& parent)
+{
+ using ctors = sol::constructors;
+ parent.new_usertype("Starfield",
+ ctors(),
+ sol::call_constructor, ctors(),
+
+ /*** (int) Stars count.
+
+ Values can be between [0, 6000], 0 resulting in no stars being rendered, and 6000 resulting in the maximum number of stars being rendered.
+
+ @mem starsCount*/
+ "starsCount", sol::property(&Starfield::GetStarsCount, &Starfield::SetStarsCount),
+
+ /*** (int) Meteors count.
+
+ Values can be between [0, 100], 0 resulting in no meteors being rendered, and 100 resulting in the maximum number of meteors being rendered.
+
+ @mem meteorsCount*/
+ "meteorsCount", sol::property(&Starfield::GetMeteorsCount, &Starfield::SetMeteorsCount),
+
+ /*** (int) Meteors spawn density.
+
+ @mem meteorsSpawnDensity*/
+ "meteorsSpawnDensity", sol::property(&Starfield::GetMeteorsSpawnDensity, &Starfield::SetMeteorsSpawnDensity),
+
+ /*** (float) Meteors speed.
+
+ @mem meteorsSpeed*/
+ "meteorsSpeed", sol::property(&Starfield::GetMeteorsSpeed, &Starfield::SetMeteorsSpeed)
+ );
+}
+
+/***
+@tparam int starsCount Stars count
+@treturn Starfield A starfield object with only stars enabled.
+@function Starfield
+*/
+Starfield::Starfield(int starsCount)
+{
+ SetStarsCount(starsCount);
+ SetMeteorsCount(0);
+}
+
+/***
+@tparam int starsCount Stars count
+@tparam int meteorsCount Stars count
+@treturn Starfield A starfield object with boths stars and meteors enabled.
+@function Starfield
+*/
+Starfield::Starfield(int starsCount, int meteorsCount, int meteorsSpawnDensity, int meteorsSpawnSpeed)
+{
+ SetStarsCount(starsCount);
+ SetMeteorsCount(meteorsCount);
+ SetMeteorsSpawnDensity(meteorsSpawnDensity);
+ SetMeteorsSpeed(meteorsSpawnSpeed);
+}
+
+void Starfield::SetStarsCount(int const& starsCount)
+{
+ assertion(starsCount >= 0 && starsCount <= 6000, "Stars count must be in the range 0 ... 6000");
+ StarsCount = starsCount;
+}
+
+
+int Starfield::GetStarsCount() const
+{
+ return StarsCount;
+}
+
+void Starfield::SetMeteorsCount(int const& meteorsCount)
+{
+ assertion(meteorsCount >= 0 && meteorsCount <= 100, "Stars count must be in the range 0 ... 100");
+ MeteorsCount = meteorsCount;
+}
+
+
+int Starfield::GetMeteorsCount() const
+{
+ return MeteorsCount;
+}
+
+void Starfield::SetMeteorsSpawnDensity(int const& meteorsSpawnDensity)
+{
+ MeteorsSpawnDensity = meteorsSpawnDensity;
+}
+
+
+int Starfield::GetMeteorsSpawnDensity() const
+{
+ return MeteorsSpawnDensity;
+}
+
+void Starfield::SetMeteorsSpeed(float const& meteorsSpeed)
+{
+ MeteorsSpeed = meteorsSpeed;
+}
+
+
+float Starfield::GetMeteorsSpeed() const
+{
+ return MeteorsSpeed;
+}
+
+bool Starfield::GetEnabled() const
+{
+ return (StarsCount > 0);
+}
+
+bool Starfield::GetMeteorsEnabled() const
+{
+ return (MeteorsCount > 0);
+}
\ No newline at end of file
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.h b/TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.h
new file mode 100644
index 000000000..4144bb516
--- /dev/null
+++ b/TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.h
@@ -0,0 +1,36 @@
+#pragma once
+
+#include "Scripting/Internal/TEN/Color/Color.h"
+#include "Scripting/Internal/TEN/Vec2/Vec2.h"
+
+namespace sol { class state; }
+
+struct Starfield
+{
+ int StarsCount = 0; // No need for StarryNight flag, if stars count = 0, shader is bypassed
+
+ int MeteorsCount = 0; // No need for EnableMeteors flag, if meteors count = 0, shader is bypassed
+ int MeteorsSpawnDensity = 0;
+ int MeteorsSpeed = 0;
+
+ Starfield() = default;
+ Starfield(int starsCount);
+ Starfield(int starsCount, int meteorsCount, int meteorsSpawnDensity, int meteorsSpeed);
+
+ void SetStarsCount(int const& starsCount);
+ int GetStarsCount() const;
+
+ void SetMeteorsCount(int const& meteorsCount);
+ int GetMeteorsCount() const;
+
+ void SetMeteorsSpawnDensity(int const& spawnDensity);
+ int GetMeteorsSpawnDensity() const;
+
+ void SetMeteorsSpeed(float const& meteorsSpeed);
+ float GetMeteorsSpeed() const;
+
+ bool GetEnabled() const;
+ bool GetMeteorsEnabled() const;
+
+ static void Register(sol::table&);
+};
\ No newline at end of file
diff --git a/TombEngine/Shaders/CBPostProcess.hlsli b/TombEngine/Shaders/CBPostProcess.hlsli
index dfe6f2514..f31a7d75f 100644
--- a/TombEngine/Shaders/CBPostProcess.hlsli
+++ b/TombEngine/Shaders/CBPostProcess.hlsli
@@ -3,7 +3,10 @@
struct ShaderLensFlare
{
float3 Position;
- float Padding;
+ float Padding1;
+ //--
+ float3 Color;
+ float Padding2;
};
cbuffer CBPostProcess : register(b7)
diff --git a/TombEngine/Shaders/PostProcess.fx b/TombEngine/Shaders/PostProcess.fx
index 1fa91fb39..3d7b7b786 100644
--- a/TombEngine/Shaders/PostProcess.fx
+++ b/TombEngine/Shaders/PostProcess.fx
@@ -102,9 +102,9 @@ float3 LensFlare(float2 uv, float2 pos)
float f1 = max(0.01f - pow(length(uv + 1.2f * pos), 1.9f), 0.0f) * 7.0f;
- float f2 = max(1.0f / (1.0f + 32.0f * pow(length(uvd + 0.8f * pos), 2.0f)), 0.0f) * 00.1f;
- float f22 = max(1.0f / (1.0f + 32.0f * pow(length(uvd + 0.85f * pos), 2.0f)), 0.0f) * 00.08f;
- float f23 = max(1.0f / (1.0f + 32.0f * pow(length(uvd + 0.9f * pos), 2.0f)), 0.0f) * 00.06f;
+ float f2 = max(1.0f / (1.0f + 32.0f * pow(length(uvd + 0.8f * pos), 2.0f)), 0.0f) * 0.1f;
+ float f22 = max(1.0f / (1.0f + 32.0f * pow(length(uvd + 0.85f * pos), 2.0f)), 0.0f) * 0.08f;
+ float f23 = max(1.0f / (1.0f + 32.0f * pow(length(uvd + 0.9f * pos), 2.0f)), 0.0f) * 0.06f;
float2 uvx = lerp(uv, uvd, -0.5f);
@@ -154,7 +154,10 @@ float4 PSLensFlare(PixelShaderInput input) : SV_Target
lensFlarePosition = mul(mul(lensFlarePosition, View), Projection);
lensFlarePosition.xyz /= lensFlarePosition.w;
- float3 lensFlareColor = max(float3(0.0f, 0.0f, 0.0f), float3(4.5f, 3.6f, 3.6f) * LensFlare(position.xy, lensFlarePosition.xy));
+ float3 lensFlareColor = max(float3(0.0f, 0.0f, 0.0f),
+ LensFlares[i].Color *
+ float3(4.5f, 3.6f, 3.6f) *
+ LensFlare(position.xy, lensFlarePosition.xy));
lensFlareColor = LensFlareColorCorrection(lensFlareColor, 0.5f, 0.1f);
totalLensFlareColor += lensFlareColor;
}
diff --git a/TombEngine/TombEngine.vcxproj b/TombEngine/TombEngine.vcxproj
index 6464b9af8..e734a2fb8 100644
--- a/TombEngine/TombEngine.vcxproj
+++ b/TombEngine/TombEngine.vcxproj
@@ -1,4 +1,4 @@
-
+
@@ -777,10 +777,12 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
+
+
@@ -1208,10 +1210,12 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
+
+
From b3f8261c9bf7ea252e23358af5d6d29ef34dc0f5 Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Sun, 28 Apr 2024 11:07:03 +0200
Subject: [PATCH 112/410] Fix sound update
---
TombEngine/Game/control/control.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index 629ab4e9a..e4b7ecd8f 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -270,6 +270,7 @@ GameStatus ControlPhase(int numFrames)
RumbleScreen();
PlaySoundSources();
+ Sound_UpdateScene();
DoFlipEffect(FlipEffect, LaraItem);
// Post-loop script and event handling.
@@ -661,8 +662,6 @@ GameStatus DoGameLoop(int levelIndex)
float interpolateFactor = std::min((float)controlLag / (float)controlFrameTime, 1.0f);
DrawPhase(!levelIndex, interpolateFactor);
drawCalls++;
-
- Sound_UpdateScene();
}
EndGameLoop(levelIndex, status);
From 6e551b97df1f6080f8e8df7f15efde4a723628eb Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Sun, 28 Apr 2024 13:54:16 +0200
Subject: [PATCH 113/410] Make some order in renderer functions, fix flickering
user strings and sprites
---
TombEngine/Game/control/control.cpp | 11 +++++------
TombEngine/Renderer/Renderer.cpp | 10 ----------
TombEngine/Renderer/Renderer.h | 2 +-
TombEngine/Renderer/RendererDraw.cpp | 25 +++++++++++++++----------
TombEngine/Renderer/RendererString.cpp | 3 ---
5 files changed, 21 insertions(+), 30 deletions(-)
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index e4b7ecd8f..5712c6f08 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -126,9 +126,6 @@ int DrawPhase(bool isTitle, float interpolateFactor)
g_Renderer.Render(interpolateFactor);
}
- // Clear display sprites.
- ClearDisplaySprites();
-
//Camera.numberFrames = g_Renderer.Synchronize();
return Camera.numberFrames;
}
@@ -139,10 +136,11 @@ GameStatus ControlPhase(int numFrames)
bool isTitle = (CurrentLevel == 0);
- ClearFires();
- g_Renderer.ClearDynamicLights();
+ g_Renderer.PrepareScene();
RegeneratePickups();
+ ClearFires();
ClearLensFlares();
+ ClearDisplaySprites();
numFrames = std::clamp(numFrames, 0, 10);
@@ -270,9 +268,10 @@ GameStatus ControlPhase(int numFrames)
RumbleScreen();
PlaySoundSources();
- Sound_UpdateScene();
DoFlipEffect(FlipEffect, LaraItem);
+ Sound_UpdateScene();
+
// Post-loop script and event handling.
g_GameScript->OnLoop(DELTA_TIME, true);
diff --git a/TombEngine/Renderer/Renderer.cpp b/TombEngine/Renderer/Renderer.cpp
index 3b6b4d87e..144eb2542 100644
--- a/TombEngine/Renderer/Renderer.cpp
+++ b/TombEngine/Renderer/Renderer.cpp
@@ -34,8 +34,6 @@ namespace TEN::Renderer
{
_shadowLight = nullptr;
- ClearSceneItems();
-
_moveableObjects.resize(0);
_staticObjects.resize(0);
_sprites.resize(0);
@@ -60,14 +58,6 @@ namespace TEN::Renderer
}
}
- void Renderer::ClearSceneItems()
- {
- _lines2DToDraw.clear();
- _lines3DToDraw.clear();
- _triangles3DToDraw.clear();
- _gameCamera.Clear();
- }
-
void Renderer::Lock()
{
_isLocked = true;
diff --git a/TombEngine/Renderer/Renderer.h b/TombEngine/Renderer/Renderer.h
index f84914316..2154befb1 100644
--- a/TombEngine/Renderer/Renderer.h
+++ b/TombEngine/Renderer/Renderer.h
@@ -598,6 +598,7 @@ namespace TEN::Renderer
void DumpGameScene();
void RenderInventory();
void RenderScene(RenderTarget2D* renderTarget, bool doAntialiasing, RenderView& view);
+ void PrepareScene();
void ClearScene();
void SaveScreenshot();
void PrintDebugMessage(LPCSTR message, ...);
@@ -616,7 +617,6 @@ namespace TEN::Renderer
void SetFullScreen();
bool IsFullsScreen();
void RenderTitleImage();
- void ClearDynamicLights();
void AddLine2D(const Vector2& origin, const Vector2& target, const Color& color, RendererDebugPage page = RendererDebugPage::None);
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index 6c110c6cc..736eaac32 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -1627,22 +1627,26 @@ namespace TEN::Renderer
_dynamicLights.push_back(dynamicLight);
}
- void Renderer::ClearDynamicLights()
+ void Renderer::PrepareScene()
{
_dynamicLights.clear();
- }
-
- void Renderer::ClearScene()
- {
- ResetAnimations();
-
- ClearSceneItems();
- ClearShadowMap();
+ _lines2DToDraw.clear();
+ _lines3DToDraw.clear();
+ _triangles3DToDraw.clear();
+ _stringsToDraw.clear();
_currentCausticsFrame++;
_currentCausticsFrame %= 32;
- CalculateFrameRate();
+ _isBlinkUpdated = false;
+ }
+
+ void Renderer::ClearScene()
+ {
+ _gameCamera.Clear();
+
+ ResetAnimations();
+ ClearShadowMap();
}
void Renderer::RenderScene(RenderTarget2D* renderTarget, bool doAntialiasing, RenderView& view)
@@ -1934,6 +1938,7 @@ namespace TEN::Renderer
DrawAllStrings();
ClearScene();
+ CalculateFrameRate();
}
void Renderer::RenderSimpleSceneToParaboloid(RenderTarget2D* renderTarget, Vector3 position, int emisphere)
diff --git a/TombEngine/Renderer/RendererString.cpp b/TombEngine/Renderer/RendererString.cpp
index b26196f44..1aacef836 100644
--- a/TombEngine/Renderer/RendererString.cpp
+++ b/TombEngine/Renderer/RendererString.cpp
@@ -127,8 +127,5 @@ namespace TEN::Renderer
}
_spriteBatch->End();
-
- _isBlinkUpdated = false;
- _stringsToDraw.clear();
}
}
From 08ca9bacef86fe7f1f422f86754bdf3956ab4e4d Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Sun, 28 Apr 2024 13:59:56 +0200
Subject: [PATCH 114/410] Update Renderer.h
---
TombEngine/Renderer/Renderer.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/TombEngine/Renderer/Renderer.h b/TombEngine/Renderer/Renderer.h
index 2154befb1..9a2f37bd5 100644
--- a/TombEngine/Renderer/Renderer.h
+++ b/TombEngine/Renderer/Renderer.h
@@ -407,7 +407,6 @@ namespace TEN::Renderer
void CollectLightsForCamera();
void CalculateLightFades(RendererItem* item);
void CollectEffects(short roomNumber);
- void ClearSceneItems();
void ClearShadowMap();
void CalculateSSAO(RenderView& view);
void UpdateItemAnimations(RenderView& view);
From f2a55eec8b940443b8b7d5686f88a33244642965 Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Sun, 28 Apr 2024 15:18:24 +0200
Subject: [PATCH 115/410] Fix double-draw in menus and title flyby
---
TombEngine/Game/control/control.cpp | 86 ++++++++++----------------
TombEngine/Game/gui.cpp | 3 +
TombEngine/Renderer/Renderer.h | 3 +-
TombEngine/Renderer/RendererDraw.cpp | 16 ++++-
TombEngine/Renderer/RendererString.cpp | 17 -----
5 files changed, 49 insertions(+), 76 deletions(-)
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index 5712c6f08..3528c0528 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -126,14 +126,17 @@ int DrawPhase(bool isTitle, float interpolateFactor)
g_Renderer.Render(interpolateFactor);
}
+ g_Renderer.Lock();
+
//Camera.numberFrames = g_Renderer.Synchronize();
return Camera.numberFrames;
}
GameStatus ControlPhase(int numFrames)
{
- auto time1 = std::chrono::high_resolution_clock::now();
+ static int framesCount = 0;
+ auto time1 = std::chrono::high_resolution_clock::now();
bool isTitle = (CurrentLevel == 0);
g_Renderer.PrepareScene();
@@ -152,9 +155,6 @@ GameStatus ControlPhase(int numFrames)
g_GameStringsHandler->ProcessDisplayStrings(DELTA_TIME);
- bool isFirstTime = true;
- static int framesCount = 0;
-
// Save current state to old variables for interpolation
SaveOldState();
g_Renderer.SaveOldState();
@@ -282,13 +282,6 @@ GameStatus ControlPhase(int numFrames)
GameTimer++;
GlobalCounter++;
- // Add renderer objects on the first processed frame.
- if (isFirstTime)
- {
- g_Renderer.Lock();
- isFirstTime = false;
- }
-
using ns = std::chrono::nanoseconds;
using get_time = std::chrono::steady_clock;
@@ -622,41 +615,8 @@ GameStatus DoGameLoop(int levelIndex)
controlCalls++;
}
- if (!levelIndex)
- {
- UpdateInputActions(LaraItem);
-
- auto invStatus = g_Gui.TitleOptions(LaraItem);
-
- switch (invStatus)
- {
- case InventoryResult::NewGame:
- case InventoryResult::NewGameSelectedLevel:
- status = GameStatus::NewGame;
- break;
-
- case InventoryResult::LoadGame:
- status = GameStatus::LoadGame;
- break;
-
- case InventoryResult::ExitGame:
- status = GameStatus::ExitGame;
- break;
- }
-
- if (invStatus != InventoryResult::None)
- break;
- }
- else
- {
- if (status == GameStatus::ExitToTitle ||
- status == GameStatus::LaraDead ||
- status == GameStatus::LoadGame ||
- status == GameStatus::LevelComplete)
- {
- break;
- }
- }
+ if (status != GameStatus::Normal)
+ break;
float interpolateFactor = std::min((float)controlLag / (float)controlFrameTime, 1.0f);
DrawPhase(!levelIndex, interpolateFactor);
@@ -686,24 +646,40 @@ void SaveOldState()
void HandleControls(bool isTitle)
{
// Poll input devices and update input variables.
- if (!isTitle)
- {
- // TODO: To allow cutscene skipping later, don't clear Deselect action.
- UpdateInputActions(LaraItem, true);
- }
- else
- {
+ // TODO: To allow cutscene skipping later, don't clear Deselect action.
+ UpdateInputActions(LaraItem, true);
+
+ if (isTitle)
ClearAction(In::Look);
- }
}
GameStatus HandleMenuCalls(bool isTitle)
{
auto result = GameStatus::Normal;
- if (isTitle || ScreenFading)
+ if (ScreenFading)
return result;
+ if (isTitle)
+ {
+ auto invStatus = g_Gui.TitleOptions(LaraItem);
+
+ switch (invStatus)
+ {
+ case InventoryResult::NewGame:
+ case InventoryResult::NewGameSelectedLevel:
+ return GameStatus::NewGame;
+
+ case InventoryResult::LoadGame:
+ return GameStatus::LoadGame;
+
+ case InventoryResult::ExitGame:
+ return GameStatus::ExitGame;
+ }
+
+ return result;
+ }
+
// Does the player want to enter inventory?
if (IsClicked(In::Save) && LaraItem->HitPoints > 0 &&
g_Gui.GetInventoryMode() != InventoryMode::Save &&
diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp
index a283317e2..51332bd7c 100644
--- a/TombEngine/Game/gui.cpp
+++ b/TombEngine/Game/gui.cpp
@@ -274,7 +274,9 @@ namespace TEN::Gui
void GuiController::DrawInventory()
{
+ g_Renderer.PrepareScene();
g_Renderer.RenderInventory();
+ g_Renderer.Lock(); // TODO: When inventory is converted to 60 FPS, move this lock call outside of render loop.
}
InventoryResult GuiController::TitleOptions(ItemInfo* item)
@@ -3374,6 +3376,7 @@ namespace TEN::Gui
UseItem(*item, InventoryObjectTable[LastInvItem].ObjectNumber);
AlterFOV(LastFOV);
+ g_Renderer.PrepareScene();
ResumeAllSounds(SoundPauseMode::Inventory);
lara->Inventory.IsBusy = lara->Inventory.OldBusy;
diff --git a/TombEngine/Renderer/Renderer.h b/TombEngine/Renderer/Renderer.h
index 9a2f37bd5..8a4dad0b6 100644
--- a/TombEngine/Renderer/Renderer.h
+++ b/TombEngine/Renderer/Renderer.h
@@ -202,7 +202,6 @@ namespace TEN::Renderer
std::vector _stringsToDraw;
float _blinkColorValue = 0.0f;
float _blinkTime = 0.0f;
- bool _isBlinkUpdated = false;
// Graphics resources
Texture2D _logo;
@@ -309,7 +308,7 @@ namespace TEN::Renderer
bool _isWindowed;
float _farView = DEFAULT_FAR_VIEW;
- // A flag to prevent extra renderer object addition
+ // A flag to prevent extra renderer object additions
bool _isLocked = false;
// Caching state changes
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index 736eaac32..cf23ac649 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -1638,7 +1638,19 @@ namespace TEN::Renderer
_currentCausticsFrame++;
_currentCausticsFrame %= 32;
- _isBlinkUpdated = false;
+ constexpr auto BLINK_VALUE_MAX = 1.0f;
+ constexpr auto BLINK_VALUE_MIN = 0.1f;
+ constexpr auto BLINK_TIME_STEP = 0.2f;
+
+ // Calculate blink increment based on sine wave.
+ _blinkColorValue = ((sin(_blinkTime) + BLINK_VALUE_MAX) * 0.5f) + BLINK_VALUE_MIN;
+
+ // Update blink time.
+ _blinkTime += BLINK_TIME_STEP;
+ if (_blinkTime > PI_MUL_2)
+ _blinkTime -= PI_MUL_2;
+
+ _isLocked = false;
}
void Renderer::ClearScene()
@@ -1655,7 +1667,6 @@ namespace TEN::Renderer
using get_time = std::chrono::steady_clock;
ResetDebugVariables();
- _isLocked = false;
_doingFullscreenPass = false;
auto& level = *g_GameFlow->GetLevel(CurrentLevel);
@@ -3098,6 +3109,7 @@ namespace TEN::Renderer
//_gameCamera = _currentGameCamera;
RenderScene(&_backBuffer, true, _gameCamera);
+
_context->ClearState();
_swapChain->Present(1, 0);
}
diff --git a/TombEngine/Renderer/RendererString.cpp b/TombEngine/Renderer/RendererString.cpp
index 1aacef836..3f8325389 100644
--- a/TombEngine/Renderer/RendererString.cpp
+++ b/TombEngine/Renderer/RendererString.cpp
@@ -22,10 +22,6 @@ namespace TEN::Renderer
void Renderer::AddString(const std::string& string, const Vector2& pos, const Color& color, float scale, int flags)
{
- constexpr auto BLINK_VALUE_MAX = 1.0f;
- constexpr auto BLINK_VALUE_MIN = 0.1f;
- constexpr auto BLINK_TIME_STEP = 0.2f;
-
if (_isLocked)
return;
@@ -75,19 +71,6 @@ namespace TEN::Renderer
if (flags & (int)PrintStringFlags::Blink)
{
rString.Color *= _blinkColorValue;
-
- if (!_isBlinkUpdated)
- {
- // Calculate blink increment based on sine wave.
- _blinkColorValue = ((sin(_blinkTime) + BLINK_VALUE_MAX) * 0.5f) + BLINK_VALUE_MIN;
-
- // Update blink time.
- _blinkTime += BLINK_TIME_STEP;
- if (_blinkTime > PI_MUL_2)
- _blinkTime -= PI_MUL_2;
-
- _isBlinkUpdated = true;
- }
}
yOffset += size.y;
From 33807e8198a4cc0504694089c5c5a3ae34f943cd Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Sun, 28 Apr 2024 15:51:51 +0200
Subject: [PATCH 116/410] Remove locked flag checks from internal renderer
sprite methods
---
TombEngine/Renderer/RendererSprites.cpp | 15 ---------------
1 file changed, 15 deletions(-)
diff --git a/TombEngine/Renderer/RendererSprites.cpp b/TombEngine/Renderer/RendererSprites.cpp
index b969a0efe..28d3cc8ad 100644
--- a/TombEngine/Renderer/RendererSprites.cpp
+++ b/TombEngine/Renderer/RendererSprites.cpp
@@ -10,9 +10,6 @@ namespace TEN::Renderer
void Renderer::AddSpriteBillboard(RendererSprite* sprite, const Vector3& pos, const Vector4& color, float orient2D, float scale,
Vector2 size, BlendMode blendMode, bool isSoftParticle, RenderView& view, SpriteRenderType renderType)
{
- if (_isLocked)
- return;
-
if (scale <= 0.0f)
scale = 1.0f;
@@ -44,9 +41,6 @@ namespace TEN::Renderer
float scale, Vector2 size, BlendMode blendMode, const Vector3& constrainAxis,
bool softParticles, RenderView& view, SpriteRenderType renderType)
{
- if (_isLocked)
- return;
-
if (scale <= 0.0f)
scale = 1.0f;
@@ -79,9 +73,6 @@ namespace TEN::Renderer
float scale, Vector2 size, BlendMode blendMode, const Vector3& lookAtAxis,
bool isSoftParticle, RenderView& view, SpriteRenderType renderType)
{
- if (_isLocked)
- return;
-
if (scale <= 0.0f)
scale = 1.0f;
@@ -121,9 +112,6 @@ namespace TEN::Renderer
const Vector4& color0, const Vector4& color1, const Vector4& color2, const Vector4& color3, float orient2D,
float scale, Vector2 size, BlendMode blendMode, bool isSoftParticle, RenderView& view, SpriteRenderType renderType)
{
- if (_isLocked)
- return;
-
if (scale <= 0.0f)
scale = 1.0f;
@@ -164,9 +152,6 @@ namespace TEN::Renderer
const Vector4& color0, const Vector4& color1, const Vector4& color2, const Vector4& color3,
BlendMode blendMode, RenderView& view, SpriteRenderType renderType)
{
- if (_isLocked)
- return;
-
auto sprite = RendererSpriteToDraw{};
sprite.Type = SpriteType::ThreeD;
From 77cd0644f76f587e9554f4e521e588bb4a1b20f7 Mon Sep 17 00:00:00 2001
From: Joey Quint
Date: Sun, 28 Apr 2024 22:05:58 +0200
Subject: [PATCH 117/410] Fixed camera rotating with Lara's hips when climbing
out of water - fixes #1311
---
Documentation/Changes.txt | 1 +
TombEngine/Game/Lara/lara_surface.cpp | 3 +--
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Documentation/Changes.txt b/Documentation/Changes.txt
index 035d60ef2..08900121d 100644
--- a/Documentation/Changes.txt
+++ b/Documentation/Changes.txt
@@ -3,6 +3,7 @@ Version 1.5
* Fixed original issue with classic switch off trigger wrongly activating some trigger actions.
* Fixed incorrect diving animation when swandiving from a high place.
+* Fixed camera rotating with Lara's hips when climbing out of water.
* Fixed AI for skidoo driver and worker with shotgun TR2 enemies.
Lua API changes:
diff --git a/TombEngine/Game/Lara/lara_surface.cpp b/TombEngine/Game/Lara/lara_surface.cpp
index c79e89cd3..9ec72f52f 100644
--- a/TombEngine/Game/Lara/lara_surface.cpp
+++ b/TombEngine/Game/Lara/lara_surface.cpp
@@ -273,6 +273,5 @@ void lara_as_surface_climb_out(ItemInfo* item, CollisionInfo* coll)
player.Control.Look.Mode = LookMode::None;
coll->Setup.EnableObjectPush = false;
coll->Setup.EnableSpasm = false;
- Camera.flags = CF_FOLLOW_CENTER;
- Camera.laraNode = LM_HIPS; // Forces the camera to follow Lara instead of snapping.
+ Camera.flags = CF_FOLLOW_CENTER; // Forces the camera to follow Lara instead of snapping.
}
From f5adbec7c88074213610f1695f216fa80c87e655 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Mon, 29 Apr 2024 05:18:11 +0200
Subject: [PATCH 118/410] Added DisableInterpolation flag for items; Fixed
shaders;
---
TombEngine/Game/animation.cpp | 2 ++
TombEngine/Game/control/control.cpp | 9 ++++---
TombEngine/Game/control/control.h | 2 +-
TombEngine/Game/control/flipeffect.cpp | 2 ++
TombEngine/Game/items.h | 2 ++
TombEngine/Renderer/Renderer.h | 2 +-
TombEngine/Renderer/RendererDraw.cpp | 25 +++----------------
TombEngine/Renderer/RendererFrame.cpp | 19 +++++++++++---
.../TEN/Objects/Moveable/MoveableObject.cpp | 4 +++
TombEngine/Shaders/CBCamera.hlsli | 7 +++++-
TombEngine/Shaders/ShaderLight.hlsli | 1 +
11 files changed, 44 insertions(+), 31 deletions(-)
diff --git a/TombEngine/Game/animation.cpp b/TombEngine/Game/animation.cpp
index 3003f6292..823c67cbf 100644
--- a/TombEngine/Game/animation.cpp
+++ b/TombEngine/Game/animation.cpp
@@ -60,6 +60,8 @@ static void PerformAnimCommands(ItemInfo& item, bool isFrameBased)
{
UpdateItemRoom(item.Index);
}
+
+ item.DisableInterpolation = true;
}
commandDataPtr += 3;
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index 629ab4e9a..72a7dec23 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -158,7 +158,7 @@ GameStatus ControlPhase(int numFrames)
static int framesCount = 0;
// Save current state to old variables for interpolation
- SaveOldState();
+ SetupInterpolation();
g_Renderer.SaveOldState();
// Controls are polled before OnLoop, so input data could be
@@ -680,9 +680,12 @@ void EndGameLoop(int levelIndex, GameStatus reason)
StopRumble();
}
-void SaveOldState()
+void SetupInterpolation()
{
-
+ for (int i = 0; i < g_Level.Items.size(); i++)
+ {
+ g_Level.Items[i].DisableInterpolation = false;
+ }
}
void HandleControls(bool isTitle)
diff --git a/TombEngine/Game/control/control.h b/TombEngine/Game/control/control.h
index c8191810d..b9b8b78d2 100644
--- a/TombEngine/Game/control/control.h
+++ b/TombEngine/Game/control/control.h
@@ -105,6 +105,6 @@ void InitializeOrLoadGame(bool loadGame);
void InitializeScripting(int levelIndex, LevelLoadType type);
void DeInitializeScripting(int levelIndex);
-void SaveOldState();
+void SetupInterpolation();
unsigned CALLBACK GameMain(void*);
diff --git a/TombEngine/Game/control/flipeffect.cpp b/TombEngine/Game/control/flipeffect.cpp
index b128351a8..76ccbeba5 100644
--- a/TombEngine/Game/control/flipeffect.cpp
+++ b/TombEngine/Game/control/flipeffect.cpp
@@ -331,6 +331,8 @@ void Turn180(ItemInfo* item)
item->Pose.Orientation.x = -item->Pose.Orientation.x;
item->Pose.Orientation.y += ANGLE(180.0f);
item->Pose.Orientation.z = -item->Pose.Orientation.z;
+
+ item->DisableInterpolation = true;
}
void FinishLevel(ItemInfo* item)
diff --git a/TombEngine/Game/items.h b/TombEngine/Game/items.h
index 9e0faed69..86c4045ff 100644
--- a/TombEngine/Game/items.h
+++ b/TombEngine/Game/items.h
@@ -174,6 +174,8 @@ struct ItemInfo
bool IsCreature() const;
bool IsBridge() const;
+ bool DisableInterpolation = false;
+
void StoreInterpolationData()
{
OldPose = Pose;
diff --git a/TombEngine/Renderer/Renderer.h b/TombEngine/Renderer/Renderer.h
index f84914316..7988baced 100644
--- a/TombEngine/Renderer/Renderer.h
+++ b/TombEngine/Renderer/Renderer.h
@@ -502,7 +502,7 @@ namespace TEN::Renderer
void SetScissor(RendererRectangle rectangle);
bool SetupBlendModeAndAlphaTest(BlendMode blendMode, RendererPass rendererPass, int drawPass);
void SortAndPrepareSprites(RenderView& view);
- void ResetAnimations();
+ void ResetItems();
void ResetScissor();
void ResetDebugVariables();
float CalculateFrameRate();
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index 6c110c6cc..30008a2d6 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -1634,7 +1634,7 @@ namespace TEN::Renderer
void Renderer::ClearScene()
{
- ResetAnimations();
+ ResetItems();
ClearSceneItems();
ClearShadowMap();
@@ -3057,26 +3057,7 @@ namespace TEN::Renderer
{
//RenderToCubemap(reflectionCubemap, Vector3(LaraItem->pos.xPos, LaraItem->pos.yPos - 1024, LaraItem->pos.zPos), LaraItem->roomNumber);
- /*RenderView oldCamera = RenderView(
- &PreviousCamera,
- 0,
- TO_RAD(CurrentFOV / 1.333333f) ,
- 32, 100*1024, g_Configuration.ScreenWidth, g_Configuration.ScreenHeight);
-
- RenderView newCamera = RenderView(
- &Camera,
- 0,
- TO_RAD(CurrentFOV / 1.333333f),
- 32, 100 * 1024, g_Configuration.ScreenWidth, g_Configuration.ScreenHeight);
-
- _gameCamera.Camera = oldCamera.Camera;
- _gameCamera.Camera.WorldPosition = Vector3::Lerp(oldCamera.Camera.WorldPosition, newCamera.Camera.WorldPosition, interpolateFactor);
- _gameCamera.Camera.WorldDirection = Vector3::Lerp(oldCamera.Camera.WorldDirection, newCamera.Camera.WorldDirection, interpolateFactor);
- _gameCamera.Camera.View = Matrix::Lerp(oldCamera.Camera.View, newCamera.Camera.View, interpolateFactor);
- _gameCamera.Camera.Projection = Matrix::Lerp(oldCamera.Camera.Projection, newCamera.Camera.Projection, interpolateFactor);
- _gameCamera.Camera.View = _gameCamera.Camera.View * _gameCamera.Camera.Projection;
-*/
-
+ // Interpolate camera
_gameCamera.Camera.WorldPosition = Vector3::Lerp(_oldGameCamera.Camera.WorldPosition, _currentGameCamera.Camera.WorldPosition, interpolateFactor);
_gameCamera.Camera.WorldDirection = Vector3::Lerp(_oldGameCamera.Camera.WorldDirection, _currentGameCamera.Camera.WorldDirection, interpolateFactor);
_gameCamera.Camera.View = Matrix::Lerp(_oldGameCamera.Camera.View, _currentGameCamera.Camera.View, interpolateFactor);
@@ -3091,8 +3072,8 @@ namespace TEN::Renderer
_interpolationFactor = interpolateFactor;
- //_gameCamera = _currentGameCamera;
RenderScene(&_backBuffer, true, _gameCamera);
+
_context->ClearState();
_swapChain->Present(1, 0);
}
diff --git a/TombEngine/Renderer/RendererFrame.cpp b/TombEngine/Renderer/RendererFrame.cpp
index e552f5772..3c8171dd5 100644
--- a/TombEngine/Renderer/RendererFrame.cpp
+++ b/TombEngine/Renderer/RendererFrame.cpp
@@ -420,7 +420,7 @@ namespace TEN::Renderer
// Blow up sphere radius by half for cases of too small calculated spheres.
if (renderView.Camera.Frustum.SphereInFrustum(spheres[i].Center, spheres[i].Radius * 1.5f))
inFrustum = true;
-
+
if (!inFrustum)
continue;
}
@@ -436,12 +436,23 @@ namespace TEN::Renderer
newItem->Scale = Matrix::CreateScale(1.0f);
newItem->World = newItem->Rotation * newItem->Translation;
+ if (item->DisableInterpolation)
+ {
+ // In this way the interpolation will return always the same result
+ newItem->OldPosition = newItem->Position;
+ newItem->OldTranslation = newItem->Translation;
+ newItem->OldRotation = newItem->Rotation;
+ newItem->OldWorld = newItem->World;
+ for (int j = 0; j < MAX_BONES; j++)
+ newItem->OldAnimationTransforms[j] = newItem->AnimationTransforms[j];
+ }
+
newItem->InterpolatedPosition = Vector3::Lerp(newItem->OldPosition, newItem->Position, _interpolationFactor);
newItem->InterpolatedTranslation = Matrix::Lerp(newItem->OldTranslation, newItem->Translation, _interpolationFactor);
newItem->InterpolatedRotation = Matrix::Lerp(newItem->InterpolatedRotation, newItem->Rotation, _interpolationFactor);
newItem->InterpolatedWorld = Matrix::Lerp(newItem->OldWorld, newItem->World, _interpolationFactor);
for (int j = 0; j < MAX_BONES; j++)
- newItem->InterpolatedAnimationTransforms[j] = Matrix::Lerp(newItem->OldAnimationTransforms[j], newItem->AnimationTransforms[j], _interpolationFactor);
+ newItem->InterpolatedAnimationTransforms[j] = Matrix::Lerp(newItem->OldAnimationTransforms[j], newItem->AnimationTransforms[j], _interpolationFactor);
CalculateLightFades(newItem);
CollectLightsForItem(newItem);
@@ -884,10 +895,12 @@ namespace TEN::Renderer
}
}
- void Renderer::ResetAnimations()
+ void Renderer::ResetItems()
{
for (int i = 0; i < ITEM_COUNT_MAX; i++)
+ {
_items[i].DoneAnimations = false;
+ }
}
diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp
index 76610d3f1..4e5a62952 100644
--- a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp
@@ -601,6 +601,8 @@ void Moveable::SetPos(const Vec3& pos, sol::optional updateRoom)
if (m_item->IsBridge())
UpdateBridgeItem(*m_item);
+
+ m_item->DisableInterpolation = true;
}
Vec3 Moveable::GetJointPos(int jointIndex) const
@@ -631,6 +633,8 @@ void Moveable::SetRot(const Rotation& rot)
if (m_item->IsBridge())
UpdateBridgeItem(*m_item);
+
+ m_item->DisableInterpolation = true;
}
short Moveable::GetHP() const
diff --git a/TombEngine/Shaders/CBCamera.hlsli b/TombEngine/Shaders/CBCamera.hlsli
index ff1f232db..85dc4ac3d 100644
--- a/TombEngine/Shaders/CBCamera.hlsli
+++ b/TombEngine/Shaders/CBCamera.hlsli
@@ -1,3 +1,6 @@
+#ifndef CBCAMERASHADER
+#define CBCAMERASHADER
+
#include "./Math.hlsli"
cbuffer CBCamera : register(b0)
@@ -34,4 +37,6 @@ cbuffer CBCamera : register(b0)
float3 Padding2;
//--
ShaderFogBulb FogBulbs[MAX_FOG_BULBS];
-};
\ No newline at end of file
+};
+
+#endif
\ No newline at end of file
diff --git a/TombEngine/Shaders/ShaderLight.hlsli b/TombEngine/Shaders/ShaderLight.hlsli
index eae69ab08..64c47f13e 100644
--- a/TombEngine/Shaders/ShaderLight.hlsli
+++ b/TombEngine/Shaders/ShaderLight.hlsli
@@ -1,6 +1,7 @@
#ifndef SHADER_LIGHT
#define SHADER_LIGHT
+#include "./CBCamera.hlsli"
#include "./Math.hlsli"
float3 DoSpecularPoint(float3 pos, float3 n, ShaderLight light, float strength)
From 539bafc1b08d51b3bcba496a87ea7668340f844c Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Mon, 29 Apr 2024 09:09:35 +0200
Subject: [PATCH 119/410] Added debris interpolation; Added effects
interpolation (missiles, projectiles...);
---
TombEngine/Game/effects/debris.cpp | 2 ++
TombEngine/Game/effects/debris.h | 6 +++++
TombEngine/Game/effects/effects.h | 2 ++
TombEngine/Game/items.cpp | 5 ----
TombEngine/Game/items.h | 6 -----
TombEngine/Renderer/RendererDrawEffect.cpp | 4 ++--
TombEngine/Renderer/RendererFrame.cpp | 24 +++++++++++++++----
.../Renderer/Structures/RendererEffect.h | 15 ++++++++++++
8 files changed, 47 insertions(+), 17 deletions(-)
diff --git a/TombEngine/Game/effects/debris.cpp b/TombEngine/Game/effects/debris.cpp
index 9d98a0ada..e0faa1630 100644
--- a/TombEngine/Game/effects/debris.cpp
+++ b/TombEngine/Game/effects/debris.cpp
@@ -217,6 +217,8 @@ void UpdateDebris()
{
if (deb.active)
{
+ deb.StoreInterpolationData();
+
FloorInfo* floor;
short roomNumber;
diff --git a/TombEngine/Game/effects/debris.h b/TombEngine/Game/effects/debris.h
index 1c2df5372..513d096ed 100644
--- a/TombEngine/Game/effects/debris.h
+++ b/TombEngine/Game/effects/debris.h
@@ -71,6 +71,12 @@ struct DebrisFragment
bool active;
bool isStatic;
Matrix Transform;
+ Matrix OldTransform;
+
+ void StoreInterpolationData()
+ {
+ OldTransform = Transform;
+ }
};
extern SHATTER_ITEM ShatterItem;
diff --git a/TombEngine/Game/effects/effects.h b/TombEngine/Game/effects/effects.h
index ba45f28c4..bb87f3a04 100644
--- a/TombEngine/Game/effects/effects.h
+++ b/TombEngine/Game/effects/effects.h
@@ -89,6 +89,8 @@ struct FX_INFO
Vector4 color;
short flag1;
short flag2;
+
+ bool DisableInterpolation;
};
struct NODEOFFSET_INFO
diff --git a/TombEngine/Game/items.cpp b/TombEngine/Game/items.cpp
index 590de6614..29a4cf9bc 100644
--- a/TombEngine/Game/items.cpp
+++ b/TombEngine/Game/items.cpp
@@ -745,11 +745,6 @@ int FindItem(ItemInfo* item)
void UpdateAllItems()
{
- for (int i = 0; i < g_Level.Items.size(); i++)
- {
- g_Level.Items[i].StoreInterpolationData();
- }
-
InItemControlLoop = true;
short itemNumber = NextItemActive;
diff --git a/TombEngine/Game/items.h b/TombEngine/Game/items.h
index 86c4045ff..f5ea6aa21 100644
--- a/TombEngine/Game/items.h
+++ b/TombEngine/Game/items.h
@@ -122,7 +122,6 @@ struct ItemInfo
EntityEffectData Effect = {};
EntityModelData Model = {};
- Pose OldPose = Pose::Zero;
Pose StartPose = Pose::Zero;
Pose Pose = Pose::Zero;
RoomVector Location = {}; // NOTE: Describes vertical position in room.
@@ -175,11 +174,6 @@ struct ItemInfo
bool IsBridge() const;
bool DisableInterpolation = false;
-
- void StoreInterpolationData()
- {
- OldPose = Pose;
- }
};
bool TestState(int refState, const std::vector& stateList);
diff --git a/TombEngine/Renderer/RendererDrawEffect.cpp b/TombEngine/Renderer/RendererDrawEffect.cpp
index 26e6e40b3..0c4cab6c0 100644
--- a/TombEngine/Renderer/RendererDrawEffect.cpp
+++ b/TombEngine/Renderer/RendererDrawEffect.cpp
@@ -1320,7 +1320,7 @@ namespace TEN::Renderer
{
const auto& room = _rooms[effect->RoomNumber];
- _stStatic.World = effect->World;
+ _stStatic.World = effect->InterpolatedWorld;
_stStatic.Color = effect->Color;
_stStatic.AmbientLight = effect->AmbientLight;
_stStatic.LightMode = (int)LightMode::Dynamic;
@@ -1419,7 +1419,7 @@ namespace TEN::Renderer
BindTexture(TextureRegister::ColorMap, &std::get<0>(_moveablesTextures[deb.mesh.tex]), SamplerStateRegister::LinearClamp);
}
- _stStatic.World = deb.Transform;
+ _stStatic.World = Matrix::Lerp(deb.OldTransform, deb.Transform, _interpolationFactor);
_stStatic.Color = deb.color;
_stStatic.AmbientLight = _rooms[deb.roomNumber].AmbientLight;
_stStatic.LightMode = (int)deb.lightMode;
diff --git a/TombEngine/Renderer/RendererFrame.cpp b/TombEngine/Renderer/RendererFrame.cpp
index 3c8171dd5..9a59de126 100644
--- a/TombEngine/Renderer/RendererFrame.cpp
+++ b/TombEngine/Renderer/RendererFrame.cpp
@@ -878,17 +878,33 @@ namespace TEN::Renderer
RendererEffect *newEffect = &_effects[fxNum];
- Matrix translation = Matrix::CreateTranslation(fx->pos.Position.x, fx->pos.Position.y, fx->pos.Position.z);
- Matrix rotation = fx->pos.Orientation.ToRotationMatrix();
-
+ newEffect->Translation = Matrix::CreateTranslation(fx->pos.Position.x, fx->pos.Position.y, fx->pos.Position.z);
+ newEffect->Rotation = fx->pos.Orientation.ToRotationMatrix();
+ newEffect->Scale = Matrix::CreateScale(1.0f);
+ newEffect->World = newEffect->Rotation * newEffect->Translation;
newEffect->ObjectNumber = fx->objectNumber;
newEffect->RoomNumber = fx->roomNumber;
newEffect->Position = fx->pos.Position.ToVector3();
newEffect->AmbientLight = room.AmbientLight;
newEffect->Color = fx->color;
- newEffect->World = rotation * translation;
newEffect->Mesh = GetMesh(obj->nmeshes ? obj->meshIndex : fx->frameNumber);
+ if (fx->DisableInterpolation)
+ {
+ // In this way the interpolation will return always the same result
+ newEffect->OldPosition = newEffect->Position;
+ newEffect->OldTranslation = newEffect->Translation;
+ newEffect->OldRotation = newEffect->Rotation;
+ newEffect->OldWorld = newEffect->World;
+ newEffect->OldScale = newEffect->Scale;
+ }
+
+ newEffect->InterpolatedPosition = Vector3::Lerp(newEffect->OldPosition, newEffect->Position, _interpolationFactor);
+ newEffect->InterpolatedTranslation = Matrix::Lerp(newEffect->OldTranslation, newEffect->Translation, _interpolationFactor);
+ newEffect->InterpolatedRotation = Matrix::Lerp(newEffect->InterpolatedRotation, newEffect->Rotation, _interpolationFactor);
+ newEffect->InterpolatedWorld = Matrix::Lerp(newEffect->OldWorld, newEffect->World, _interpolationFactor);
+ newEffect->InterpolatedScale = Matrix::Lerp(newEffect->OldScale, newEffect->Scale, _interpolationFactor);
+
CollectLightsForEffect(fx->roomNumber, newEffect);
room.EffectsToDraw.push_back(newEffect);
diff --git a/TombEngine/Renderer/Structures/RendererEffect.h b/TombEngine/Renderer/Structures/RendererEffect.h
index e4c7904e7..492df404d 100644
--- a/TombEngine/Renderer/Structures/RendererEffect.h
+++ b/TombEngine/Renderer/Structures/RendererEffect.h
@@ -13,9 +13,24 @@ namespace TEN::Renderer::Structures
int RoomNumber;
Vector3 Position;
Matrix World;
+ Matrix Translation;
+ Matrix Rotation;
+ Matrix Scale;
Vector4 Color;
Vector4 AmbientLight;
RendererMesh* Mesh;
std::vector LightsToDraw;
+
+ Vector3 OldPosition;
+ Matrix OldWorld;
+ Matrix OldTranslation;
+ Matrix OldRotation;
+ Matrix OldScale;
+
+ Vector3 InterpolatedPosition;
+ Matrix InterpolatedWorld;
+ Matrix InterpolatedTranslation;
+ Matrix InterpolatedRotation;
+ Matrix InterpolatedScale;
};
}
From d83a84036e0860dfc16ba6966c2a4075248d6442 Mon Sep 17 00:00:00 2001
From: Jakub <80340234+Jakub768@users.noreply.github.com>
Date: Mon, 29 Apr 2024 12:55:59 +0100
Subject: [PATCH 120/410] Update Changes.txt
---
Documentation/Changes.txt | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/Changes.txt b/Documentation/Changes.txt
index 08900121d..61d2938c7 100644
--- a/Documentation/Changes.txt
+++ b/Documentation/Changes.txt
@@ -5,6 +5,8 @@ Version 1.5
* Fixed incorrect diving animation when swandiving from a high place.
* Fixed camera rotating with Lara's hips when climbing out of water.
* Fixed AI for skidoo driver and worker with shotgun TR2 enemies.
+* Fixed Ember emitter crashing when ocb is between -1 and -10
+* Fixed Electric cleaner and Squishy block not detecting collision with certain block heights.
Lua API changes:
* Added Inventory.GetUsedItem(), Inventory.SetUsedItem() and Inventory.ClearUsedItem() functions.
From 2122a14d0e102aa8932dcf3746fcdd59d26b66bf Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Tue, 30 Apr 2024 10:29:01 +0200
Subject: [PATCH 121/410] Variable framerate now is optional
---
TombEngine/Game/camera.cpp | 1 -
TombEngine/Game/camera.h | 1 -
TombEngine/Game/control/control.cpp | 26 +++++++++++++------
TombEngine/Game/gui.cpp | 14 +++++++++-
TombEngine/Renderer/RendererDrawMenu.cpp | 9 +++++--
.../Scripting/Internal/LanguageScript.h | 1 +
TombEngine/Specific/configuration.cpp | 9 +++++--
TombEngine/Specific/configuration.h | 2 ++
8 files changed, 48 insertions(+), 15 deletions(-)
diff --git a/TombEngine/Game/camera.cpp b/TombEngine/Game/camera.cpp
index ee176e7d7..1fd9628d4 100644
--- a/TombEngine/Game/camera.cpp
+++ b/TombEngine/Game/camera.cpp
@@ -58,7 +58,6 @@ GameVector LookCamPosition;
GameVector LookCamTarget;
Vector3i CamOldPos;
CAMERA_INFO Camera;
-CAMERA_INFO PreviousCamera;
ObjectCameraInfo ItemCamera;
GameVector ForcedFixedCamera;
int UseForcedFixedCamera;
diff --git a/TombEngine/Game/camera.h b/TombEngine/Game/camera.h
index 55453957b..504a59ed4 100644
--- a/TombEngine/Game/camera.h
+++ b/TombEngine/Game/camera.h
@@ -66,7 +66,6 @@ constexpr auto FADE_SCREEN_SPEED = 16.0f / 255.0f;
constexpr auto DEFAULT_FOV = 80.0f;
extern CAMERA_INFO Camera;
-extern CAMERA_INFO PreviousCamera;
extern GameVector ForcedFixedCamera;
extern int UseForcedFixedCamera;
extern CameraType BinocularOldCamera;
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index e5de091c1..e2d577141 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -587,8 +587,6 @@ GameStatus DoGameLoop(int levelIndex)
int controlCalls = 0;
int drawCalls = 0;
- memcpy(&PreviousCamera , &Camera, sizeof(CAMERA_INFO));
-
while (DoTheGame)
{
if (App.ResetClock)
@@ -609,18 +607,30 @@ GameStatus DoGameLoop(int levelIndex)
while (controlLag >= controlFrameTime)
{
- memcpy(&PreviousCamera, &Camera, sizeof(CAMERA_INFO));
status = ControlPhase(0);
controlLag -= controlFrameTime;
controlCalls++;
+
+ if (!g_Configuration.EnableVariableFramerate)
+ {
+ if (status != GameStatus::Normal)
+ break;
+
+ float interpolateFactor = 0.0f;
+ DrawPhase(!levelIndex, interpolateFactor);
+ drawCalls++;
+ }
}
- if (status != GameStatus::Normal)
- break;
+ if (g_Configuration.EnableVariableFramerate)
+ {
+ if (status != GameStatus::Normal)
+ break;
- float interpolateFactor = std::min((float)controlLag / (float)controlFrameTime, 1.0f);
- DrawPhase(!levelIndex, interpolateFactor);
- drawCalls++;
+ float interpolateFactor = std::min((float)controlLag / (float)controlFrameTime, 1.0f);
+ DrawPhase(!levelIndex, interpolateFactor);
+ drawCalls++;
+ }
}
EndGameLoop(levelIndex, status);
diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp
index 51332bd7c..f256de218 100644
--- a/TombEngine/Game/gui.cpp
+++ b/TombEngine/Game/gui.cpp
@@ -470,11 +470,12 @@ namespace TEN::Gui
Caustics,
Antialiasing,
AmbientOcclusion,
+ VariableFramerate,
Save,
Cancel
};
- static const int numDisplaySettingsOptions = 7;
+ static const int numDisplaySettingsOptions = 8;
OptionCount = numDisplaySettingsOptions;
@@ -531,6 +532,12 @@ namespace TEN::Gui
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
CurrentSettings.Configuration.EnableAmbientOcclusion = !CurrentSettings.Configuration.EnableAmbientOcclusion;
break;
+
+ case DisplaySettingsOption::VariableFramerate:
+ SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
+ CurrentSettings.Configuration.EnableVariableFramerate = !CurrentSettings.Configuration.EnableVariableFramerate;
+ break;
+
}
}
@@ -577,6 +584,11 @@ namespace TEN::Gui
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
CurrentSettings.Configuration.EnableAmbientOcclusion = !CurrentSettings.Configuration.EnableAmbientOcclusion;
break;
+
+ case DisplaySettingsOption::VariableFramerate:
+ SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
+ CurrentSettings.Configuration.EnableVariableFramerate = !CurrentSettings.Configuration.EnableVariableFramerate;
+ break;
}
}
diff --git a/TombEngine/Renderer/RendererDrawMenu.cpp b/TombEngine/Renderer/RendererDrawMenu.cpp
index 8289f1453..58ca41759 100644
--- a/TombEngine/Renderer/RendererDrawMenu.cpp
+++ b/TombEngine/Renderer/RendererDrawMenu.cpp
@@ -189,14 +189,19 @@ namespace TEN::Renderer
// Enable SSAO
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_AMBIENT_OCCLUSION), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 5));
AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableAmbientOcclusion), PRINTSTRING_COLOR_WHITE, SF(titleOption == 5));
+ GetNextLinePosition(&y);
+
+ // Enable variable framerate
+ AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_VARIABLE_FRAMERATE), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 6));
+ AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableVariableFramerate), PRINTSTRING_COLOR_WHITE, SF(titleOption == 6));
GetNextBlockPosition(&y);
// Apply
- AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_APPLY), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == 6));
+ AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_APPLY), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == 7));
GetNextLinePosition(&y);
// Cancel
- AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CANCEL), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == 7));
+ AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CANCEL), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == 8));
break;
case Menu::OtherSettings:
diff --git a/TombEngine/Scripting/Internal/LanguageScript.h b/TombEngine/Scripting/Internal/LanguageScript.h
index a2c04feaf..4b2b7a35c 100644
--- a/TombEngine/Scripting/Internal/LanguageScript.h
+++ b/TombEngine/Scripting/Internal/LanguageScript.h
@@ -71,6 +71,7 @@
#define STRING_VOLUMETRIC_FOG "volumetric_fog"
#define STRING_ANTIALIASING "antialiasing"
#define STRING_AMBIENT_OCCLUSION "ambient_occlusion"
+#define STRING_VARIABLE_FRAMERATE "variable_framerate"
#define STRING_ANTIALIASING_NONE "none"
#define STRING_ANTIALIASING_LOW "low"
#define STRING_ANTIALIASING_MEDIUM "medium"
diff --git a/TombEngine/Specific/configuration.cpp b/TombEngine/Specific/configuration.cpp
index 6e0b39d26..bd971c961 100644
--- a/TombEngine/Specific/configuration.cpp
+++ b/TombEngine/Specific/configuration.cpp
@@ -187,7 +187,8 @@ bool SaveConfiguration()
SetDWORDRegKey(graphicsKey, REGKEY_SHADOW_BLOBS_MAX, g_Configuration.ShadowBlobsMax) != ERROR_SUCCESS ||
SetBoolRegKey(graphicsKey, REGKEY_ENABLE_CAUSTICS, g_Configuration.EnableCaustics) != ERROR_SUCCESS ||
SetDWORDRegKey(graphicsKey, REGKEY_ANTIALIASING_MODE, (DWORD)g_Configuration.AntialiasingMode) != ERROR_SUCCESS ||
- SetBoolRegKey(graphicsKey, REGKEY_AMBIENT_OCCLUSION, g_Configuration.EnableAmbientOcclusion) != ERROR_SUCCESS)
+ SetBoolRegKey(graphicsKey, REGKEY_AMBIENT_OCCLUSION, g_Configuration.EnableAmbientOcclusion) != ERROR_SUCCESS ||
+ SetBoolRegKey(graphicsKey, REGKEY_VARIABLE_FRAMERATE, g_Configuration.EnableVariableFramerate) != ERROR_SUCCESS)
{
RegCloseKey(rootKey);
RegCloseKey(graphicsKey);
@@ -314,6 +315,7 @@ void InitDefaultConfiguration()
g_Configuration.EnableCaustics = true;
g_Configuration.AntialiasingMode = AntialiasingMode::Medium;
g_Configuration.EnableAmbientOcclusion = true;
+ g_Configuration.EnableVariableFramerate = true;
g_Configuration.SoundDevice = 1;
g_Configuration.EnableSound = true;
@@ -362,6 +364,7 @@ bool LoadConfiguration()
bool enableCaustics = false;
DWORD antialiasingMode = 1;
bool enableAmbientOcclusion = false;
+ bool enableVariableFramerate = false;
// Load Graphics keys.
if (GetDWORDRegKey(graphicsKey, REGKEY_SCREEN_WIDTH, &screenWidth, 0) != ERROR_SUCCESS ||
@@ -372,7 +375,8 @@ bool LoadConfiguration()
GetDWORDRegKey(graphicsKey, REGKEY_SHADOW_BLOBS_MAX, &shadowBlobsMax, GameConfiguration::DEFAULT_SHADOW_BLOBS_MAX) != ERROR_SUCCESS ||
GetBoolRegKey(graphicsKey, REGKEY_ENABLE_CAUSTICS, &enableCaustics, true) != ERROR_SUCCESS ||
GetDWORDRegKey(graphicsKey, REGKEY_ANTIALIASING_MODE, &antialiasingMode, true) != ERROR_SUCCESS ||
- GetBoolRegKey(graphicsKey, REGKEY_AMBIENT_OCCLUSION, &enableAmbientOcclusion, false) != ERROR_SUCCESS)
+ GetBoolRegKey(graphicsKey, REGKEY_AMBIENT_OCCLUSION, &enableAmbientOcclusion, false) != ERROR_SUCCESS ||
+ GetBoolRegKey(graphicsKey, REGKEY_VARIABLE_FRAMERATE, &enableVariableFramerate, false) != ERROR_SUCCESS)
{
RegCloseKey(rootKey);
RegCloseKey(graphicsKey);
@@ -500,6 +504,7 @@ bool LoadConfiguration()
g_Configuration.AntialiasingMode = AntialiasingMode(antialiasingMode);
g_Configuration.ShadowMapSize = shadowMapSize;
g_Configuration.EnableAmbientOcclusion = enableAmbientOcclusion;
+ g_Configuration.EnableVariableFramerate = enableVariableFramerate;
g_Configuration.EnableSound = enableSound;
g_Configuration.EnableReverb = enableReverb;
diff --git a/TombEngine/Specific/configuration.h b/TombEngine/Specific/configuration.h
index cf10f970c..25c6b0d7e 100644
--- a/TombEngine/Specific/configuration.h
+++ b/TombEngine/Specific/configuration.h
@@ -23,6 +23,7 @@ constexpr auto REGKEY_SHADOW_BLOBS_MAX = "ShadowBlobsMax";
constexpr auto REGKEY_ENABLE_CAUSTICS = "EnableCaustics";
constexpr auto REGKEY_ANTIALIASING_MODE = "AntialiasingMode";
constexpr auto REGKEY_AMBIENT_OCCLUSION = "AmbientOcclusion";
+constexpr auto REGKEY_VARIABLE_FRAMERATE = "EnableVariableFramerate";
// Sound keys
constexpr auto REGKEY_SOUND_DEVICE = "SoundDevice";
@@ -58,6 +59,7 @@ struct GameConfiguration
int ShadowBlobsMax = DEFAULT_SHADOW_BLOBS_MAX;
bool EnableCaustics = false;
bool EnableAmbientOcclusion = false;
+ bool EnableVariableFramerate = true;
AntialiasingMode AntialiasingMode = AntialiasingMode::None;
// Sound
From b2f7c83372566518351c62415b3e0ed0915dd253 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Tue, 30 Apr 2024 11:16:14 +0200
Subject: [PATCH 122/410] Started working on 60 fps inventory
---
TombEngine/Game/gui.cpp | 11 +++++++----
TombEngine/Renderer/RendererDrawMenu.cpp | 10 ++++++++++
2 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp
index f256de218..6dedb76b1 100644
--- a/TombEngine/Game/gui.cpp
+++ b/TombEngine/Game/gui.cpp
@@ -2801,6 +2801,9 @@ namespace TEN::Gui
const auto& player = GetLaraInfo(*item);
auto& ring = Rings[(int)ringType];
+ float multiplier = g_Configuration.EnableVariableFramerate ? 2.0f : 1.0f;
+
+
if (ring.CurrentObjectList <= 0)
return;
@@ -3188,17 +3191,17 @@ namespace TEN::Gui
if (ring.NumObjectsInList != 1 && (ringType != RingTypes::Ammo || CombineRingFadeVal == 128))
{
if (ring.ObjectListMovement > 0)
- ring.ObjectListMovement += ANGLE(45.0f);
+ ring.ObjectListMovement += ANGLE(45.0f / multiplier);
if (ring.ObjectListMovement < 0)
- ring.ObjectListMovement -= ANGLE(45.0f);
+ ring.ObjectListMovement -= ANGLE(45.0f / multiplier);
if (IsHeld(In::Left))
{
if (!ring.ObjectListMovement)
{
SoundEffect(SFX_TR4_MENU_ROTATE, nullptr, SoundEnvironment::Always);
- ring.ObjectListMovement += ANGLE(45.0f);
+ ring.ObjectListMovement += ANGLE(45.0f / multiplier);
if (AmmoSelectorFlag)
AmmoSelectorFadeDir = 2;
@@ -3210,7 +3213,7 @@ namespace TEN::Gui
if (!ring.ObjectListMovement)
{
SoundEffect(SFX_TR4_MENU_ROTATE, nullptr, SoundEnvironment::Always);
- ring.ObjectListMovement -= ANGLE(45.0f);
+ ring.ObjectListMovement -= ANGLE(45.0f / multiplier);
if (AmmoSelectorFlag)
AmmoSelectorFadeDir = 2;
diff --git a/TombEngine/Renderer/RendererDrawMenu.cpp b/TombEngine/Renderer/RendererDrawMenu.cpp
index 58ca41759..8011391c1 100644
--- a/TombEngine/Renderer/RendererDrawMenu.cpp
+++ b/TombEngine/Renderer/RendererDrawMenu.cpp
@@ -1108,6 +1108,16 @@ namespace TEN::Renderer
RenderInventoryScene(&_backBuffer, &_dumpScreenRenderTarget, 0.5f);
_swapChain->Present(0, 0);
+
+ if (g_Configuration.EnableVariableFramerate)
+ {
+ _context->ClearDepthStencilView(_backBuffer.DepthStencilView.Get(), D3D11_CLEAR_STENCIL | D3D11_CLEAR_DEPTH, 1.0f, 0);
+ _context->ClearRenderTargetView(_backBuffer.RenderTargetView.Get(), Colors::Black);
+
+ RenderInventoryScene(&_backBuffer, &_dumpScreenRenderTarget, 0.5f);
+
+ _swapChain->Present(0, 0);
+ }
}
void Renderer::RenderTitle()
From c4f532268d2e7e60f34b888456d647f3cd066ab1 Mon Sep 17 00:00:00 2001
From: Stranger1992 <84292688+Stranger1992@users.noreply.github.com>
Date: Tue, 30 Apr 2024 16:19:30 +0100
Subject: [PATCH 123/410] Updated system strings for Variable Framerate
---
Scripts/SystemStrings.lua | 1 +
1 file changed, 1 insertion(+)
diff --git a/Scripts/SystemStrings.lua b/Scripts/SystemStrings.lua
index 2bb0d2e47..69009d8eb 100644
--- a/Scripts/SystemStrings.lua
+++ b/Scripts/SystemStrings.lua
@@ -113,6 +113,7 @@ local strings =
vehicle_actions = { "Vehicle Actions" },
view = { "View" },
volumetric_fog = { "Volumetric Fog" },
+ variable_framerate = { "Variable Framerate" },
waiting_for_input = { "Waiting For Input" },
window_title = { "TombEngine" },
windowed = { "Windowed" },
From 368f74e75415870cf9df37c7f7bf40a7b314cf50 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Wed, 1 May 2024 05:32:49 +0200
Subject: [PATCH 124/410] Added interpolation for title level
---
TombEngine/Game/control/control.cpp | 19 +++++++------------
TombEngine/Game/control/control.h | 2 +-
TombEngine/Game/gui.cpp | 2 +-
TombEngine/Renderer/Renderer.h | 4 ++--
TombEngine/Renderer/RendererDraw.cpp | 12 ++++++------
TombEngine/Renderer/RendererDrawMenu.cpp | 16 +++++++++++++++-
6 files changed, 32 insertions(+), 23 deletions(-)
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index e2d577141..d71e3ab63 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -115,21 +115,18 @@ short NextFxFree;
int ControlPhaseTime;
-int DrawPhase(bool isTitle, float interpolateFactor)
+void DrawPhase(bool isTitle, float interpolationFactor)
{
if (isTitle)
{
- g_Renderer.RenderTitle();
+ g_Renderer.RenderTitle(interpolationFactor);
}
else
{
- g_Renderer.Render(interpolateFactor);
+ g_Renderer.Render(interpolationFactor);
}
g_Renderer.Lock();
-
- //Camera.numberFrames = g_Renderer.Synchronize();
- return Camera.numberFrames;
}
GameStatus ControlPhase(int numFrames)
@@ -155,9 +152,7 @@ GameStatus ControlPhase(int numFrames)
g_GameStringsHandler->ProcessDisplayStrings(DELTA_TIME);
- // Save current state to old variables for interpolation
SetupInterpolation();
- g_Renderer.SaveOldState();
// Controls are polled before OnLoop, so input data could be
// overwritten by script API methods.
@@ -616,8 +611,8 @@ GameStatus DoGameLoop(int levelIndex)
if (status != GameStatus::Normal)
break;
- float interpolateFactor = 0.0f;
- DrawPhase(!levelIndex, interpolateFactor);
+ float interpolationFactor = 0.0f;
+ DrawPhase(!levelIndex, interpolationFactor);
drawCalls++;
}
}
@@ -627,8 +622,8 @@ GameStatus DoGameLoop(int levelIndex)
if (status != GameStatus::Normal)
break;
- float interpolateFactor = std::min((float)controlLag / (float)controlFrameTime, 1.0f);
- DrawPhase(!levelIndex, interpolateFactor);
+ float interpolationFactor = std::min((float)controlLag / (float)controlFrameTime, 1.0f);
+ DrawPhase(!levelIndex, interpolationFactor);
drawCalls++;
}
}
diff --git a/TombEngine/Game/control/control.h b/TombEngine/Game/control/control.h
index b9b8b78d2..cd44f11e2 100644
--- a/TombEngine/Game/control/control.h
+++ b/TombEngine/Game/control/control.h
@@ -81,7 +81,7 @@ extern int ControlPhaseTime;
extern std::vector OutsideRoomTable[OUTSIDE_SIZE][OUTSIDE_SIZE];
-int DrawPhase(bool isTitle, float interpolateFactor);
+void DrawPhase(bool isTitle, float interpolationFactor);
GameStatus ControlPhase(int numFrames);
GameStatus DoLevel(int levelIndex, bool loadGame = false);
diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp
index 6dedb76b1..0e5d311a9 100644
--- a/TombEngine/Game/gui.cpp
+++ b/TombEngine/Game/gui.cpp
@@ -749,7 +749,7 @@ namespace TEN::Gui
}
else
{
- g_Renderer.RenderTitle();
+ g_Renderer.RenderTitle(0);
Camera.numberFrames = g_Renderer.Synchronize();
int numFrames = Camera.numberFrames;
ControlPhase(numFrames);
diff --git a/TombEngine/Renderer/Renderer.h b/TombEngine/Renderer/Renderer.h
index dc8f19993..527c7a33d 100644
--- a/TombEngine/Renderer/Renderer.h
+++ b/TombEngine/Renderer/Renderer.h
@@ -587,8 +587,8 @@ namespace TEN::Renderer
void DrawBar(float percent, const RendererHudBar& bar, GAME_OBJECT_ID textureSlot, int frame, bool poison);
void Create();
void Initialize(int w, int h, bool windowed, HWND handle);
- void Render(float interpolateFactor);
- void RenderTitle();
+ void Render(float interpolationFactor);
+ void RenderTitle(float interpolationFactor);
void Lock();
bool PrepareDataForTheRenderer();
void UpdateCameraMatrices(CAMERA_INFO* cam, float roll, float fov, float farView);
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index 102c37040..04da60923 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -3069,15 +3069,15 @@ namespace TEN::Renderer
_context->ClearDepthStencilView(depthTarget, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
}
- void Renderer::Render(float interpolateFactor)
+ void Renderer::Render(float interpolationFactor)
{
//RenderToCubemap(reflectionCubemap, Vector3(LaraItem->pos.xPos, LaraItem->pos.yPos - 1024, LaraItem->pos.zPos), LaraItem->roomNumber);
// Interpolate camera
- _gameCamera.Camera.WorldPosition = Vector3::Lerp(_oldGameCamera.Camera.WorldPosition, _currentGameCamera.Camera.WorldPosition, interpolateFactor);
- _gameCamera.Camera.WorldDirection = Vector3::Lerp(_oldGameCamera.Camera.WorldDirection, _currentGameCamera.Camera.WorldDirection, interpolateFactor);
- _gameCamera.Camera.View = Matrix::Lerp(_oldGameCamera.Camera.View, _currentGameCamera.Camera.View, interpolateFactor);
- _gameCamera.Camera.Projection = Matrix::Lerp(_oldGameCamera.Camera.Projection, _currentGameCamera.Camera.Projection, interpolateFactor);
+ _gameCamera.Camera.WorldPosition = Vector3::Lerp(_oldGameCamera.Camera.WorldPosition, _currentGameCamera.Camera.WorldPosition, interpolationFactor);
+ _gameCamera.Camera.WorldDirection = Vector3::Lerp(_oldGameCamera.Camera.WorldDirection, _currentGameCamera.Camera.WorldDirection, interpolationFactor);
+ _gameCamera.Camera.View = Matrix::Lerp(_oldGameCamera.Camera.View, _currentGameCamera.Camera.View, interpolationFactor);
+ _gameCamera.Camera.Projection = Matrix::Lerp(_oldGameCamera.Camera.Projection, _currentGameCamera.Camera.Projection, interpolationFactor);
_gameCamera.Camera.ViewProjection = _gameCamera.Camera.View * _gameCamera.Camera.Projection;
_gameCamera.Camera.FOV = _currentGameCamera.Camera.FOV;
_gameCamera.Camera.Frustum=_currentGameCamera.Camera.Frustum;
@@ -3086,7 +3086,7 @@ namespace TEN::Renderer
_gameCamera.Camera.NearPlane = _currentGameCamera.Camera.NearPlane;
_gameCamera.Camera.FarPlane = _currentGameCamera.Camera.FarPlane;
- _interpolationFactor = interpolateFactor;
+ _interpolationFactor = interpolationFactor;
RenderScene(&_backBuffer, true, _gameCamera);
diff --git a/TombEngine/Renderer/RendererDrawMenu.cpp b/TombEngine/Renderer/RendererDrawMenu.cpp
index 8011391c1..3955c77a8 100644
--- a/TombEngine/Renderer/RendererDrawMenu.cpp
+++ b/TombEngine/Renderer/RendererDrawMenu.cpp
@@ -1120,8 +1120,22 @@ namespace TEN::Renderer
}
}
- void Renderer::RenderTitle()
+ void Renderer::RenderTitle(float interpolationFactor)
{
+ _gameCamera.Camera.WorldPosition = Vector3::Lerp(_oldGameCamera.Camera.WorldPosition, _currentGameCamera.Camera.WorldPosition, interpolationFactor);
+ _gameCamera.Camera.WorldDirection = Vector3::Lerp(_oldGameCamera.Camera.WorldDirection, _currentGameCamera.Camera.WorldDirection, interpolationFactor);
+ _gameCamera.Camera.View = Matrix::Lerp(_oldGameCamera.Camera.View, _currentGameCamera.Camera.View, interpolationFactor);
+ _gameCamera.Camera.Projection = Matrix::Lerp(_oldGameCamera.Camera.Projection, _currentGameCamera.Camera.Projection, interpolationFactor);
+ _gameCamera.Camera.ViewProjection = _gameCamera.Camera.View * _gameCamera.Camera.Projection;
+ _gameCamera.Camera.FOV = _currentGameCamera.Camera.FOV;
+ _gameCamera.Camera.Frustum = _currentGameCamera.Camera.Frustum;
+ _gameCamera.Camera.ViewSize = _currentGameCamera.Camera.ViewSize;
+ _gameCamera.Camera.InvViewSize = _currentGameCamera.Camera.InvViewSize;
+ _gameCamera.Camera.NearPlane = _currentGameCamera.Camera.NearPlane;
+ _gameCamera.Camera.FarPlane = _currentGameCamera.Camera.FarPlane;
+
+ _interpolationFactor = interpolationFactor;
+
RenderScene(&_dumpScreenRenderTarget, false, _gameCamera);
_context->ClearDepthStencilView(_backBuffer.DepthStencilView.Get(), D3D11_CLEAR_STENCIL | D3D11_CLEAR_DEPTH, 1.0f, 0);
From 62d28a08d1e4b1d9fe0d4d05dffb93849118f57c Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Wed, 1 May 2024 06:11:49 +0200
Subject: [PATCH 125/410] Fixed corrupted items
---
TombEngine/Game/control/control.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index d71e3ab63..dfeab3584 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -153,6 +153,7 @@ GameStatus ControlPhase(int numFrames)
g_GameStringsHandler->ProcessDisplayStrings(DELTA_TIME);
SetupInterpolation();
+ g_Renderer.SaveOldState();
// Controls are polled before OnLoop, so input data could be
// overwritten by script API methods.
From b868d6c5186a0f8b6784ae64d19cc4f1373d3e83 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 1 May 2024 21:27:54 +1000
Subject: [PATCH 126/410] Remove Ptr suffix usage in floordata
---
TombEngine/Game/collision/floordata.cpp | 172 ++++++++++++------------
TombEngine/Game/collision/floordata.h | 12 +-
2 files changed, 92 insertions(+), 92 deletions(-)
diff --git a/TombEngine/Game/collision/floordata.cpp b/TombEngine/Game/collision/floordata.cpp
index a15e2d8fe..f1efec5bc 100644
--- a/TombEngine/Game/collision/floordata.cpp
+++ b/TombEngine/Game/collision/floordata.cpp
@@ -424,22 +424,22 @@ namespace TEN::Collision::Floordata
return roomGridCoords;
}
- std::vector GetNeighborSectorPtrs(const Vector3i& pos, int roomNumber, unsigned int searchDepth)
+ std::vector GetNeighborSectors(const Vector3i& pos, int roomNumber, unsigned int searchDepth)
{
- auto sectorPtrs = std::vector{};
+ auto sectors = std::vector{};
// Run through neighbor rooms.
auto& room = g_Level.Rooms[roomNumber];
for (int neighborRoomNumber : room.neighbors)
{
- // Collect neighbor sector pointers.
+ // Collect neighbor sectors.
auto roomGridCoords = GetNeighborRoomGridCoords(pos, neighborRoomNumber, searchDepth);
for (const auto& roomGridCoord : roomGridCoords)
- sectorPtrs.push_back(&GetFloor(neighborRoomNumber, roomGridCoord));
+ sectors.push_back(&GetFloor(neighborRoomNumber, roomGridCoord));
}
- // Return neighbor sector pointers.
- return sectorPtrs;
+ // Return neighbor sectors.
+ return sectors;
}
FloorInfo& GetFloor(int roomNumber, const Vector2i& roomGridCoord)
@@ -458,88 +458,88 @@ namespace TEN::Collision::Floordata
FloorInfo& GetFarthestSector(int roomNumber, int x, int z, bool isBottom)
{
- auto* sectorPtr = &GetSideSector(roomNumber, x, z);
+ auto* sector = &GetSideSector(roomNumber, x, z);
// Find bottom or top sector.
- bool isWall = sectorPtr->IsWall(x, z);
+ bool isWall = sector->IsWall(x, z);
while (isWall)
{
- auto nextRoomNumber = sectorPtr->GetNextRoomNumber(x, z, isBottom);
+ auto nextRoomNumber = sector->GetNextRoomNumber(x, z, isBottom);
if (!nextRoomNumber.has_value())
break;
// TODO: Check.
- sectorPtr = &GetSideSector(*nextRoomNumber, x, z);
- isWall = sectorPtr->IsWall(x, z);
+ sector = &GetSideSector(*nextRoomNumber, x, z);
+ isWall = sector->IsWall(x, z);
}
- return *sectorPtr;
+ return *sector;
}
FloorInfo& GetSideSector(int roomNumber, int x, int z)
{
- auto* sectorPtr = &GetFloor(roomNumber, x, z);
+ auto* sector = &GetFloor(roomNumber, x, z);
// Find side sector.
- auto sideRoomNumber = sectorPtr->GetSideRoomNumber();
+ auto sideRoomNumber = sector->GetSideRoomNumber();
while (sideRoomNumber.has_value())
{
- sectorPtr = &GetFloor(*sideRoomNumber, x, z);
- sideRoomNumber = sectorPtr->GetSideRoomNumber();
+ sector = &GetFloor(*sideRoomNumber, x, z);
+ sideRoomNumber = sector->GetSideRoomNumber();
}
- return *sectorPtr;
+ return *sector;
}
static std::optional GetFarthestHeightData(FloorInfo& currentSector, Vector3i pos, bool isBottom)
{
// Find bottom or top height while bridge exists(?).
- auto* sectorPtr = ¤tSector;
+ auto* sector = ¤tSector;
do
{
// Set vertical position to lowest bridge ceiling height or highest bridge floor height.
- pos.y = sectorPtr->GetBridgeSurfaceHeight(pos, !isBottom);
+ pos.y = sector->GetBridgeSurfaceHeight(pos, !isBottom);
// Find sector at lowest bridge floor height or highest bridge ceiling height.
while (isBottom ?
- (pos.y >= sectorPtr->GetSurfaceHeight(pos.x, pos.z, true)) :
- (pos.y <= sectorPtr->GetSurfaceHeight(pos.x, pos.z, false)))
+ (pos.y >= sector->GetSurfaceHeight(pos.x, pos.z, true)) :
+ (pos.y <= sector->GetSurfaceHeight(pos.x, pos.z, false)))
{
- auto nextRoomNumber = sectorPtr->GetNextRoomNumber(pos.x, pos.z, isBottom);
+ auto nextRoomNumber = sector->GetNextRoomNumber(pos.x, pos.z, isBottom);
if (!nextRoomNumber.has_value())
return std::nullopt;
- sectorPtr = &GetSideSector(*nextRoomNumber, pos.x, pos.z);
+ sector = &GetSideSector(*nextRoomNumber, pos.x, pos.z);
}
}
- while (sectorPtr->GetInsideBridgeItemNumber(pos, isBottom, !isBottom) != NO_VALUE);
+ while (sector->GetInsideBridgeItemNumber(pos, isBottom, !isBottom) != NO_VALUE);
- return FarthestHeightData{ *sectorPtr, pos.y };
+ return FarthestHeightData{ *sector, pos.y };
}
std::optional GetSurfaceHeight(const RoomVector& location, int x, int z, bool isFloor)
{
- auto* sectorPtr = &GetSideSector(location.RoomNumber, x, z);
+ auto* sector = &GetSideSector(location.RoomNumber, x, z);
auto pos = Vector3i(x, location.Height, z);
int polarity = 0;
- if (sectorPtr->IsWall(x, z))
+ if (sector->IsWall(x, z))
{
- sectorPtr = &GetFarthestSector(location.RoomNumber, x, z, !isFloor);
+ sector = &GetFarthestSector(location.RoomNumber, x, z, !isFloor);
- if (!sectorPtr->IsWall(x, z))
+ if (!sector->IsWall(x, z))
{
- pos.y = sectorPtr->GetSurfaceHeight(x, z, isFloor);
+ pos.y = sector->GetSurfaceHeight(x, z, isFloor);
polarity = isFloor ? -1 : 1;
}
else
{
- sectorPtr = &GetFarthestSector(location.RoomNumber, x, z, isFloor);
+ sector = &GetFarthestSector(location.RoomNumber, x, z, isFloor);
- if (!sectorPtr->IsWall(x, z))
+ if (!sector->IsWall(x, z))
{
- pos.y = sectorPtr->GetSurfaceHeight(x, z, !isFloor);
+ pos.y = sector->GetSurfaceHeight(x, z, !isFloor);
polarity = isFloor ? 1 : -1;
}
else
@@ -549,81 +549,81 @@ namespace TEN::Collision::Floordata
}
}
- int floorHeight = sectorPtr->GetSurfaceHeight(pos, true);
- int ceilingHeight = sectorPtr->GetSurfaceHeight(pos, false);
+ int floorHeight = sector->GetSurfaceHeight(pos, true);
+ int ceilingHeight = sector->GetSurfaceHeight(pos, false);
pos.y = std::clamp(pos.y, std::min(floorHeight, ceilingHeight), std::max(floorHeight, ceilingHeight));
bool testFloorBorder = (pos.y == ceilingHeight);
bool testCeilBorder = (pos.y == floorHeight);
- int insideBridgeItemNumber = sectorPtr->GetInsideBridgeItemNumber(pos, testFloorBorder, testCeilBorder);
+ int insideBridgeItemNumber = sector->GetInsideBridgeItemNumber(pos, testFloorBorder, testCeilBorder);
if (insideBridgeItemNumber != NO_VALUE)
{
if (isFloor ? (polarity <= 0) : (polarity >= 0))
{
- auto heightData = GetFarthestHeightData(*sectorPtr, pos, !isFloor);
+ auto heightData = GetFarthestHeightData(*sector, pos, !isFloor);
if (heightData.has_value())
return heightData->Height;
}
if (isFloor ? (polarity >= 0) : (polarity <= 0))
{
- auto heightData = GetFarthestHeightData(*sectorPtr, pos, isFloor);
+ auto heightData = GetFarthestHeightData(*sector, pos, isFloor);
if (!heightData.has_value())
return std::nullopt;
- sectorPtr = &heightData->Sector;
+ sector = &heightData->Sector;
pos.y = heightData->Height;
}
}
if (isFloor ? (polarity >= 0) : (polarity <= 0))
{
- auto nextRoomNumber = sectorPtr->GetNextRoomNumber(pos, isFloor);
+ auto nextRoomNumber = sector->GetNextRoomNumber(pos, isFloor);
while (nextRoomNumber.has_value())
{
- sectorPtr = &GetSideSector(*nextRoomNumber, x, z);
- nextRoomNumber = sectorPtr->GetNextRoomNumber(pos, isFloor);
+ sector = &GetSideSector(*nextRoomNumber, x, z);
+ nextRoomNumber = sector->GetNextRoomNumber(pos, isFloor);
}
}
- return sectorPtr->GetSurfaceHeight(pos, isFloor);
+ return sector->GetSurfaceHeight(pos, isFloor);
}
static std::optional GetFarthestRoomVector(RoomVector location, const Vector3i& pos, bool isBottom)
{
- auto* sectorPtr = &GetSideSector(location.RoomNumber, pos.x, pos.z);
- location.RoomNumber = sectorPtr->RoomNumber;
+ auto* sector = &GetSideSector(location.RoomNumber, pos.x, pos.z);
+ location.RoomNumber = sector->RoomNumber;
- if (sectorPtr->IsWall(pos.x, pos.z))
+ if (sector->IsWall(pos.x, pos.z))
{
- sectorPtr = &GetFarthestSector(location.RoomNumber, pos.x, pos.z, isBottom);
- location.RoomNumber = sectorPtr->RoomNumber;
+ sector = &GetFarthestSector(location.RoomNumber, pos.x, pos.z, isBottom);
+ location.RoomNumber = sector->RoomNumber;
- if (sectorPtr->IsWall(pos.x, pos.z))
+ if (sector->IsWall(pos.x, pos.z))
return std::nullopt;
- location.Height = sectorPtr->GetSurfaceHeight(pos.x, pos.z, !isBottom);
+ location.Height = sector->GetSurfaceHeight(pos.x, pos.z, !isBottom);
}
- int floorHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), true);
- int ceilingHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), false);
+ int floorHeight = sector->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), true);
+ int ceilingHeight = sector->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), false);
location.Height = std::clamp(location.Height, std::min(ceilingHeight, floorHeight), std::max(ceilingHeight, floorHeight));
bool testFloorBorder = (location.Height == ceilingHeight);
bool testCeilBorder = (location.Height == floorHeight);
- int insideBridgeItemNumber = sectorPtr->GetInsideBridgeItemNumber(Vector3i(pos.x, location.Height, pos.z), testFloorBorder, testCeilBorder);
+ int insideBridgeItemNumber = sector->GetInsideBridgeItemNumber(Vector3i(pos.x, location.Height, pos.z), testFloorBorder, testCeilBorder);
if (insideBridgeItemNumber != NO_VALUE)
{
- auto heightData = GetFarthestHeightData(*sectorPtr, Vector3i(pos.x, location.Height, pos.z), isBottom);
+ auto heightData = GetFarthestHeightData(*sector, Vector3i(pos.x, location.Height, pos.z), isBottom);
if (!heightData.has_value())
return std::nullopt;
- sectorPtr = &heightData->Sector;
- location.RoomNumber = sectorPtr->RoomNumber;
+ sector = &heightData->Sector;
+ location.RoomNumber = sector->RoomNumber;
location.Height = heightData->Height;
}
@@ -633,19 +633,19 @@ namespace TEN::Collision::Floordata
{
if (!isFirstSector)
{
- sectorPtr = &GetSideSector(*nextRoomNumber, pos.x, pos.z);
- location.RoomNumber = sectorPtr->RoomNumber;
- location.Height = sectorPtr->GetSurfaceHeight(pos.x, pos.z, !isBottom);
+ sector = &GetSideSector(*nextRoomNumber, pos.x, pos.z);
+ location.RoomNumber = sector->RoomNumber;
+ location.Height = sector->GetSurfaceHeight(pos.x, pos.z, !isBottom);
}
isFirstSector = false;
if (isBottom)
{
- ceilingHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), false);
- if (pos.y < ceilingHeight && sectorPtr->GetNextRoomNumber(Vector3i(pos.x, location.Height, pos.z), false))
+ ceilingHeight = sector->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), false);
+ if (pos.y < ceilingHeight && sector->GetNextRoomNumber(Vector3i(pos.x, location.Height, pos.z), false))
return std::nullopt;
- floorHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), true);
+ floorHeight = sector->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), true);
if (pos.y <= floorHeight)
{
location.Height = std::max(pos.y, ceilingHeight);
@@ -654,11 +654,11 @@ namespace TEN::Collision::Floordata
}
else
{
- floorHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), true);
- if (pos.y > floorHeight && sectorPtr->GetNextRoomNumber(Vector3i(pos.x, location.Height, pos.z), true))
+ floorHeight = sector->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), true);
+ if (pos.y > floorHeight && sector->GetNextRoomNumber(Vector3i(pos.x, location.Height, pos.z), true))
return std::nullopt;
- ceilingHeight = sectorPtr->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), false);
+ ceilingHeight = sector->GetSurfaceHeight(Vector3i(pos.x, location.Height, pos.z), false);
if (pos.y >= ceilingHeight)
{
location.Height = std::min(pos.y, floorHeight);
@@ -666,7 +666,7 @@ namespace TEN::Collision::Floordata
}
}
- nextRoomNumber = sectorPtr->GetNextRoomNumber(Vector3i(pos.x, location.Height, pos.z), isBottom);
+ nextRoomNumber = sector->GetNextRoomNumber(Vector3i(pos.x, location.Height, pos.z), isBottom);
}
return std::nullopt;
@@ -696,34 +696,34 @@ namespace TEN::Collision::Floordata
x += bridgeItem.Pose.Position.x;
z += bridgeItem.Pose.Position.z;
- auto* sectorPtr = &GetSideSector(bridgeItem.RoomNumber, x, z);
- sectorPtr->AddBridge(itemNumber);
+ auto* sector = &GetSideSector(bridgeItem.RoomNumber, x, z);
+ sector->AddBridge(itemNumber);
if (bridge.GetFloorBorder != nullptr)
{
int floorBorder = bridge.GetFloorBorder(bridgeItem);
- while (floorBorder <= sectorPtr->GetSurfaceHeight(x, z, false))
+ while (floorBorder <= sector->GetSurfaceHeight(x, z, false))
{
- auto roomNumberAbove = sectorPtr->GetNextRoomNumber(x, z, false);
+ auto roomNumberAbove = sector->GetNextRoomNumber(x, z, false);
if (!roomNumberAbove.has_value())
break;
- sectorPtr = &GetSideSector(*roomNumberAbove, x, z);
- sectorPtr->AddBridge(itemNumber);
+ sector = &GetSideSector(*roomNumberAbove, x, z);
+ sector->AddBridge(itemNumber);
}
}
if (bridge.GetCeilingBorder != nullptr)
{
int ceilingBorder = bridge.GetCeilingBorder(bridgeItem);
- while (ceilingBorder >= sectorPtr->GetSurfaceHeight(x, z, true))
+ while (ceilingBorder >= sector->GetSurfaceHeight(x, z, true))
{
- auto roomNumberBelow = sectorPtr->GetNextRoomNumber(x, z, true);
+ auto roomNumberBelow = sector->GetNextRoomNumber(x, z, true);
if (!roomNumberBelow.has_value())
break;
- sectorPtr = &GetSideSector(*roomNumberBelow, x, z);
- sectorPtr->AddBridge(itemNumber);
+ sector = &GetSideSector(*roomNumberBelow, x, z);
+ sector->AddBridge(itemNumber);
}
}
}
@@ -739,34 +739,34 @@ namespace TEN::Collision::Floordata
x += bridgeItem.Pose.Position.x;
z += bridgeItem.Pose.Position.z;
- auto* sectorPtr = &GetSideSector(bridgeItem.RoomNumber, x, z);
- sectorPtr->RemoveBridge(itemNumber);
+ auto* sector = &GetSideSector(bridgeItem.RoomNumber, x, z);
+ sector->RemoveBridge(itemNumber);
if (bridge.GetFloorBorder != nullptr)
{
int floorBorder = bridge.GetFloorBorder(bridgeItem);
- while (floorBorder <= sectorPtr->GetSurfaceHeight(x, z, false))
+ while (floorBorder <= sector->GetSurfaceHeight(x, z, false))
{
- auto roomNumberAbove = sectorPtr->GetNextRoomNumber(x, z, false);
+ auto roomNumberAbove = sector->GetNextRoomNumber(x, z, false);
if (!roomNumberAbove.has_value())
break;
- sectorPtr = &GetSideSector(*roomNumberAbove, x, z);
- sectorPtr->RemoveBridge(itemNumber);
+ sector = &GetSideSector(*roomNumberAbove, x, z);
+ sector->RemoveBridge(itemNumber);
}
}
if (bridge.GetCeilingBorder != nullptr)
{
int ceilingBorder = bridge.GetCeilingBorder(bridgeItem);
- while (ceilingBorder >= sectorPtr->GetSurfaceHeight(x, z, true))
+ while (ceilingBorder >= sector->GetSurfaceHeight(x, z, true))
{
- auto roomNumberBelow = sectorPtr->GetNextRoomNumber(x, z, true);
+ auto roomNumberBelow = sector->GetNextRoomNumber(x, z, true);
if (!roomNumberBelow.has_value())
break;
- sectorPtr = &GetSideSector(*roomNumberBelow, x, z);
- sectorPtr->RemoveBridge(itemNumber);
+ sector = &GetSideSector(*roomNumberBelow, x, z);
+ sector->RemoveBridge(itemNumber);
}
}
}
diff --git a/TombEngine/Game/collision/floordata.h b/TombEngine/Game/collision/floordata.h
index 891e130f5..be6e2c456 100644
--- a/TombEngine/Game/collision/floordata.h
+++ b/TombEngine/Game/collision/floordata.h
@@ -49,10 +49,10 @@ enum class MaterialType
enum class ClimbDirectionFlags
{
- North = (1 << 8),
- East = (1 << 9),
- South = (1 << 10),
- West = (1 << 11)
+ North = 1 << 8,
+ East = 1 << 9,
+ South = 1 << 10,
+ West = 1 << 11
};
// NOTE: Describes vertical room location.
@@ -135,7 +135,7 @@ struct SectorFlagData
class FloorInfo
{
public:
- // Components
+ // Members
int RoomNumber = 0;
int SidePortalRoomNumber = 0;
SectorSurfaceData FloorSurface = {};
@@ -184,7 +184,7 @@ namespace TEN::Collision::Floordata
Vector2i GetSectorPoint(int x, int z);
Vector2i GetRoomGridCoord(int roomNumber, int x, int z, bool clampToBounds = true);
std::vector GetNeighborRoomGridCoords(const Vector3i& pos, int roomNumber, unsigned int searchDepth);
- std::vector GetNeighborSectorPtrs(const Vector3i& pos, int roomNumber, unsigned int searchDepth);
+ std::vector GetNeighborSectors(const Vector3i& pos, int roomNumber, unsigned int searchDepth);
FloorInfo& GetFloor(int roomNumber, const Vector2i& roomGridCoord);
FloorInfo& GetFloor(int roomNumber, int x, int z);
From 37267e99f198fac77080d61e42323162728efe01 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Thu, 2 May 2024 00:39:12 +1000
Subject: [PATCH 127/410] Give meaning to magic numbers
---
TombEngine/Game/collision/floordata.cpp | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/TombEngine/Game/collision/floordata.cpp b/TombEngine/Game/collision/floordata.cpp
index f1efec5bc..356997d3e 100644
--- a/TombEngine/Game/collision/floordata.cpp
+++ b/TombEngine/Game/collision/floordata.cpp
@@ -519,10 +519,17 @@ namespace TEN::Collision::Floordata
std::optional GetSurfaceHeight(const RoomVector& location, int x, int z, bool isFloor)
{
+ enum class Polarity
+ {
+ None,
+ Floor,
+ Ceiling
+ };
+
auto* sector = &GetSideSector(location.RoomNumber, x, z);
auto pos = Vector3i(x, location.Height, z);
- int polarity = 0;
+ auto polarity = Polarity::None;
if (sector->IsWall(x, z))
{
@@ -531,7 +538,7 @@ namespace TEN::Collision::Floordata
if (!sector->IsWall(x, z))
{
pos.y = sector->GetSurfaceHeight(x, z, isFloor);
- polarity = isFloor ? -1 : 1;
+ polarity = isFloor ? Polarity::Floor : Polarity::Ceiling;
}
else
{
@@ -540,7 +547,7 @@ namespace TEN::Collision::Floordata
if (!sector->IsWall(x, z))
{
pos.y = sector->GetSurfaceHeight(x, z, !isFloor);
- polarity = isFloor ? 1 : -1;
+ polarity = isFloor ? Polarity::Ceiling : Polarity::Floor;
}
else
{
@@ -560,14 +567,14 @@ namespace TEN::Collision::Floordata
if (insideBridgeItemNumber != NO_VALUE)
{
- if (isFloor ? (polarity <= 0) : (polarity >= 0))
+ if (polarity == Polarity::None || (isFloor ? (polarity == Polarity::Floor) : (polarity == Polarity::Ceiling)))
{
auto heightData = GetFarthestHeightData(*sector, pos, !isFloor);
if (heightData.has_value())
return heightData->Height;
}
- if (isFloor ? (polarity >= 0) : (polarity <= 0))
+ if (polarity == Polarity::None || (isFloor ? (polarity == Polarity::Ceiling) : (polarity == Polarity::Floor)))
{
auto heightData = GetFarthestHeightData(*sector, pos, isFloor);
if (!heightData.has_value())
@@ -578,7 +585,7 @@ namespace TEN::Collision::Floordata
}
}
- if (isFloor ? (polarity >= 0) : (polarity <= 0))
+ if (polarity == Polarity::None || (isFloor ? (polarity == Polarity::Ceiling) : (polarity == Polarity::Floor)))
{
auto nextRoomNumber = sector->GetNextRoomNumber(pos, isFloor);
while (nextRoomNumber.has_value())
From 54346e4d85ce59082f1a2bab39213628e8e1795e Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Thu, 2 May 2024 06:03:56 +0200
Subject: [PATCH 128/410] Fixed flickering of strings in title level
---
TombEngine/Renderer/RendererDrawMenu.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/TombEngine/Renderer/RendererDrawMenu.cpp b/TombEngine/Renderer/RendererDrawMenu.cpp
index 3955c77a8..1f940ff8f 100644
--- a/TombEngine/Renderer/RendererDrawMenu.cpp
+++ b/TombEngine/Renderer/RendererDrawMenu.cpp
@@ -1141,7 +1141,7 @@ namespace TEN::Renderer
_context->ClearDepthStencilView(_backBuffer.DepthStencilView.Get(), D3D11_CLEAR_STENCIL | D3D11_CLEAR_DEPTH, 1.0f, 0);
_context->ClearRenderTargetView(_backBuffer.RenderTargetView.Get(), Colors::Black);
- RenderInventoryScene(&_backBuffer, &_dumpScreenRenderTarget, 1.0f);
+ RenderInventoryScene(&_backBuffer, nullptr, 1.0f);
DrawAllStrings();
_swapChain->Present(0, 0);
From e3563bffb1da34ab521d439cda583db26109b95f Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Thu, 2 May 2024 09:19:25 +0300
Subject: [PATCH 129/410] Fix hair glitch when stepping up
---
TombEngine/Game/Lara/lara_helpers.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/TombEngine/Game/Lara/lara_helpers.cpp b/TombEngine/Game/Lara/lara_helpers.cpp
index 35596d7df..31cc6e48c 100644
--- a/TombEngine/Game/Lara/lara_helpers.cpp
+++ b/TombEngine/Game/Lara/lara_helpers.cpp
@@ -1048,6 +1048,8 @@ void HandlePlayerElevationChange(ItemInfo* item, CollisionInfo* coll)
if (CanStepUp(*item, *coll))
{
item->Animation.TargetState = LS_STEP_UP;
+ item->DisableInterpolation = true;
+
if (GetStateDispatch(item, GetAnimData(*item)))
{
item->Pose.Position.y += coll->Middle.Floor;
From 63a8de13f8a3ab6eccbf34e4514c95ce680b27a6 Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Thu, 2 May 2024 09:42:00 +0300
Subject: [PATCH 130/410] Fix leveljumps if 60 FPS is off
---
TombEngine/Game/control/control.cpp | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index dfeab3584..1d548b664 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -609,9 +609,6 @@ GameStatus DoGameLoop(int levelIndex)
if (!g_Configuration.EnableVariableFramerate)
{
- if (status != GameStatus::Normal)
- break;
-
float interpolationFactor = 0.0f;
DrawPhase(!levelIndex, interpolationFactor);
drawCalls++;
@@ -620,13 +617,14 @@ GameStatus DoGameLoop(int levelIndex)
if (g_Configuration.EnableVariableFramerate)
{
- if (status != GameStatus::Normal)
- break;
-
float interpolationFactor = std::min((float)controlLag / (float)controlFrameTime, 1.0f);
DrawPhase(!levelIndex, interpolationFactor);
drawCalls++;
}
+
+ if (status != GameStatus::Normal)
+ break;
+
}
EndGameLoop(levelIndex, status);
From 0a28ddb7cf50f362cbaa563bebc0e1eb20557f68 Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Thu, 2 May 2024 09:47:53 +0300
Subject: [PATCH 131/410] Fix garbage frames on game status change
---
TombEngine/Game/control/control.cpp | 28 +++++++++++++---------------
1 file changed, 13 insertions(+), 15 deletions(-)
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index 1d548b664..6537743d2 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -601,20 +601,6 @@ GameStatus DoGameLoop(int levelIndex)
controlLag += frameTime;
}
- while (controlLag >= controlFrameTime)
- {
- status = ControlPhase(0);
- controlLag -= controlFrameTime;
- controlCalls++;
-
- if (!g_Configuration.EnableVariableFramerate)
- {
- float interpolationFactor = 0.0f;
- DrawPhase(!levelIndex, interpolationFactor);
- drawCalls++;
- }
- }
-
if (g_Configuration.EnableVariableFramerate)
{
float interpolationFactor = std::min((float)controlLag / (float)controlFrameTime, 1.0f);
@@ -622,9 +608,21 @@ GameStatus DoGameLoop(int levelIndex)
drawCalls++;
}
+ while (controlLag >= controlFrameTime)
+ {
+ if (!g_Configuration.EnableVariableFramerate)
+ {
+ DrawPhase(!levelIndex, 0.0f);
+ drawCalls++;
+ }
+
+ status = ControlPhase(0);
+ controlLag -= controlFrameTime;
+ controlCalls++;
+ }
+
if (status != GameStatus::Normal)
break;
-
}
EndGameLoop(levelIndex, status);
From 4e9d4940a7aac84e56a19f1f69f4803b78a41298 Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Thu, 2 May 2024 09:53:21 +0300
Subject: [PATCH 132/410] Simplify code
---
TombEngine/Game/control/control.cpp | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index 6537743d2..13237c9bf 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -601,28 +601,28 @@ GameStatus DoGameLoop(int levelIndex)
controlLag += frameTime;
}
- if (g_Configuration.EnableVariableFramerate)
- {
- float interpolationFactor = std::min((float)controlLag / (float)controlFrameTime, 1.0f);
- DrawPhase(!levelIndex, interpolationFactor);
- drawCalls++;
- }
-
while (controlLag >= controlFrameTime)
{
+ status = ControlPhase(0);
+ controlLag -= controlFrameTime;
+ controlCalls++;
+
if (!g_Configuration.EnableVariableFramerate)
{
DrawPhase(!levelIndex, 0.0f);
drawCalls++;
}
-
- status = ControlPhase(0);
- controlLag -= controlFrameTime;
- controlCalls++;
}
if (status != GameStatus::Normal)
break;
+
+ if (!g_Configuration.EnableVariableFramerate)
+ continue;
+
+ float interpolationFactor = std::min((float)controlLag / (float)controlFrameTime, 1.0f);
+ DrawPhase(!levelIndex, interpolationFactor);
+ drawCalls++;
}
EndGameLoop(levelIndex, status);
From cd7583ab7a74d5ca6079f5b41973670d9042cc01 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Thu, 2 May 2024 14:19:34 +0200
Subject: [PATCH 133/410] Enabled vsync; Better mode switch between 30 and 60
fps; Fixed flickering of strings in level (except for title);
---
TombEngine/Game/control/control.cpp | 8 +++-----
TombEngine/Game/control/control.h | 2 +-
TombEngine/Game/gui.cpp | 19 +++++++++++++------
TombEngine/Renderer/RendererDrawMenu.cpp | 23 ++++++++---------------
4 files changed, 25 insertions(+), 27 deletions(-)
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index 13237c9bf..2e408359a 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -129,7 +129,7 @@ void DrawPhase(bool isTitle, float interpolationFactor)
g_Renderer.Lock();
}
-GameStatus ControlPhase(int numFrames)
+GameStatus ControlPhase()
{
static int framesCount = 0;
@@ -142,8 +142,6 @@ GameStatus ControlPhase(int numFrames)
ClearLensFlares();
ClearDisplaySprites();
- numFrames = std::clamp(numFrames, 0, 10);
-
if (TrackCameraInit)
{
UseSpotCam = false;
@@ -568,7 +566,7 @@ GameStatus DoGameLoop(int levelIndex)
// Before entering actual game loop, ControlPhase must be
// called once to sort out various runtime shenanigangs (e.g. hair).
- status = ControlPhase(numFrames);
+ status = ControlPhase();
LARGE_INTEGER lastTime;
LARGE_INTEGER currentTime;
@@ -603,7 +601,7 @@ GameStatus DoGameLoop(int levelIndex)
while (controlLag >= controlFrameTime)
{
- status = ControlPhase(0);
+ status = ControlPhase();
controlLag -= controlFrameTime;
controlCalls++;
diff --git a/TombEngine/Game/control/control.h b/TombEngine/Game/control/control.h
index cd44f11e2..955729e68 100644
--- a/TombEngine/Game/control/control.h
+++ b/TombEngine/Game/control/control.h
@@ -83,7 +83,7 @@ extern std::vector OutsideRoomTable[OUTSIDE_SIZE][OUTSIDE_SIZE];
void DrawPhase(bool isTitle, float interpolationFactor);
-GameStatus ControlPhase(int numFrames);
+GameStatus ControlPhase();
GameStatus DoLevel(int levelIndex, bool loadGame = false);
GameStatus DoGameLoop(int levelIndex);
void EndGameLoop(int levelIndex, GameStatus reason);
diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp
index 0e5d311a9..18cb9d315 100644
--- a/TombEngine/Game/gui.cpp
+++ b/TombEngine/Game/gui.cpp
@@ -745,14 +745,19 @@ namespace TEN::Gui
if (fromPauseMenu)
{
g_Renderer.RenderInventory();
- Camera.numberFrames = g_Renderer.Synchronize();
+ if (!g_Configuration.EnableVariableFramerate)
+ {
+ g_Renderer.Synchronize();
+ }
}
else
{
g_Renderer.RenderTitle(0);
- Camera.numberFrames = g_Renderer.Synchronize();
- int numFrames = Camera.numberFrames;
- ControlPhase(numFrames);
+ if (!g_Configuration.EnableVariableFramerate)
+ {
+ g_Renderer.Synchronize();
+ }
+ ControlPhase();
}
}
}
@@ -3323,7 +3328,6 @@ namespace TEN::Gui
}
DrawInventory();
- DrawCompass(item);
switch (InvMode)
{
@@ -3381,7 +3385,10 @@ namespace TEN::Gui
SetEnterInventory(NO_VALUE);
- Camera.numberFrames = g_Renderer.Synchronize();
+ if (!g_Configuration.EnableVariableFramerate)
+ {
+ g_Renderer.Synchronize();
+ }
}
LastInvItem = Rings[(int)RingTypes::Inventory].CurrentObjectList[Rings[(int)RingTypes::Inventory].CurrentObjectInList].InventoryItem;
diff --git a/TombEngine/Renderer/RendererDrawMenu.cpp b/TombEngine/Renderer/RendererDrawMenu.cpp
index 1f940ff8f..6fc1176aa 100644
--- a/TombEngine/Renderer/RendererDrawMenu.cpp
+++ b/TombEngine/Renderer/RendererDrawMenu.cpp
@@ -876,7 +876,7 @@ namespace TEN::Renderer
DrawFullScreenImage(texture.ShaderResourceView.Get(), Smoothstep(currentFade), _backBuffer.RenderTargetView.Get(), _backBuffer.DepthStencilView.Get());
Synchronize();
- _swapChain->Present(0, 0);
+ _swapChain->Present(1, 0);
_context->ClearDepthStencilView(_backBuffer.DepthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
}
}
@@ -957,6 +957,9 @@ namespace TEN::Renderer
_context->RSSetViewports(1, &_viewport);
ResetScissor();
+ _context->ClearDepthStencilView(_renderTarget.DepthStencilView.Get(), D3D11_CLEAR_STENCIL | D3D11_CLEAR_DEPTH, 1.0f, 0);
+ _context->ClearRenderTargetView(_renderTarget.RenderTargetView.Get(), Colors::Black);
+
if (background != nullptr)
{
DrawFullScreenImage(background->ShaderResourceView.Get(), backgroundFade, _renderTarget.RenderTargetView.Get(), _renderTarget.DepthStencilView.Get());
@@ -1091,7 +1094,7 @@ namespace TEN::Renderer
if (ScreenFadeCurrent && percentage > 0.0f && percentage < 100.0f)
DrawLoadingBar(percentage);
- _swapChain->Present(0, 0);
+ _swapChain->Present(1, 0);
_context->ClearState();
Synchronize();
@@ -1107,17 +1110,7 @@ namespace TEN::Renderer
RenderInventoryScene(&_backBuffer, &_dumpScreenRenderTarget, 0.5f);
- _swapChain->Present(0, 0);
-
- if (g_Configuration.EnableVariableFramerate)
- {
- _context->ClearDepthStencilView(_backBuffer.DepthStencilView.Get(), D3D11_CLEAR_STENCIL | D3D11_CLEAR_DEPTH, 1.0f, 0);
- _context->ClearRenderTargetView(_backBuffer.RenderTargetView.Get(), Colors::Black);
-
- RenderInventoryScene(&_backBuffer, &_dumpScreenRenderTarget, 0.5f);
-
- _swapChain->Present(0, 0);
- }
+ _swapChain->Present(1, 0);
}
void Renderer::RenderTitle(float interpolationFactor)
@@ -1141,10 +1134,10 @@ namespace TEN::Renderer
_context->ClearDepthStencilView(_backBuffer.DepthStencilView.Get(), D3D11_CLEAR_STENCIL | D3D11_CLEAR_DEPTH, 1.0f, 0);
_context->ClearRenderTargetView(_backBuffer.RenderTargetView.Get(), Colors::Black);
- RenderInventoryScene(&_backBuffer, nullptr, 1.0f);
+ RenderInventoryScene(&_backBuffer, &_dumpScreenRenderTarget, 1.0f);
DrawAllStrings();
- _swapChain->Present(0, 0);
+ _swapChain->Present(1, 0);
}
void Renderer::DrawDebugInfo(RenderView& view)
From 2c59e89fc4b4ed72727dc20d2770b0e8e778d633 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Thu, 2 May 2024 16:31:22 +0200
Subject: [PATCH 134/410] Fixed vsync at screen initialization; Fixed rotation
of inventory objects;
---
TombEngine/Game/gui.cpp | 7 +++----
TombEngine/Renderer/RendererInit.cpp | 14 ++++++++++++--
2 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp
index 18cb9d315..7767da684 100644
--- a/TombEngine/Game/gui.cpp
+++ b/TombEngine/Game/gui.cpp
@@ -2808,7 +2808,6 @@ namespace TEN::Gui
float multiplier = g_Configuration.EnableVariableFramerate ? 2.0f : 1.0f;
-
if (ring.CurrentObjectList <= 0)
return;
@@ -3134,13 +3133,13 @@ namespace TEN::Gui
if (!i && !ring.ObjectListMovement)
{
if (invObject.RotFlags & INV_ROT_X)
- listObject.Orientation.x += ANGLE(5.0f);
+ listObject.Orientation.x += ANGLE(5.0f / multiplier);
if (invObject.RotFlags & INV_ROT_Y)
- listObject.Orientation.y += ANGLE(5.0f);
+ listObject.Orientation.y += ANGLE(5.0f / multiplier);
if (invObject.RotFlags & INV_ROT_Z)
- listObject.Orientation.z += ANGLE(5.0f);
+ listObject.Orientation.z += ANGLE(5.0f / multiplier);
}
else
{
diff --git a/TombEngine/Renderer/RendererInit.cpp b/TombEngine/Renderer/RendererInit.cpp
index b918d6a4d..9eb926176 100644
--- a/TombEngine/Renderer/RendererInit.cpp
+++ b/TombEngine/Renderer/RendererInit.cpp
@@ -463,8 +463,18 @@ namespace TEN::Renderer
DXGI_SWAP_CHAIN_DESC sd;
sd.BufferDesc.Width = w;
sd.BufferDesc.Height = h;
- sd.BufferDesc.RefreshRate.Numerator = 0;
- sd.BufferDesc.RefreshRate.Denominator = 0;
+ if (!g_Configuration.EnableVariableFramerate)
+ {
+ sd.BufferDesc.RefreshRate.Numerator = 0;
+ sd.BufferDesc.RefreshRate.Denominator = 0;
+ }
+ else
+ {
+ sd.BufferDesc.RefreshRate.Numerator = 60;
+ sd.BufferDesc.RefreshRate.Denominator = 1;
+ }
+ sd.BufferDesc.RefreshRate.Numerator = 60;
+ sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
sd.BufferDesc.Scaling = DXGI_MODE_SCALING_STRETCHED;
From 46d2de40a0bbc978ee5005c07f00d2b627767aaf Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Fri, 3 May 2024 09:01:36 +0200
Subject: [PATCH 135/410] Possible fix for debug mode
---
TombEngine/Game/control/control.cpp | 12 ++++++++++++
TombEngine/Renderer/RendererDrawMenu.cpp | 1 +
2 files changed, 13 insertions(+)
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index 2e408359a..19c97faea 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -601,6 +601,18 @@ GameStatus DoGameLoop(int levelIndex)
while (controlLag >= controlFrameTime)
{
+#if _DEBUG
+
+ constexpr auto DEBUG_SKIP_FRAMES = 10;
+
+ if (controlLag >= DEBUG_SKIP_FRAMES * controlFrameTime)
+ {
+ TENLog("Game loop is running too slow!", LogLevel::Warning);
+ App.ResetClock = true;
+ break;
+ }
+#endif
+
status = ControlPhase();
controlLag -= controlFrameTime;
controlCalls++;
diff --git a/TombEngine/Renderer/RendererDrawMenu.cpp b/TombEngine/Renderer/RendererDrawMenu.cpp
index 6fc1176aa..f38ba9add 100644
--- a/TombEngine/Renderer/RendererDrawMenu.cpp
+++ b/TombEngine/Renderer/RendererDrawMenu.cpp
@@ -1137,6 +1137,7 @@ namespace TEN::Renderer
RenderInventoryScene(&_backBuffer, &_dumpScreenRenderTarget, 1.0f);
DrawAllStrings();
+ _context->ClearState();
_swapChain->Present(1, 0);
}
From 57cf323d7325b800200198a05218fc51cb3d303c Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Fri, 3 May 2024 10:16:32 +0300
Subject: [PATCH 136/410] Add autodelete parameter to ShowString
---
Documentation/doc/1 modules/Strings.html | 11 +++++++++--
.../Scripting/Internal/TEN/Strings/StringsHandler.cpp | 9 +++++++--
.../Scripting/Internal/TEN/Strings/StringsHandler.h | 2 +-
3 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/Documentation/doc/1 modules/Strings.html b/Documentation/doc/1 modules/Strings.html
index 63f90605b..c56b1fd46 100644
--- a/Documentation/doc/1 modules/Strings.html
+++ b/Documentation/doc/1 modules/Strings.html
@@ -109,7 +109,7 @@
- ShowString(str, time)
+ ShowString(str, time, autoDelete)
Show some text on-screen.
@@ -131,7 +131,7 @@
- ShowString(str, time)
+ ShowString(str, time, autoDelete)
Show some text on-screen.
@@ -151,6 +151,13 @@ If not given, the string will have an "infinite" life, and will show
until HideString is called or until the level is finished.
Default: nil (i.e. infinite)
+ autoDelete
+ bool
+ should be string automatically deleted after timeout is reached.
+If not given, the string will remain allocated even after timeout is reached, and can be
+shown again without re-initialization.
+Default: false
+
diff --git a/TombEngine/Scripting/Internal/TEN/Strings/StringsHandler.cpp b/TombEngine/Scripting/Internal/TEN/Strings/StringsHandler.cpp
index d2b5ba582..2f34efd13 100644
--- a/TombEngine/Scripting/Internal/TEN/Strings/StringsHandler.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Strings/StringsHandler.cpp
@@ -27,6 +27,10 @@ Show some text on-screen.
If not given, the string will have an "infinite" life, and will show
until @{HideString} is called or until the level is finished.
Default: nil (i.e. infinite)
+@tparam bool autoDelete should be string automatically deleted after timeout is reached.
+If not given, the string will remain allocated even after timeout is reached, and can be
+shown again without re-initialization.
+Default: false
*/
table.set_function(ScriptReserved_ShowString, &StringsHandler::ShowString, this);
@@ -36,7 +40,7 @@ Hide some on-screen text.
@tparam DisplayString str the string object to hide. Must previously have been shown
with a call to @{ShowString}, or this function will have no effect.
*/
- table.set_function(ScriptReserved_HideString, [this](const DisplayString& string) { ShowString(string, 0.0f); });
+ table.set_function(ScriptReserved_HideString, [this](const DisplayString& string) { ShowString(string, 0.0f, false); });
/***
Checks if the string is shown
@@ -84,11 +88,12 @@ bool StringsHandler::SetDisplayString(DisplayStringID id, const UserDisplayStrin
return m_userDisplayStrings.insert_or_assign(id, displayString).second;
}
-void StringsHandler::ShowString(const DisplayString& str, sol::optional numSeconds)
+void StringsHandler::ShowString(const DisplayString& str, sol::optional numSeconds, sol::optional autoDelete)
{
auto it = m_userDisplayStrings.find(str.GetID());
it->second._timeRemaining = numSeconds.value_or(0.0f);
it->second._isInfinite = !numSeconds.has_value();
+ it->second._deleteWhenZero = autoDelete.value_or(false);
}
bool StringsHandler::IsStringDisplaying(const DisplayString& displayString)
diff --git a/TombEngine/Scripting/Internal/TEN/Strings/StringsHandler.h b/TombEngine/Scripting/Internal/TEN/Strings/StringsHandler.h
index 6b28edf85..96c10f7db 100644
--- a/TombEngine/Scripting/Internal/TEN/Strings/StringsHandler.h
+++ b/TombEngine/Scripting/Internal/TEN/Strings/StringsHandler.h
@@ -26,7 +26,7 @@ public:
std::optional> GetDisplayString(DisplayStringID id);
bool ScheduleRemoveDisplayString(DisplayStringID id);
- void ShowString(DisplayString const&, sol::optional nSeconds);
+ void ShowString(DisplayString const&, sol::optional nSeconds, sol::optional autoDelete);
bool IsStringDisplaying(DisplayString const& str);
From 1bf60287e3ac5c4be06ac51edd71d357650c0c92 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Fri, 3 May 2024 23:55:31 +1000
Subject: [PATCH 137/410] Fix bouncing pushables
---
.../Generic/Object/Pushable/PushableCollision.cpp | 9 +++++----
.../Objects/Generic/Object/Pushable/PushableObject.cpp | 2 +-
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp b/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
index 733ae4c86..b41cf3b11 100644
--- a/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
+++ b/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
@@ -13,8 +13,8 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
-using namespace TEN::Collision::Point;
using namespace TEN::Collision::Floordata;
+using namespace TEN::Collision::Point;
using namespace TEN::Entities::Generic;
using namespace TEN::Input;
@@ -307,7 +307,9 @@ namespace TEN::Entities::Generic
RemovePushableBridge(item);
pointColl = GetPointCollision(item);
- waterHeight = GetWaterSurface(item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z, item.RoomNumber);
+ pointColl.GetFloorHeight();
+
+ waterHeight = pointColl.GetWaterSurfaceHeight();
if (waterHeight == NO_HEIGHT && TestEnvironment(ENV_FLAG_SWAMP, item.RoomNumber))
waterHeight = g_Level.Rooms[item.RoomNumber].maxceiling;
@@ -316,8 +318,7 @@ namespace TEN::Entities::Generic
}
else
{
- pointColl = GetPointCollision(item);
- waterHeight = GetWaterSurface(item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z, item.RoomNumber);
+ waterHeight = pointColl.GetWaterSurfaceHeight();
if (waterHeight == NO_HEIGHT && TestEnvironment(ENV_FLAG_SWAMP, item.RoomNumber))
waterHeight = g_Level.Rooms[item.RoomNumber].maxceiling;
diff --git a/TombEngine/Objects/Generic/Object/Pushable/PushableObject.cpp b/TombEngine/Objects/Generic/Object/Pushable/PushableObject.cpp
index 491caea4f..4ef806982 100644
--- a/TombEngine/Objects/Generic/Object/Pushable/PushableObject.cpp
+++ b/TombEngine/Objects/Generic/Object/Pushable/PushableObject.cpp
@@ -227,7 +227,7 @@ namespace TEN::Entities::Generic
void SetPushableStopperFlag(bool isStopper, const Vector3i& pos, int roomNumber)
{
auto pointColl = GetPointCollision(pos, roomNumber);
- pointColl.GetSector().Stopper = isStopper;
+ pointColl.GetSector().Stopper = isStopper;
// TODO: There is a problem, it also has to set/reset the flag in the flipped room.
// Because when flipmaps happens, it forgets about the old flag.
From 3faf25c92f2cbfd0f48c071465f7e61cd09eddd3 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Fri, 3 May 2024 23:59:38 +1000
Subject: [PATCH 138/410] Fix pushable grab ban
---
.../Objects/Generic/Object/Pushable/PushableCollision.cpp | 3 +++
1 file changed, 3 insertions(+)
diff --git a/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp b/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
index b41cf3b11..bf526c49a 100644
--- a/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
+++ b/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
@@ -34,7 +34,10 @@ namespace TEN::Entities::Generic
if (pushable.UseRoomCollision)
{
RemovePushableBridge(pushableItem);
+
pointColl = GetPointCollision(pushableItem);
+ pointColl.GetFloorHeight();
+
AddPushableBridge(pushableItem);
}
From 7b7473b660ce93c82ebc48dd218b4a035a075734 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Sat, 4 May 2024 06:02:44 +0200
Subject: [PATCH 139/410] Added laser beams interpolation; Addes streamer
interpolation; Added sparks interpolation; Cleaned smoke interpolation;
---
TombEngine/Game/control/control.cpp | 1 -
TombEngine/Game/effects/Streamer.cpp | 9 ++
TombEngine/Game/effects/Streamer.h | 4 +
TombEngine/Game/effects/smoke.cpp | 38 +-------
TombEngine/Game/effects/smoke.h | 9 ++
TombEngine/Game/effects/spark.cpp | 2 +
TombEngine/Game/effects/spark.h | 9 ++
TombEngine/Objects/TR5/Trap/LaserBeam.cpp | 12 +++
TombEngine/Objects/TR5/Trap/LaserBeam.h | 5 +
TombEngine/Renderer/RendererDrawEffect.cpp | 103 ++++++++++++++++-----
10 files changed, 130 insertions(+), 62 deletions(-)
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index 19c97faea..942b3d875 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -602,7 +602,6 @@ GameStatus DoGameLoop(int levelIndex)
while (controlLag >= controlFrameTime)
{
#if _DEBUG
-
constexpr auto DEBUG_SKIP_FRAMES = 10;
if (controlLag >= DEBUG_SKIP_FRAMES * controlFrameTime)
diff --git a/TombEngine/Game/effects/Streamer.cpp b/TombEngine/Game/effects/Streamer.cpp
index ec7bad158..48ffb14f8 100644
--- a/TombEngine/Game/effects/Streamer.cpp
+++ b/TombEngine/Game/effects/Streamer.cpp
@@ -21,6 +21,8 @@ namespace TEN::Effects::Streamer
void Streamer::StreamerSegment::Update()
{
+ StoreInterpolationData();
+
// Update opacity.
if (Color.w > 0.0f)
Color.w = InterpolateCos(0.0f, OpacityMax, Life / LifeMax);
@@ -36,6 +38,13 @@ namespace TEN::Effects::Streamer
Life -= 1.0f;
}
+ void Streamer::StreamerSegment::StoreInterpolationData()
+ {
+ OldVertices[0] = Vertices[0];
+ OldVertices[1] = Vertices[1];
+ OldColor = Color;
+ }
+
void Streamer::StreamerSegment::TransformVertices(float vel, float scaleRate)
{
// Apply expansion.
diff --git a/TombEngine/Game/effects/Streamer.h b/TombEngine/Game/effects/Streamer.h
index ea712a44a..5a189d83d 100644
--- a/TombEngine/Game/effects/Streamer.h
+++ b/TombEngine/Game/effects/Streamer.h
@@ -39,11 +39,15 @@ namespace TEN::Effects::Streamer
std::array Vertices = {};
+ std::array OldVertices = {};
+ Vector4 OldColor = Vector4::Zero;
+
void InitializeVertices(const Vector3& pos, float width);
void Update();
private:
void TransformVertices(float vel, float scaleRate);
+ void StoreInterpolationData();
};
// Members
diff --git a/TombEngine/Game/effects/smoke.cpp b/TombEngine/Game/effects/smoke.cpp
index a428f893f..ed5c78535 100644
--- a/TombEngine/Game/effects/smoke.cpp
+++ b/TombEngine/Game/effects/smoke.cpp
@@ -45,6 +45,8 @@ namespace TEN::Effects::Smoke
if (!s.active)
continue;
+ s.StoreInterpolationData();
+
s.age += 1;
if (s.age > s.life)
{
@@ -52,12 +54,6 @@ namespace TEN::Effects::Smoke
continue;
}
- // Interpolation
- s.oldPosition = s.position;
- s.oldColor = s.color;
- s.oldRotation = s.rotation;
- s.oldSize = s.size;
-
s.velocity.y += s.gravity;
if (s.terminalVelocity != 0)
@@ -114,11 +110,6 @@ namespace TEN::Effects::Smoke
s.affectedByWind = true;
s.active = true;
s.room = room;
-
- s.oldPosition = s.position;
- s.oldColor = s.color;
- s.oldRotation = s.rotation;
- s.oldSize = s.size;
}
//TODO: add additional "Weapon Special" param or something. Currently initial == 2 means Rocket Launcher backwards smoke.
@@ -205,11 +196,6 @@ namespace TEN::Effects::Smoke
s.angularVelocity = Random::GenerateFloat(-PI_DIV_4, PI_DIV_4);
s.angularDrag = 0.95f;
s.room = roomNumber;
-
- s.oldPosition = s.position;
- s.oldColor = s.color;
- s.oldRotation = s.rotation;
- s.oldSize = s.size;
}
void TriggerQuadExhaustSmoke(int x, int y, int z, short angle, int velocity, int moving)
@@ -233,11 +219,6 @@ namespace TEN::Effects::Smoke
s.destinationSize = Random::GenerateFloat(128, 160);
s.angularVelocity = Random::GenerateFloat(-1, 1);
s.angularDrag = Random::GenerateFloat(0.97f, 0.999f);
-
- s.oldPosition = s.position;
- s.oldColor = s.color;
- s.oldRotation = s.rotation;
- s.oldSize = s.size;
}
void TriggerRocketSmoke(int x, int y, int z)
@@ -257,11 +238,6 @@ namespace TEN::Effects::Smoke
s.destinationSize = Random::GenerateFloat(1024, 1152);
s.angularVelocity = Random::GenerateFloat(-0.6f, 0.6f);
s.angularDrag = Random::GenerateFloat(0.87f, 0.99f);
-
- s.oldPosition = s.position;
- s.oldColor = s.color;
- s.oldRotation = s.rotation;
- s.oldSize = s.size;
}
void SpawnCorpseEffect(const Vector3& pos)
@@ -285,11 +261,6 @@ namespace TEN::Effects::Smoke
smoke.destinationSize = Random::GenerateFloat(BLOCK(1), BLOCK(1.1f));
smoke.angularVelocity = Random::GenerateFloat(-0.1f, 0.1f);
smoke.angularDrag = Random::GenerateFloat(0.8f, 0.9f);
-
- smoke.oldPosition = smoke.position;
- smoke.oldColor = smoke.color;
- smoke.oldRotation = smoke.rotation;
- smoke.oldSize = smoke.size;
}
void TriggerBreathSmoke(long x, long y, long z, short angle)
@@ -313,10 +284,5 @@ namespace TEN::Effects::Smoke
s.destinationSize = Random::GenerateFloat(128, 160);
s.angularVelocity = Random::GenerateFloat(-0.5f, 0.5f);
s.angularDrag = Random::GenerateFloat(0.95f, 0.95f);
-
- s.oldPosition = s.position;
- s.oldColor = s.color;
- s.oldRotation = s.rotation;
- s.oldSize = s.size;
}
}
diff --git a/TombEngine/Game/effects/smoke.h b/TombEngine/Game/effects/smoke.h
index 41fef8a8f..fb0dfb7ab 100644
--- a/TombEngine/Game/effects/smoke.h
+++ b/TombEngine/Game/effects/smoke.h
@@ -27,10 +27,19 @@ namespace TEN::Effects::Smoke
float terminalVelocity;
bool affectedByWind;
bool active;
+
Vector4 oldColor;
Vector3 oldPosition;
float oldRotation;
float oldSize;
+
+ void StoreInterpolationData()
+ {
+ oldColor = color;
+ oldPosition = position;
+ oldRotation = rotation;
+ oldSize = size;
+ }
};
extern std::array SmokeParticles;
diff --git a/TombEngine/Game/effects/spark.cpp b/TombEngine/Game/effects/spark.cpp
index 3cf7fcb9f..521906e6d 100644
--- a/TombEngine/Game/effects/spark.cpp
+++ b/TombEngine/Game/effects/spark.cpp
@@ -23,6 +23,8 @@ namespace TEN::Effects::Spark
if (!s.active)
continue;
+
+ s.StoreInterpolationData();
s.age += 1;
if (s.age > s.life)
diff --git a/TombEngine/Game/effects/spark.h b/TombEngine/Game/effects/spark.h
index 308d43f41..34fe6b386 100644
--- a/TombEngine/Game/effects/spark.h
+++ b/TombEngine/Game/effects/spark.h
@@ -22,6 +22,15 @@ namespace TEN::Effects::Spark
float width;
float height;
bool active;
+
+ Vector3 oldPos;
+ Vector3 oldVelocity;
+
+ void StoreInterpolationData()
+ {
+ oldPos = pos;
+ oldVelocity = velocity;
+ }
};
extern std::array SparkParticles;
diff --git a/TombEngine/Objects/TR5/Trap/LaserBeam.cpp b/TombEngine/Objects/TR5/Trap/LaserBeam.cpp
index ae227bcbc..130d30cb2 100644
--- a/TombEngine/Objects/TR5/Trap/LaserBeam.cpp
+++ b/TombEngine/Objects/TR5/Trap/LaserBeam.cpp
@@ -80,6 +80,16 @@ namespace TEN::Traps::TR5
TriggerDynamicLight(pos, color * intensityNorm, FALLOFF);
}
+ void LaserBeamEffect::StoreInterpolationData()
+ {
+ for (int i = 0; i < Vertices.size(); i++)
+ {
+ OldVertices[i] = Vertices[i];
+ }
+
+ OldColor = Color;
+ }
+
void LaserBeamEffect::Update(const ItemInfo& item)
{
auto orient = EulerAngles(item.Pose.Orientation.x + ANGLE(180.0f), item.Pose.Orientation.y, item.Pose.Orientation.z);
@@ -154,6 +164,8 @@ namespace TEN::Traps::TR5
return;
}
+ beam.StoreInterpolationData();
+
// Brightness fade-in and distortion.
if (item.Model.Color.w < 1.0f)
item.Model.Color.w += 0.02f;
diff --git a/TombEngine/Objects/TR5/Trap/LaserBeam.h b/TombEngine/Objects/TR5/Trap/LaserBeam.h
index 168e1e2fc..64a6056d6 100644
--- a/TombEngine/Objects/TR5/Trap/LaserBeam.h
+++ b/TombEngine/Objects/TR5/Trap/LaserBeam.h
@@ -22,8 +22,13 @@ namespace TEN::Traps::TR5
bool IsLethal = false;
bool IsHeavyActivator = false;
+ std::array OldVertices = {};
+ Vector4 OldColor;
+
void Initialize(const ItemInfo& item);
void Update(const ItemInfo& item);
+
+ void StoreInterpolationData();
};
extern std::unordered_map LaserBeams;
diff --git a/TombEngine/Renderer/RendererDrawEffect.cpp b/TombEngine/Renderer/RendererDrawEffect.cpp
index 0c4cab6c0..8b4dfe37a 100644
--- a/TombEngine/Renderer/RendererDrawEffect.cpp
+++ b/TombEngine/Renderer/RendererDrawEffect.cpp
@@ -88,14 +88,32 @@ namespace TEN::Renderer
{
bool isLastSubdivision = (i == (LaserBeamEffect::SUBDIVISION_COUNT - 1));
+ Vector4 color = Vector4::Lerp(beam.OldColor, beam.Color, _interpolationFactor);
+
AddColoredQuad(
- beam.Vertices[i],
- beam.Vertices[isLastSubdivision ? 0 : (i + 1)],
- beam.Vertices[LaserBeamEffect::SUBDIVISION_COUNT + (isLastSubdivision ? 0 : (i + 1))],
- beam.Vertices[LaserBeamEffect::SUBDIVISION_COUNT + i],
- beam.Color, beam.Color,
- beam.Color, beam.Color,
- BlendMode::Additive, view, SpriteRenderType::LaserBeam);
+ Vector3::Lerp(
+ beam.OldVertices[i],
+ beam.Vertices[i],
+ _interpolationFactor),
+ Vector3::Lerp(
+ beam.OldVertices[isLastSubdivision ? 0 : (i + 1)],
+ beam.Vertices[isLastSubdivision ? 0 : (i + 1)],
+ _interpolationFactor),
+ Vector3::Lerp(
+ beam.OldVertices[LaserBeamEffect::SUBDIVISION_COUNT + (isLastSubdivision ? 0 : (i + 1))],
+ beam.Vertices[LaserBeamEffect::SUBDIVISION_COUNT + (isLastSubdivision ? 0 : (i + 1))],
+ _interpolationFactor),
+ Vector3::Lerp(
+ beam.OldVertices[LaserBeamEffect::SUBDIVISION_COUNT + i],
+ beam.Vertices[LaserBeamEffect::SUBDIVISION_COUNT + i],
+ _interpolationFactor),
+ color,
+ color,
+ color,
+ color,
+ BlendMode::Additive,
+ view,
+ SpriteRenderType::LaserBeam);
}
}
}
@@ -126,29 +144,44 @@ namespace TEN::Renderer
if (segment.Flags & (int)StreamerFlags::FadeLeft)
{
AddColoredQuad(
- segment.Vertices[0], segment.Vertices[1],
- prevSegment.Vertices[1], prevSegment.Vertices[0],
- Vector4::Zero, segment.Color,
- prevSegment.Color, Vector4::Zero,
- blendMode, view);
+ Vector3::Lerp(segment.OldVertices[0], segment.Vertices[0], _interpolationFactor),
+ Vector3::Lerp(segment.OldVertices[1], segment.Vertices[1], _interpolationFactor),
+ Vector3::Lerp(prevSegment.OldVertices[1], prevSegment.Vertices[1], _interpolationFactor),
+ Vector3::Lerp(prevSegment.OldVertices[0], prevSegment.Vertices[0], _interpolationFactor),
+ Vector4::Zero,
+ Vector4::Lerp(segment.OldColor, segment.Color, _interpolationFactor),
+ Vector4::Lerp(prevSegment.OldColor, prevSegment.Color, _interpolationFactor),
+ Vector4::Zero,
+ blendMode,
+ view);
}
else if (segment.Flags & (int)StreamerFlags::FadeRight)
{
AddColoredQuad(
- segment.Vertices[0], segment.Vertices[1],
- prevSegment.Vertices[1], prevSegment.Vertices[0],
- segment.Color, Vector4::Zero,
- Vector4::Zero, prevSegment.Color,
- blendMode, view);
+ Vector3::Lerp(segment.OldVertices[0], segment.Vertices[0], _interpolationFactor),
+ Vector3::Lerp(segment.OldVertices[1], segment.Vertices[1], _interpolationFactor),
+ Vector3::Lerp(prevSegment.OldVertices[1], prevSegment.Vertices[1], _interpolationFactor),
+ Vector3::Lerp(prevSegment.OldVertices[0], prevSegment.Vertices[0], _interpolationFactor),
+ Vector4::Lerp(segment.OldColor, segment.Color, _interpolationFactor),
+ Vector4::Zero,
+ Vector4::Zero,
+ Vector4::Lerp(prevSegment.OldColor, prevSegment.Color, _interpolationFactor),
+ blendMode,
+ view);
}
else
{
AddColoredQuad(
- segment.Vertices[0], segment.Vertices[1],
- prevSegment.Vertices[1], prevSegment.Vertices[0],
- segment.Color, segment.Color,
- prevSegment.Color, prevSegment.Color,
- blendMode, view);
+ Vector3::Lerp(segment.OldVertices[0], segment.Vertices[0], _interpolationFactor),
+ Vector3::Lerp(segment.OldVertices[1], segment.Vertices[1], _interpolationFactor),
+ Vector3::Lerp(prevSegment.OldVertices[1], prevSegment.Vertices[1], _interpolationFactor),
+ Vector3::Lerp(prevSegment.OldVertices[0], prevSegment.Vertices[0], _interpolationFactor),
+ Vector4::Lerp(segment.OldColor, segment.Color, _interpolationFactor),
+ Vector4::Lerp(segment.OldColor, segment.Color, _interpolationFactor),
+ Vector4::Lerp(prevSegment.OldColor, prevSegment.Color, _interpolationFactor),
+ Vector4::Lerp(prevSegment.OldColor, prevSegment.Color, _interpolationFactor),
+ blendMode,
+ view);
}
}
}
@@ -1505,16 +1538,36 @@ namespace TEN::Renderer
if (!s.active) continue;
if (!CheckIfSlotExists(ID_SPARK_SPRITE, "Spark particle rendering"))
+ {
return;
+ }
- Vector3 v;
- s.velocity.Normalize(v);
+ Vector3 oldVelocity;
+ Vector3 velocity;
+ s.oldVelocity.Normalize(oldVelocity);
+ s.velocity.Normalize(velocity);
+
+ velocity = Vector3::Lerp(oldVelocity, velocity, _interpolationFactor);
+ velocity.Normalize();
float normalizedLife = s.age / s.life;
auto height = Lerp(1.0f, 0.0f, normalizedLife);
auto color = Vector4::Lerp(s.sourceColor, s.destinationColor, normalizedLife);
- AddSpriteBillboardConstrained(&_sprites[Objects[ID_SPARK_SPRITE].meshIndex], s.pos, color, 0, 1, { s.width, s.height * height }, BlendMode::Additive, -v, false, view);
+ AddSpriteBillboardConstrained(
+ &_sprites[Objects[ID_SPARK_SPRITE].meshIndex],
+ Vector3::Lerp(s.oldPos, s.pos, _interpolationFactor),
+ color,
+ 0,
+ 1,
+ {
+ s.width,
+ s.height * height
+ },
+ BlendMode::Additive,
+ -velocity,
+ false,
+ view);
}
}
From ee3bc5db0f8c5c6bf5d5007c537e307aff4b3053 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Sun, 5 May 2024 05:54:21 +0200
Subject: [PATCH 140/410] Fixed display sprites multiple draws
---
TombEngine/Game/Hud/Speedometer.cpp | 6 ++++--
TombEngine/Game/Hud/TargetHighlighter.cpp | 4 ++--
TombEngine/Game/control/control.cpp | 4 ++--
TombEngine/Game/effects/DisplaySprite.cpp | 13 +++++++++++--
TombEngine/Game/effects/DisplaySprite.h | 14 ++++++++++++--
TombEngine/Renderer/RendererDraw.cpp | 5 +++++
.../TEN/DisplaySprite/ScriptDisplaySprite.cpp | 3 ++-
7 files changed, 38 insertions(+), 11 deletions(-)
diff --git a/TombEngine/Game/Hud/Speedometer.cpp b/TombEngine/Game/Hud/Speedometer.cpp
index 5768c69cf..edd22a230 100644
--- a/TombEngine/Game/Hud/Speedometer.cpp
+++ b/TombEngine/Game/Hud/Speedometer.cpp
@@ -64,13 +64,15 @@ namespace TEN::Hud
AddDisplaySprite(
ID_SPEEDOMETER, DIAL_ELEMENT_SPRITE_ID,
POS, 0, SCALE, color,
- DIAL_PRIORITY, DisplaySpriteAlignMode::Center, DisplaySpriteScaleMode::Fit, BlendMode::AlphaBlend);
+ DIAL_PRIORITY, DisplaySpriteAlignMode::Center, DisplaySpriteScaleMode::Fit, BlendMode::AlphaBlend,
+ DisplaySpriteSource::DrawPhase);
// Draw pointer.
AddDisplaySprite(
ID_SPEEDOMETER, POINTER_ELEMENT_SPRITE_ID,
POS, _pointerAngle + ORIENT_OFFSET, SCALE, color,
- POINTER_PRIORITY, DisplaySpriteAlignMode::Center, DisplaySpriteScaleMode::Fit, BlendMode::AlphaBlend);
+ POINTER_PRIORITY, DisplaySpriteAlignMode::Center, DisplaySpriteScaleMode::Fit, BlendMode::AlphaBlend,
+ DisplaySpriteSource::DrawPhase);
}
void SpeedometerController::Clear()
diff --git a/TombEngine/Game/Hud/TargetHighlighter.cpp b/TombEngine/Game/Hud/TargetHighlighter.cpp
index 34638f991..8ad619221 100644
--- a/TombEngine/Game/Hud/TargetHighlighter.cpp
+++ b/TombEngine/Game/Hud/TargetHighlighter.cpp
@@ -144,7 +144,7 @@ namespace TEN::Hud
AddDisplaySprite(
SPRITE_SEQUENCE_OBJECT_ID, STATIC_ELEMENT_SPRITE_ID,
*Position, Orientation, Vector2(Scale), Color,
- PRIORITY, ALIGN_MODE, SCALE_MODE, BLEND_MODE);
+ PRIORITY, ALIGN_MODE, SCALE_MODE, BLEND_MODE, DisplaySpriteSource::DrawPhase);
// Draw animated outer segment elements.
for (const auto& segment : Segments)
@@ -156,7 +156,7 @@ namespace TEN::Hud
AddDisplaySprite(
SPRITE_SEQUENCE_OBJECT_ID, SEGMENT_ELEMENT_SPRITE_ID,
pos, orient, scale, Color,
- PRIORITY, ALIGN_MODE, SCALE_MODE, BLEND_MODE);
+ PRIORITY, ALIGN_MODE, SCALE_MODE, BLEND_MODE, DisplaySpriteSource::DrawPhase);
}
}
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index 942b3d875..a0a3b981b 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -140,7 +140,7 @@ GameStatus ControlPhase()
RegeneratePickups();
ClearFires();
ClearLensFlares();
- ClearDisplaySprites();
+ ClearAllDisplaySprites();
if (TrackCameraInit)
{
@@ -438,7 +438,7 @@ void CleanUp()
StreamerEffect.Clear();
ClearUnderwaterBloodParticles();
ClearBubbles();
- ClearDisplaySprites();
+ ClearAllDisplaySprites();
ClearFootprints();
ClearDrips();
ClearRipples();
diff --git a/TombEngine/Game/effects/DisplaySprite.cpp b/TombEngine/Game/effects/DisplaySprite.cpp
index 9a6b410c3..efcfb1236 100644
--- a/TombEngine/Game/effects/DisplaySprite.cpp
+++ b/TombEngine/Game/effects/DisplaySprite.cpp
@@ -14,7 +14,8 @@ namespace TEN::Effects::DisplaySprite
std::vector DisplaySprites = {};
void AddDisplaySprite(GAME_OBJECT_ID objectID, int spriteID, const Vector2& pos, short orient, const Vector2& scale, const Vector4& color,
- int priority, DisplaySpriteAlignMode alignMode, DisplaySpriteScaleMode scaleMode, BlendMode blendMode)
+ int priority, DisplaySpriteAlignMode alignMode, DisplaySpriteScaleMode scaleMode,
+ BlendMode blendMode, DisplaySpriteSource source)
{
auto displaySprite = DisplaySprite{};
displaySprite.ObjectID = objectID;
@@ -27,12 +28,20 @@ namespace TEN::Effects::DisplaySprite
displaySprite.AlignMode = alignMode;
displaySprite.ScaleMode = scaleMode;
displaySprite.BlendMode = blendMode;
+ displaySprite.Source = source;
DisplaySprites.push_back(displaySprite);
}
- void ClearDisplaySprites()
+ void ClearAllDisplaySprites()
{
DisplaySprites.clear();
}
+
+ void ClearDrawPhaseDisplaySprites()
+ {
+ DisplaySprites.erase(std::remove_if(DisplaySprites.begin(), DisplaySprites.end(),
+ [](const DisplaySprite& displaySprite) { return displaySprite.Source == DisplaySpriteSource::DrawPhase; }),
+ DisplaySprites.end());
+ }
}
diff --git a/TombEngine/Game/effects/DisplaySprite.h b/TombEngine/Game/effects/DisplaySprite.h
index 2f9eb4564..26947e796 100644
--- a/TombEngine/Game/effects/DisplaySprite.h
+++ b/TombEngine/Game/effects/DisplaySprite.h
@@ -23,6 +23,12 @@ namespace TEN::Effects::DisplaySprite
Fill,
Stretch
};
+
+ enum class DisplaySpriteSource
+ {
+ ControlPhase,
+ DrawPhase
+ };
struct DisplaySprite
{
@@ -38,11 +44,15 @@ namespace TEN::Effects::DisplaySprite
DisplaySpriteAlignMode AlignMode = DisplaySpriteAlignMode::Center;
DisplaySpriteScaleMode ScaleMode = DisplaySpriteScaleMode::Fit;
BlendMode BlendMode = BlendMode::AlphaBlend;
+
+ DisplaySpriteSource Source = DisplaySpriteSource::ControlPhase;
};
extern std::vector DisplaySprites;
void AddDisplaySprite(GAME_OBJECT_ID objectID, int spriteID, const Vector2& pos, short orient, const Vector2& scale, const Vector4& color,
- int priority, DisplaySpriteAlignMode alignMode, DisplaySpriteScaleMode scaleMode, BlendMode blendMode);
- void ClearDisplaySprites();
+ int priority, DisplaySpriteAlignMode alignMode, DisplaySpriteScaleMode scaleMode,
+ BlendMode blendMode, DisplaySpriteSource source);
+ void ClearAllDisplaySprites();
+ void ClearDrawPhaseDisplaySprites();
}
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index 04da60923..b2571b504 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -32,6 +32,7 @@
#include "Specific/winmain.h"
#include "Renderer/Structures/RendererSortableObject.h"
#include "Game/effects/weather.h"
+#include "Game/effects/DisplaySprite.h"
using namespace std::chrono;
using namespace TEN::Effects::Hair;
@@ -40,6 +41,7 @@ using namespace TEN::Entities::Generic;
using namespace TEN::Hud;
using namespace TEN::Renderer::Structures;
using namespace TEN::Effects::Environment;
+using namespace TEN::Effects::DisplaySprite;
extern GUNSHELL_STRUCT Gunshells[MAX_GUNSHELL];
@@ -1667,6 +1669,7 @@ namespace TEN::Renderer
using get_time = std::chrono::steady_clock;
ResetDebugVariables();
+
_doingFullscreenPass = false;
auto& level = *g_GameFlow->GetLevel(CurrentLevel);
@@ -1902,6 +1905,8 @@ namespace TEN::Renderer
DrawTriangles3D(view);
// Draw HUD.
+ ClearDrawPhaseDisplaySprites();
+
_context->ClearDepthStencilView(_renderTarget.DepthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
g_Hud.Draw(*LaraItem);
diff --git a/TombEngine/Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.cpp b/TombEngine/Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.cpp
index 12529806d..63de5efcf 100644
--- a/TombEngine/Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.cpp
+++ b/TombEngine/Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.cpp
@@ -220,6 +220,7 @@ namespace TEN::Scripting::DisplaySprite
priority.value_or(DEFAULT_PRIORITY),
alignMode.value_or(DEFAULT_ALIGN_MODE),
scaleMode.value_or(DEFAULT_SCALE_MODE),
- blendMode.value_or(DEFAULT_BLEND_MODE));
+ blendMode.value_or(DEFAULT_BLEND_MODE),
+ DisplaySpriteSource::ControlPhase);
}
}
From 9f27821ff6ff854e9a3e7451aca478fd1d7773cd Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Mon, 6 May 2024 05:56:08 +0200
Subject: [PATCH 141/410] Fixed hairs detached from head
---
TombEngine/Renderer/RendererLara.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/TombEngine/Renderer/RendererLara.cpp b/TombEngine/Renderer/RendererLara.cpp
index b36f8113f..2685390bc 100644
--- a/TombEngine/Renderer/RendererLara.cpp
+++ b/TombEngine/Renderer/RendererLara.cpp
@@ -345,7 +345,7 @@ void Renderer::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, Render
// First matrix is Lara's head matrix, then all hair unit segment matrices.
// Bones are adjusted at load time to account for this.
_stItem.World = Matrix::Identity;
- _stItem.BonesMatrices[0] = itemToDraw->InterpolatedAnimationTransforms[LM_HEAD] * _laraWorldMatrix;
+ _stItem.BonesMatrices[0] = itemToDraw->InterpolatedAnimationTransforms[LM_HEAD] * itemToDraw->InterpolatedWorld;
for (int i = 0; i < unit.Segments.size(); i++)
{
From 8995973c2a4d98c8fcdf38b7c7590555cf399b5d Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Tue, 7 May 2024 05:33:54 +0200
Subject: [PATCH 142/410] Fixed GPU not reset after sun sprite draw
---
TombEngine/Renderer/RendererDraw.cpp | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index b2571b504..9b838b6bf 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -3072,6 +3072,11 @@ namespace TEN::Renderer
// Clear just the Z-buffer to start drawing on top of horizon.
_context->ClearDepthStencilView(depthTarget, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
+
+ // Reset the GPU state
+ SetDepthState(DepthState::Write);
+ SetBlendMode(BlendMode::Opaque);
+ SetCullMode(CullMode::CounterClockwise);
}
void Renderer::Render(float interpolationFactor)
From fb0519eb49c33e76edebee58ab84d4e5e5992af3 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 8 May 2024 03:13:52 +1000
Subject: [PATCH 143/410] Lens flare cleanup
---
TombEngine/Game/control/control.cpp | 5 +-
TombEngine/Game/effects/weather.h | 5 +-
TombEngine/Objects/Effects/LensFlare.cpp | 99 +++++++++++++++
TombEngine/Objects/Effects/LensFlare.h | 21 ++++
TombEngine/Objects/Effects/effect_objects.cpp | 11 +-
TombEngine/Objects/Effects/lens_flare.cpp | 115 ------------------
TombEngine/Objects/Effects/lens_flare.h | 25 ----
.../Objects/Effects/tr5_electricity.cpp | 2 +-
.../Objects/TR5/Entity/tr5_roman_statue.cpp | 2 +-
.../Objects/TR5/Entity/tr5_submarine.cpp | 2 +-
TombEngine/Objects/objectslist.h | 12 +-
.../ConstantBuffers/PostProcessBuffer.h | 5 +-
TombEngine/Renderer/RendererDraw.cpp | 72 ++++++-----
TombEngine/Renderer/RendererFrame.cpp | 58 ++++-----
TombEngine/Renderer/RendererPostProcess.cpp | 38 +++---
.../Renderer/Structures/RendererLensFlare.h | 19 ++-
.../Internal/TEN/Flow/LensFlare/LensFlare.h | 2 +-
TombEngine/Specific/RGBAColor8Byte.cpp | 5 +
TombEngine/Specific/RGBAColor8Byte.h | 1 +
TombEngine/TombEngine.vcxproj | 4 +-
20 files changed, 239 insertions(+), 264 deletions(-)
create mode 100644 TombEngine/Objects/Effects/LensFlare.cpp
create mode 100644 TombEngine/Objects/Effects/LensFlare.h
delete mode 100644 TombEngine/Objects/Effects/lens_flare.cpp
delete mode 100644 TombEngine/Objects/Effects/lens_flare.h
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index a0a3b981b..9a4347a1b 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -40,6 +40,7 @@
#include "Game/Setup.h"
#include "Game/spotcam.h"
#include "Math/Math.h"
+#include "Objects/Effects/LensFlare.h"
#include "Objects/Effects/tr4_locusts.h"
#include "Objects/Generic/Object/objects.h"
#include "Objects/Generic/Object/rope.h"
@@ -60,7 +61,6 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
#include "Specific/winmain.h"
-#include "Objects/Effects/lens_flare.h"
using namespace std::chrono;
using namespace TEN::Effects;
@@ -249,8 +249,7 @@ GameStatus ControlPhase()
SetupGlobalLensFlare(
g_GameFlow->GetLevel(CurrentLevel)->GetLensFlarePosition(),
g_GameFlow->GetLevel(CurrentLevel)->GetLensFlareColor(),
- g_GameFlow->GetLevel(CurrentLevel)->GetLensFlareSpriteID()
- );
+ g_GameFlow->GetLevel(CurrentLevel)->GetLensFlareSpriteID());
}
// Update HUD.
diff --git a/TombEngine/Game/effects/weather.h b/TombEngine/Game/effects/weather.h
index 07ac92765..677ef175b 100644
--- a/TombEngine/Game/effects/weather.h
+++ b/TombEngine/Game/effects/weather.h
@@ -1,8 +1,7 @@
#pragma once
-#include
-#include "Scripting/Include/ScriptInterfaceLevel.h"
#include "Math/Math.h"
-#include "Objects/Effects/lens_flare.h"
+#include "Objects/Effects/LensFlare.h"
+#include "Scripting/Include/ScriptInterfaceLevel.h"
using namespace TEN::Entities::Effects;
diff --git a/TombEngine/Objects/Effects/LensFlare.cpp b/TombEngine/Objects/Effects/LensFlare.cpp
new file mode 100644
index 000000000..8f320e137
--- /dev/null
+++ b/TombEngine/Objects/Effects/LensFlare.cpp
@@ -0,0 +1,99 @@
+#include "framework.h"
+#include "Objects/Effects/LensFlare.h"
+
+#include "Game/camera.h"
+#include "Game/control/los.h"
+#include "Specific/level.h"
+
+namespace TEN::Entities::Effects
+{
+ std::vector LensFlares;
+
+ static void SetupLensFlare(const Vector3& pos, int roomNumber, const Color& color, bool isGlobal, int spriteIndex)
+ {
+ auto lensFlarePos = Vector3::Zero;
+ if (isGlobal)
+ {
+ if (TestEnvironment(ENV_FLAG_NO_LENSFLARE, Camera.pos.RoomNumber))
+ return;
+
+ lensFlarePos = pos;
+ auto delta = (lensFlarePos - Camera.pos.ToVector3()) / 16.0f;
+ while (abs(delta.x) > BLOCK(200) || abs(delta.y) > BLOCK(200) || abs(delta.z) > BLOCK(200))
+ lensFlarePos -= delta;
+
+ delta = (lensFlarePos - Camera.pos.ToVector3()) / 16.0f;
+ while (abs(delta.x) > BLOCK(32) || abs(delta.y) > BLOCK(32) || abs(delta.z) > BLOCK(32))
+ lensFlarePos -= delta;
+
+ delta = (lensFlarePos - Camera.pos.ToVector3()) / 16.0f;
+ for (int i = 0; i < 16; i++)
+ {
+ int foundRoomNumber = IsRoomOutside(lensFlarePos.x, lensFlarePos.y, lensFlarePos.z);
+ if (foundRoomNumber != NO_VALUE)
+ {
+ roomNumber = foundRoomNumber;
+ break;
+ }
+
+ lensFlarePos -= delta;
+ }
+ }
+ else
+ {
+ float dist = Vector3::Distance(pos, Camera.pos.ToVector3());
+ if (dist > BLOCK(32))
+ return;
+
+ lensFlarePos = pos;
+ }
+
+ bool isVisible = false;
+ if (roomNumber != NO_VALUE)
+ {
+ if (TestEnvironment(ENV_FLAG_NOT_NEAR_OUTSIDE, roomNumber) || !isGlobal)
+ {
+ auto origin = Camera.pos;
+ auto target = GameVector(lensFlarePos, roomNumber);
+ isVisible = LOS(&origin, &target);
+ }
+ }
+
+ if (!isVisible && !isGlobal)
+ return;
+
+ auto lensFlare = LensFlare{};
+ lensFlare.Position = pos;
+ lensFlare.RoomNumber = roomNumber;
+ lensFlare.IsGlobal = isGlobal;
+ lensFlare.Color = color;
+ lensFlare.SpriteIndex = spriteIndex;
+
+ LensFlares.push_back(lensFlare);
+ }
+
+ void ControlLensFlare(int itemNumber)
+ {
+ auto& item = g_Level.Items[itemNumber];
+
+ if (TriggerActive(&item))
+ SetupLensFlare(item.Pose.Position.ToVector3(), item.RoomNumber, Color(), false, SPR_LENS_FLARE_3);
+ }
+
+ void ClearLensFlares()
+ {
+ LensFlares.clear();
+ }
+
+ void SetupGlobalLensFlare(const Vector2& yawAndPitchInDegrees, const Color& color, int spriteIndex)
+ {
+ auto pos = Camera.pos.ToVector3();
+ auto rotMatrix = Matrix::CreateFromYawPitchRoll(
+ DEG_TO_RAD(yawAndPitchInDegrees.x),
+ DEG_TO_RAD(yawAndPitchInDegrees.y),
+ 0.0f);
+
+ pos += Vector3::Transform(Vector3(0.0f, 0.0f, BLOCK(256)), rotMatrix);
+ SetupLensFlare(pos, NO_VALUE, color, true, spriteIndex);
+ }
+}
diff --git a/TombEngine/Objects/Effects/LensFlare.h b/TombEngine/Objects/Effects/LensFlare.h
new file mode 100644
index 000000000..6beca5e52
--- /dev/null
+++ b/TombEngine/Objects/Effects/LensFlare.h
@@ -0,0 +1,21 @@
+#pragma once
+
+namespace TEN::Entities::Effects
+{
+ struct LensFlare
+ {
+ int SpriteIndex = 0;
+
+ Vector3 Position = Vector3::Zero;
+ int RoomNumber = 0;
+ Color Color = {};
+
+ bool IsGlobal = false;
+ };
+
+ extern std::vector LensFlares;
+
+ void ControlLensFlare(int itemNumber);
+ void ClearLensFlares();
+ void SetupGlobalLensFlare(const Vector2& yawAndPitchInDegrees, const Color& color, int spriteIndex);
+}
diff --git a/TombEngine/Objects/Effects/effect_objects.cpp b/TombEngine/Objects/Effects/effect_objects.cpp
index 1449d8ed2..0b6b1f9ec 100644
--- a/TombEngine/Objects/Effects/effect_objects.cpp
+++ b/TombEngine/Objects/Effects/effect_objects.cpp
@@ -2,9 +2,9 @@
#include "Objects/Effects/effect_objects.h"
#include "Game/Setup.h"
-#include "Objects/Effects/flame_emitters.h"
#include "Objects/Effects/enemy_missile.h"
-#include "Objects/Effects/lens_flare.h"
+#include "Objects/Effects/flame_emitters.h"
+#include "Objects/Effects/LensFlare.h"
using namespace TEN::Entities::Effects;
@@ -58,8 +58,5 @@ void InitializeEffectsObjects()
obj = &Objects[ID_LENS_FLARE];
if (obj->loaded)
- {
- obj->control = LensFlareControl;
- }
-
-}
\ No newline at end of file
+ obj->control = ControlLensFlare;
+}
diff --git a/TombEngine/Objects/Effects/lens_flare.cpp b/TombEngine/Objects/Effects/lens_flare.cpp
deleted file mode 100644
index 2d585bae7..000000000
--- a/TombEngine/Objects/Effects/lens_flare.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-#include "framework.h"
-#include "Objects/Effects/lens_flare.h"
-#include "Specific/level.h"
-#include "Game/camera.h"
-#include "Game/control/los.h"
-
-namespace TEN::Entities::Effects
-{
- std::vector LensFlares;
-
- void LensFlareControl(short itemNumber)
- {
- auto* item = &g_Level.Items[itemNumber];
-
- if (TriggerActive(item))
- {
- SetupLensFlare(
- item->Pose.Position.ToVector3(),
- Vector3::One,
- item->RoomNumber,
- false,
- SPR_LENSFLARE3);
- }
- }
-
- void ClearLensFlares()
- {
- LensFlares.clear();
- }
-
- void SetupGlobalLensFlare(Vector2 yawAndPitchInDegrees, Vector3 color, int spriteIndex)
- {
- Vector3 position = Camera.pos.ToVector3();
- Matrix rotation = Matrix::CreateFromYawPitchRoll(
- DEG_TO_RAD(yawAndPitchInDegrees.x),
- DEG_TO_RAD(yawAndPitchInDegrees.y),
- 0
- );
- position += Vector3::Transform(Vector3(0, 0, BLOCK(256)), rotation);
- SetupLensFlare(position, color, NO_VALUE, true, spriteIndex);
- }
-
- void SetupLensFlare(Vector3 position, Vector3 color, short roomNumber, bool global, int spriteIndex)
- {
- Vector3 lensFlarePosition;
-
- if (global)
- {
- if (g_Level.Rooms[Camera.pos.RoomNumber].flags & ENV_FLAG_NO_LENSFLARE)
- {
- return;
- }
-
- lensFlarePosition = position;
- Vector3 delta = (lensFlarePosition - Camera.pos.ToVector3()) / 16.0f;
- while (abs(delta.x) > BLOCK(200) || abs(delta.y) > BLOCK(200) || abs(delta.z) > BLOCK(200))
- {
- lensFlarePosition -= delta;
- }
-
- delta = (lensFlarePosition - Camera.pos.ToVector3()) / 16.0f;
- while (abs(delta.x) > BLOCK(32) || abs(delta.y) > BLOCK(32) || abs(delta.z) > BLOCK(32))
- {
- lensFlarePosition -= delta;
- }
-
- delta = (lensFlarePosition - Camera.pos.ToVector3()) / 16.0f;
- for (int i = 0; i < 16; i++)
- {
- short foundRoomNumber = IsRoomOutside(lensFlarePosition.x, lensFlarePosition.y, lensFlarePosition.z);
- if (foundRoomNumber != NO_VALUE)
- {
- roomNumber = foundRoomNumber;
- break;
- }
- lensFlarePosition -= delta;
- }
- }
- else
- {
- if (Vector3::Distance(position, Camera.pos.ToVector3()) > BLOCK(32))
- {
- return;
- }
- lensFlarePosition = position;
- }
-
- bool flareVisible = false;
-
- if (roomNumber != NO_VALUE)
- {
- if (g_Level.Rooms[roomNumber].flags & ENV_FLAG_NOT_NEAR_OUTSIDE || !global)
- {
- GameVector source = { Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.pos.RoomNumber };
- GameVector destination = { (int)lensFlarePosition.x, (int)lensFlarePosition.y, (int)lensFlarePosition.z, roomNumber };
- flareVisible = LOS(&source, &destination);
- }
- }
-
- if (!flareVisible && !global)
- {
- return;
- }
-
- LensFlare lensFlare;
-
- lensFlare.Position = position;
- lensFlare.RoomNumber = roomNumber;
- lensFlare.Global = global;
- lensFlare.Color = color;
- lensFlare.SpriteIndex = spriteIndex;
-
- LensFlares.push_back(lensFlare);
- }
-}
\ No newline at end of file
diff --git a/TombEngine/Objects/Effects/lens_flare.h b/TombEngine/Objects/Effects/lens_flare.h
deleted file mode 100644
index 553866f4f..000000000
--- a/TombEngine/Objects/Effects/lens_flare.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#pragma once
-
-#include
-#include
-
-namespace TEN::Entities::Effects
-{
- using namespace DirectX::SimpleMath;
-
- struct LensFlare
- {
- Vector3 Position;
- Vector3 Color;
- short RoomNumber;
- bool Global;
- int SpriteIndex;
- };
-
- extern std::vector LensFlares;
-
- void LensFlareControl(short itemNumber);
- void ClearLensFlares();
- void SetupLensFlare(Vector3 position, Vector3 color, short roomNumber, bool global, int spriteIndex);
- void SetupGlobalLensFlare(Vector2 yawAndPitchInDegrees, Vector3 color, int spriteIndex);
-}
\ No newline at end of file
diff --git a/TombEngine/Objects/Effects/tr5_electricity.cpp b/TombEngine/Objects/Effects/tr5_electricity.cpp
index abfd748a3..5eecfe617 100644
--- a/TombEngine/Objects/Effects/tr5_electricity.cpp
+++ b/TombEngine/Objects/Effects/tr5_electricity.cpp
@@ -75,7 +75,7 @@ void TriggerElectricityWireSparks(int x, int z, byte objNum, byte node, bool glo
if (glow)
{
spark->scalar = 1;
- spark->spriteIndex = Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LENSFLARE_LIGHT;
+ spark->spriteIndex = Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LENS_FLARE__LIGHT;
spark->size = spark->sSize = (GetRandomControl() & 0x1F) + 160;
}
else
diff --git a/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp b/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp
index 24770e50b..fdd46a288 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp
@@ -160,7 +160,7 @@ namespace TEN::Entities::Creatures::TR5
spark->flags = SP_SCALE | SP_DEF;
spark->scalar = 3;
spark->maxYvel = 0;
- spark->spriteIndex = Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LENSFLARE_LIGHT;
+ spark->spriteIndex = Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LENS_FLARE__LIGHT;
spark->gravity = 0;
spark->dSize = spark->sSize = spark->size = size + (GetRandomControl() & 3);
}
diff --git a/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp b/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp
index 081e13aa8..d9a9d57b7 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp
@@ -65,7 +65,7 @@ namespace TEN::Entities::Creatures::TR5
spark->maxYvel = 0;
spark->gravity = 0;
spark->scalar = 1;
- spark->spriteIndex = Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LENSFLARE_LIGHT;
+ spark->spriteIndex = Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LENS_FLARE__LIGHT;
spark->dSize = spark->sSize = spark->size = (GetRandomControl() & 7) + 192;
}
diff --git a/TombEngine/Objects/objectslist.h b/TombEngine/Objects/objectslist.h
index 73f48b3b1..ea4d252d3 100644
--- a/TombEngine/Objects/objectslist.h
+++ b/TombEngine/Objects/objectslist.h
@@ -32,8 +32,8 @@ template std::enable_if_t std::enable_if_t
#include "Renderer/RendererEnums.h"
namespace TEN::Renderer::ConstantBuffers
{
- using namespace DirectX::SimpleMath;
-
struct alignas(16) ShaderLensFlare
{
Vector3 Position;
@@ -30,4 +27,4 @@ namespace TEN::Renderer::ConstantBuffers
//--
int NumLensFlares;
};
-}
\ No newline at end of file
+}
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index 9b838b6bf..d7490688d 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -2782,6 +2782,9 @@ namespace TEN::Renderer
void Renderer::DrawHorizonAndSky(RenderView& renderView, ID3D11DepthStencilView* depthTarget)
{
+ constexpr auto STAR_SIZE = 2;
+ constexpr auto SUN_SIZE = 64;
+
auto* levelPtr = g_GameFlow->GetLevel(CurrentLevel);
bool anyOutsideRooms = false;
@@ -2858,38 +2861,36 @@ namespace TEN::Renderer
UINT offset = 0;
_context->IASetVertexBuffers(0, 1, _quadVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
- BindTexture(TextureRegister::ColorMap, _sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LENSFLARE3].Texture, SamplerStateRegister::LinearClamp);
+ BindTexture(TextureRegister::ColorMap, _sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LENS_FLARE_3].Texture, SamplerStateRegister::LinearClamp);
int drawnStars = 0;
- int starsCount = (int)Weather.GetStars().size();
+ int starCount = (int)Weather.GetStars().size();
- while (drawnStars < starsCount)
+ while (drawnStars < starCount)
{
- int starsToDraw = (starsCount - drawnStars) > 100 ? 100 : (starsCount - drawnStars);
+ int starsToDraw = (starCount - drawnStars) > 100 ? 100 : (starCount - drawnStars);
int i = 0;
for (int i = 0; i < starsToDraw; i++)
{
- auto& s = Weather.GetStars()[drawnStars + i];
+ auto& star = Weather.GetStars()[drawnStars + i];
RendererSpriteToDraw rDrawSprite;
- rDrawSprite.Sprite = &_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LENSFLARE3];
-
- constexpr auto STAR_SIZE = 2;
+ rDrawSprite.Sprite = &_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LENS_FLARE_3];
rDrawSprite.Type = SpriteType::Billboard;
- rDrawSprite.pos = renderView.Camera.WorldPosition + s.Direction * BLOCK(1);
+ rDrawSprite.pos = renderView.Camera.WorldPosition + star.Direction * BLOCK(1);
rDrawSprite.Rotation = 0;
rDrawSprite.Scale = 1;
- rDrawSprite.Width = STAR_SIZE * s.Scale;
- rDrawSprite.Height = STAR_SIZE * s.Scale;
+ rDrawSprite.Width = STAR_SIZE * star.Scale;
+ rDrawSprite.Height = STAR_SIZE * star.Scale;
_stInstancedSpriteBuffer.Sprites[i].World = GetWorldMatrixForSprite(&rDrawSprite, renderView);
_stInstancedSpriteBuffer.Sprites[i].Color = Vector4(
- s.Color.x,
- s.Color.y,
- s.Color.z,
- s.Blinking * s.Extinction);
+ star.Color.x,
+ star.Color.y,
+ star.Color.z,
+ star.Blinking * star.Extinction);
_stInstancedSpriteBuffer.Sprites[i].IsBillboard = 1;
_stInstancedSpriteBuffer.Sprites[i].IsSoftParticle = 0;
@@ -2916,14 +2917,14 @@ namespace TEN::Renderer
if (Weather.GetMeteors().size() > 0)
{
RendererSpriteToDraw rDrawSprite;
- rDrawSprite.Sprite = &_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LENSFLARE3];
+ rDrawSprite.Sprite = &_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LENS_FLARE_3];
BindTexture(TextureRegister::ColorMap, rDrawSprite.Sprite->Texture, SamplerStateRegister::LinearClamp);
- int meteorsCount = 0;
+ int meteorCount = 0;
for (int i = 0; i < Weather.GetMeteors().size(); i++)
{
- MeteorParticle meteor = Weather.GetMeteors()[i];
+ auto meteor = Weather.GetMeteors()[i];
if (meteor.Active == false)
continue;
@@ -2938,33 +2939,32 @@ namespace TEN::Renderer
rDrawSprite.Height = 192;
rDrawSprite.ConstrainAxis = meteor.Direction;
- _stInstancedSpriteBuffer.Sprites[meteorsCount].World = GetWorldMatrixForSprite(&rDrawSprite, renderView);
- _stInstancedSpriteBuffer.Sprites[meteorsCount].Color = Vector4(
+ _stInstancedSpriteBuffer.Sprites[meteorCount].World = GetWorldMatrixForSprite(&rDrawSprite, renderView);
+ _stInstancedSpriteBuffer.Sprites[meteorCount].Color = Vector4(
meteor.Color.x,
meteor.Color.y,
meteor.Color.z,
- Lerp(meteor.OldFade, meteor.Fade, _interpolationFactor)
- );
- _stInstancedSpriteBuffer.Sprites[meteorsCount].IsBillboard = 1;
+ Lerp(meteor.OldFade, meteor.Fade, _interpolationFactor));
+ _stInstancedSpriteBuffer.Sprites[meteorCount].IsBillboard = 1;
_stInstancedSpriteBuffer.Sprites[i].IsSoftParticle = 0;
// NOTE: Strange packing due to particular HLSL 16 byte alignment requirements.
- _stInstancedSpriteBuffer.Sprites[meteorsCount].UV[0].x = rDrawSprite.Sprite->UV[0].x;
- _stInstancedSpriteBuffer.Sprites[meteorsCount].UV[0].y = rDrawSprite.Sprite->UV[1].x;
- _stInstancedSpriteBuffer.Sprites[meteorsCount].UV[0].z = rDrawSprite.Sprite->UV[2].x;
- _stInstancedSpriteBuffer.Sprites[meteorsCount].UV[0].w = rDrawSprite.Sprite->UV[3].x;
- _stInstancedSpriteBuffer.Sprites[meteorsCount].UV[1].x = rDrawSprite.Sprite->UV[0].y;
- _stInstancedSpriteBuffer.Sprites[meteorsCount].UV[1].y = rDrawSprite.Sprite->UV[1].y;
- _stInstancedSpriteBuffer.Sprites[meteorsCount].UV[1].z = rDrawSprite.Sprite->UV[2].y;
- _stInstancedSpriteBuffer.Sprites[meteorsCount].UV[1].w = rDrawSprite.Sprite->UV[3].y;
+ _stInstancedSpriteBuffer.Sprites[meteorCount].UV[0].x = rDrawSprite.Sprite->UV[0].x;
+ _stInstancedSpriteBuffer.Sprites[meteorCount].UV[0].y = rDrawSprite.Sprite->UV[1].x;
+ _stInstancedSpriteBuffer.Sprites[meteorCount].UV[0].z = rDrawSprite.Sprite->UV[2].x;
+ _stInstancedSpriteBuffer.Sprites[meteorCount].UV[0].w = rDrawSprite.Sprite->UV[3].x;
+ _stInstancedSpriteBuffer.Sprites[meteorCount].UV[1].x = rDrawSprite.Sprite->UV[0].y;
+ _stInstancedSpriteBuffer.Sprites[meteorCount].UV[1].y = rDrawSprite.Sprite->UV[1].y;
+ _stInstancedSpriteBuffer.Sprites[meteorCount].UV[1].z = rDrawSprite.Sprite->UV[2].y;
+ _stInstancedSpriteBuffer.Sprites[meteorCount].UV[1].w = rDrawSprite.Sprite->UV[3].y;
- meteorsCount++;
+ meteorCount++;
}
_cbInstancedSpriteBuffer.UpdateData(_stInstancedSpriteBuffer, _context.Get());
// Draw sprites with instancing.
- DrawInstancedTriangles(4, meteorsCount, 0);
+ DrawInstancedTriangles(4, meteorCount, 0);
}
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
@@ -3016,8 +3016,8 @@ namespace TEN::Renderer
}
}
- // Eventually draw the sun sprite
- if (renderView.LensFlaresToDraw.size() > 0 && renderView.LensFlaresToDraw[0].Global)
+ // Eventually draw the sun sprite.
+ if (!renderView.LensFlaresToDraw.empty() && renderView.LensFlaresToDraw[0].IsGlobal)
{
SetDepthState(DepthState::Read);
SetBlendMode(BlendMode::Additive);
@@ -3036,8 +3036,6 @@ namespace TEN::Renderer
RendererSpriteToDraw rDrawSprite;
rDrawSprite.Sprite = &_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + renderView.LensFlaresToDraw[0].SpriteIndex];
- constexpr auto SUN_SIZE = 64;
-
rDrawSprite.Type = SpriteType::Billboard;
rDrawSprite.pos = renderView.Camera.WorldPosition + renderView.LensFlaresToDraw[0].Direction * BLOCK(1);
rDrawSprite.Rotation = 0;
diff --git a/TombEngine/Renderer/RendererFrame.cpp b/TombEngine/Renderer/RendererFrame.cpp
index 9a59de126..b4c11ea62 100644
--- a/TombEngine/Renderer/RendererFrame.cpp
+++ b/TombEngine/Renderer/RendererFrame.cpp
@@ -1,22 +1,22 @@
#include "framework.h"
#include "Renderer/Renderer.h"
-#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
#include "Game/animation.h"
#include "Game/camera.h"
#include "Game/collision/sphere.h"
#include "Game/effects/effects.h"
#include "Game/items.h"
#include "Game/Lara/lara.h"
-#include "Game/spotcam.h"
#include "Game/Setup.h"
+#include "Game/spotcam.h"
#include "Math/Math.h"
-#include "Specific/level.h"
+#include "Objects/Effects/LensFlare.h"
#include "Renderer/RenderView.h"
-#include "Objects/Effects/lens_flare.h"
+#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
+#include "Specific/level.h"
-using namespace TEN::Math;
using namespace TEN::Entities::Effects;
+using namespace TEN::Math;
namespace TEN::Renderer
{
@@ -92,8 +92,7 @@ namespace TEN::Renderer
}
std::sort(
- tempFogBulbs.begin(),
- tempFogBulbs.end(),
+ tempFogBulbs.begin(), tempFogBulbs.end(),
[](const RendererFogBulb& bulb0, const RendererFogBulb& bulb1)
{
return bulb0.Distance < bulb1.Distance;
@@ -102,55 +101,56 @@ namespace TEN::Renderer
for (int i = 0; i < std::min(MAX_FOG_BULBS_DRAW, (int)tempFogBulbs.size()); i++)
renderView.FogBulbsToDraw.push_back(tempFogBulbs[i]);
- // Collect lens flares
- std::vector tempLensFlares;
+ // Collect lens flares.
+ auto tempLensFlares = std::vector{};
tempLensFlares.reserve(MAX_LENS_FLARES_DRAW);
- for (auto lensFlare : LensFlares)
+ for (const auto& lensFlare : LensFlares)
{
- Vector3 lensFlareToCamera = lensFlare.Position - renderView.Camera.WorldPosition;
- float distance = 0.0f;
- if (!lensFlare.Global)
- {
- distance = lensFlareToCamera.Length();
- }
+ auto lensFlareToCamera = lensFlare.Position - renderView.Camera.WorldPosition;
+
+ float dist = 0.0f;
+ if (!lensFlare.IsGlobal)
+ dist = lensFlareToCamera.Length();
lensFlareToCamera.Normalize();
- Vector3 cameraDirection = renderView.Camera.WorldDirection;
- cameraDirection.Normalize();
+ auto cameraDir = renderView.Camera.WorldDirection;
+ cameraDir.Normalize();
- if (lensFlareToCamera.Dot(cameraDirection) >= 0.0f)
+ if (lensFlareToCamera.Dot(cameraDir) >= 0.0f)
{
- RendererLensFlare lensFlareToDraw;
-
+ auto lensFlareToDraw = RendererLensFlare{};
lensFlareToDraw.Position = lensFlare.Position;
- lensFlareToDraw.Distance = distance;
+ lensFlareToDraw.Distance = dist;
lensFlareToDraw.Color = lensFlare.Color;
lensFlareToDraw.SpriteIndex = lensFlare.SpriteIndex;
lensFlareToDraw.Direction = lensFlareToCamera;
- lensFlareToDraw.Global = lensFlare.Global;
+ lensFlareToDraw.IsGlobal = lensFlare.IsGlobal;
tempLensFlares.push_back(lensFlareToDraw);
}
}
std::sort(
- tempLensFlares.begin(),
- tempLensFlares.end(),
+ tempLensFlares.begin(), tempLensFlares.end(),
[](const RendererLensFlare& lensFlare0, const RendererLensFlare& lensFlare1)
{
- if (lensFlare0.Global && !lensFlare1.Global)
+ if (lensFlare0.IsGlobal && !lensFlare1.IsGlobal)
+ {
return true;
- else if (!lensFlare0.Global && lensFlare1.Global)
+ }
+ else if (!lensFlare0.IsGlobal && lensFlare1.IsGlobal)
+ {
return false;
+ }
else
+ {
return lensFlare0.Distance < lensFlare1.Distance;
+ }
});
for (int i = 0; i < std::min(MAX_LENS_FLARES_DRAW, (int)tempLensFlares.size()); i++)
- {
renderView.LensFlaresToDraw.push_back(tempLensFlares[i]);
- }
}
bool Renderer::CheckPortal(short parentRoomNumber, RendererDoor* door, Vector4 viewPort, Vector4* clipPort, RenderView& renderView)
diff --git a/TombEngine/Renderer/RendererPostProcess.cpp b/TombEngine/Renderer/RendererPostProcess.cpp
index d34e05187..1c00be4a8 100644
--- a/TombEngine/Renderer/RendererPostProcess.cpp
+++ b/TombEngine/Renderer/RendererPostProcess.cpp
@@ -20,15 +20,15 @@ namespace TEN::Renderer
_stPostProcessBuffer.Tint = _postProcessTint;
_cbPostProcessBuffer.UpdateData(_stPostProcessBuffer, _context.Get());
- // Common vertex shader to all fullscreen effects
+ // Common vertex shader to all fullscreen effects.
_context->VSSetShader(_vsPostProcess.Get(), nullptr, 0);
- // We draw a fullscreen triangle
+ // Draw fullscreen triangle.
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
_context->IASetInputLayout(_fullscreenTriangleInputLayout.Get());
- UINT stride = sizeof(PostProcessVertex);
- UINT offset = 0;
+ unsigned int stride = sizeof(PostProcessVertex);
+ unsigned int offset = 0;
_context->IASetVertexBuffers(0, 1, _fullscreenTriangleVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
@@ -41,15 +41,15 @@ namespace TEN::Renderer
BindRenderTargetAsTexture(TextureRegister::ColorMap, &_renderTarget, SamplerStateRegister::PointWrap);
DrawTriangles(3, 0);
- // Let's do ping-pong between the two post-process render targets
+ // Ping-pong between two post-process render targets.
int currentRenderTarget = 0;
- int destinationRenderTarget = 1;
+ int destRenderTarget = 1;
- // Apply color scheme
+ // Apply color scheme.
if (_postProcessMode != PostProcessMode::None && _postProcessStrength > EPSILON)
{
- _context->ClearRenderTargetView(_postProcessRenderTarget[destinationRenderTarget].RenderTargetView.Get(), clearColor);
- _context->OMSetRenderTargets(1, _postProcessRenderTarget[destinationRenderTarget].RenderTargetView.GetAddressOf(), nullptr);
+ _context->ClearRenderTargetView(_postProcessRenderTarget[destRenderTarget].RenderTargetView.Get(), clearColor);
+ _context->OMSetRenderTargets(1, _postProcessRenderTarget[destRenderTarget].RenderTargetView.GetAddressOf(), nullptr);
switch (_postProcessMode)
{
@@ -72,22 +72,22 @@ namespace TEN::Renderer
BindRenderTargetAsTexture(TextureRegister::ColorMap, &_postProcessRenderTarget[currentRenderTarget], SamplerStateRegister::PointWrap);
DrawTriangles(3, 0);
- destinationRenderTarget = destinationRenderTarget == 1 ? 0 : 1;
- currentRenderTarget = currentRenderTarget == 1 ? 0 : 1;
+ destRenderTarget = (destRenderTarget == 1) ? 0 : 1;
+ currentRenderTarget = (currentRenderTarget == 1) ? 0 : 1;
}
- // Lens flares
- if (view.LensFlaresToDraw.size() > 0)
+ // Lens flares.
+ if (!view.LensFlaresToDraw.empty())
{
- _context->ClearRenderTargetView(_postProcessRenderTarget[destinationRenderTarget].RenderTargetView.Get(), clearColor);
- _context->OMSetRenderTargets(1, _postProcessRenderTarget[destinationRenderTarget].RenderTargetView.GetAddressOf(), nullptr);
+ _context->ClearRenderTargetView(_postProcessRenderTarget[destRenderTarget].RenderTargetView.Get(), clearColor);
+ _context->OMSetRenderTargets(1, _postProcessRenderTarget[destRenderTarget].RenderTargetView.GetAddressOf(), nullptr);
_context->PSSetShader(_psPostProcessLensFlare.Get(), nullptr, 0);
for (int i = 0; i < view.LensFlaresToDraw.size(); i++)
{
_stPostProcessBuffer.LensFlares[i].Position = view.LensFlaresToDraw[i].Position;
- _stPostProcessBuffer.LensFlares[i].Color = view.LensFlaresToDraw[i].Color;
+ _stPostProcessBuffer.LensFlares[i].Color = view.LensFlaresToDraw[i].Color.ToVector3();
}
_stPostProcessBuffer.NumLensFlares = (int)view.LensFlaresToDraw.size();
_cbPostProcessBuffer.UpdateData(_stPostProcessBuffer, _context.Get());
@@ -95,11 +95,11 @@ namespace TEN::Renderer
BindRenderTargetAsTexture(TextureRegister::ColorMap, &_postProcessRenderTarget[currentRenderTarget], SamplerStateRegister::PointWrap);
DrawTriangles(3, 0);
- destinationRenderTarget = destinationRenderTarget == 1 ? 0 : 1;
- currentRenderTarget = currentRenderTarget == 1 ? 0 : 1;
+ destRenderTarget = (destRenderTarget) == 1 ? 0 : 1;
+ currentRenderTarget = (currentRenderTarget == 1) ? 0 : 1;
}
- // Do the final pass
+ // Do final pass.
_context->PSSetShader(_psPostProcessFinalPass.Get(), nullptr, 0);
_context->ClearRenderTargetView(renderTarget->RenderTargetView.Get(), Colors::Black);
diff --git a/TombEngine/Renderer/Structures/RendererLensFlare.h b/TombEngine/Renderer/Structures/RendererLensFlare.h
index 1c88d8fb3..a6e6de847 100644
--- a/TombEngine/Renderer/Structures/RendererLensFlare.h
+++ b/TombEngine/Renderer/Structures/RendererLensFlare.h
@@ -1,18 +1,17 @@
#pragma once
-#include
#include "Renderer/RendererEnums.h"
namespace TEN::Renderer::Structures
{
- using namespace DirectX::SimpleMath;
-
struct RendererLensFlare
{
- Vector3 Position;
- Vector3 Color;
- Vector3 Direction;
- float Distance;
- bool Global;
- int SpriteIndex;
+ int SpriteIndex = 0;
+
+ Vector3 Position = Vector3::Zero;
+ Vector3 Direction = Vector3::Zero;
+ Color Color = {};
+
+ float Distance = 0.0f;
+ bool IsGlobal = false;
};
-}
\ No newline at end of file
+}
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.h b/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.h
index d14f4c7b6..2970bd4dc 100644
--- a/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.h
+++ b/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.h
@@ -9,7 +9,7 @@ namespace sol { class state; }
struct LensFlare
{
bool Enabled;
- int SunSpriteID = SPR_LENSFLARE3; // Index into sprites
+ int SunSpriteID = SPR_LENS_FLARE_3; // Index into sprites
byte R;
byte G;
byte B;
diff --git a/TombEngine/Specific/RGBAColor8Byte.cpp b/TombEngine/Specific/RGBAColor8Byte.cpp
index b627b21e4..15e7003a9 100644
--- a/TombEngine/Specific/RGBAColor8Byte.cpp
+++ b/TombEngine/Specific/RGBAColor8Byte.cpp
@@ -98,6 +98,11 @@ RGBAColor8Byte::RGBAColor8Byte(Vector4 const& col) :
{
}
+RGBAColor8Byte::operator Color() const
+{
+ return Color(ByteComponentToFloat(r), ByteComponentToFloat(g), ByteComponentToFloat(b));
+}
+
RGBAColor8Byte::operator Vector3() const
{
return Vector3{ ByteComponentToFloat(r), ByteComponentToFloat(g), ByteComponentToFloat(b) };
diff --git a/TombEngine/Specific/RGBAColor8Byte.h b/TombEngine/Specific/RGBAColor8Byte.h
index e89eb7cd3..7c7b63208 100644
--- a/TombEngine/Specific/RGBAColor8Byte.h
+++ b/TombEngine/Specific/RGBAColor8Byte.h
@@ -12,6 +12,7 @@ public:
RGBAColor8Byte(Vector3 const &);
RGBAColor8Byte(Vector4 const &);
+ operator Color() const;
operator Vector3() const;
operator Vector4() const;
operator D3DCOLOR() const;
diff --git a/TombEngine/TombEngine.vcxproj b/TombEngine/TombEngine.vcxproj
index 5b8ec1744..24ff002ab 100644
--- a/TombEngine/TombEngine.vcxproj
+++ b/TombEngine/TombEngine.vcxproj
@@ -442,7 +442,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
-
+
@@ -956,7 +956,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
-
+
From 2eb2ff877d20c98f3be7a3a2705cc384c1d0ae65 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 8 May 2024 13:47:47 +1000
Subject: [PATCH 144/410] Starfield and lens flare cleanup
---
.../doc/2 classes/Flow.LensFlare.html | 131 +++---
Documentation/doc/2 classes/Flow.Level.html | 28 +-
.../doc/2 classes/Flow.Starfield.html | 391 ++++++++++++------
.../doc/2 classes/View.DisplaySprite.html | 2 +-
Documentation/doc/index.html | 4 +-
TombEngine/Game/control/control.cpp | 4 +-
TombEngine/Game/effects/weather.cpp | 137 +++---
TombEngine/Game/effects/weather.h | 48 +--
TombEngine/Objects/Effects/LensFlare.cpp | 24 +-
TombEngine/Objects/Effects/LensFlare.h | 6 +-
.../Objects/Effects/tr5_electricity.cpp | 2 +-
.../Objects/TR5/Entity/tr5_roman_statue.cpp | 2 +-
.../Objects/TR5/Entity/tr5_submarine.cpp | 2 +-
TombEngine/Objects/objectslist.h | 4 +-
TombEngine/Renderer/RendererDraw.cpp | 20 +-
TombEngine/Renderer/RendererFrame.cpp | 15 +-
.../Renderer/Structures/RendererLensFlare.h | 4 +-
.../Scripting/Include/ScriptInterfaceLevel.h | 24 +-
.../TEN/DisplaySprite/ScriptDisplaySprite.cpp | 14 +-
.../Internal/TEN/Flow/LensFlare/LensFlare.cpp | 173 ++++----
.../Internal/TEN/Flow/LensFlare/LensFlare.h | 51 +--
.../Internal/TEN/Flow/Level/FlowLevel.cpp | 71 ++--
.../Internal/TEN/Flow/Level/FlowLevel.h | 33 +-
.../Internal/TEN/Flow/Starfield/Starfield.cpp | 248 ++++++-----
.../Internal/TEN/Flow/Starfield/Starfield.h | 58 +--
25 files changed, 856 insertions(+), 640 deletions(-)
diff --git a/Documentation/doc/2 classes/Flow.LensFlare.html b/Documentation/doc/2 classes/Flow.LensFlare.html
index 8ae3ca788..574b42065 100644
--- a/Documentation/doc/2 classes/Flow.LensFlare.html
+++ b/Documentation/doc/2 classes/Flow.LensFlare.html
@@ -102,30 +102,25 @@
Class Flow.LensFlare
-
LensFlare
+
Represents a lens flare.
-
-
@@ -133,69 +128,31 @@
-
-
-
-
-
- lensFlareColor
-
-
- (Color ) RGB lens flare color
-
-
-
-
-
-
-
-
-
-
-
- lensFlarePosition
-
-
-
-(Vec2 ) Lens flare orientation.
-
- This is the position of the lens flare in the sky. The X value is the horizontal position, and the Y value is the vertical position. Angles must be specified in degrees.
-
-
-
-
-
-
-
-
-
-
-
-
-
- LensFlare(yawPitchInDegrees, color)
+ LensFlare(Rotation., Color.)
-
-
-
+ Create a LensFlare object. ()
Parameters:
- yawPitchInDegrees
- Vec2
- Position of the lens flare (yaw and pitch) in degrees
+ Rotation.
+ Rotation
+
+
+
- color
+ Color.
Color
- RGB color
+
+
+
@@ -203,7 +160,49 @@
LensFlare
- A lens flare object.
+ A new LensFlare object.
+
+
+
+
+
+
+
+
+ LensFlare:GetEnabled()
+
+
+ Get the lens flare's enabled status. ()
+
+
+
+
+ Returns:
+
+
+ bool
+ Lens flare's enabled status.
+
+
+
+
+
+
+
+
+ LensFlare:GetObjectID()
+
+
+ Get the sun's sprite ID. ()
+
+
+
+
+ Returns:
+
+
+ int
+ Sprite ID.
diff --git a/Documentation/doc/2 classes/Flow.Level.html b/Documentation/doc/2 classes/Flow.Level.html
index a3309e70d..942ae6163 100644
--- a/Documentation/doc/2 classes/Flow.Level.html
+++ b/Documentation/doc/2 classes/Flow.Level.html
@@ -108,10 +108,6 @@
-
- nameKey
- (string) string key for the level's (localised) name.
-
scriptFile
(string) Level-specific Lua script file.
@@ -138,11 +134,11 @@
starfield
- (Flow.Starfield ) Starfield
+ (Flow.Starfield ) Starfield.
lensFlare
- (Flow.LensFlare ) Global lens flare
+ (Flow.LensFlare ) Global lens flare .
fog
@@ -208,22 +204,6 @@
-
-
- nameKey
-
-
- (string) string key for the level's (localised) name.
- Corresponds to an entry in strings.lua.
-
-
-
-
-
-
-
-
-
scriptFile
@@ -323,7 +303,7 @@
starfield
- (Flow.Starfield ) Starfield
+ (Flow.Starfield ) Starfield.
@@ -338,7 +318,7 @@
lensFlare
- (Flow.LensFlare ) Global lens flare
+ (Flow.LensFlare ) Global lens flare .
diff --git a/Documentation/doc/2 classes/Flow.Starfield.html b/Documentation/doc/2 classes/Flow.Starfield.html
index 9b75c5427..07749c388 100644
--- a/Documentation/doc/2 classes/Flow.Starfield.html
+++ b/Documentation/doc/2 classes/Flow.Starfield.html
@@ -102,44 +102,61 @@
Class Flow.Starfield
-
Starfield
+
Represents a starfield.
-
-
@@ -147,101 +164,23 @@
-
-
-
-
-
- starsCount
-
-
-
-(int) Stars count.
-
- Values can be between [0, 6000], 0 resulting in no stars being rendered, and 6000 resulting in the maximum number of stars being rendered.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- meteorsCount
-
-
-
-(int) Meteors count.
-
- Values can be between [0, 100], 0 resulting in no meteors being rendered, and 100 resulting in the maximum number of meteors being rendered.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- meteorsSpawnDensity
-
-
- (int) Meteors spawn density.
-
-
-
-
-
-
-
-
-
-
-
- meteorsSpeed
-
-
- (float) Meteors speed.
-
-
-
-
-
-
-
-
-
-
- Starfield(starsCount)
+ Starfield(starCount)
-
-
-
+ Create a starfield object with only stars. ()
Parameters:
- starsCount
+ starCount
int
- Stars count
+ Star count.
@@ -249,7 +188,7 @@
Starfield
- A starfield object with only stars enabled.
+ A new Starfield object.
@@ -258,24 +197,22 @@
- Starfield(starsCount, meteorsCount)
+ Starfield(starCount, meteorCount)
-
-
-
+ Create a starfield object with stars and meteors. ()
Parameters:
- starsCount
+ starCount
int
- Stars count
+ Star count.
- meteorsCount
+ meteorCount
int
- Stars count
+ Meteor count.
@@ -283,12 +220,226 @@
Starfield
- A starfield object with boths stars and meteors enabled.
+ A new Starfield object.
+
+
+
+ Starfield:GetStarsEnabled()
+
+
+ Get the starfield's enabled status of stars. ()
+
+
+
+
+ Returns:
+
+
+ bool
+ Stars enabled status.
+
+
+
+
+
+
+
+
+ Starfield:GetMeteorsEnabled()
+
+
+ Get the starfield's enabled status of meteors. ()
+
+
+
+
+ Returns:
+
+
+ bool
+ Meteors enabled status.
+
+
+
+
+
+
+
+
+ Starfield:GetStarCount()
+
+
+ Get the starfield's number of stars. ()
+
+
+
+
+ Returns:
+
+
+ int
+ Count.
+
+
+
+
+
+
+
+
+ Starfield:GetMeteorCount()
+
+
+ Get the starfield's number of meteors. ()
+
+
+
+
+ Returns:
+
+
+ int
+ Count.
+
+
+
+
+
+
+
+
+ Starfield:GetMeteorSpawnDensity()
+
+
+ Get the starfield's meteor spawn density. ()
+
+
+
+
+ Returns:
+
+
+ int
+ Spawn density.
+
+
+
+
+
+
+
+
+ Starfield:GetMeteorVelocity()
+
+
+ Get the starfield's meteor velocity. ()
+
+
+
+
+ Returns:
+
+
+ float
+ Velocity.
+
+
+
+
+
+
+
+
+ Starfield:SetStarCount(New)
+
+
+ Set the starfield's number of stars. (int)
+
+
+
+ Parameters:
+
+
+
+
+
+
+
+
+
+ Starfield:SetMeteorCount(New)
+
+
+ Set the starfield's number of meteors. (int)
+
+
+
+ Parameters:
+
+
+
+
+
+
+
+
+
+ Starfield:SetMeteorSpawnDensity(New)
+
+
+ Set the starfield's meteor spawn density. (int)
+
+
+
+ Parameters:
+
+ New
+ int
+ spawn density.
+
+
+
+
+
+
+
+
+
+
+ Starfield:SetMeteorVelocity(New)
+
+
+ Set the starfield's meteor velocity. (float)
+
+
+
+ Parameters:
+
+ New
+ int
+ velocity.
+
+
+
+
+
+
+
diff --git a/Documentation/doc/2 classes/View.DisplaySprite.html b/Documentation/doc/2 classes/View.DisplaySprite.html
index f17aabb51..376e1fc4f 100644
--- a/Documentation/doc/2 classes/View.DisplaySprite.html
+++ b/Documentation/doc/2 classes/View.DisplaySprite.html
@@ -180,7 +180,7 @@
DisplaySprite(ID, int, pos, rot, scale[, color])
- Create a DisplaySprite object.
+ Create a DisplaySprite object. ()
diff --git a/Documentation/doc/index.html b/Documentation/doc/index.html
index 6ae912f78..3cfe02e63 100644
--- a/Documentation/doc/index.html
+++ b/Documentation/doc/index.html
@@ -187,7 +187,7 @@ local door = GetMoveableByName("door_type4_14")
Flow.LensFlare
- LensFlare
+ Represents a lens flare.
Flow.Level
@@ -207,7 +207,7 @@ local door = GetMoveableByName("door_type4_14")
Flow.Starfield
- Starfield
+ Represents a starfield.
Objects.AIObject
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index 9a4347a1b..23f028319 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -247,9 +247,9 @@ GameStatus ControlPhase()
if (g_GameFlow->GetLevel(CurrentLevel)->GetLensFlareEnabled())
{
SetupGlobalLensFlare(
- g_GameFlow->GetLevel(CurrentLevel)->GetLensFlarePosition(),
+ g_GameFlow->GetLevel(CurrentLevel)->GetLensFlareRotation(),
g_GameFlow->GetLevel(CurrentLevel)->GetLensFlareColor(),
- g_GameFlow->GetLevel(CurrentLevel)->GetLensFlareSpriteID());
+ g_GameFlow->GetLevel(CurrentLevel)->GetLensFlareSunSpriteID());
}
// Update HUD.
diff --git a/TombEngine/Game/effects/weather.cpp b/TombEngine/Game/effects/weather.cpp
index 1771554bf..e91a0f546 100644
--- a/TombEngine/Game/effects/weather.cpp
+++ b/TombEngine/Game/effects/weather.cpp
@@ -9,14 +9,15 @@
#include "Game/effects/tomb4fx.h"
#include "Game/savegame.h"
#include "Game/Setup.h"
-#include "Math/Random.h"
+#include "Math.h"
+#include "Objects/game_object_ids.h"
#include "Sound/sound.h"
-#include "Specific/level.h"
#include "Scripting/Include/ScriptInterfaceLevel.h"
+#include "Specific/level.h"
using namespace TEN::Collision::Point;
using namespace TEN::Effects::Ripple;
-using namespace TEN::Math::Random;
+using namespace TEN::Math;
namespace TEN::Effects::Environment
{
@@ -78,7 +79,7 @@ namespace TEN::Effects::Environment
// Clear weather
Particles.clear();
- // Clear starfield
+ // Clear starfield.
ResetStarField = true;
Meteors.clear();
}
@@ -211,33 +212,32 @@ namespace TEN::Effects::Environment
void EnvironmentController::UpdateStarfield(ScriptInterfaceLevel* level)
{
- if (!level->GetStarfieldEnabled())
+ if (!level->GetStarfieldStarsEnabled())
return;
if (ResetStarField)
{
- int starsCount = level->GetStarfieldStarsCount();
+ int starCount = level->GetStarfieldStarCount();
Stars.clear();
- Stars.reserve(starsCount);
+ Stars.reserve(starCount);
- for (int i = 0; i < starsCount; i++)
+ for (int i = 0; i < starCount; i++)
{
- Vector3 starDirection = Random::GenerateDirectionInCone(-Vector3::UnitY, 70.0f);
- starDirection.Normalize();
+ auto starDir = Random::GenerateDirectionInCone(-Vector3::UnitY, 70.0f);
+ starDir.Normalize();
- StarParticle star;
- star.Direction = starDirection;
+ auto star = StarParticle{};
+ star.Direction = starDir;
star.Color = Vector3(
Random::GenerateFloat(0.6f, 1.0f),
Random::GenerateFloat(0.6f, 1.0f),
- Random::GenerateFloat(0.6f, 1.0f)
- );
+ Random::GenerateFloat(0.6f, 1.0f));
star.Scale = Random::GenerateFloat(0.5f, 1.5f);
- float cosine = Vector3::UnitY.Dot(starDirection);
- float maxCosine = cos(DEG_TO_RAD(50));
- float minCosine = cos(DEG_TO_RAD(70));
+ float cosine = Vector3::UnitY.Dot(starDir);
+ float maxCosine = cos(DEG_TO_RAD(50.0f));
+ float minCosine = cos(DEG_TO_RAD(70.0f));
if (cosine >= minCosine && cosine <= maxCosine)
{
@@ -254,33 +254,37 @@ namespace TEN::Effects::Environment
ResetStarField = false;
}
- for (auto& s : Stars)
- {
- s.Blinking = Random::GenerateFloat(0.5f, 1.0f);
- }
+ for (auto& star : Stars)
+ star.Blinking = Random::GenerateFloat(0.5f, 1.0f);
if (level->GetStarfieldMeteorsEnabled())
{
- for (auto& m : Meteors)
+ for (auto& meteor : Meteors)
{
- m.Life--;
+ meteor.Life--;
- if (m.Life <= 0)
+ if (meteor.Life <= 0)
{
- m.Active = false;
+ meteor.Active = false;
continue;
}
- m.StoreInterpolationData();
+ meteor.StoreInterpolationData();
- if (m.Life <= METEOR_PARTICLES_FADE_TIME)
- m.Fade = m.Life / (float)METEOR_PARTICLES_FADE_TIME;
- else if (m.Life >= METEOR_PARTICLES_MAX_LIFE - METEOR_PARTICLES_FADE_TIME)
- m.Fade = (METEOR_PARTICLES_MAX_LIFE - m.Life) / (float)METEOR_PARTICLES_FADE_TIME;
+ if (meteor.Life <= METEOR_PARTICLE_FADE_TIME)
+ {
+ meteor.Fade = meteor.Life / METEOR_PARTICLE_FADE_TIME;
+ }
+ else if (meteor.Life >= METEOR_PARTICLE_LIFE_MAX - METEOR_PARTICLE_FADE_TIME)
+ {
+ meteor.Fade = (METEOR_PARTICLE_LIFE_MAX - meteor.Life) / METEOR_PARTICLE_FADE_TIME;
+ }
else
- m.Fade = 1.0f;
+ {
+ meteor.Fade = 1.0f;
+ }
- m.Position += m.Direction * level->GetStarfieldMeteorsSpeed();
+ meteor.Position += meteor.Direction * level->GetStarfieldMeteorVelocity();
}
}
}
@@ -422,14 +426,14 @@ namespace TEN::Effects::Environment
case WeatherType::Snow:
if (p.Velocity.x < (WindX << 2))
- p.Velocity.x += GenerateFloat(0.5f, 2.5f);
+ p.Velocity.x += Random::GenerateFloat(0.5f, 2.5f);
else if (p.Velocity.x > (WindX << 2))
- p.Velocity.x -= GenerateFloat(0.5f, 2.5f);
+ p.Velocity.x -= Random::GenerateFloat(0.5f, 2.5f);
if (p.Velocity.z < (WindZ << 2))
- p.Velocity.z += GenerateFloat(0.5f, 2.5f);
+ p.Velocity.z += Random::GenerateFloat(0.5f, 2.5f);
else if (p.Velocity.z > (WindZ << 2))
- p.Velocity.z -= GenerateFloat(0.5f, 2.5f);
+ p.Velocity.z -= Random::GenerateFloat(0.5f, 2.5f);
if (p.Velocity.y < p.Size / 2)
p.Velocity.y += p.Size / 5.0f;
@@ -438,7 +442,7 @@ namespace TEN::Effects::Environment
case WeatherType::Rain:
- auto random = GenerateInt();
+ auto random = Random::GenerateInt();
if ((random & 3) != 3)
{
p.Velocity.x += (float)((random & 3) - 1);
@@ -489,10 +493,10 @@ namespace TEN::Effects::Environment
part.Velocity = Random::GenerateDirection() * MAX_DUST_SPEED;
- part.Size = GenerateFloat(MAX_DUST_SIZE / 2, MAX_DUST_SIZE);
+ part.Size = Random::GenerateFloat(MAX_DUST_SIZE / 2, MAX_DUST_SIZE);
part.Type = WeatherType::None;
- part.Life = DUST_LIFE + GenerateInt(-10, 10);
+ part.Life = DUST_LIFE + Random::GenerateInt(-10, 10);
part.Room = roomNumber;
part.Position.x = xPos;
part.Position.y = yPos;
@@ -531,12 +535,12 @@ namespace TEN::Effects::Environment
newParticlesCount++;
auto distance = level->GetWeatherType() == WeatherType::Snow ? COLLISION_CHECK_DISTANCE : COLLISION_CHECK_DISTANCE / 2;
- auto radius = GenerateInt(0, distance);
- short angle = GenerateInt(ANGLE(0), ANGLE(180));
+ auto radius = Random::GenerateInt(0, distance);
+ short angle = Random::GenerateInt(ANGLE(0), ANGLE(180));
auto xPos = Camera.pos.x + ((int)(phd_cos(angle) * radius));
auto zPos = Camera.pos.z + ((int)(phd_sin(angle) * radius));
- auto yPos = Camera.pos.y - (BLOCK(4) + GenerateInt() & (BLOCK(4) - 1));
+ auto yPos = Camera.pos.y - (BLOCK(4) + Random::GenerateInt() & (BLOCK(4) - 1));
auto outsideRoom = IsRoomOutside(xPos, yPos, zPos);
@@ -556,20 +560,20 @@ namespace TEN::Effects::Environment
switch (level->GetWeatherType())
{
case WeatherType::Snow:
- part.Size = GenerateFloat(MAX_SNOW_SIZE / 3, MAX_SNOW_SIZE);
- part.Velocity.y = GenerateFloat(MAX_SNOW_SPEED / 4, MAX_SNOW_SPEED) * (part.Size / MAX_SNOW_SIZE);
+ part.Size = Random::GenerateFloat(MAX_SNOW_SIZE / 3, MAX_SNOW_SIZE);
+ part.Velocity.y = Random::GenerateFloat(MAX_SNOW_SPEED / 4, MAX_SNOW_SPEED) * (part.Size / MAX_SNOW_SIZE);
part.Life = (MAX_SNOW_SPEED / 3) + ((MAX_SNOW_SPEED / 2) - ((int)part.Velocity.y >> 2));
break;
case WeatherType::Rain:
- part.Size = GenerateFloat(MAX_RAIN_SIZE / 2, MAX_RAIN_SIZE);
- part.Velocity.y = GenerateFloat(MAX_RAIN_SPEED / 2, MAX_RAIN_SPEED) * (part.Size / MAX_RAIN_SIZE) * std::clamp(level->GetWeatherStrength(), 0.6f, 1.0f);
+ part.Size = Random::GenerateFloat(MAX_RAIN_SIZE / 2, MAX_RAIN_SIZE);
+ part.Velocity.y = Random::GenerateFloat(MAX_RAIN_SPEED / 2, MAX_RAIN_SPEED) * (part.Size / MAX_RAIN_SIZE) * std::clamp(level->GetWeatherStrength(), 0.6f, 1.0f);
part.Life = (MAX_RAIN_SPEED * 2) - part.Velocity.y;
break;
}
- part.Velocity.x = GenerateFloat(WEATHER_PARTICLE_HORIZONTAL_SPEED / 2, WEATHER_PARTICLE_HORIZONTAL_SPEED);
- part.Velocity.z = GenerateFloat(WEATHER_PARTICLE_HORIZONTAL_SPEED / 2, WEATHER_PARTICLE_HORIZONTAL_SPEED);
+ part.Velocity.x = Random::GenerateFloat(WEATHER_PARTICLE_HORIZONTAL_SPEED / 2, WEATHER_PARTICLE_HORIZONTAL_SPEED);
+ part.Velocity.z = Random::GenerateFloat(WEATHER_PARTICLE_HORIZONTAL_SPEED / 2, WEATHER_PARTICLE_HORIZONTAL_SPEED);
part.Type = level->GetWeatherType();
part.Room = outsideRoom;
@@ -588,40 +592,45 @@ namespace TEN::Effects::Environment
void EnvironmentController::SpawnMeteorParticles(ScriptInterfaceLevel* level)
{
- // Clean up dead particles
- if (Meteors.size() > 0)
- Meteors.erase(std::remove_if(Meteors.begin(), Meteors.end(), [](const MeteorParticle& part) { return !part.Active; }), Meteors.end());
+ // Clean up dead particles.
+ if (!Meteors.empty())
+ {
+ Meteors.erase(
+ std::remove_if(
+ Meteors.begin(), Meteors.end(),
+ [](const MeteorParticle& part)
+ {
+ return !part.Active;
+ }),
+ Meteors.end());
+ }
if (!level->GetStarfieldMeteorsEnabled())
return;
- int newParticlesCount = 0;
- int density = level->GetStarfieldMeteorsSpawnDensity();
- int meteorsCount = level->GetStarfieldMeteorsCount();
-
+ int density = level->GetStarfieldMeteorSpawnDensity();
if (density > 0)
{
- while (Meteors.size() < meteorsCount)
+ for (int i = 0; i < level->GetStarfieldMeteorCount(); i++)
{
- if (newParticlesCount > density)
+ if (i > density)
break;
- newParticlesCount++;
+ auto horizontalDir = Random::GenerateDirection2D();
auto part = MeteorParticle();
part.Active = true;
- part.Life = METEOR_PARTICLES_MAX_LIFE;
- part.StartPosition = part.Position = Random::GenerateDirectionInCone(-Vector3::UnitY, 40.0f) * BLOCK(1.5f);
+ part.Life = METEOR_PARTICLE_LIFE_MAX;
+ part.StartPosition =
+ part.Position = Random::GenerateDirectionInCone(-Vector3::UnitY, 40.0f) * BLOCK(1.5f);
part.Fade = 0.0f;
part.Color = Vector3(
Random::GenerateFloat(0.6f, 1.0f),
Random::GenerateFloat(0.6f, 1.0f),
- Random::GenerateFloat(0.6f, 1.0f)
- );
+ Random::GenerateFloat(0.6f, 1.0f));
- Vector2 horizontalDirection = Random::GenerateDirection2D();
- part.Direction = Random::GenerateDirectionInCone(Vector3(horizontalDirection.x, 0, horizontalDirection.y), 10.0f);
+ part.Direction = Random::GenerateDirectionInCone(Vector3(horizontalDir.x, 0, horizontalDir.y), 10.0f);
if (part.Direction.y < 0.0f)
part.Direction.y = -part.Direction.y;
diff --git a/TombEngine/Game/effects/weather.h b/TombEngine/Game/effects/weather.h
index 677ef175b..15ff5452f 100644
--- a/TombEngine/Game/effects/weather.h
+++ b/TombEngine/Game/effects/weather.h
@@ -28,39 +28,41 @@ namespace TEN::Effects::Environment
constexpr auto DUST_LIFE = 40;
constexpr auto DUST_SPAWN_RADIUS = (10 * 1024);
- constexpr auto METEOR_PARTICLES_MAX_COUNT = 10;
- constexpr auto METEOR_PARTICLES_MAX_LIFE = 150;
- constexpr auto METEOR_PARTICLES_SPEED = 32.0f;
- constexpr auto METEOR_PARTICLES_SPAWN_DENSITY = 4;
- constexpr auto METEOR_PARTICLES_FADE_TIME = 30;
+ constexpr auto METEOR_PARTICLE_COUNT_MAX = 10;
+ constexpr auto METEOR_PARTICLE_LIFE_MAX = 150;
+ constexpr auto METEOR_PARTICLE_VELOCITY = 32.0f;
+ constexpr auto METEOR_PARTICLE_SPAWN_DENSITY = 4;
+ constexpr auto METEOR_PARTICLE_FADE_TIME = 30.0f;
struct StarParticle
{
- Vector3 Position = Vector3::Zero;
+ Vector3 Position = Vector3::Zero;
Vector3 Direction = Vector3::Zero;
- Vector3 Color = Vector3::Zero;
+ Vector3 Color = Vector3::Zero;
+
float Extinction = 1.0f;
- float Scale = 1.0f;
- float Blinking = 1.0f;
+ float Scale = 1.0f;
+ float Blinking = 1.0f;
};
struct MeteorParticle
{
- Vector3 Position = Vector3::Zero;
- Vector3 Direction = Vector3::Zero;
+ Vector3 Position = Vector3::Zero;
+ Vector3 Direction = Vector3::Zero;
Vector3 StartPosition = Vector3::Zero;
- Vector3 Color = Vector3::Zero;
- float Life;
- bool Active;
- float Fade;
+ Vector3 Color = Vector3::Zero;
- Vector3 OldPosition = Vector3::Zero;
- float OldFade = 0.0f;
+ bool Active = false;
+ float Life = 0.0f;
+ float Fade = 0.0f;
+
+ Vector3 PrevPosition = Vector3::Zero;
+ float PrevFade = 0.0f;
void StoreInterpolationData()
{
- OldPosition = Position;
- OldFade = Fade;
+ PrevPosition = Position;
+ PrevFade = Fade;
}
};
@@ -68,7 +70,7 @@ namespace TEN::Effects::Environment
{
WeatherType Type = WeatherType::None;
- int Room = -1;
+ int Room = NO_VALUE;
Vector3 Position = Vector3::Zero;
Vector3 Velocity = Vector3::Zero;
@@ -142,12 +144,12 @@ namespace TEN::Effects::Environment
byte StormSkyColor2 = 1;
// Starfield
- std::vector Stars;
- std::vector Meteors;
+ std::vector Stars = {};
+ std::vector Meteors = {};
bool ResetStarField = true;
// Lens flare
- LensFlare GlobalLensFlare;
+ LensFlare GlobalLensFlare = {};
void UpdateStarfield(ScriptInterfaceLevel* level);
void UpdateSky(ScriptInterfaceLevel* level);
diff --git a/TombEngine/Objects/Effects/LensFlare.cpp b/TombEngine/Objects/Effects/LensFlare.cpp
index 8f320e137..080605a63 100644
--- a/TombEngine/Objects/Effects/LensFlare.cpp
+++ b/TombEngine/Objects/Effects/LensFlare.cpp
@@ -3,13 +3,16 @@
#include "Game/camera.h"
#include "Game/control/los.h"
+#include "Math/Math.h"
#include "Specific/level.h"
+using namespace TEN::Math;
+
namespace TEN::Entities::Effects
{
std::vector LensFlares;
- static void SetupLensFlare(const Vector3& pos, int roomNumber, const Color& color, bool isGlobal, int spriteIndex)
+ static void SetupLensFlare(const Vector3& pos, int roomNumber, const Color& color, bool isGlobal, int spriteID)
{
auto lensFlarePos = Vector3::Zero;
if (isGlobal)
@@ -67,7 +70,7 @@ namespace TEN::Entities::Effects
lensFlare.RoomNumber = roomNumber;
lensFlare.IsGlobal = isGlobal;
lensFlare.Color = color;
- lensFlare.SpriteIndex = spriteIndex;
+ lensFlare.SpriteID = spriteID;
LensFlares.push_back(lensFlare);
}
@@ -77,7 +80,7 @@ namespace TEN::Entities::Effects
auto& item = g_Level.Items[itemNumber];
if (TriggerActive(&item))
- SetupLensFlare(item.Pose.Position.ToVector3(), item.RoomNumber, Color(), false, SPR_LENS_FLARE_3);
+ SetupLensFlare(item.Pose.Position.ToVector3(), item.RoomNumber, Color(), false, SPRITE_TYPES::SPR_LENS_FLARE_3);
}
void ClearLensFlares()
@@ -85,15 +88,14 @@ namespace TEN::Entities::Effects
LensFlares.clear();
}
- void SetupGlobalLensFlare(const Vector2& yawAndPitchInDegrees, const Color& color, int spriteIndex)
+ void SetupGlobalLensFlare(const EulerAngles& orient, const Color& color, int spriteID)
{
- auto pos = Camera.pos.ToVector3();
- auto rotMatrix = Matrix::CreateFromYawPitchRoll(
- DEG_TO_RAD(yawAndPitchInDegrees.x),
- DEG_TO_RAD(yawAndPitchInDegrees.y),
- 0.0f);
+ constexpr auto BASE_POS = Vector3(0.0f, 0.0f, BLOCK(256));
- pos += Vector3::Transform(Vector3(0.0f, 0.0f, BLOCK(256)), rotMatrix);
- SetupLensFlare(pos, NO_VALUE, color, true, spriteIndex);
+ auto pos = Camera.pos.ToVector3();
+ auto rotMatrix = orient.ToRotationMatrix();
+
+ pos += Vector3::Transform(BASE_POS, rotMatrix);
+ SetupLensFlare(pos, NO_VALUE, color, true, spriteID);
}
}
diff --git a/TombEngine/Objects/Effects/LensFlare.h b/TombEngine/Objects/Effects/LensFlare.h
index 6beca5e52..be1e88f8f 100644
--- a/TombEngine/Objects/Effects/LensFlare.h
+++ b/TombEngine/Objects/Effects/LensFlare.h
@@ -1,10 +1,12 @@
#pragma once
+class EulerAngles;
+
namespace TEN::Entities::Effects
{
struct LensFlare
{
- int SpriteIndex = 0;
+ int SpriteID = 0;
Vector3 Position = Vector3::Zero;
int RoomNumber = 0;
@@ -17,5 +19,5 @@ namespace TEN::Entities::Effects
void ControlLensFlare(int itemNumber);
void ClearLensFlares();
- void SetupGlobalLensFlare(const Vector2& yawAndPitchInDegrees, const Color& color, int spriteIndex);
+ void SetupGlobalLensFlare(const EulerAngles& orient, const Color& color, int spriteID);
}
diff --git a/TombEngine/Objects/Effects/tr5_electricity.cpp b/TombEngine/Objects/Effects/tr5_electricity.cpp
index 5eecfe617..26774f4e1 100644
--- a/TombEngine/Objects/Effects/tr5_electricity.cpp
+++ b/TombEngine/Objects/Effects/tr5_electricity.cpp
@@ -75,7 +75,7 @@ void TriggerElectricityWireSparks(int x, int z, byte objNum, byte node, bool glo
if (glow)
{
spark->scalar = 1;
- spark->spriteIndex = Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LENS_FLARE__LIGHT;
+ spark->spriteIndex = Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LENS_FLARE_LIGHT;
spark->size = spark->sSize = (GetRandomControl() & 0x1F) + 160;
}
else
diff --git a/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp b/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp
index fdd46a288..87ad99739 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp
@@ -160,7 +160,7 @@ namespace TEN::Entities::Creatures::TR5
spark->flags = SP_SCALE | SP_DEF;
spark->scalar = 3;
spark->maxYvel = 0;
- spark->spriteIndex = Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LENS_FLARE__LIGHT;
+ spark->spriteIndex = Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LENS_FLARE_LIGHT;
spark->gravity = 0;
spark->dSize = spark->sSize = spark->size = size + (GetRandomControl() & 3);
}
diff --git a/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp b/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp
index d9a9d57b7..04a4b4ed3 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp
@@ -65,7 +65,7 @@ namespace TEN::Entities::Creatures::TR5
spark->maxYvel = 0;
spark->gravity = 0;
spark->scalar = 1;
- spark->spriteIndex = Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LENS_FLARE__LIGHT;
+ spark->spriteIndex = Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LENS_FLARE_LIGHT;
spark->dSize = spark->sSize = spark->size = (GetRandomControl() & 7) + 192;
}
diff --git a/TombEngine/Objects/objectslist.h b/TombEngine/Objects/objectslist.h
index ea4d252d3..267bbfb7a 100644
--- a/TombEngine/Objects/objectslist.h
+++ b/TombEngine/Objects/objectslist.h
@@ -32,8 +32,8 @@ template std::enable_if_tPSSetShader(_psInstancedSprites.Get(), nullptr, 0);
// Set up vertex buffer and parameters.
- UINT stride = sizeof(Vertex);
- UINT offset = 0;
+ unsigned int stride = sizeof(Vertex);
+ unsigned int offset = 0;
_context->IASetVertexBuffers(0, 1, _quadVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
- RendererSpriteToDraw rDrawSprite;
- rDrawSprite.Sprite = &_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + renderView.LensFlaresToDraw[0].SpriteIndex];
+ auto rDrawSprite = RendererSpriteToDraw{};
+ rDrawSprite.Sprite = &_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + renderView.LensFlaresToDraw[0].SpriteID];
rDrawSprite.Type = SpriteType::Billboard;
rDrawSprite.pos = renderView.Camera.WorldPosition + renderView.LensFlaresToDraw[0].Direction * BLOCK(1);
- rDrawSprite.Rotation = 0;
- rDrawSprite.Scale = 1;
+ rDrawSprite.Rotation = 0.0f;
+ rDrawSprite.Scale = 1.0f;
rDrawSprite.Width = SUN_SIZE;
rDrawSprite.Height = SUN_SIZE;
@@ -3081,7 +3081,7 @@ namespace TEN::Renderer
{
//RenderToCubemap(reflectionCubemap, Vector3(LaraItem->pos.xPos, LaraItem->pos.yPos - 1024, LaraItem->pos.zPos), LaraItem->roomNumber);
- // Interpolate camera
+ // Interpolate camera.
_gameCamera.Camera.WorldPosition = Vector3::Lerp(_oldGameCamera.Camera.WorldPosition, _currentGameCamera.Camera.WorldPosition, interpolationFactor);
_gameCamera.Camera.WorldDirection = Vector3::Lerp(_oldGameCamera.Camera.WorldDirection, _currentGameCamera.Camera.WorldDirection, interpolationFactor);
_gameCamera.Camera.View = Matrix::Lerp(_oldGameCamera.Camera.View, _currentGameCamera.Camera.View, interpolationFactor);
@@ -3142,9 +3142,7 @@ namespace TEN::Renderer
for (auto& bucket : mesh->Buckets)
{
if (bucket.NumVertices == 0)
- {
continue;
- }
if (rendererPass == RendererPass::ShadowMap)
{
diff --git a/TombEngine/Renderer/RendererFrame.cpp b/TombEngine/Renderer/RendererFrame.cpp
index b4c11ea62..8014cb3e2 100644
--- a/TombEngine/Renderer/RendererFrame.cpp
+++ b/TombEngine/Renderer/RendererFrame.cpp
@@ -123,7 +123,7 @@ namespace TEN::Renderer
lensFlareToDraw.Position = lensFlare.Position;
lensFlareToDraw.Distance = dist;
lensFlareToDraw.Color = lensFlare.Color;
- lensFlareToDraw.SpriteIndex = lensFlare.SpriteIndex;
+ lensFlareToDraw.SpriteID = lensFlare.SpriteID;
lensFlareToDraw.Direction = lensFlareToCamera;
lensFlareToDraw.IsGlobal = lensFlare.IsGlobal;
@@ -136,17 +136,12 @@ namespace TEN::Renderer
[](const RendererLensFlare& lensFlare0, const RendererLensFlare& lensFlare1)
{
if (lensFlare0.IsGlobal && !lensFlare1.IsGlobal)
- {
return true;
- }
- else if (!lensFlare0.IsGlobal && lensFlare1.IsGlobal)
- {
+
+ if (!lensFlare0.IsGlobal && lensFlare1.IsGlobal)
return false;
- }
- else
- {
- return lensFlare0.Distance < lensFlare1.Distance;
- }
+
+ return (lensFlare0.Distance < lensFlare1.Distance);
});
for (int i = 0; i < std::min(MAX_LENS_FLARES_DRAW, (int)tempLensFlares.size()); i++)
diff --git a/TombEngine/Renderer/Structures/RendererLensFlare.h b/TombEngine/Renderer/Structures/RendererLensFlare.h
index a6e6de847..1fa9edfdd 100644
--- a/TombEngine/Renderer/Structures/RendererLensFlare.h
+++ b/TombEngine/Renderer/Structures/RendererLensFlare.h
@@ -1,11 +1,11 @@
#pragma once
#include "Renderer/RendererEnums.h"
-
+
namespace TEN::Renderer::Structures
{
struct RendererLensFlare
{
- int SpriteIndex = 0;
+ int SpriteID = 0;
Vector3 Position = Vector3::Zero;
Vector3 Direction = Vector3::Zero;
diff --git a/TombEngine/Scripting/Include/ScriptInterfaceLevel.h b/TombEngine/Scripting/Include/ScriptInterfaceLevel.h
index 1302d22d7..b96635db7 100644
--- a/TombEngine/Scripting/Include/ScriptInterfaceLevel.h
+++ b/TombEngine/Scripting/Include/ScriptInterfaceLevel.h
@@ -48,14 +48,18 @@ public:
virtual int GetSecrets() const = 0;
virtual std::string GetAmbientTrack() const = 0;
virtual bool GetResetHubEnabled() const = 0;
- virtual bool GetLensFlareEnabled() const = 0;
- virtual Vector2 GetLensFlarePosition() const = 0;
- virtual RGBAColor8Byte GetLensFlareColor() const = 0;
- virtual int GetLensFlareSpriteID() const = 0;
- virtual bool GetStarfieldEnabled() const = 0;
- virtual bool GetStarfieldMeteorsEnabled() const = 0;
- virtual int GetStarfieldStarsCount() const = 0;
- virtual int GetStarfieldMeteorsCount() const = 0;
- virtual int GetStarfieldMeteorsSpawnDensity() const = 0;
- virtual float GetStarfieldMeteorsSpeed() const = 0;
+
+ // Lens flare getters
+ virtual bool GetLensFlareEnabled() const = 0;
+ virtual int GetLensFlareSunSpriteID() const = 0;
+ virtual EulerAngles GetLensFlareRotation() const = 0;
+ virtual Color GetLensFlareColor() const = 0;
+
+ // Starfield getters
+ virtual bool GetStarfieldStarsEnabled() const = 0;
+ virtual bool GetStarfieldMeteorsEnabled() const = 0;
+ virtual int GetStarfieldStarCount() const = 0;
+ virtual int GetStarfieldMeteorCount() const = 0;
+ virtual int GetStarfieldMeteorSpawnDensity() const = 0;
+ virtual float GetStarfieldMeteorVelocity() const = 0;
};
diff --git a/TombEngine/Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.cpp b/TombEngine/Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.cpp
index 63de5efcf..7b241639d 100644
--- a/TombEngine/Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.cpp
+++ b/TombEngine/Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.cpp
@@ -12,12 +12,10 @@
using TEN::Renderer::g_Renderer;
-/***
-Represents a display sprite.
-
-@tenclass View.DisplaySprite
-@pragma nostrip
-*/
+/// Represents a display sprite.
+//
+// @tenclass View.DisplaySprite
+// @pragma nostrip
namespace TEN::Scripting::DisplaySprite
{
@@ -50,7 +48,7 @@ namespace TEN::Scripting::DisplaySprite
}
/// Create a DisplaySprite object.
- // @function DisplaySprite
+ // @function DisplaySprite()
// @tparam Objects.ObjID ID of the sprite sequence object.
// @tparam int int spriteID ID of the sprite in the sequence.
// @tparam Vec2 pos Display position in percent.
@@ -190,7 +188,7 @@ namespace TEN::Scripting::DisplaySprite
constexpr auto DEFAULT_SCALE_MODE = DisplaySpriteScaleMode::Fit;
constexpr auto DEFAULT_BLEND_MODE = BlendMode::AlphaBlend;
- // Object is not a sprite sequence object; return early.
+ // Object is not a sprite sequence; return early.
if (_objectID < GAME_OBJECT_ID::ID_HORIZON || _objectID >= GAME_OBJECT_ID::ID_NUMBER_OBJECTS)
{
TENLog("Attempted to draw display sprite from non-sprite sequence object " + std::to_string(_objectID), LogLevel::Warning);
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.cpp b/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.cpp
index 690e1a214..aab754268 100644
--- a/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.cpp
@@ -1,85 +1,108 @@
#include "framework.h"
-#include "LensFlare.h"
-#include
+#include "Scripting/Internal/TEN/Flow/LensFlare/LensFlare.h"
-/***
-LensFlare
+#include "Objects/game_object_ids.h"
+#include "Scripting/Internal/TEN/Rotation/Rotation.h"
+#include "Specific\level.h"
-@tenclass Flow.LensFlare
-@pragma nostrip
-*/
+/// Represents a lens flare.
+//
+// @tenclass Flow.LensFlare
+// @pragma nostrip
-void LensFlare::Register(sol::table& parent)
+namespace TEN::Scripting
{
- using ctors = sol::constructors;
- parent.new_usertype("LensFlare",
- ctors(),
- sol::call_constructor, ctors(),
+ void LensFlare::Register(sol::table& parent)
+ {
+ using ctors = sol::constructors<
+ LensFlare(const Rotation& rot, const ScriptColor& color)>;
- /// (@{Color}) RGB lens flare color
- //@mem lensFlareColor
- "color", sol::property(&LensFlare::GetColor, &LensFlare::SetColor),
+ // Register type.
+ parent.new_usertype(
+ "LensFlare",
+ ctors(),
+ sol::call_constructor, ctors(),
- /*** (@{Vec2}) Lens flare orientation.
+ "GetEnabled", &LensFlare::GetEnabled,
+ "GetSunSpriteID", &LensFlare::GetSunSpriteID,
+ "GetRotation", &LensFlare::GetRotation,
+ "GetColor", &LensFlare::GetColor,
+ "SetSunSpriteID", &LensFlare::SetSunSpriteID,
+ "SetRotation", &LensFlare::SetRotation,
+ "SetColor", &LensFlare::SetColor);
+ }
- This is the position of the lens flare in the sky. The X value is the horizontal position, and the Y value is the vertical position. Angles must be specified in degrees.
+ /// Create a LensFlare object.
+ // @function LensFlare()
+ // @tparam Rotation Rotation.
+ // @tparam Color Color.
+ // @treturn LensFlare A new LensFlare object.
+ LensFlare::LensFlare(const Rotation& rot, const ScriptColor& color)
+ {
+ _isEnabled = true;
+ _color = color;
+ _rotation = rot;
+ }
- @mem lensFlarePosition*/
- "position", sol::property(&LensFlare::GetPosition, &LensFlare::SetPosition)
- );
+ /// Get the lens flare's enabled status.
+ // @function LensFlare:GetEnabled()
+ // @treturn bool Lens flare's enabled status.
+ bool LensFlare::GetEnabled() const
+ {
+ return _isEnabled;
+ }
+
+ /// Get the sun's sprite ID.
+ // @function LensFlare:GetObjectID()
+ // @treturn int Sprite ID.
+ int LensFlare::GetSunSpriteID() const
+ {
+ return _sunSpriteID;
+ }
+
+ // Get the lens flare's euler rotation.
+ // @function LensFlare:GetRotation()
+ // @treturn Rotation Rotation.
+ Rotation LensFlare::GetRotation() const
+ {
+ return _rotation;
+ }
+
+ // Get the lens flare's color.
+ // @function LensFlare:SetColor()
+ ScriptColor LensFlare::GetColor() const
+ {
+ return _color;
+ }
+
+ // Set the lens flare's sun sprite ID.
+ // @function LensFlare:SetSunbjectID()
+ // @tparam int New sprite ID.
+ void LensFlare::SetSunSpriteID(int spriteID)
+ {
+ // Sprite ID out of range; return early.
+ if (spriteID < 0 || g_Level.Sprites.size() > spriteID)
+ {
+ TENLog("Sub sprite ID out of range.");
+ return;
+ }
+
+ _sunSpriteID = spriteID;
+ }
+
+ // Set the lens flare's euler rotation.
+ // @function LensFlare:SetRotation(Rotation)
+ // @tparam Rotation New euler rotation.
+ void LensFlare::SetRotation(const Rotation& rot)
+ {
+ _rotation = rot;
+ }
+
+ // Set the lens flare's color.
+ // @function LensFlare:SetColor(Color)
+ // @tparam Color New color.
+ void LensFlare::SetColor(const ScriptColor& color)
+ {
+ _color = color;
+ }
}
-
-/***
-@tparam Vec2 yawPitchInDegrees Position of the lens flare (yaw and pitch) in degrees
-@tparam Color color RGB color
-@treturn LensFlare A lens flare object.
-@function LensFlare
-*/
-LensFlare::LensFlare(Vec2 const& yawPitchInDegrees, ScriptColor const& col)
-{
- SetColor(col);
- SetPosition(yawPitchInDegrees);
- Enabled = true;
-}
-
-void LensFlare::SetColor(ScriptColor const& col)
-{
- R = col.GetR();
- G = col.GetG();
- B = col.GetB();
-}
-
-
-ScriptColor LensFlare::GetColor() const
-{
- return ScriptColor{ R, G, B };
-}
-
-void LensFlare::SetPosition(Vec2 const& yawPitchInDegrees)
-{
- Yaw = yawPitchInDegrees.x;
- Pitch = yawPitchInDegrees.y;
-}
-
-
-Vec2 LensFlare::GetPosition() const
-{
- return Vec2{ Yaw, Pitch };
-}
-
-bool LensFlare::GetEnabled() const
-{
- return Enabled;
-}
-
-void LensFlare::SetSunSpriteID(int const& spriteIndex)
-{
- assertion(spriteIndex >= 0 && spriteIndex < g_Level.Sprites.size(), "Sprite Index must be in a valid range");
-
- SunSpriteID = spriteIndex;
-}
-
-int LensFlare::GetSunSpriteID() const
-{
- return SunSpriteID;
-}
\ No newline at end of file
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.h b/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.h
index 2970bd4dc..8b034b9f0 100644
--- a/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.h
+++ b/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.h
@@ -1,34 +1,39 @@
#pragma once
-
-#include "Scripting/Internal/TEN/Color/Color.h"
-#include "Scripting/Internal/TEN/Vec2/Vec2.h"
+#include "Objects/game_object_ids.h"
#include "Objects/objectslist.h"
+#include "Scripting/Internal/TEN/Color/Color.h"
+#include "Scripting/Internal/TEN/Rotation/Rotation.h"
namespace sol { class state; }
-struct LensFlare
+namespace TEN::Scripting
{
- bool Enabled;
- int SunSpriteID = SPR_LENS_FLARE_3; // Index into sprites
- byte R;
- byte G;
- byte B;
- float Yaw;
- float Pitch;
+ class LensFlare
+ {
+ private:
+ // Members
+ int _sunSpriteID = SPRITE_TYPES::SPR_LENS_FLARE_3;
+ bool _isEnabled;
- LensFlare() = default;
- LensFlare(Vec2 const& yawPitchInDegrees, ScriptColor const& col);
+ Rotation _rotation = {};
+ ScriptColor _color = 0;
- void SetColor(ScriptColor const& color);
- ScriptColor GetColor() const;
+ public:
+ static void Register(sol::table& table);
- void SetPosition(Vec2 const& yawPitchInDegrees);
- Vec2 GetPosition() const;
+ // Constructors
+ LensFlare() = default;
+ LensFlare(const Rotation& rot, const ScriptColor& color);
- void SetSunSpriteID(int const& spriteIndex);
- int GetSunSpriteID() const;
+ // Getters
+ bool GetEnabled() const;
+ int GetSunSpriteID() const;
+ Rotation GetRotation() const;
+ ScriptColor GetColor() const;
- bool GetEnabled() const;
-
- static void Register(sol::table&);
-};
\ No newline at end of file
+ // Setters
+ void SetSunSpriteID(int spriteID);
+ void SetRotation(const Rotation& rot);
+ void SetColor(const ScriptColor& color);
+ };
+}
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp b/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp
index 919174fdd..2f419cf1d 100644
--- a/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp
@@ -1,7 +1,10 @@
#include "framework.h"
-#include "FlowLevel.h"
+#include "Scripting/Internal/TEN/Flow/Level/FlowLevel.h"
+
#include "Scripting/Internal/ScriptAssert.h"
+using namespace TEN::Scripting;
+
/***
Stores level metadata.
These are things things which aren't present in the compiled level file itself.
@@ -15,12 +18,14 @@ These are things things which aren't present in the compiled level file itself.
@treturn Level a Level object
*/
void Level::Register(sol::table& parent)
-{
- parent.new_usertype("Level",
+{
+ // Register type.
+ parent.new_usertype(
+ "Level",
sol::constructors(),
sol::call_constructor, sol::constructors(),
-/// (string) string key for the level's (localised) name.
-// Corresponds to an entry in strings.lua.
+
+ // Corresponds to an entry in strings.lua.
//@mem nameKey
"nameKey", &Level::NameStringKey,
@@ -52,13 +57,13 @@ void Level::Register(sol::table& parent)
//@mem layer2
"layer2", &Level::Layer2,
-/// (@{Flow.Starfield}) Starfield
-//@mem starfield
- "starfield", & Level::Starfield,
+ /// (@{Flow.Starfield}) Starfield.
+ // @mem starfield
+ "starfield", &Level::Starfield,
-/// (@{Flow.LensFlare}) Global lens flare
-//@mem lensFlare
- "lensFlare", & Level::LensFlare,
+ /// (@{Flow.LensFlare}) Global lens flare .
+ // @mem lensFlare
+ "lensFlare", &Level::LensFlare,
/// (@{Flow.Fog}) omni fog RGB color and distance.
// As seen in TR4's Desert Railroad.
@@ -291,24 +296,24 @@ bool Level::GetLensFlareEnabled() const
return LensFlare.GetEnabled();
}
-Vector2 Level::GetLensFlarePosition() const
-{
- return LensFlare.GetPosition();
-}
-
-RGBAColor8Byte Level::GetLensFlareColor() const
-{
- return LensFlare.GetColor();
-}
-
-int Level::GetLensFlareSpriteID() const
+int Level::GetLensFlareSunSpriteID() const
{
return LensFlare.GetSunSpriteID();
}
-bool Level::GetStarfieldEnabled() const
+EulerAngles Level::GetLensFlareRotation() const
{
- return Starfield.GetEnabled();
+ return LensFlare.GetRotation().ToEulerAngles();
+}
+
+Color Level::GetLensFlareColor() const
+{
+ return LensFlare.GetColor();
+}
+
+bool Level::GetStarfieldStarsEnabled() const
+{
+ return Starfield.GetStarsEnabled();
}
bool Level::GetStarfieldMeteorsEnabled() const
@@ -316,22 +321,22 @@ bool Level::GetStarfieldMeteorsEnabled() const
return Starfield.GetMeteorsEnabled();
}
-int Level::GetStarfieldStarsCount() const
+int Level::GetStarfieldStarCount() const
{
- return Starfield.GetStarsCount();
+ return Starfield.GetStarCount();
}
-int Level::GetStarfieldMeteorsCount() const
+int Level::GetStarfieldMeteorCount() const
{
- return Starfield.GetMeteorsCount();
+ return Starfield.GetMeteorCount();
}
-int Level::GetStarfieldMeteorsSpawnDensity() const
+int Level::GetStarfieldMeteorSpawnDensity() const
{
- return Starfield.GetMeteorsSpawnDensity();
+ return Starfield.GetMeteorSpawnDensity();
}
-float Level::GetStarfieldMeteorsSpeed() const
+float Level::GetStarfieldMeteorVelocity() const
{
- return Starfield.GetMeteorsSpeed();
-}
\ No newline at end of file
+ return Starfield.GetMeteorVelocity();
+}
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.h b/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.h
index 0460e6a9b..4b8610f5c 100644
--- a/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.h
+++ b/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.h
@@ -1,5 +1,4 @@
#pragma once
-#include
#include "Scripting/Internal/TEN/Flow/SkyLayer/SkyLayer.h"
#include "Scripting/Internal/TEN/Flow/LensFlare/LensFlare.h"
#include "Scripting/Internal/TEN/Flow/Starfield/Starfield.h"
@@ -8,6 +7,8 @@
#include "Scripting/Include/ScriptInterfaceLevel.h"
#include "Scripting/Internal/TEN/Flow/InventoryItem/InventoryItem.h"
+using namespace TEN::Scripting;
+
static const std::unordered_map WEATHER_TYPES
{
{ "None", WeatherType::None },
@@ -34,8 +35,8 @@ struct Level : public ScriptInterfaceLevel
int LevelFarView = 0;
std::string AmbientTrack = {};
- LensFlare LensFlare = {};
- Starfield Starfield = {};
+ LensFlare LensFlare = {};
+ Starfield Starfield = {};
WeatherType Weather = WeatherType::None;
float WeatherStrength = 1.0f;
@@ -47,6 +48,8 @@ struct Level : public ScriptInterfaceLevel
bool ResetHub = false;
+ // TODO: Clean up this mess.
+
RGBAColor8Byte GetFogColor() const override;
bool GetFogEnabled() const override;
float GetWeatherStrength() const override;
@@ -67,14 +70,18 @@ struct Level : public ScriptInterfaceLevel
int GetSecrets() const override;
std::string GetAmbientTrack() const override;
bool GetResetHubEnabled() const override;
- bool GetLensFlareEnabled() const override;
- Vector2 GetLensFlarePosition() const override;
- RGBAColor8Byte GetLensFlareColor() const override;
- int GetLensFlareSpriteID() const override;
- bool GetStarfieldEnabled() const override;
- bool GetStarfieldMeteorsEnabled() const override;
- int GetStarfieldStarsCount() const override;
- int GetStarfieldMeteorsCount() const override;
- int GetStarfieldMeteorsSpawnDensity() const override;
- float GetStarfieldMeteorsSpeed() const override;
+
+ // Lens flare getters
+ bool GetLensFlareEnabled() const override;
+ int GetLensFlareSunSpriteID() const override;
+ EulerAngles GetLensFlareRotation() const override;
+ Color GetLensFlareColor() const override;
+
+ // Starfield getters
+ bool GetStarfieldStarsEnabled() const override;
+ bool GetStarfieldMeteorsEnabled() const override;
+ int GetStarfieldStarCount() const override;
+ int GetStarfieldMeteorCount() const override;
+ int GetStarfieldMeteorSpawnDensity() const override;
+ float GetStarfieldMeteorVelocity() const override;
};
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.cpp b/TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.cpp
index 56f957300..a2f030a6e 100644
--- a/TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.cpp
@@ -1,127 +1,157 @@
#include "framework.h"
-#include "Starfield.h"
-#include "Specific/level.h"
+#include "Scripting/Internal/TEN/Flow/Starfield/Starfield.h"
+
#include "Game/effects/weather.h"
+#include "Specific/level.h"
using namespace TEN::Effects::Environment;
-/***
-Starfield
+/// Represents a starfield.
+//
+// @tenclass Flow.Starfield
+// @pragma nostrip
-@tenclass Flow.Starfield
-@pragma nostrip
-*/
-
-void Starfield::Register(sol::table& parent)
+namespace TEN::Scripting
{
- using ctors = sol::constructors;
- parent.new_usertype("Starfield",
- ctors(),
- sol::call_constructor, ctors(),
+ void Starfield::Register(sol::table& parent)
+ {
+ using ctors = sol::constructors<
+ Starfield(int starCount),
+ Starfield(int starCount, int meteorCount, int meteorSpawnDensity, float meteorVel)>;
+
+ // Register type.
+ parent.new_usertype(
+ "Starfield",
+ ctors(),
+ sol::call_constructor, ctors(),
+
+ "GetStarsEnabled", &Starfield::GetStarsEnabled,
+ "GetMeteorsEnabled", &Starfield::GetMeteorsEnabled,
+ "GetStarCount", &Starfield::GetStarCount,
+ "GetMeteorCount", &Starfield::GetMeteorCount,
+ "GetMeteorSpawnDensity", &Starfield::GetMeteorSpawnDensity,
+ "GetMeteorVelocity", &Starfield::GetMeteorVelocity,
+ "SetStarCount", &Starfield::SetStarCount,
+ "SetMeteorCount", &Starfield::SetMeteorCount,
+ "SetMeteorSpawnDensity", &Starfield::SetMeteorSpawnDensity,
+ "SetMeteorVelocity", &Starfield::SetMeteorVelocity);
+ }
- /*** (int) Stars count.
+ /// Create a starfield object with only stars.
+ // @function Starfield()
+ // @tparam int starCount Star count.
+ // @treturn Starfield A new Starfield object.
+ Starfield::Starfield(int starCount)
+ {
+ _starCount = starCount;
+ }
- Values can be between [0, 6000], 0 resulting in no stars being rendered, and 6000 resulting in the maximum number of stars being rendered.
+ /// Create a starfield object with stars and meteors.
+ // @function Starfield()
+ // @tparam int starCount Star count.
+ // @tparam int meteorCount Meteor count.
+ // @treturn Starfield A new Starfield object.
+ Starfield::Starfield(int starCount, int meteorCount, int meteorSpawnDensity, float meteorVel)
+ {
+ _starCount = starCount;
+ _meteorCount = meteorCount;
+ _meteorSpawnDensity = meteorSpawnDensity;
+ _meteorVelocity = meteorVel;
+ }
- @mem starsCount*/
- "starsCount", sol::property(&Starfield::GetStarsCount, &Starfield::SetStarsCount),
+ /// Get the starfield's enabled status of stars.
+ // @function Starfield:GetStarsEnabled()
+ // @treturn bool Stars enabled status.
+ bool Starfield::GetStarsEnabled() const
+ {
+ return (_starCount > 0);
+ }
- /*** (int) Meteors count.
+ /// Get the starfield's enabled status of meteors.
+ // @function Starfield:GetMeteorsEnabled()
+ // @treturn bool Meteors enabled status.
+ bool Starfield::GetMeteorsEnabled() const
+ {
+ return (_meteorCount > 0);
+ }
- Values can be between [0, 100], 0 resulting in no meteors being rendered, and 100 resulting in the maximum number of meteors being rendered.
+ /// Get the starfield's number of stars.
+ // @function Starfield:GetStarCount()
+ // @treturn int Count.
+ int Starfield::GetStarCount() const
+ {
+ return _starCount;
+ }
- @mem meteorsCount*/
- "meteorsCount", sol::property(&Starfield::GetMeteorsCount, &Starfield::SetMeteorsCount),
+ /// Get the starfield's number of meteors.
+ // @function Starfield:GetMeteorCount()
+ // @treturn int Count.
+ int Starfield::GetMeteorCount() const
+ {
+ return _meteorCount;
+ }
- /*** (int) Meteors spawn density.
+ /// Get the starfield's meteor spawn density.
+ // @function Starfield:GetMeteorSpawnDensity()
+ // @treturn int Spawn density.
+ int Starfield::GetMeteorSpawnDensity() const
+ {
+ return _meteorSpawnDensity;
+ }
- @mem meteorsSpawnDensity*/
- "meteorsSpawnDensity", sol::property(&Starfield::GetMeteorsSpawnDensity, &Starfield::SetMeteorsSpawnDensity),
+ /// Get the starfield's meteor velocity.
+ // @function Starfield:GetMeteorVelocity()
+ // @treturn float Velocity.
+ float Starfield::GetMeteorVelocity() const
+ {
+ return _meteorVelocity;
+ }
- /*** (float) Meteors speed.
+ /// Set the starfield's number of stars.
+ // @function Starfield:SetStarCount(int)
+ // @tparam int New count.
+ void Starfield::SetStarCount(int count)
+ {
+ // Star count out of range; set max.
+ if (count < 0 || count > STAR_COUNT_MAX)
+ {
+ TENLog("Star count must be in range [0, " + std::to_string(STAR_COUNT_MAX) + "].", LogLevel::Warning);
+ _starCount = STAR_COUNT_MAX;
+ return;
+ }
- @mem meteorsSpeed*/
- "meteorsSpeed", sol::property(&Starfield::GetMeteorsSpeed, &Starfield::SetMeteorsSpeed)
- );
+ _starCount = count;
+ }
+
+ /// Set the starfield's number of meteors.
+ // @function Starfield:SetMeteorCount(int)
+ // @tparam int New count.
+ void Starfield::SetMeteorCount(int count)
+ {
+ // Meteor count out of range; set max.
+ if (count < 0 || count > METEOR_COUNT_MAX)
+ {
+ TENLog("Meteor count must be in range [0, " + std::to_string(METEOR_COUNT_MAX) + "].", LogLevel::Warning);
+ _meteorCount = METEOR_COUNT_MAX;
+ return;
+ }
+
+ _meteorCount = count;
+ }
+
+ /// Set the starfield's meteor spawn density.
+ // @function Starfield:SetMeteorSpawnDensity(int)
+ // @tparam int New spawn density.
+ void Starfield::SetMeteorSpawnDensity(int spawnDensity)
+ {
+ _meteorSpawnDensity = spawnDensity;
+ }
+
+ /// Set the starfield's meteor velocity.
+ // @function Starfield:SetMeteorVelocity(float)
+ // @tparam int New velocity.
+ void Starfield::SetMeteorVelocity(float vel)
+ {
+ _meteorVelocity = vel;
+ }
}
-
-/***
-@tparam int starsCount Stars count
-@treturn Starfield A starfield object with only stars enabled.
-@function Starfield
-*/
-Starfield::Starfield(int starsCount)
-{
- SetStarsCount(starsCount);
- SetMeteorsCount(0);
-}
-
-/***
-@tparam int starsCount Stars count
-@tparam int meteorsCount Stars count
-@treturn Starfield A starfield object with boths stars and meteors enabled.
-@function Starfield
-*/
-Starfield::Starfield(int starsCount, int meteorsCount, int meteorsSpawnDensity, int meteorsSpawnSpeed)
-{
- SetStarsCount(starsCount);
- SetMeteorsCount(meteorsCount);
- SetMeteorsSpawnDensity(meteorsSpawnDensity);
- SetMeteorsSpeed(meteorsSpawnSpeed);
-}
-
-void Starfield::SetStarsCount(int const& starsCount)
-{
- assertion(starsCount >= 0 && starsCount <= 6000, "Stars count must be in the range 0 ... 6000");
- StarsCount = starsCount;
-}
-
-
-int Starfield::GetStarsCount() const
-{
- return StarsCount;
-}
-
-void Starfield::SetMeteorsCount(int const& meteorsCount)
-{
- assertion(meteorsCount >= 0 && meteorsCount <= 100, "Stars count must be in the range 0 ... 100");
- MeteorsCount = meteorsCount;
-}
-
-
-int Starfield::GetMeteorsCount() const
-{
- return MeteorsCount;
-}
-
-void Starfield::SetMeteorsSpawnDensity(int const& meteorsSpawnDensity)
-{
- MeteorsSpawnDensity = meteorsSpawnDensity;
-}
-
-
-int Starfield::GetMeteorsSpawnDensity() const
-{
- return MeteorsSpawnDensity;
-}
-
-void Starfield::SetMeteorsSpeed(float const& meteorsSpeed)
-{
- MeteorsSpeed = meteorsSpeed;
-}
-
-
-float Starfield::GetMeteorsSpeed() const
-{
- return MeteorsSpeed;
-}
-
-bool Starfield::GetEnabled() const
-{
- return (StarsCount > 0);
-}
-
-bool Starfield::GetMeteorsEnabled() const
-{
- return (MeteorsCount > 0);
-}
\ No newline at end of file
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.h b/TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.h
index 4144bb516..913314088 100644
--- a/TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.h
+++ b/TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.h
@@ -1,36 +1,42 @@
#pragma once
-#include "Scripting/Internal/TEN/Color/Color.h"
-#include "Scripting/Internal/TEN/Vec2/Vec2.h"
-
namespace sol { class state; }
-struct Starfield
+namespace TEN::Scripting
{
- int StarsCount = 0; // No need for StarryNight flag, if stars count = 0, shader is bypassed
+ class Starfield
+ {
+ private:
+ // Constants
+ static const auto STAR_COUNT_MAX = 6000;
+ static const auto METEOR_COUNT_MAX = 100;
- int MeteorsCount = 0; // No need for EnableMeteors flag, if meteors count = 0, shader is bypassed
- int MeteorsSpawnDensity = 0;
- int MeteorsSpeed = 0;
+ // Members
+ int _starCount = 0;
+ int _meteorCount = 0;
+ int _meteorSpawnDensity = 0;
+ float _meteorVelocity = 0;
- Starfield() = default;
- Starfield(int starsCount);
- Starfield(int starsCount, int meteorsCount, int meteorsSpawnDensity, int meteorsSpeed);
+ public:
+ static void Register(sol::table& table);
- void SetStarsCount(int const& starsCount);
- int GetStarsCount() const;
+ // Constructors
+ Starfield() = default;
+ Starfield(int starCount);
+ Starfield(int starCount, int meteorCount, int meteorSpawnDensity, float meteorVel);
- void SetMeteorsCount(int const& meteorsCount);
- int GetMeteorsCount() const;
+ // Getters
+ bool GetStarsEnabled() const;
+ bool GetMeteorsEnabled() const;
+ int GetStarCount() const;
+ int GetMeteorCount() const;
+ int GetMeteorSpawnDensity() const;
+ float GetMeteorVelocity() const;
- void SetMeteorsSpawnDensity(int const& spawnDensity);
- int GetMeteorsSpawnDensity() const;
-
- void SetMeteorsSpeed(float const& meteorsSpeed);
- float GetMeteorsSpeed() const;
-
- bool GetEnabled() const;
- bool GetMeteorsEnabled() const;
-
- static void Register(sol::table&);
-};
\ No newline at end of file
+ // Setters
+ void SetStarCount(int count);
+ void SetMeteorCount(int count);
+ void SetMeteorSpawnDensity(int spawnDensity);
+ void SetMeteorVelocity(float vel);
+ };
+}
From e7889d2b8806113b5de52ee254a3bad991cae243 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 8 May 2024 14:10:45 +1000
Subject: [PATCH 145/410] Update colour objects
---
.../doc/3 primitive classes/Color.html | 72 ++------
Documentation/doc/index.html | 2 +-
.../Scripting/Internal/TEN/Color/Color.cpp | 169 +++++++++---------
.../Scripting/Internal/TEN/Color/Color.h | 17 +-
TombEngine/Specific/RGBAColor8Byte.cpp | 105 +++++------
TombEngine/Specific/RGBAColor8Byte.h | 46 ++---
6 files changed, 186 insertions(+), 225 deletions(-)
diff --git a/Documentation/doc/3 primitive classes/Color.html b/Documentation/doc/3 primitive classes/Color.html
index 58efaffe6..f627b4d9e 100644
--- a/Documentation/doc/3 primitive classes/Color.html
+++ b/Documentation/doc/3 primitive classes/Color.html
@@ -100,27 +100,27 @@
Primitive Class Color
-
An RGBA or RGB color.
-
Components are specified in bytes; all values are clamped to [0, 255].
+
Represents an RGBA or RGB color.
+
Components are specified in bytes. All values are clamped to the range [0, 255].
r
- (int) red component
+ (int) Red component.
g
- (int) green component
+ (int) Green component.
b
- (int) blue component
+ (int) Blue component.
a
- (int) alpha component (255 = opaque, 0 = invisible)
+ (int) Alpha component (0 = invisible, 255 = opaque).
@@ -129,12 +129,6 @@
Color(R, G, B)
-
-
-
- Color(R, G, B, A)
-
-
@@ -157,7 +151,7 @@
r
- (int) red component
+ (int) Red component.
@@ -172,7 +166,7 @@
g
- (int) green component
+ (int) Green component.
@@ -187,7 +181,7 @@
b
- (int) blue component
+ (int) Blue component.
@@ -202,7 +196,7 @@
a
- (int) alpha component (255 = opaque, 0 = invisible)
+ (int) Alpha component (0 = invisible, 255 = opaque).
@@ -253,48 +247,6 @@
-
-
-
- Color(R, G, B, A)
-
-
-
-
-
-
-
-
- Parameters:
-
- R
- int
- red component
-
- G
- int
- green component
-
- B
- int
- blue component
-
- A
- int
- alpha component (255 is opaque, 0 is invisible)
-
-
-
- Returns:
-
-
- Color
- A new Color object.
-
-
-
-
-
@@ -311,7 +263,7 @@
color
Color
- this color
+ This color.
@@ -319,7 +271,7 @@
string
- A string showing the r, g, b, and a values of the color
+ A string representing the r, g, b, and a values of the color.
diff --git a/Documentation/doc/index.html b/Documentation/doc/index.html
index 77f425919..e481a6133 100644
--- a/Documentation/doc/index.html
+++ b/Documentation/doc/index.html
@@ -244,7 +244,7 @@ local door = GetMoveableByName("door_type4_14")
Color
- An RGBA or RGB color.
+ Represents an RGBA or RGB color.
Rotation
diff --git a/TombEngine/Scripting/Internal/TEN/Color/Color.cpp b/TombEngine/Scripting/Internal/TEN/Color/Color.cpp
index ab08c199c..88af10b3f 100644
--- a/TombEngine/Scripting/Internal/TEN/Color/Color.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Color/Color.cpp
@@ -1,150 +1,147 @@
#include "framework.h"
#include "Scripting/Internal/TEN/Color/Color.h"
-#include
-
-/***
-An RGBA or RGB color.
-Components are specified in bytes; all values are clamped to [0, 255].
-
-@tenprimitive Color
-@pragma nostrip
-*/
+/// Represents an RGBA or RGB color.
+// Components are specified in bytes. All values are clamped to the range [0, 255].
+//
+// @tenprimitive Color
+// @pragma nostrip
void ScriptColor::Register(sol::table& parent)
{
using ctors = sol::constructors;
+
+ // Register type.
parent.new_usertype(
"Color",
ctors(),
sol::call_constructor, ctors(),
sol::meta_function::to_string, &ScriptColor::ToString,
-/// (int) red component
-//@mem r
+ /// (int) Red component.
+ // @mem r
"r", sol::property(&ScriptColor::GetR, &ScriptColor::SetR),
-/// (int) green component
-//@mem g
+ /// (int) Green component.
+ // @mem g
"g", sol::property(&ScriptColor::GetG, &ScriptColor::SetG),
-/// (int) blue component
-//@mem b
+ /// (int) Blue component.
+ // @mem b
"b", sol::property(&ScriptColor::GetB, &ScriptColor::SetB),
-/// (int) alpha component (255 = opaque, 0 = invisible)
-//@mem a
- "a", sol::property(&ScriptColor::GetA, &ScriptColor::SetA)
- );
+ /// (int) Alpha component (0 = invisible, 255 = opaque).
+ // @mem a
+ "a", sol::property(&ScriptColor::GetA, &ScriptColor::SetA));
}
-/***
-@int R red component
-@int G green component
-@int B blue component
-@treturn Color A new Color object.
-@function Color
-*/
+/// @int R red component
+// @int G green component
+// @int B blue component
+// @treturn Color A new Color object.
+// @function Color
ScriptColor::ScriptColor(byte r, byte g, byte b) :
-m_color(r, g, b)
+_color(r, g, b)
{
}
-/***
-@int R red component
-@int G green component
-@int B blue component
-@int A alpha component (255 is opaque, 0 is invisible)
-@treturn Color A new Color object.
-@function Color
-*/
-ScriptColor::ScriptColor(byte r, byte g, byte b, byte a) : ScriptColor(r, g, b)
+// @function Color()
+// @int R Red component.
+// @int G Green component.
+// @int B Blue component.
+// @int A Alpha component (0 = invisible, 255 = opaque).
+// @treturn Color A new Color object.
+ScriptColor::ScriptColor(byte r, byte g, byte b, byte a) :
+ ScriptColor(r, g, b)
{
SetA(a);
}
ScriptColor::ScriptColor(const Vector3& color) :
- m_color(color)
+ _color(color)
{
}
ScriptColor::ScriptColor(const Vector4& color) :
- m_color(color)
+ _color(color)
{
}
ScriptColor::ScriptColor(D3DCOLOR color) :
- m_color(color)
+ _color(color)
{
}
-ScriptColor::operator Vector3() const
-{
- return m_color;
-}
-
-ScriptColor::operator Vector4() const
-{
- return m_color;
-}
-
-// D3DCOLOR is 32 bits and is laid out as ARGB.
-ScriptColor::operator D3DCOLOR() const
-{
- return m_color;
-}
-
-ScriptColor::operator RGBAColor8Byte() const
-{
- return m_color;
-}
-
byte ScriptColor::GetR() const
{
- return m_color.GetR();
-}
-
-void ScriptColor::SetR(byte value)
-{
- m_color.SetR(value);
+ return _color.GetR();
}
byte ScriptColor::GetG() const
{
- return m_color.GetG();
-}
-
-void ScriptColor::SetG(byte value)
-{
- m_color.SetG(value);
+ return _color.GetG();
}
byte ScriptColor::GetB() const
{
- return m_color.GetB();
-}
-
-void ScriptColor::SetB(byte value)
-{
- m_color.SetB(value);
+ return _color.GetB();
}
byte ScriptColor::GetA() const
{
- return m_color.GetA();
+ return _color.GetA();
+}
+
+void ScriptColor::SetR(byte value)
+{
+ _color.SetR(value);
+}
+
+void ScriptColor::SetG(byte value)
+{
+ _color.SetG(value);
+}
+
+void ScriptColor::SetB(byte value)
+{
+ _color.SetB(value);
}
void ScriptColor::SetA(byte value)
{
- m_color.SetA(value);
+ _color.SetA(value);
}
-/***
-@tparam Color color this color
-@treturn string A string showing the r, g, b, and a values of the color
-@function __tostring
-*/
+/// @tparam Color color This color.
+// @treturn string A string representing the r, g, b, and a values of the color.
+// @function __tostring
std::string ScriptColor::ToString() const
{
- return "{" + std::to_string(GetR()) + ", " + std::to_string(GetG()) + ", " + std::to_string(GetB()) + ", " + std::to_string(GetA()) + "}";
+ return "{ " + std::to_string(GetR()) + ", " + std::to_string(GetG()) + ", " + std::to_string(GetB()) + ", " + std::to_string(GetA()) + " }";
+}
+
+ScriptColor::operator Color() const
+{
+ return _color;
+}
+
+ScriptColor::operator Vector3() const
+{
+ return _color;
+}
+
+ScriptColor::operator Vector4() const
+{
+ return _color;
+}
+
+// NOTE: D3DCOLOR is 32 bits and is laid out as ARGB.
+ScriptColor::operator D3DCOLOR() const
+{
+ return _color;
+}
+
+ScriptColor::operator RGBAColor8Byte() const
+{
+ return _color;
}
diff --git a/TombEngine/Scripting/Internal/TEN/Color/Color.h b/TombEngine/Scripting/Internal/TEN/Color/Color.h
index 03f75630d..701d133d5 100644
--- a/TombEngine/Scripting/Internal/TEN/Color/Color.h
+++ b/TombEngine/Scripting/Internal/TEN/Color/Color.h
@@ -11,32 +11,39 @@ namespace sol
class ScriptColor
{
+private:
+ // Members
+ RGBAColor8Byte _color;
+
public:
+ static void Register(sol::table& parent);
+
+ // Constructors
ScriptColor(byte r, byte g, byte b);
ScriptColor(byte r, byte g, byte b, byte a);
ScriptColor(const Vector3& color);
ScriptColor(const Vector4& color);
ScriptColor(D3DCOLOR);
+ // Getters
byte GetR() const;
byte GetG() const;
byte GetB() const;
byte GetA() const;
+ // Setters
void SetR(byte value);
void SetG(byte value);
void SetB(byte value);
void SetA(byte value);
+ // Converters
std::string ToString() const;
+ // Operators
+ operator Color() const;
operator Vector3() const;
operator Vector4() const;
operator D3DCOLOR() const;
operator RGBAColor8Byte() const;
-
- static void Register(sol::table& parent);
-
-private:
- RGBAColor8Byte m_color;
};
diff --git a/TombEngine/Specific/RGBAColor8Byte.cpp b/TombEngine/Specific/RGBAColor8Byte.cpp
index b627b21e4..7ec856d3e 100644
--- a/TombEngine/Specific/RGBAColor8Byte.cpp
+++ b/TombEngine/Specific/RGBAColor8Byte.cpp
@@ -1,46 +1,57 @@
#include "framework.h"
-#include "RGBAColor8Byte.h"
+#include "Specific/RGBAColor8Byte.h"
-static byte FloatComponentToByte(float v)
+static byte FloatComponentToByte(float value)
{
- //todo look into what these actually do AND TEST THEM
- //todo like, see if these are actually not undefined or some shit
- auto lval = std::lroundf((v / 2.0f) * 255.0f);
- return static_cast(lval);
+ // TODO: Look into what these actually do and test them to see if they are actually not undefined.
+ long byteValue = std::lroundf((value / 2.0f) * 255.0f);
+ return (byte)byteValue;
}
static float ByteComponentToFloat(byte b)
{
- //todo look into what these actually do AND TEST THEM
- //todo like, see if these are actually not undefined or some shit
- float f = b;
- f = (f / 255.0f) * 2.0f;
- return f;
+ // TODO: Look into what these actually do and test them to see if they are actually not undefined.
+ float value = (b / 255.0f) * 2;
+ return value;
}
-
-RGBAColor8Byte::RGBAColor8Byte(D3DCOLOR col)
+RGBAColor8Byte::RGBAColor8Byte(D3DCOLOR color)
{
- b = col & 0xFF;
- col >>= 8;
- g = col & 0xFF;
- col >>= 8;
- r = col & 0xFF;
- col >>= 8;
- a = col & 0xFF;
+ b = color & 0xFF;
+ color >>= 8;
+ g = color & 0xFF;
+ color >>= 8;
+ r = color & 0xFF;
+ color >>= 8;
+ a = color & 0xFF;
}
-RGBAColor8Byte::operator D3DCOLOR() const
+RGBAColor8Byte::RGBAColor8Byte(byte r, byte g, byte b)
{
- D3DCOLOR col = a;
- col <<= 8;
- col += r;
- col <<= 8;
- col += g;
- col <<= 8;
- col += b;
+ SetR(r);
+ SetG(g);
+ SetB(b);
+}
- return col;
+RGBAColor8Byte::RGBAColor8Byte(byte r, byte g, byte b, byte a) :
+ RGBAColor8Byte(r, g, b)
+{
+ SetA(a);
+}
+
+RGBAColor8Byte::RGBAColor8Byte(const Vector3& color)
+{
+ r = FloatComponentToByte(color.x);
+ g = FloatComponentToByte(color.y);
+ b = FloatComponentToByte(color.z);
+}
+
+RGBAColor8Byte::RGBAColor8Byte(const Vector4& color)
+{
+ r = FloatComponentToByte(color.x);
+ g = FloatComponentToByte(color.y);
+ b = FloatComponentToByte(color.z);
+ a = FloatComponentToByte(color.w);
}
byte RGBAColor8Byte::GetR() const
@@ -83,40 +94,30 @@ void RGBAColor8Byte::SetA(byte v)
a = std::clamp(v, 0, 255);
}
-RGBAColor8Byte::RGBAColor8Byte(Vector3 const& col) :
- r(FloatComponentToByte(col.x)),
- g(FloatComponentToByte(col.y)),
- b(FloatComponentToByte(col.z))
-{
-}
-
-RGBAColor8Byte::RGBAColor8Byte(Vector4 const& col) :
- r(FloatComponentToByte(col.x)),
- g(FloatComponentToByte(col.y)),
- b(FloatComponentToByte(col.z)),
- a(FloatComponentToByte(col.w))
+RGBAColor8Byte::operator Color() const
{
+ return Color(ByteComponentToFloat(r), ByteComponentToFloat(g), ByteComponentToFloat(b));
}
RGBAColor8Byte::operator Vector3() const
{
- return Vector3{ ByteComponentToFloat(r), ByteComponentToFloat(g), ByteComponentToFloat(b) };
+ return Vector3(ByteComponentToFloat(r), ByteComponentToFloat(g), ByteComponentToFloat(b));
}
RGBAColor8Byte::operator Vector4() const
{
- return Vector4{ ByteComponentToFloat(r), ByteComponentToFloat(g), ByteComponentToFloat(b), ByteComponentToFloat(a) };
+ return Vector4(ByteComponentToFloat(r), ByteComponentToFloat(g), ByteComponentToFloat(b), ByteComponentToFloat(a));
}
-RGBAColor8Byte::RGBAColor8Byte(byte r, byte g, byte b)
+RGBAColor8Byte::operator D3DCOLOR() const
{
- SetR(r);
- SetG(g);
- SetB(b);
-}
+ D3DCOLOR color = a;
+ color <<= 8;
+ color += r;
+ color <<= 8;
+ color += g;
+ color <<= 8;
+ color += b;
-RGBAColor8Byte::RGBAColor8Byte(byte r, byte g, byte b, byte a) : RGBAColor8Byte(r, g, b)
-{
- SetA(a);
+ return color;
}
-
diff --git a/TombEngine/Specific/RGBAColor8Byte.h b/TombEngine/Specific/RGBAColor8Byte.h
index e89eb7cd3..8566b00b0 100644
--- a/TombEngine/Specific/RGBAColor8Byte.h
+++ b/TombEngine/Specific/RGBAColor8Byte.h
@@ -4,32 +4,36 @@ typedef DWORD D3DCOLOR;
class RGBAColor8Byte
{
-public:
- RGBAColor8Byte(D3DCOLOR);
+private:
+ // Members
+ byte r = 0;
+ byte g = 0;
+ byte b = 0;
+ byte a = 255;
+public:
+ // Constructors
+ RGBAColor8Byte(D3DCOLOR color);
RGBAColor8Byte(byte r, byte g, byte b);
RGBAColor8Byte(byte r, byte g, byte b, byte a);
- RGBAColor8Byte(Vector3 const &);
- RGBAColor8Byte(Vector4 const &);
+ RGBAColor8Byte(const Vector3& color);
+ RGBAColor8Byte(const Vector4& color);
+ // Getters
+ byte GetR() const;
+ byte GetG() const;
+ byte GetB() const;
+ byte GetA() const;
+
+ // Setters
+ void SetR(byte value);
+ void SetG(byte value);
+ void SetB(byte value);
+ void SetA(byte value);
+
+ // Operators
+ operator Color() const;
operator Vector3() const;
operator Vector4() const;
operator D3DCOLOR() const;
-
- byte GetR() const;
- void SetR(byte v);
- byte GetG() const;
- void SetG(byte v);
- byte GetB() const;
- void SetB(byte v);
- byte GetA() const;
- void SetA(byte v);
-
-private:
- byte r{ 0 };
- byte g{ 0 };
- byte b{ 0 };
- byte a{ 255 };
-
};
-
From 3ff70b29153791ae81fe7744f9e7416bee4b3da6 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 8 May 2024 14:38:00 +1000
Subject: [PATCH 146/410] Remove unnecessary string constants
---
.../Scripting/Internal/ReservedScriptNames.h | 16 -----------
.../TEN/DisplaySprite/ScriptDisplaySprite.cpp | 28 +++++++++----------
2 files changed, 14 insertions(+), 30 deletions(-)
diff --git a/TombEngine/Scripting/Internal/ReservedScriptNames.h b/TombEngine/Scripting/Internal/ReservedScriptNames.h
index 8d0e58181..ba1134907 100644
--- a/TombEngine/Scripting/Internal/ReservedScriptNames.h
+++ b/TombEngine/Scripting/Internal/ReservedScriptNames.h
@@ -37,22 +37,6 @@ static constexpr char ScriptReserved_MoveableStatus[] = "MoveableStatus";
static constexpr char ScriptReserved_Lara[] = "Lara";
static constexpr char ScriptReserved_GetPlayerInteractedMoveable[] = "GetInteractedMoveable";
-// DisplaySprite object
-static constexpr char ScriptReserved_DisplaySprite[] = "DisplaySprite";
-static constexpr char ScriptReserved_DisplayStringGetObjectID[] = "GetObjectID";
-static constexpr char ScriptReserved_DisplayStringGetSpriteID[] = "GetSpriteID";
-static constexpr char ScriptReserved_DisplayStringGetPosition[] = "GetPosition";
-static constexpr char ScriptReserved_DisplayStringGetRotation[] = "GetRotation";
-static constexpr char ScriptReserved_DisplayStringGetScale[] = "GetScale";
-static constexpr char ScriptReserved_DisplayStringGetColor[] = "GetColor";
-static constexpr char ScriptReserved_DisplayStringSetObjectID[] = "SetObjectID";
-static constexpr char ScriptReserved_DisplayStringSetSpriteID[] = "SetSpriteID";
-static constexpr char ScriptReserved_DisplayStringSetPosition[] = "SetPosition";
-static constexpr char ScriptReserved_DisplayStringSetRotation[] = "SetRotation";
-static constexpr char ScriptReserved_DisplayStringSetScale[] = "SetScale";
-static constexpr char ScriptReserved_DisplayStringSetColor[] = "SetColor";
-static constexpr char ScriptReserved_DisplaySpriteDraw[] = "Draw";
-
static constexpr char ScriptReserved_EndReasonExitToTitle[] = "EXITTOTITLE";
static constexpr char ScriptReserved_EndReasonLevelComplete[] = "LEVELCOMPLETE";
static constexpr char ScriptReserved_EndReasonLoadGame[] = "LOADGAME";
diff --git a/TombEngine/Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.cpp b/TombEngine/Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.cpp
index 12529806d..aed2f4908 100644
--- a/TombEngine/Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.cpp
+++ b/TombEngine/Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.cpp
@@ -30,23 +30,23 @@ namespace TEN::Scripting::DisplaySprite
// Register type.
parent.new_usertype(
- ScriptReserved_DisplaySprite,
+ "DisplaySprite",
ctors(),
sol::call_constructor, ctors(),
- ScriptReserved_DisplayStringGetObjectID, &ScriptDisplaySprite::GetObjectID,
- ScriptReserved_DisplayStringGetSpriteID, &ScriptDisplaySprite::GetSpriteID,
- ScriptReserved_DisplayStringGetPosition, &ScriptDisplaySprite::GetPosition,
- ScriptReserved_DisplayStringGetRotation, &ScriptDisplaySprite::GetRotation,
- ScriptReserved_DisplayStringGetScale, &ScriptDisplaySprite::GetScale,
- ScriptReserved_DisplayStringGetColor, &ScriptDisplaySprite::GetColor,
- ScriptReserved_DisplayStringSetObjectID, &ScriptDisplaySprite::SetObjectID,
- ScriptReserved_DisplayStringSetSpriteID, &ScriptDisplaySprite::SetSpriteID,
- ScriptReserved_DisplayStringSetPosition, &ScriptDisplaySprite::SetPosition,
- ScriptReserved_DisplayStringSetRotation, &ScriptDisplaySprite::SetRotation,
- ScriptReserved_DisplayStringSetScale, &ScriptDisplaySprite::SetScale,
- ScriptReserved_DisplayStringSetColor, &ScriptDisplaySprite::SetColor,
- ScriptReserved_DisplaySpriteDraw, &ScriptDisplaySprite::Draw);
+ "GetObjectID", & ScriptDisplaySprite::GetObjectID,
+ "GetSpriteID", &ScriptDisplaySprite::GetSpriteID,
+ "GetPosition", &ScriptDisplaySprite::GetPosition,
+ "GetRotation", &ScriptDisplaySprite::GetRotation,
+ "GetScale", &ScriptDisplaySprite::GetScale,
+ "GetColor", &ScriptDisplaySprite::GetColor,
+ "SetObjectID", &ScriptDisplaySprite::SetObjectID,
+ "SetSpriteID", &ScriptDisplaySprite::SetSpriteID,
+ "SetPosition", &ScriptDisplaySprite::SetPosition,
+ "SetRotation", &ScriptDisplaySprite::SetRotation,
+ "SetScale", &ScriptDisplaySprite::SetScale,
+ "SetColor", &ScriptDisplaySprite::SetColor,
+ "Draw", &ScriptDisplaySprite::Draw);
}
/// Create a DisplaySprite object.
From 59e74212adee129be69715d8461fc86411e63124 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 8 May 2024 18:47:10 +1000
Subject: [PATCH 147/410] Clean up effect and HUD objects
---
TombEngine/Game/Hud/Speedometer.cpp | 4 +-
TombEngine/Game/Hud/TargetHighlighter.cpp | 9 +-
TombEngine/Game/Lara/lara.cpp | 6 +-
TombEngine/Game/Lara/lara.h | 2 +-
TombEngine/Game/effects/Blood.h | 20 +-
TombEngine/Game/effects/DisplaySprite.cpp | 13 +-
TombEngine/Game/effects/DisplaySprite.h | 10 +-
TombEngine/Game/effects/Electricity.h | 80 ++---
TombEngine/Game/effects/Ripple.h | 12 +-
TombEngine/Game/effects/Streamer.cpp | 7 -
TombEngine/Game/effects/Streamer.h | 12 +-
TombEngine/Game/effects/bubble.h | 16 +-
TombEngine/Game/effects/weather.cpp | 319 ++++++++++--------
TombEngine/Game/effects/weather.h | 108 +++---
TombEngine/Game/items.h | 13 +-
TombEngine/Renderer/RendererDrawEffect.cpp | 108 +++---
.../TEN/DisplaySprite/ScriptDisplaySprite.cpp | 2 +-
TombEngine/Specific/RGBAColor8Byte.cpp | 5 -
18 files changed, 389 insertions(+), 357 deletions(-)
diff --git a/TombEngine/Game/Hud/Speedometer.cpp b/TombEngine/Game/Hud/Speedometer.cpp
index edd22a230..dbfa3044d 100644
--- a/TombEngine/Game/Hud/Speedometer.cpp
+++ b/TombEngine/Game/Hud/Speedometer.cpp
@@ -65,14 +65,14 @@ namespace TEN::Hud
ID_SPEEDOMETER, DIAL_ELEMENT_SPRITE_ID,
POS, 0, SCALE, color,
DIAL_PRIORITY, DisplaySpriteAlignMode::Center, DisplaySpriteScaleMode::Fit, BlendMode::AlphaBlend,
- DisplaySpriteSource::DrawPhase);
+ DisplaySpritePhase::Draw);
// Draw pointer.
AddDisplaySprite(
ID_SPEEDOMETER, POINTER_ELEMENT_SPRITE_ID,
POS, _pointerAngle + ORIENT_OFFSET, SCALE, color,
POINTER_PRIORITY, DisplaySpriteAlignMode::Center, DisplaySpriteScaleMode::Fit, BlendMode::AlphaBlend,
- DisplaySpriteSource::DrawPhase);
+ DisplaySpritePhase::Draw);
}
void SpeedometerController::Clear()
diff --git a/TombEngine/Game/Hud/TargetHighlighter.cpp b/TombEngine/Game/Hud/TargetHighlighter.cpp
index 8ad619221..166dc66a8 100644
--- a/TombEngine/Game/Hud/TargetHighlighter.cpp
+++ b/TombEngine/Game/Hud/TargetHighlighter.cpp
@@ -133,9 +133,6 @@ namespace TEN::Hud
constexpr auto STATIC_ELEMENT_SPRITE_ID = 0;
constexpr auto SEGMENT_ELEMENT_SPRITE_ID = 1;
constexpr auto PRIORITY = 0; // TODO: Check later. May interfere with Lua display sprites. -- Sezz 2023.10.06
- constexpr auto ALIGN_MODE = DisplaySpriteAlignMode::Center;
- constexpr auto SCALE_MODE = DisplaySpriteScaleMode::Fill;
- constexpr auto BLEND_MODE = BlendMode::Additive;
if (!Position.has_value())
return;
@@ -144,7 +141,8 @@ namespace TEN::Hud
AddDisplaySprite(
SPRITE_SEQUENCE_OBJECT_ID, STATIC_ELEMENT_SPRITE_ID,
*Position, Orientation, Vector2(Scale), Color,
- PRIORITY, ALIGN_MODE, SCALE_MODE, BLEND_MODE, DisplaySpriteSource::DrawPhase);
+ PRIORITY, DisplaySpriteAlignMode::Center, DisplaySpriteScaleMode::Fill,
+ BlendMode::Additive, DisplaySpritePhase::Draw);
// Draw animated outer segment elements.
for (const auto& segment : Segments)
@@ -156,7 +154,8 @@ namespace TEN::Hud
AddDisplaySprite(
SPRITE_SEQUENCE_OBJECT_ID, SEGMENT_ELEMENT_SPRITE_ID,
pos, orient, scale, Color,
- PRIORITY, ALIGN_MODE, SCALE_MODE, BLEND_MODE, DisplaySpriteSource::DrawPhase);
+ PRIORITY, DisplaySpriteAlignMode::Center, DisplaySpriteScaleMode::Fill,
+ BlendMode::Additive, DisplaySpritePhase::Draw);
}
}
diff --git a/TombEngine/Game/Lara/lara.cpp b/TombEngine/Game/Lara/lara.cpp
index 87632d5dc..b39f9c246 100644
--- a/TombEngine/Game/Lara/lara.cpp
+++ b/TombEngine/Game/Lara/lara.cpp
@@ -59,9 +59,9 @@ using namespace TEN::Gui;
using TEN::Renderer::g_Renderer;
-LaraInfo Lara = {};
-LaraInfo OldLara = {};
-ItemInfo* LaraItem;
+LaraInfo Lara = {};
+LaraInfo PrevLara = {};
+ItemInfo* LaraItem = nullptr;
CollisionInfo LaraCollision = {};
void LaraControl(ItemInfo* item, CollisionInfo* coll)
diff --git a/TombEngine/Game/Lara/lara.h b/TombEngine/Game/Lara/lara.h
index b2562147b..223f47f77 100644
--- a/TombEngine/Game/Lara/lara.h
+++ b/TombEngine/Game/Lara/lara.h
@@ -94,7 +94,7 @@ constexpr auto SWIM_WATER_DEPTH = CLICK(2.75f);
constexpr auto SLOPE_DIFFERENCE = 60;
extern LaraInfo Lara;
-extern LaraInfo OldLara;
+extern LaraInfo PrevLara;
extern ItemInfo* LaraItem;
extern CollisionInfo LaraCollision;
diff --git a/TombEngine/Game/effects/Blood.h b/TombEngine/Game/effects/Blood.h
index 37939810b..b30e60761 100644
--- a/TombEngine/Game/effects/Blood.h
+++ b/TombEngine/Game/effects/Blood.h
@@ -15,19 +15,19 @@ namespace TEN::Effects::Blood
float Size = 0.0f;
float Opacity = 0.0f;
- Vector3 OldPosition = Vector3::Zero;
- Vector4 OldColor = Vector4::Zero;
- float OldSize = 0.0f;
- float OldOpacity = 0.0f;
- float OldLife = 0.0f;
+ Vector3 PrevPosition = Vector3::Zero;
+ Vector4 PrevColor = Vector4::Zero;
+ float PrevLife = 0.0f;
+ float PrevSize = 0.0f;
+ float PrevOpacity = 0.0f;
void StoreInterpolationData()
{
- OldPosition = Position;
- OldColor = Color;
- OldSize = Size;
- OldOpacity = Opacity;
- OldLife = Life;
+ PrevPosition = Position;
+ PrevColor = Color;
+ PrevLife = Life;
+ PrevSize = Size;
+ PrevOpacity = Opacity;
}
};
diff --git a/TombEngine/Game/effects/DisplaySprite.cpp b/TombEngine/Game/effects/DisplaySprite.cpp
index efcfb1236..dd3713d6b 100644
--- a/TombEngine/Game/effects/DisplaySprite.cpp
+++ b/TombEngine/Game/effects/DisplaySprite.cpp
@@ -15,7 +15,7 @@ namespace TEN::Effects::DisplaySprite
void AddDisplaySprite(GAME_OBJECT_ID objectID, int spriteID, const Vector2& pos, short orient, const Vector2& scale, const Vector4& color,
int priority, DisplaySpriteAlignMode alignMode, DisplaySpriteScaleMode scaleMode,
- BlendMode blendMode, DisplaySpriteSource source)
+ BlendMode blendMode, DisplaySpritePhase source)
{
auto displaySprite = DisplaySprite{};
displaySprite.ObjectID = objectID;
@@ -40,8 +40,13 @@ namespace TEN::Effects::DisplaySprite
void ClearDrawPhaseDisplaySprites()
{
- DisplaySprites.erase(std::remove_if(DisplaySprites.begin(), DisplaySprites.end(),
- [](const DisplaySprite& displaySprite) { return displaySprite.Source == DisplaySpriteSource::DrawPhase; }),
- DisplaySprites.end());
+ DisplaySprites.erase(
+ std::remove_if(
+ DisplaySprites.begin(), DisplaySprites.end(),
+ [](const DisplaySprite& displaySprite)
+ {
+ return (displaySprite.Source == DisplaySpritePhase::Draw);
+ }),
+ DisplaySprites.end());
}
}
diff --git a/TombEngine/Game/effects/DisplaySprite.h b/TombEngine/Game/effects/DisplaySprite.h
index 26947e796..f8928f10a 100644
--- a/TombEngine/Game/effects/DisplaySprite.h
+++ b/TombEngine/Game/effects/DisplaySprite.h
@@ -24,10 +24,10 @@ namespace TEN::Effects::DisplaySprite
Stretch
};
- enum class DisplaySpriteSource
+ enum class DisplaySpritePhase
{
- ControlPhase,
- DrawPhase
+ Control,
+ Draw
};
struct DisplaySprite
@@ -45,14 +45,14 @@ namespace TEN::Effects::DisplaySprite
DisplaySpriteScaleMode ScaleMode = DisplaySpriteScaleMode::Fit;
BlendMode BlendMode = BlendMode::AlphaBlend;
- DisplaySpriteSource Source = DisplaySpriteSource::ControlPhase;
+ DisplaySpritePhase Source = DisplaySpritePhase::Control;
};
extern std::vector DisplaySprites;
void AddDisplaySprite(GAME_OBJECT_ID objectID, int spriteID, const Vector2& pos, short orient, const Vector2& scale, const Vector4& color,
int priority, DisplaySpriteAlignMode alignMode, DisplaySpriteScaleMode scaleMode,
- BlendMode blendMode, DisplaySpriteSource source);
+ BlendMode blendMode, DisplaySpritePhase source);
void ClearAllDisplaySprites();
void ClearDrawPhaseDisplaySprites();
}
diff --git a/TombEngine/Game/effects/Electricity.h b/TombEngine/Game/effects/Electricity.h
index 0aa4fa764..98be1f93d 100644
--- a/TombEngine/Game/effects/Electricity.h
+++ b/TombEngine/Game/effects/Electricity.h
@@ -40,25 +40,25 @@ namespace TEN::Effects::Electricity
int type;
int flags;
- Vector3 oldPos1;
- Vector3 oldPos2;
- Vector3 oldPos3;
- Vector3 oldPos4;
- byte oldR;
- byte oldG;
- byte oldB;
- float oldLife;
+ Vector3 PrevPos1 = Vector3::Zero;
+ Vector3 PrevPos2 = Vector3::Zero;
+ Vector3 PrevPos3 = Vector3::Zero;
+ Vector3 PrevPos4 = Vector3::Zero;
+ byte PrevR = 0;
+ byte PrevG = 0;
+ byte PrevB = 0;
+ float PrevLife = 0.0f;
void StoreInterpolationData()
{
- oldPos1 = pos1;
- oldPos2 = pos2;
- oldPos3 = pos3;
- oldPos4 = pos4;
- oldR = r;
- oldG = g;
- oldB = b;
- oldLife = life;
+ PrevPos1 = pos1;
+ PrevPos2 = pos2;
+ PrevPos3 = pos3;
+ PrevPos4 = pos4;
+ PrevR = r;
+ PrevG = g;
+ PrevB = b;
+ PrevLife = life;
}
};
@@ -66,38 +66,38 @@ namespace TEN::Effects::Electricity
{
unsigned int NumSegments = 0;
- Vector3 Origin = Vector3::Zero;
- Vector3 Target = Vector3::Zero;
+ Vector3 Origin = Vector3::Zero;
+ Vector3 Target = Vector3::Zero;
short Orientation2D = 0;
Vector3 LightPosition = Vector3::Zero; // TODO: Use light cone instead?
- Vector4 Color = Vector4::Zero;
+ Vector4 Color = Vector4::Zero;
- float Life = 0.0f;
- float Radius = 0.0f;
- float Length = 0.0f;
+ float Life = 0.0f;
+ float Radius = 0.0f;
+ float Length = 0.0f;
float LengthEnd = 0.0f;
- float Opacity = 0.0f;
- short Rotation = 0;
+ float Opacity = 0.0f;
+ short Rotation = 0;
- Vector3 OldOrigin = Vector3::Zero;
- Vector3 OldTarget = Vector3::Zero;
- float OldLife = 0.0f;
- float OldRadius = 0.0f;
- float OldLength = 0.0f;
- float OldOpacity = 0.0f;
- Vector4 OldColor = Vector4::Zero;
- short OldOrientation2D = 0;
+ Vector3 PrevOrigin = Vector3::Zero;
+ Vector3 PrevTarget = Vector3::Zero;
+ short PrevOrientation2D = 0;
+ Vector4 PrevColor = Vector4::Zero;
+ float PrevLife = 0.0f;
+ float PrevRadius = 0.0f;
+ float PrevLength = 0.0f;
+ float PrevOpacity = 0.0f;
void StoreInterpolationData()
{
- OldOrigin = Origin;
- OldTarget = Target;
- OldLife = Life;
- OldRadius = Radius;
- OldLength = Length;
- OldOpacity = Opacity;
- OldColor = Color;
- OldOrientation2D = Orientation2D;
+ PrevOrigin = Origin;
+ PrevTarget = Target;
+ PrevOrientation2D = Orientation2D;
+ PrevColor = Color;
+ PrevLife = Life;
+ PrevRadius = Radius;
+ PrevLength = Length;
+ PrevOpacity = Opacity;
}
};
diff --git a/TombEngine/Game/effects/Ripple.h b/TombEngine/Game/effects/Ripple.h
index 031301911..261b647d3 100644
--- a/TombEngine/Game/effects/Ripple.h
+++ b/TombEngine/Game/effects/Ripple.h
@@ -24,15 +24,15 @@ namespace TEN::Effects::Ripple
float FadeDuration = 0.0f;
int Flags = 0;
- Vector3 OldPosition;
- Vector4 OldColor;
- float OldSize;
+ Vector3 PrevPosition = Vector3::Zero;
+ Vector4 PrevColor = Vector4::Zero;
+ float PrevSize = 0.0f;
void StoreInterpolationData()
{
- OldPosition = Position;
- OldColor = Color;
- OldSize = Size;
+ PrevPosition = Position;
+ PrevColor = Color;
+ PrevSize = Size;
}
};
diff --git a/TombEngine/Game/effects/Streamer.cpp b/TombEngine/Game/effects/Streamer.cpp
index 48ffb14f8..8e346db3d 100644
--- a/TombEngine/Game/effects/Streamer.cpp
+++ b/TombEngine/Game/effects/Streamer.cpp
@@ -38,13 +38,6 @@ namespace TEN::Effects::Streamer
Life -= 1.0f;
}
- void Streamer::StreamerSegment::StoreInterpolationData()
- {
- OldVertices[0] = Vertices[0];
- OldVertices[1] = Vertices[1];
- OldColor = Color;
- }
-
void Streamer::StreamerSegment::TransformVertices(float vel, float scaleRate)
{
// Apply expansion.
diff --git a/TombEngine/Game/effects/Streamer.h b/TombEngine/Game/effects/Streamer.h
index 5a189d83d..39db32d22 100644
--- a/TombEngine/Game/effects/Streamer.h
+++ b/TombEngine/Game/effects/Streamer.h
@@ -39,15 +39,21 @@ namespace TEN::Effects::Streamer
std::array Vertices = {};
- std::array OldVertices = {};
- Vector4 OldColor = Vector4::Zero;
+ std::array PrevVertices = {};
+ Vector4 PrevColor = Vector4::Zero;
void InitializeVertices(const Vector3& pos, float width);
void Update();
private:
void TransformVertices(float vel, float scaleRate);
- void StoreInterpolationData();
+
+ void StoreInterpolationData()
+ {
+ PrevVertices[0] = Vertices[0];
+ PrevVertices[1] = Vertices[1];
+ PrevColor = Color;
+ }
};
// Members
diff --git a/TombEngine/Game/effects/bubble.h b/TombEngine/Game/effects/bubble.h
index e410842a9..dff0c523a 100644
--- a/TombEngine/Game/effects/bubble.h
+++ b/TombEngine/Game/effects/bubble.h
@@ -31,17 +31,17 @@ namespace TEN::Effects::Bubble
float OscillationPeriod = 0.0f;
float OscillationVelocity = 0.0f;
- Vector3 OldPosition = Vector3::Zero;
- Vector4 OldColor = Vector4::Zero;
- Vector2 OldSize = Vector2::Zero;
- float OldLife = 0.0f;
+ Vector3 PrevPosition = Vector3::Zero;
+ Vector4 PrevColor = Vector4::Zero;
+ Vector2 PrevSize = Vector2::Zero;
+ float PrevLife = 0.0f;
void StoreInterpolationData()
{
- OldPosition = Position;
- OldColor = Color;
- OldSize = Size;
- OldLife = Life;
+ PrevPosition = Position;
+ PrevColor = Color;
+ PrevSize = Size;
+ PrevLife = Life;
}
};
diff --git a/TombEngine/Game/effects/weather.cpp b/TombEngine/Game/effects/weather.cpp
index e91a0f546..f8ad60ac7 100644
--- a/TombEngine/Game/effects/weather.cpp
+++ b/TombEngine/Game/effects/weather.cpp
@@ -25,8 +25,8 @@ namespace TEN::Effects::Environment
float WeatherParticle::Transparency() const
{
- float result = WEATHER_PARTICLES_TRANSPARENCY;
- float fade = WEATHER_PARTICLES_NEAR_DEATH_LIFE_VALUE;
+ float result = WEATHER_PARTICLE_OPACITY;
+ float fade = WEATHER_PARTICLE_NEAR_DEATH_LIFE;
if (Life <= fade)
result *= Life / fade;
@@ -42,12 +42,12 @@ namespace TEN::Effects::Environment
EnvironmentController::EnvironmentController()
{
- Particles.reserve(WEATHER_PARTICLES_MAX_COUNT);
+ Particles.reserve(WEATHER_PARTICLE_COUNT_MAX);
}
void EnvironmentController::Update()
{
- ScriptInterfaceLevel* level = g_GameFlow->GetLevel(CurrentLevel);
+ const auto& level = *g_GameFlow->GetLevel(CurrentLevel);
UpdateSky(level);
UpdateStorm(level);
@@ -63,20 +63,23 @@ namespace TEN::Effects::Environment
void EnvironmentController::Clear()
{
- // Clear storm vars
+ // Clear storm variables.
StormTimer = 0;
StormSkyColor = 1;
StormSkyColor2 = 1;
- // Clear wind vars
- WindCurrent = WindX = WindZ = 0;
- WindAngle = WindDAngle = 2048;
+ // Clear wind variables.
+ WindCurrent =
+ WindX =
+ WindZ = 0;
+ WindAngle =
+ WindDAngle = 2048;
- // Clear flash vars
+ // Clear flash variables.
FlashProgress = 0.0f;
FlashColorBase = Vector3::Zero;
- // Clear weather
+ // Clear weather.
Particles.clear();
// Clear starfield.
@@ -93,27 +96,31 @@ namespace TEN::Effects::Environment
std::clamp(b, 0, UCHAR_MAX) / (float)UCHAR_MAX);
}
- void EnvironmentController::UpdateSky(ScriptInterfaceLevel* level)
+ void EnvironmentController::UpdateSky(const ScriptInterfaceLevel& level)
{
for (int i = 0; i < 2; i++)
{
- if (!level->GetSkyLayerEnabled(i))
+ if (!level.GetSkyLayerEnabled(i))
continue;
- SkyCurrentPosition[i] += level->GetSkyLayerSpeed(i);
- if (SkyCurrentPosition[i] <= SKY_SIZE)
+ auto& skyPos = SkyCurrentPosition[i];
+
+ skyPos += level.GetSkyLayerSpeed(i);
+ if (skyPos <= SKY_SIZE)
{
- if (SkyCurrentPosition[i] < 0)
- SkyCurrentPosition[i] += SKY_SIZE;
+ if (skyPos < 0)
+ skyPos += SKY_SIZE;
}
else
- SkyCurrentPosition[i] -= SKY_SIZE;
+ {
+ skyPos -= SKY_SIZE;
+ }
}
}
- void EnvironmentController::UpdateStorm(ScriptInterfaceLevel* level)
+ void EnvironmentController::UpdateStorm(const ScriptInterfaceLevel& level)
{
- if (level->GetStormEnabled())
+ if (level.GetStormEnabled())
{
if (StormCount || StormRand)
{
@@ -121,7 +128,7 @@ namespace TEN::Effects::Environment
if (StormTimer > -1)
StormTimer--;
if (!StormTimer)
- SoundEffect(SFX_TR4_THUNDER_RUMBLE, NULL);
+ SoundEffect(SFX_TR4_THUNDER_RUMBLE, nullptr);
}
else if (!(rand() & 0x7F))
{
@@ -132,11 +139,13 @@ namespace TEN::Effects::Environment
for (int i = 0; i < 2; i++)
{
- auto color = Vector4(level->GetSkyLayerColor(i).GetR() / 255.0f,
- level->GetSkyLayerColor(i).GetG() / 255.0f,
- level->GetSkyLayerColor(i).GetB() / 255.0f, 1.0f);
+ auto color = Color(
+ level.GetSkyLayerColor(i).GetR() / 255.0f,
+ level.GetSkyLayerColor(i).GetG() / 255.0f,
+ level.GetSkyLayerColor(i).GetB() / 255.0f,
+ 1.0f);
- if (level->GetStormEnabled())
+ if (level.GetStormEnabled())
{
auto flashBrightness = StormSkyColor / 255.0f;
auto r = std::clamp(color.x + flashBrightness, 0.0f, 1.0f);
@@ -146,7 +155,9 @@ namespace TEN::Effects::Environment
SkyCurrentColor[i] = Vector4(r, g, b, color.w);
}
else
+ {
SkyCurrentColor[i] = color;
+ }
}
}
@@ -161,7 +172,7 @@ namespace TEN::Effects::Environment
}
else if (StormCount < 5 && StormSkyColor < 50)
{
- auto newColor = StormSkyColor - StormCount * 2;
+ auto newColor = StormSkyColor - (StormCount * 2);
if (newColor < 0)
newColor = 0;
StormSkyColor = newColor;
@@ -176,20 +187,28 @@ namespace TEN::Effects::Environment
}
}
- void EnvironmentController::UpdateWind(ScriptInterfaceLevel* level)
+ void EnvironmentController::UpdateWind(const ScriptInterfaceLevel& level)
{
WindCurrent += (GetRandomControl() & 7) - 3;
if (WindCurrent <= -2)
+ {
WindCurrent++;
+ }
else if (WindCurrent >= 9)
+ {
WindCurrent--;
+ }
WindDAngle = (WindDAngle + 2 * (GetRandomControl() & 63) - 64) & 0x1FFE;
if (WindDAngle < 1024)
+ {
WindDAngle = 2048 - WindDAngle;
+ }
else if (WindDAngle > 3072)
+ {
WindDAngle += 6144 - 2 * WindDAngle;
+ }
WindAngle = (WindAngle + ((WindDAngle - WindAngle) >> 3)) & 0x1FFE;
@@ -197,7 +216,7 @@ namespace TEN::Effects::Environment
WindZ = WindCurrent * phd_cos(WindAngle << 3);
}
- void EnvironmentController::UpdateFlash(ScriptInterfaceLevel* level)
+ void EnvironmentController::UpdateFlash(const ScriptInterfaceLevel& level)
{
if (FlashProgress > 0.0f)
{
@@ -210,14 +229,14 @@ namespace TEN::Effects::Environment
FlashColorBase = Vector3::Zero;
}
- void EnvironmentController::UpdateStarfield(ScriptInterfaceLevel* level)
+ void EnvironmentController::UpdateStarfield(const ScriptInterfaceLevel& level)
{
- if (!level->GetStarfieldStarsEnabled())
+ if (!level.GetStarfieldStarsEnabled())
return;
if (ResetStarField)
{
- int starCount = level->GetStarfieldStarCount();
+ int starCount = level.GetStarfieldStarCount();
Stars.clear();
Stars.reserve(starCount);
@@ -257,7 +276,7 @@ namespace TEN::Effects::Environment
for (auto& star : Stars)
star.Blinking = Random::GenerateFloat(0.5f, 1.0f);
- if (level->GetStarfieldMeteorsEnabled())
+ if (level.GetStarfieldMeteorsEnabled())
{
for (auto& meteor : Meteors)
{
@@ -284,159 +303,158 @@ namespace TEN::Effects::Environment
meteor.Fade = 1.0f;
}
- meteor.Position += meteor.Direction * level->GetStarfieldMeteorVelocity();
+ meteor.Position += meteor.Direction * level.GetStarfieldMeteorVelocity();
}
}
}
- void EnvironmentController::UpdateWeather(ScriptInterfaceLevel* level)
+ void EnvironmentController::UpdateWeather(const ScriptInterfaceLevel& level)
{
- for (auto& p : Particles)
+ for (auto& part : Particles)
{
- p.StoreInterpolationData();
+ part.StoreInterpolationData();
- p.Life -= 2;
+ part.Life -= 2;
- // Disable particle if it is dead. It will be cleaned on next call of
- // SpawnWeatherParticles().
-
- if (p.Life <= 0)
+ // Disable particle if dead. Will be cleaned on next call of SpawnWeatherParticles().
+ if (part.Life <= 0)
{
- p.Enabled = false;
+ part.Enabled = false;
continue;
}
- // Check if particle got out of collision check radius, and fade it out if it did.
-
- if (abs(Camera.pos.x - p.Position.x) > COLLISION_CHECK_DISTANCE ||
- abs(Camera.pos.z - p.Position.z) > COLLISION_CHECK_DISTANCE)
+ // Check if particle got out of collision check radius and fade out if it did.
+ if (abs(Camera.pos.x - part.Position.x) > COLLISION_CHECK_DISTANCE ||
+ abs(Camera.pos.z - part.Position.z) > COLLISION_CHECK_DISTANCE)
{
- p.Life = std::clamp(p.Life, 0.0f, WEATHER_PARTICLES_NEAR_DEATH_LIFE_VALUE);
+ part.Life = std::clamp(part.Life, 0.0f, WEATHER_PARTICLE_NEAR_DEATH_LIFE);
}
// If particle was locked (after landing or stucking in substance such as water or swamp),
- // fade it out and bypass any collision checks and movement updates.
-
- if (p.Stopped)
+ // fade out and bypass collision checks and movement updates.
+ if (part.Stopped)
{
- if (p.Type == WeatherType::Snow)
- p.Size *= WEATHER_PARTICLES_NEAR_DEATH_MELT_FACTOR;
+ if (part.Type == WeatherType::Snow)
+ part.Size *= WEATHER_PARTICLE_NEAR_DEATH_MELT_FACTOR;
continue;
}
- // Backup old position and progress new position according to velocity.
+ // Backup previous position and progress new position according to velocity.
+ auto prevPos = part.Position;
+ part.Position.x += part.Velocity.x;
+ part.Position.z += part.Velocity.z;
- auto oldPos = p.Position;
- p.Position.x += p.Velocity.x;
- p.Position.z += p.Velocity.z;
-
- switch (p.Type)
+ switch (part.Type)
{
case WeatherType::None:
- p.Position.y += p.Velocity.y;
+ part.Position.y += part.Velocity.y;
break;
case WeatherType::Rain:
case WeatherType::Snow:
- p.Position.y += (p.Velocity.y / 2.0f);
+ part.Position.y += (part.Velocity.y / 2.0f);
break;
}
- // Particle is inert, don't check collisions.
-
- if (p.Type == WeatherType::None)
+ // Particle is inert; don't check collisions.
+ if (part.Type == WeatherType::None)
continue;
- auto pointColl = GetPointCollision(p.Position, p.Room);
+ auto pointColl = GetPointCollision(part.Position, part.RoomNumber);
bool collisionCalculated = false;
- if (p.CollisionCheckDelay <= 0)
+ if (part.CollisionCheckDelay <= 0)
{
- pointColl = GetPointCollision(p.Position, p.Room);
+ pointColl = GetPointCollision(part.Position, part.RoomNumber);
// Determine collision checking frequency based on nearest floor/ceiling surface position.
- // If floor and ceiling is too far, don't do precise collision checks, instead doing it
+ // If floor and ceiling are too far, don't do precise collision checks, instead doing it
// every 5th frame. If particle approaches floor or ceiling, make checks more frequent.
- // This allows to avoid unnecessary thousands of calls to GetCollisionResult for every particle.
+ // This avoids calls to GetPointCollision() for every particle.
- auto coeff = std::min(std::max(0.0f, (pointColl.GetFloorHeight() - p.Position.y)), std::max(0.0f, (p.Position.y - pointColl.GetCeilingHeight())));
- p.CollisionCheckDelay = std::min(floor(coeff / std::max(std::numeric_limits::denorm_min(), p.Velocity.y)), WEATHER_PARTICLES_MAX_COLL_CHECK_DELAY);
+ auto coeff = std::min(std::max(0.0f, (pointColl.GetFloorHeight() - part.Position.y)), std::max(0.0f, (part.Position.y - pointColl.GetCeilingHeight())));
+ part.CollisionCheckDelay = std::min(floor(coeff / std::max(std::numeric_limits::denorm_min(), part.Velocity.y)), WEATHER_PARTICLE_COLL_CHECK_DELAY_MAX);
collisionCalculated = true;
}
else
{
- p.CollisionCheckDelay--;
+ part.CollisionCheckDelay--;
}
- // Check if particle got out of room bounds
-
- if (!IsPointInRoom(p.Position, p.Room))
+ // Check if particle is beyond room bounds.
+ if (!IsPointInRoom(part.Position, part.RoomNumber))
{
if (!collisionCalculated)
{
- pointColl = GetPointCollision(p.Position, p.Room);
+ pointColl = GetPointCollision(part.Position, part.RoomNumber);
collisionCalculated = true;
}
- if (pointColl.GetRoomNumber() == p.Room)
+ if (pointColl.GetRoomNumber() == part.RoomNumber)
{
- p.Enabled = false; // Not landed on door, so out of room bounds - delete
+ // Not landed on door, so out of room bounds - delete.
+ part.Enabled = false;
continue;
}
else
{
- p.Room = pointColl.GetRoomNumber();
+ part.RoomNumber = pointColl.GetRoomNumber();
}
}
// If collision was updated, process with position checks.
-
if (collisionCalculated)
{
// If particle is inside water or swamp, count it as "inSubstance".
// If particle got below floor or above ceiling, count it as "landed".
-
bool inSubstance = g_Level.Rooms[pointColl.GetRoomNumber()].flags & (ENV_FLAG_WATER | ENV_FLAG_SWAMP);
- bool landed = (pointColl.GetFloorHeight() <= p.Position.y) || (pointColl.GetCeilingHeight() >= p.Position.y);
+ bool landed = (pointColl.GetFloorHeight() <= part.Position.y) || (pointColl.GetCeilingHeight() >= part.Position.y);
if (inSubstance || landed)
{
- p.Stopped = true;
- p.Position = oldPos;
- p.Life = std::clamp(p.Life, 0.0f, WEATHER_PARTICLES_NEAR_DEATH_LIFE_VALUE);
+ part.Stopped = true;
+ part.Position = prevPos;
+ part.Life = std::clamp(part.Life, 0.0f, WEATHER_PARTICLE_NEAR_DEATH_LIFE);
// Produce ripples if particle got into substance (water or swamp).
if (inSubstance)
- SpawnRipple(p.Position, p.Room, Random::GenerateFloat(16.0f, 24.0f), (int)RippleFlags::SlowFade | (int)RippleFlags::LowOpacity);
+ SpawnRipple(part.Position, part.RoomNumber, Random::GenerateFloat(16.0f, 24.0f), (int)RippleFlags::SlowFade | (int)RippleFlags::LowOpacity);
// Immediately disable rain particle because it doesn't need fading out.
- if (p.Type == WeatherType::Rain)
+ if (part.Type == WeatherType::Rain)
{
- p.Enabled = false;
- AddWaterSparks(oldPos.x, oldPos.y, oldPos.z, 6);
+ part.Enabled = false;
+ AddWaterSparks(prevPos.x, prevPos.y, prevPos.z, 6);
}
}
}
// Update velocities for every particle type.
-
- switch (p.Type)
+ switch (part.Type)
{
case WeatherType::Snow:
- if (p.Velocity.x < (WindX << 2))
- p.Velocity.x += Random::GenerateFloat(0.5f, 2.5f);
- else if (p.Velocity.x > (WindX << 2))
- p.Velocity.x -= Random::GenerateFloat(0.5f, 2.5f);
+ if (part.Velocity.x < (WindX << 2))
+ {
+ part.Velocity.x += Random::GenerateFloat(0.5f, 2.5f);
+ }
+ else if (part.Velocity.x > (WindX << 2))
+ {
+ part.Velocity.x -= Random::GenerateFloat(0.5f, 2.5f);
+ }
- if (p.Velocity.z < (WindZ << 2))
- p.Velocity.z += Random::GenerateFloat(0.5f, 2.5f);
- else if (p.Velocity.z > (WindZ << 2))
- p.Velocity.z -= Random::GenerateFloat(0.5f, 2.5f);
+ if (part.Velocity.z < (WindZ << 2))
+ {
+ part.Velocity.z += Random::GenerateFloat(0.5f, 2.5f);
+ }
+ else if (part.Velocity.z > (WindZ << 2))
+ {
+ part.Velocity.z -= Random::GenerateFloat(0.5f, 2.5f);
+ }
- if (p.Velocity.y < p.Size / 2)
- p.Velocity.y += p.Size / 5.0f;
+ if (part.Velocity.y < part.Size / 2)
+ part.Velocity.y += part.Size / 5.0f;
break;
@@ -445,32 +463,40 @@ namespace TEN::Effects::Environment
auto random = Random::GenerateInt();
if ((random & 3) != 3)
{
- p.Velocity.x += (float)((random & 3) - 1);
- if (p.Velocity.x < -4)
- p.Velocity.x = -4;
- else if (p.Velocity.x > 4)
- p.Velocity.x = 4;
+ part.Velocity.x += (float)((random & 3) - 1);
+ if (part.Velocity.x < -4)
+ {
+ part.Velocity.x = -4;
+ }
+ else if (part.Velocity.x > 4)
+ {
+ part.Velocity.x = 4;
+ }
}
random = (random >> 2) & 3;
if (random != 3)
{
- p.Velocity.z += random - 1;
- if (p.Velocity.z < -4)
- p.Velocity.z = -4;
- else if (p.Velocity.z > 4)
- p.Velocity.z = 4;
+ part.Velocity.z += random - 1;
+ if (part.Velocity.z < -4)
+ {
+ part.Velocity.z = -4;
+ }
+ else if (part.Velocity.z > 4)
+ {
+ part.Velocity.z = 4;
+ }
}
- if (p.Velocity.y < p.Size * 2 * std::clamp(level->GetWeatherStrength(), 0.6f, 1.0f))
- p.Velocity.y += p.Size / 5.0f;
+ if (part.Velocity.y < part.Size * 2 * std::clamp(level.GetWeatherStrength(), 0.6f, 1.0f))
+ part.Velocity.y += part.Size / 5.0f;
break;
}
}
}
- void EnvironmentController::SpawnDustParticles(ScriptInterfaceLevel* level)
+ void EnvironmentController::SpawnDustParticles(const ScriptInterfaceLevel& level)
{
for (int i = 0; i < DUST_SPAWN_DENSITY; i++)
{
@@ -478,7 +504,7 @@ namespace TEN::Effects::Environment
int yPos = Camera.pos.y + rand() % DUST_SPAWN_RADIUS - DUST_SPAWN_RADIUS / 2.0f;
int zPos = Camera.pos.z + rand() % DUST_SPAWN_RADIUS - DUST_SPAWN_RADIUS / 2.0f;
- // Use fast GetFloor instead of GetCollision as we spawn a lot of dust.
+ // Use more memory-efficient GetFloor() instead of GetPointCollision() as a lot of dust may spawn at a time.
short roomNumber = Camera.pos.RoomNumber;
auto* floor = GetFloor(xPos, yPos, zPos, &roomNumber);
@@ -491,13 +517,13 @@ namespace TEN::Effects::Environment
auto part = WeatherParticle();
- part.Velocity = Random::GenerateDirection() * MAX_DUST_SPEED;
+ part.Velocity = Random::GenerateDirection() * DUST_VELOCITY_MAX;
- part.Size = Random::GenerateFloat(MAX_DUST_SIZE / 2, MAX_DUST_SIZE);
+ part.Size = Random::GenerateFloat(DUST_SIZE_MAX / 2, DUST_SIZE_MAX);
part.Type = WeatherType::None;
part.Life = DUST_LIFE + Random::GenerateInt(-10, 10);
- part.Room = roomNumber;
+ part.RoomNumber = roomNumber;
part.Position.x = xPos;
part.Position.y = yPos;
part.Position.z = zPos;
@@ -509,33 +535,42 @@ namespace TEN::Effects::Environment
}
}
- void EnvironmentController::SpawnWeatherParticles(ScriptInterfaceLevel* level)
+ void EnvironmentController::SpawnWeatherParticles(const ScriptInterfaceLevel& level)
{
- // Clean up dead particles
+ // Clean up dead particles.
if (Particles.size() > 0)
- Particles.erase(std::remove_if(Particles.begin(), Particles.end(), [](const WeatherParticle& part) { return !part.Enabled; }), Particles.end());
+ {
+ Particles.erase(
+ std::remove_if(
+ Particles.begin(), Particles.end(),
+ [](const WeatherParticle& part)
+ {
+ return !part.Enabled;
+ }),
+ Particles.end());
+ }
- if (level->GetWeatherType() == WeatherType::None || level->GetWeatherStrength() == 0.0f)
+ if (level.GetWeatherType() == WeatherType::None || level.GetWeatherStrength() == 0.0f)
return;
int newParticlesCount = 0;
- int density = WEATHER_PARTICLES_SPAWN_DENSITY * level->GetWeatherStrength();
+ int density = WEATHER_PARTICLE_SPAWN_DENSITY * level.GetWeatherStrength();
- // Snow is falling twice as fast, and must be spawned accordingly fast
- if (level->GetWeatherType() == WeatherType::Snow)
+ // Snow is falling twice as fast and must be spawned accordingly fast.
+ if (level.GetWeatherType() == WeatherType::Snow)
density *= 2;
- if (density > 0.0f && level->GetWeatherType() != WeatherType::None)
+ if (density > 0.0f && level.GetWeatherType() != WeatherType::None)
{
- while (Particles.size() < WEATHER_PARTICLES_MAX_COUNT)
+ while (Particles.size() < WEATHER_PARTICLE_COUNT_MAX)
{
if (newParticlesCount > density)
break;
newParticlesCount++;
- auto distance = level->GetWeatherType() == WeatherType::Snow ? COLLISION_CHECK_DISTANCE : COLLISION_CHECK_DISTANCE / 2;
- auto radius = Random::GenerateInt(0, distance);
+ float dist = (level.GetWeatherType() == WeatherType::Snow) ? COLLISION_CHECK_DISTANCE : (COLLISION_CHECK_DISTANCE / 2);
+ float radius = Random::GenerateInt(0, dist);
short angle = Random::GenerateInt(ANGLE(0), ANGLE(180));
auto xPos = Camera.pos.x + ((int)(phd_cos(angle) * radius));
@@ -557,26 +592,26 @@ namespace TEN::Effects::Environment
auto part = WeatherParticle();
- switch (level->GetWeatherType())
+ switch (level.GetWeatherType())
{
case WeatherType::Snow:
- part.Size = Random::GenerateFloat(MAX_SNOW_SIZE / 3, MAX_SNOW_SIZE);
- part.Velocity.y = Random::GenerateFloat(MAX_SNOW_SPEED / 4, MAX_SNOW_SPEED) * (part.Size / MAX_SNOW_SIZE);
- part.Life = (MAX_SNOW_SPEED / 3) + ((MAX_SNOW_SPEED / 2) - ((int)part.Velocity.y >> 2));
+ part.Size = Random::GenerateFloat(SNOW_SIZE_MAX / 3, SNOW_SIZE_MAX);
+ part.Velocity.y = Random::GenerateFloat(SNOW_VELOCITY_MAX / 4, SNOW_VELOCITY_MAX) * (part.Size / SNOW_SIZE_MAX);
+ part.Life = (SNOW_VELOCITY_MAX / 3) + ((SNOW_VELOCITY_MAX / 2) - ((int)part.Velocity.y >> 2));
break;
case WeatherType::Rain:
- part.Size = Random::GenerateFloat(MAX_RAIN_SIZE / 2, MAX_RAIN_SIZE);
- part.Velocity.y = Random::GenerateFloat(MAX_RAIN_SPEED / 2, MAX_RAIN_SPEED) * (part.Size / MAX_RAIN_SIZE) * std::clamp(level->GetWeatherStrength(), 0.6f, 1.0f);
- part.Life = (MAX_RAIN_SPEED * 2) - part.Velocity.y;
+ part.Size = Random::GenerateFloat(RAIN_SIZE_MAX / 2, RAIN_SIZE_MAX);
+ part.Velocity.y = Random::GenerateFloat(RAIN_VELOCITY_MAX / 2, RAIN_VELOCITY_MAX) * (part.Size / RAIN_SIZE_MAX) * std::clamp(level.GetWeatherStrength(), 0.6f, 1.0f);
+ part.Life = (RAIN_VELOCITY_MAX * 2) - part.Velocity.y;
break;
}
- part.Velocity.x = Random::GenerateFloat(WEATHER_PARTICLE_HORIZONTAL_SPEED / 2, WEATHER_PARTICLE_HORIZONTAL_SPEED);
- part.Velocity.z = Random::GenerateFloat(WEATHER_PARTICLE_HORIZONTAL_SPEED / 2, WEATHER_PARTICLE_HORIZONTAL_SPEED);
+ part.Velocity.x = Random::GenerateFloat(WEATHER_PARTICLE_HORIZONTAL_VELOCITY / 2, WEATHER_PARTICLE_HORIZONTAL_VELOCITY);
+ part.Velocity.z = Random::GenerateFloat(WEATHER_PARTICLE_HORIZONTAL_VELOCITY / 2, WEATHER_PARTICLE_HORIZONTAL_VELOCITY);
- part.Type = level->GetWeatherType();
- part.Room = outsideRoom;
+ part.Type = level.GetWeatherType();
+ part.RoomNumber = outsideRoom;
part.Position.x = xPos;
part.Position.y = yPos;
part.Position.z = zPos;
@@ -590,7 +625,7 @@ namespace TEN::Effects::Environment
}
}
- void EnvironmentController::SpawnMeteorParticles(ScriptInterfaceLevel* level)
+ void EnvironmentController::SpawnMeteorParticles(const ScriptInterfaceLevel& level)
{
// Clean up dead particles.
if (!Meteors.empty())
@@ -605,13 +640,13 @@ namespace TEN::Effects::Environment
Meteors.end());
}
- if (!level->GetStarfieldMeteorsEnabled())
+ if (!level.GetStarfieldMeteorsEnabled())
return;
- int density = level->GetStarfieldMeteorSpawnDensity();
+ int density = level.GetStarfieldMeteorSpawnDensity();
if (density > 0)
{
- for (int i = 0; i < level->GetStarfieldMeteorCount(); i++)
+ for (int i = 0; i < level.GetStarfieldMeteorCount(); i++)
{
if (i > density)
break;
diff --git a/TombEngine/Game/effects/weather.h b/TombEngine/Game/effects/weather.h
index 15ff5452f..ad06bbc9b 100644
--- a/TombEngine/Game/effects/weather.h
+++ b/TombEngine/Game/effects/weather.h
@@ -7,32 +7,32 @@ using namespace TEN::Entities::Effects;
namespace TEN::Effects::Environment
{
- constexpr auto WEATHER_PARTICLES_SPAWN_DENSITY = 32;
- constexpr auto WEATHER_PARTICLES_MAX_COUNT = 2048;
- constexpr auto WEATHER_PARTICLES_MAX_COLL_CHECK_DELAY = 5.0f;
+ constexpr auto WEATHER_PARTICLE_SPAWN_DENSITY = 32;
+ constexpr auto WEATHER_PARTICLE_COUNT_MAX = 2048;
+ constexpr auto WEATHER_PARTICLE_COLL_CHECK_DELAY_MAX = 5.0f;
- constexpr auto MAX_DUST_SIZE = 25.0f;
- constexpr auto MAX_SNOW_SIZE = 32.0f;
- constexpr auto MAX_RAIN_SIZE = 128.0f;
+ constexpr auto DUST_SIZE_MAX = 25.0f;
+ constexpr auto SNOW_SIZE_MAX = 32.0f;
+ constexpr auto RAIN_SIZE_MAX = 128.0f;
- constexpr auto WEATHER_PARTICLE_HORIZONTAL_SPEED = 8.0f;
- constexpr auto MAX_SNOW_SPEED = 128.0f;
- constexpr auto MAX_RAIN_SPEED = 256.0f;
- constexpr auto MAX_DUST_SPEED = 1.0f;
+ constexpr auto WEATHER_PARTICLE_HORIZONTAL_VELOCITY = 8.0f;
+ constexpr auto SNOW_VELOCITY_MAX = 128.0f;
+ constexpr auto RAIN_VELOCITY_MAX = 256.0f;
+ constexpr auto DUST_VELOCITY_MAX = 1.0f;
- constexpr auto WEATHER_PARTICLES_TRANSPARENCY = 0.8f;
- constexpr auto WEATHER_PARTICLES_NEAR_DEATH_LIFE_VALUE = 20.0f;
- constexpr auto WEATHER_PARTICLES_NEAR_DEATH_MELT_FACTOR = 1.0f - (1.0f / (WEATHER_PARTICLES_NEAR_DEATH_LIFE_VALUE * 2));
+ constexpr auto WEATHER_PARTICLE_OPACITY = 0.8f;
+ constexpr auto WEATHER_PARTICLE_NEAR_DEATH_LIFE = 20.0f;
+ constexpr auto WEATHER_PARTICLE_NEAR_DEATH_MELT_FACTOR = 1.0f - (1.0f / (WEATHER_PARTICLE_NEAR_DEATH_LIFE * 2));
constexpr auto DUST_SPAWN_DENSITY = 300;
- constexpr auto DUST_LIFE = 40;
- constexpr auto DUST_SPAWN_RADIUS = (10 * 1024);
+ constexpr auto DUST_LIFE = 40;
+ constexpr auto DUST_SPAWN_RADIUS = BLOCK(10);
- constexpr auto METEOR_PARTICLE_COUNT_MAX = 10;
- constexpr auto METEOR_PARTICLE_LIFE_MAX = 150;
- constexpr auto METEOR_PARTICLE_VELOCITY = 32.0f;
+ constexpr auto METEOR_PARTICLE_COUNT_MAX = 10;
+ constexpr auto METEOR_PARTICLE_LIFE_MAX = 150;
+ constexpr auto METEOR_PARTICLE_VELOCITY = 32.0f;
constexpr auto METEOR_PARTICLE_SPAWN_DENSITY = 4;
- constexpr auto METEOR_PARTICLE_FADE_TIME = 30.0f;
+ constexpr auto METEOR_PARTICLE_FADE_TIME = 30.0f;
struct StarParticle
{
@@ -70,31 +70,31 @@ namespace TEN::Effects::Environment
{
WeatherType Type = WeatherType::None;
- int Room = NO_VALUE;
- Vector3 Position = Vector3::Zero;
- Vector3 Velocity = Vector3::Zero;
+ Vector3 Position = Vector3::Zero;
+ int RoomNumber = NO_VALUE;
+ Vector3 Velocity = Vector3::Zero;
- float StartLife = 0.0f;
- float Life = 0.0f;
+ float StartLife = 0.0f;
+ float Life = 0.0f;
float CollisionCheckDelay = 0.0f;
- float Size = 0.0f;
+ float Size = 0.0f;
bool Enabled = false;
bool Stopped = false;
float Transparency() const;
- Vector3 OldPosition = Vector3::Zero;
- Vector3 OldVelocity = Vector3::Zero;
- float OldSize = 0.0f;
- float OldLife = 0.0f;
+ Vector3 PrevPosition = Vector3::Zero;
+ Vector3 PrevVelocity = Vector3::Zero;
+ float PrevSize = 0.0f;
+ float PrevLife = 0.0f;
void StoreInterpolationData()
{
- OldPosition = Position;
- OldVelocity = Velocity;
- OldSize = Size;
- OldLife = Life;
+ PrevPosition = Position;
+ PrevVelocity = Velocity;
+ PrevSize = Size;
+ PrevLife = Life;
}
};
@@ -104,7 +104,7 @@ namespace TEN::Effects::Environment
EnvironmentController();
Vector3 Wind() { return Vector3(WindX / 2.0f, 0, WindZ / 2.0f); }
- Vector3 FlashColor() { return FlashColorBase * sin(FlashProgress * PI / 2.0f); }
+ Vector3 FlashColor() { return FlashColorBase * sin((FlashProgress * PI) / 2.0f); }
Vector4 SkyColor(int index) { return SkyCurrentColor[std::clamp(index, 0, 1)]; }
short SkyPosition(int index) { return SkyCurrentPosition[std::clamp(index, 0, 1)]; }
@@ -113,16 +113,16 @@ namespace TEN::Effects::Environment
void Clear();
const std::vector& GetParticles() const { return Particles; }
- const std::vector& GetStars() const { return Stars; }
- const std::vector& GetMeteors() { return Meteors; }
+ const std::vector& GetStars() const { return Stars; }
+ const std::vector& GetMeteors() const { return Meteors; }
private:
// Weather
- std::vector Particles;
+ std::vector Particles = {};
// Sky
- Vector4 SkyCurrentColor[2] = {};
- short SkyCurrentPosition[2] = {};
+ Vector4 SkyCurrentColor[2] = {};
+ short SkyCurrentPosition[2] = {};
// Wind
int WindX = 0;
@@ -133,14 +133,14 @@ namespace TEN::Effects::Environment
// Flash fader
Vector3 FlashColorBase = Vector3::Zero;
- float FlashSpeed = 1.0f;
- float FlashProgress = 0.0f;
+ float FlashSpeed = 1.0f;
+ float FlashProgress = 0.0f;
// Lightning
- int StormCount = 0;
- int StormRand = 0;
- int StormTimer = 0;
- byte StormSkyColor = 1;
+ int StormCount = 0;
+ int StormRand = 0;
+ int StormTimer = 0;
+ byte StormSkyColor = 1;
byte StormSkyColor2 = 1;
// Starfield
@@ -151,17 +151,17 @@ namespace TEN::Effects::Environment
// Lens flare
LensFlare GlobalLensFlare = {};
- void UpdateStarfield(ScriptInterfaceLevel* level);
- void UpdateSky(ScriptInterfaceLevel* level);
- void UpdateStorm(ScriptInterfaceLevel* level);
- void UpdateWind(ScriptInterfaceLevel* level);
- void UpdateFlash(ScriptInterfaceLevel* level);
- void UpdateWeather(ScriptInterfaceLevel* level);
+ void UpdateStarfield(const ScriptInterfaceLevel& level);
+ void UpdateSky(const ScriptInterfaceLevel& level);
+ void UpdateStorm(const ScriptInterfaceLevel& level);
+ void UpdateWind(const ScriptInterfaceLevel& level);
+ void UpdateFlash(const ScriptInterfaceLevel& level);
+ void UpdateWeather(const ScriptInterfaceLevel& level);
void UpdateLightning();
- void SpawnDustParticles(ScriptInterfaceLevel* level);
- void SpawnWeatherParticles(ScriptInterfaceLevel* level);
- void SpawnMeteorParticles(ScriptInterfaceLevel* level);
+ void SpawnDustParticles(const ScriptInterfaceLevel& level);
+ void SpawnWeatherParticles(const ScriptInterfaceLevel& level);
+ void SpawnMeteorParticles(const ScriptInterfaceLevel& level);
};
extern EnvironmentController Weather;
diff --git a/TombEngine/Game/items.h b/TombEngine/Game/items.h
index f5ea6aa21..e630fbf29 100644
--- a/TombEngine/Game/items.h
+++ b/TombEngine/Game/items.h
@@ -128,11 +128,12 @@ struct ItemInfo
short RoomNumber = 0; // TODO: Make int.
int Floor = 0;
- int HitPoints = 0;
- bool HitStatus = false;
- bool LookedAt = false;
- bool Collidable = false;
- bool InDrawRoom = false;
+ int HitPoints = 0;
+ bool HitStatus = false;
+ bool LookedAt = false;
+ bool Collidable = false;
+ bool InDrawRoom = false;
+ bool DisableInterpolation = false;
int BoxNumber = 0;
int Timer = 0;
@@ -172,8 +173,6 @@ struct ItemInfo
bool IsLara() const;
bool IsCreature() const;
bool IsBridge() const;
-
- bool DisableInterpolation = false;
};
bool TestState(int refState, const std::vector& stateList);
diff --git a/TombEngine/Renderer/RendererDrawEffect.cpp b/TombEngine/Renderer/RendererDrawEffect.cpp
index 8b4dfe37a..1d49791a7 100644
--- a/TombEngine/Renderer/RendererDrawEffect.cpp
+++ b/TombEngine/Renderer/RendererDrawEffect.cpp
@@ -144,13 +144,13 @@ namespace TEN::Renderer
if (segment.Flags & (int)StreamerFlags::FadeLeft)
{
AddColoredQuad(
- Vector3::Lerp(segment.OldVertices[0], segment.Vertices[0], _interpolationFactor),
- Vector3::Lerp(segment.OldVertices[1], segment.Vertices[1], _interpolationFactor),
- Vector3::Lerp(prevSegment.OldVertices[1], prevSegment.Vertices[1], _interpolationFactor),
- Vector3::Lerp(prevSegment.OldVertices[0], prevSegment.Vertices[0], _interpolationFactor),
+ Vector3::Lerp(segment.PrevVertices[0], segment.Vertices[0], _interpolationFactor),
+ Vector3::Lerp(segment.PrevVertices[1], segment.Vertices[1], _interpolationFactor),
+ Vector3::Lerp(prevSegment.PrevVertices[1], prevSegment.Vertices[1], _interpolationFactor),
+ Vector3::Lerp(prevSegment.PrevVertices[0], prevSegment.Vertices[0], _interpolationFactor),
Vector4::Zero,
- Vector4::Lerp(segment.OldColor, segment.Color, _interpolationFactor),
- Vector4::Lerp(prevSegment.OldColor, prevSegment.Color, _interpolationFactor),
+ Vector4::Lerp(segment.PrevColor, segment.Color, _interpolationFactor),
+ Vector4::Lerp(prevSegment.PrevColor, prevSegment.Color, _interpolationFactor),
Vector4::Zero,
blendMode,
view);
@@ -158,28 +158,28 @@ namespace TEN::Renderer
else if (segment.Flags & (int)StreamerFlags::FadeRight)
{
AddColoredQuad(
- Vector3::Lerp(segment.OldVertices[0], segment.Vertices[0], _interpolationFactor),
- Vector3::Lerp(segment.OldVertices[1], segment.Vertices[1], _interpolationFactor),
- Vector3::Lerp(prevSegment.OldVertices[1], prevSegment.Vertices[1], _interpolationFactor),
- Vector3::Lerp(prevSegment.OldVertices[0], prevSegment.Vertices[0], _interpolationFactor),
- Vector4::Lerp(segment.OldColor, segment.Color, _interpolationFactor),
+ Vector3::Lerp(segment.PrevVertices[0], segment.Vertices[0], _interpolationFactor),
+ Vector3::Lerp(segment.PrevVertices[1], segment.Vertices[1], _interpolationFactor),
+ Vector3::Lerp(prevSegment.PrevVertices[1], prevSegment.Vertices[1], _interpolationFactor),
+ Vector3::Lerp(prevSegment.PrevVertices[0], prevSegment.Vertices[0], _interpolationFactor),
+ Vector4::Lerp(segment.PrevColor, segment.Color, _interpolationFactor),
Vector4::Zero,
Vector4::Zero,
- Vector4::Lerp(prevSegment.OldColor, prevSegment.Color, _interpolationFactor),
+ Vector4::Lerp(prevSegment.PrevColor, prevSegment.Color, _interpolationFactor),
blendMode,
view);
}
else
{
AddColoredQuad(
- Vector3::Lerp(segment.OldVertices[0], segment.Vertices[0], _interpolationFactor),
- Vector3::Lerp(segment.OldVertices[1], segment.Vertices[1], _interpolationFactor),
- Vector3::Lerp(prevSegment.OldVertices[1], prevSegment.Vertices[1], _interpolationFactor),
- Vector3::Lerp(prevSegment.OldVertices[0], prevSegment.Vertices[0], _interpolationFactor),
- Vector4::Lerp(segment.OldColor, segment.Color, _interpolationFactor),
- Vector4::Lerp(segment.OldColor, segment.Color, _interpolationFactor),
- Vector4::Lerp(prevSegment.OldColor, prevSegment.Color, _interpolationFactor),
- Vector4::Lerp(prevSegment.OldColor, prevSegment.Color, _interpolationFactor),
+ Vector3::Lerp(segment.PrevVertices[0], segment.Vertices[0], _interpolationFactor),
+ Vector3::Lerp(segment.PrevVertices[1], segment.Vertices[1], _interpolationFactor),
+ Vector3::Lerp(prevSegment.PrevVertices[1], prevSegment.Vertices[1], _interpolationFactor),
+ Vector3::Lerp(prevSegment.PrevVertices[0], prevSegment.Vertices[0], _interpolationFactor),
+ Vector4::Lerp(segment.PrevColor, segment.Color, _interpolationFactor),
+ Vector4::Lerp(segment.PrevColor, segment.Color, _interpolationFactor),
+ Vector4::Lerp(prevSegment.PrevColor, prevSegment.Color, _interpolationFactor),
+ Vector4::Lerp(prevSegment.PrevColor, prevSegment.Color, _interpolationFactor),
blendMode,
view);
}
@@ -202,13 +202,13 @@ namespace TEN::Renderer
if (laser.Life <= 0.0f)
continue;
- auto color = Vector4::Lerp(laser.OldColor, laser.Color, _interpolationFactor);
- color.w = Lerp(laser.OldOpacity, laser.Opacity, _interpolationFactor);
+ auto color = Vector4::Lerp(laser.PrevColor, laser.Color, _interpolationFactor);
+ color.w = Lerp(laser.PrevOpacity, laser.Opacity, _interpolationFactor);
- Vector3 laserTarget = Vector3::Lerp(laser.OldTarget, laser.Target, _interpolationFactor);
+ Vector3 laserTarget = Vector3::Lerp(laser.PrevTarget, laser.Target, _interpolationFactor);
ElectricityKnots[0] = laserTarget;
- ElectricityKnots[1] = Vector3::Lerp(laser.OldOrigin, laser.Origin, _interpolationFactor);
+ ElectricityKnots[1] = Vector3::Lerp(laser.PrevOrigin, laser.Origin, _interpolationFactor);
for (int j = 0; j < 2; j++)
ElectricityKnots[j] -= laserTarget;
@@ -261,12 +261,12 @@ namespace TEN::Renderer
if (arc.life <= 0)
continue;
- ElectricityKnots[0] = Vector3::Lerp(arc.oldPos1, arc.pos1, _interpolationFactor);
- ElectricityKnots[1] = Vector3::Lerp(arc.oldPos1, arc.pos1, _interpolationFactor);
- ElectricityKnots[2] = Vector3::Lerp(arc.oldPos2, arc.pos2, _interpolationFactor);
- ElectricityKnots[3] = Vector3::Lerp(arc.oldPos3, arc.pos3, _interpolationFactor);
- ElectricityKnots[4] = Vector3::Lerp(arc.oldPos4, arc.pos4, _interpolationFactor);
- ElectricityKnots[5] = Vector3::Lerp(arc.oldPos4, arc.pos4, _interpolationFactor);
+ ElectricityKnots[0] = Vector3::Lerp(arc.PrevPos1, arc.pos1, _interpolationFactor);
+ ElectricityKnots[1] = Vector3::Lerp(arc.PrevPos1, arc.pos1, _interpolationFactor);
+ ElectricityKnots[2] = Vector3::Lerp(arc.PrevPos2, arc.pos2, _interpolationFactor);
+ ElectricityKnots[3] = Vector3::Lerp(arc.PrevPos3, arc.pos3, _interpolationFactor);
+ ElectricityKnots[4] = Vector3::Lerp(arc.PrevPos4, arc.pos4, _interpolationFactor);
+ ElectricityKnots[5] = Vector3::Lerp(arc.PrevPos4, arc.pos4, _interpolationFactor);
for (int j = 0; j < ElectricityKnots.size(); j++)
ElectricityKnots[j] -= LaraItem->Pose.Position.ToVector3();
@@ -307,17 +307,17 @@ namespace TEN::Renderer
byte oldR, oldG, oldB;
- if (arc.oldLife >= 16)
+ if (arc.PrevLife >= 16)
{
- oldR = arc.oldR;
- oldG = arc.oldG;
- oldB = arc.oldB;
+ oldR = arc.PrevR;
+ oldG = arc.PrevG;
+ oldB = arc.PrevB;
}
else
{
- oldR = (arc.oldLife * arc.oldR) / 16;
- oldG = (arc.oldLife * arc.oldG) / 16;
- oldB = (arc.oldLife * arc.oldB) / 16;
+ oldR = (arc.PrevLife * arc.PrevR) / 16;
+ oldG = (arc.PrevLife * arc.PrevG) / 16;
+ oldB = (arc.PrevLife * arc.PrevB) / 16;
}
r = (byte)Lerp(oldR, r, _interpolationFactor);
@@ -640,11 +640,11 @@ namespace TEN::Renderer
AddSpriteBillboard(
&_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + bubble.SpriteIndex],
- Vector3::Lerp(bubble.OldPosition, bubble.Position, _interpolationFactor),
- Vector4::Lerp(bubble.OldColor, bubble.Color, _interpolationFactor),
+ Vector3::Lerp(bubble.PrevPosition, bubble.Position, _interpolationFactor),
+ Vector4::Lerp(bubble.PrevColor, bubble.Color, _interpolationFactor),
0.0f,
1.0f,
- Vector2::Lerp(bubble.OldSize, bubble.Size, _interpolationFactor) / 2,
+ Vector2::Lerp(bubble.PrevSize, bubble.Size, _interpolationFactor) / 2,
BlendMode::Additive,
true,
view);
@@ -698,17 +698,17 @@ namespace TEN::Renderer
auto color = ripple.Color;
color.w = opacity;
- float oldOpacity = ripple.OldColor.w * ((ripple.Flags & (int)RippleFlags::LowOpacity) ? 0.5f : 1.0f);
- auto oldColor = ripple.OldColor;
+ float oldOpacity = ripple.PrevColor.w * ((ripple.Flags & (int)RippleFlags::LowOpacity) ? 0.5f : 1.0f);
+ auto oldColor = ripple.PrevColor;
oldColor.w = oldOpacity;
AddSpriteBillboardConstrainedLookAt(
&_sprites[ripple.SpriteIndex],
- Vector3::Lerp(ripple.OldPosition, ripple.Position, _interpolationFactor),
+ Vector3::Lerp(ripple.PrevPosition, ripple.Position, _interpolationFactor),
Vector4::Lerp(oldColor, color, _interpolationFactor),
0.0f,
1.0f,
- Vector2(Lerp(ripple.OldSize, ripple.Size, _interpolationFactor) * 2),
+ Vector2(Lerp(ripple.PrevSize, ripple.Size, _interpolationFactor) * 2),
BlendMode::Additive,
ripple.Normal,
true,
@@ -741,7 +741,7 @@ namespace TEN::Renderer
if (uwBlood.Init)
oldColor = Vector4(uwBlood.Init / 2, 0, uwBlood.Init / 16, UCHAR_MAX);
else
- oldColor = Vector4(uwBlood.OldLife / 2, 0, uwBlood.OldLife / 16, UCHAR_MAX);
+ oldColor = Vector4(uwBlood.PrevLife / 2, 0, uwBlood.PrevLife / 16, UCHAR_MAX);
oldColor.x = (int)std::clamp((int)oldColor.x, 0, UCHAR_MAX);
oldColor.y = (int)std::clamp((int)oldColor.y, 0, UCHAR_MAX);
@@ -750,13 +750,13 @@ namespace TEN::Renderer
AddSpriteBillboard(
&_sprites[uwBlood.SpriteIndex],
- Vector3::Lerp(uwBlood.OldPosition, uwBlood.Position, _interpolationFactor),
+ Vector3::Lerp(uwBlood.PrevPosition, uwBlood.Position, _interpolationFactor),
Vector4::Lerp(oldColor, color, _interpolationFactor),
0.0f,
1.0f,
Vector2(
- Lerp(uwBlood.OldSize, uwBlood.Size, _interpolationFactor),
- Lerp(uwBlood.OldSize, uwBlood.Size, _interpolationFactor)
+ Lerp(uwBlood.PrevSize, uwBlood.Size, _interpolationFactor),
+ Lerp(uwBlood.PrevSize, uwBlood.Size, _interpolationFactor)
) * 2,
BlendMode::Additive,
true,
@@ -994,11 +994,11 @@ namespace TEN::Renderer
AddSpriteBillboard(
&_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_UNDERWATERDUST],
- Vector3::Lerp(p.OldPosition, p.Position, _interpolationFactor),
+ Vector3::Lerp(p.PrevPosition, p.Position, _interpolationFactor),
Vector4(1.0f, 1.0f, 1.0f, p.Transparency()),
0.0f,
1.0f,
- Vector2(Lerp(p.OldSize, p.Size, _interpolationFactor)),
+ Vector2(Lerp(p.PrevSize, p.Size, _interpolationFactor)),
BlendMode::Additive,
true,
view);
@@ -1012,11 +1012,11 @@ namespace TEN::Renderer
AddSpriteBillboard(
&_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_UNDERWATERDUST],
- Vector3::Lerp(p.OldPosition, p.Position, _interpolationFactor),
+ Vector3::Lerp(p.PrevPosition, p.Position, _interpolationFactor),
Vector4(1.0f, 1.0f, 1.0f, p.Transparency()),
0.0f,
1.0f,
- Vector2(Lerp(p.OldSize, p.Size, _interpolationFactor)),
+ Vector2(Lerp(p.PrevSize, p.Size, _interpolationFactor)),
BlendMode::Additive,
true,
view);
@@ -1033,11 +1033,11 @@ namespace TEN::Renderer
AddSpriteBillboardConstrained(
&_sprites[Objects[ID_DRIP_SPRITE].meshIndex],
- Vector3::Lerp(p.OldPosition, p.Position, _interpolationFactor),
+ Vector3::Lerp(p.PrevPosition, p.Position, _interpolationFactor),
Vector4(0.8f, 1.0f, 1.0f, p.Transparency()),
0.0f,
1.0f,
- Vector2(RAIN_WIDTH, Lerp(p.OldSize, p.Size, _interpolationFactor)),
+ Vector2(RAIN_WIDTH, Lerp(p.PrevSize, p.Size, _interpolationFactor)),
BlendMode::Additive,
-v,
true,
diff --git a/TombEngine/Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.cpp b/TombEngine/Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.cpp
index 3ea31cf12..7478bafa9 100644
--- a/TombEngine/Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.cpp
+++ b/TombEngine/Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.cpp
@@ -219,6 +219,6 @@ namespace TEN::Scripting::DisplaySprite
alignMode.value_or(DEFAULT_ALIGN_MODE),
scaleMode.value_or(DEFAULT_SCALE_MODE),
blendMode.value_or(DEFAULT_BLEND_MODE),
- DisplaySpriteSource::ControlPhase);
+ DisplaySpritePhase::Control);
}
}
diff --git a/TombEngine/Specific/RGBAColor8Byte.cpp b/TombEngine/Specific/RGBAColor8Byte.cpp
index 57f1568fb..7ec856d3e 100644
--- a/TombEngine/Specific/RGBAColor8Byte.cpp
+++ b/TombEngine/Specific/RGBAColor8Byte.cpp
@@ -99,11 +99,6 @@ RGBAColor8Byte::operator Color() const
return Color(ByteComponentToFloat(r), ByteComponentToFloat(g), ByteComponentToFloat(b));
}
-RGBAColor8Byte::operator Color() const
-{
- return Color(ByteComponentToFloat(r), ByteComponentToFloat(g), ByteComponentToFloat(b));
-}
-
RGBAColor8Byte::operator Vector3() const
{
return Vector3(ByteComponentToFloat(r), ByteComponentToFloat(g), ByteComponentToFloat(b));
From 6240cce4e832c5bbf4efd6126db39a7179b61f40 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 8 May 2024 19:21:29 +1000
Subject: [PATCH 148/410] Clean up effect rendering
---
TombEngine/Renderer/RendererDrawEffect.cpp | 395 ++++++++-------------
TombEngine/Renderer/RendererSprites.cpp | 4 +-
2 files changed, 158 insertions(+), 241 deletions(-)
diff --git a/TombEngine/Renderer/RendererDrawEffect.cpp b/TombEngine/Renderer/RendererDrawEffect.cpp
index 1d49791a7..34bbb36c5 100644
--- a/TombEngine/Renderer/RendererDrawEffect.cpp
+++ b/TombEngine/Renderer/RendererDrawEffect.cpp
@@ -88,13 +88,10 @@ namespace TEN::Renderer
{
bool isLastSubdivision = (i == (LaserBeamEffect::SUBDIVISION_COUNT - 1));
- Vector4 color = Vector4::Lerp(beam.OldColor, beam.Color, _interpolationFactor);
+ auto color = Color::Lerp(beam.OldColor, beam.Color, _interpolationFactor);
AddColoredQuad(
- Vector3::Lerp(
- beam.OldVertices[i],
- beam.Vertices[i],
- _interpolationFactor),
+ Vector3::Lerp(beam.OldVertices[i], beam.Vertices[i], _interpolationFactor),
Vector3::Lerp(
beam.OldVertices[isLastSubdivision ? 0 : (i + 1)],
beam.Vertices[isLastSubdivision ? 0 : (i + 1)],
@@ -107,13 +104,8 @@ namespace TEN::Renderer
beam.OldVertices[LaserBeamEffect::SUBDIVISION_COUNT + i],
beam.Vertices[LaserBeamEffect::SUBDIVISION_COUNT + i],
_interpolationFactor),
- color,
- color,
- color,
- color,
- BlendMode::Additive,
- view,
- SpriteRenderType::LaserBeam);
+ color, color, color, color,
+ BlendMode::Additive, view, SpriteRenderType::LaserBeam);
}
}
}
@@ -152,8 +144,7 @@ namespace TEN::Renderer
Vector4::Lerp(segment.PrevColor, segment.Color, _interpolationFactor),
Vector4::Lerp(prevSegment.PrevColor, prevSegment.Color, _interpolationFactor),
Vector4::Zero,
- blendMode,
- view);
+ blendMode, view);
}
else if (segment.Flags & (int)StreamerFlags::FadeRight)
{
@@ -166,8 +157,7 @@ namespace TEN::Renderer
Vector4::Zero,
Vector4::Zero,
Vector4::Lerp(prevSegment.PrevColor, prevSegment.Color, _interpolationFactor),
- blendMode,
- view);
+ blendMode, view);
}
else
{
@@ -180,8 +170,7 @@ namespace TEN::Renderer
Vector4::Lerp(segment.PrevColor, segment.Color, _interpolationFactor),
Vector4::Lerp(prevSegment.PrevColor, prevSegment.Color, _interpolationFactor),
Vector4::Lerp(prevSegment.PrevColor, prevSegment.Color, _interpolationFactor),
- blendMode,
- view);
+ blendMode, view);
}
}
}
@@ -205,7 +194,7 @@ namespace TEN::Renderer
auto color = Vector4::Lerp(laser.PrevColor, laser.Color, _interpolationFactor);
color.w = Lerp(laser.PrevOpacity, laser.Opacity, _interpolationFactor);
- Vector3 laserTarget = Vector3::Lerp(laser.PrevTarget, laser.Target, _interpolationFactor);
+ auto laserTarget = Vector3::Lerp(laser.PrevTarget, laser.Target, _interpolationFactor);
ElectricityKnots[0] = laserTarget;
ElectricityKnots[1] = Vector3::Lerp(laser.PrevOrigin, laser.Origin, _interpolationFactor);
@@ -229,22 +218,15 @@ namespace TEN::Renderer
auto target = laserTarget + interpPosArray[bufferIndex];
auto center = (origin + target) / 2;
- auto direction = target - origin;
- direction.Normalize();
+ auto dir = target - origin;
+ dir.Normalize();
AddSpriteBillboardConstrained(
&_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LIGHTHING],
- center,
- color,
- PI_DIV_2,
- 1.0f,
- Vector2(5 * 8.0f, Vector3::Distance(origin, target)),
- BlendMode::Additive,
- direction,
- true,
- view);
+ center, color, PI_DIV_2, 1.0f, Vector2(5 * 8.0f, Vector3::Distance(origin, target)),
+ BlendMode::Additive, dir, true, view);
}
- }
+ }
}
}
@@ -288,8 +270,8 @@ namespace TEN::Renderer
auto target = (LaraItem->Pose.Position + interpPosArray[bufferIndex]).ToVector3();
auto center = (origin + target) / 2;
- auto direction = target - origin;
- direction.Normalize();
+ auto dir = target - origin;
+ dir.Normalize();
byte r, g, b;
if (arc.life >= 16)
@@ -326,15 +308,9 @@ namespace TEN::Renderer
AddSpriteBillboardConstrained(
&_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LIGHTHING],
- center,
- Vector4(r / 255.0f, g / 255.0f, b / 255.0f, 1.0f),
- PI_DIV_2,
- 1.0f,
+ center, Vector4(r / 255.0f, g / 255.0f, b / 255.0f, 1.0f), PI_DIV_2, 1.0f,
Vector2(arc.width * 8, Vector3::Distance(origin, target)),
- BlendMode::Additive,
- direction,
- true,
- view);
+ BlendMode::Additive, dir, true, view);
}
}
}
@@ -342,36 +318,31 @@ namespace TEN::Renderer
void Renderer::PrepareSmokes(RenderView& view)
{
- for (int i = 0; i < 32; i++)
+ for (const auto& smoke : SmokeSparks)
{
- SMOKE_SPARKS* spark = &SmokeSparks[i];
+ if (!smoke.on)
+ continue;
- if (spark->on)
- {
- AddSpriteBillboard(
- &_sprites[spark->def],
- Vector3::Lerp(
- Vector3(spark->oldPosition.x, spark->oldPosition.y, spark->oldPosition.z),
- Vector3(spark->position.x, spark->position.y, spark->position.z),
- _interpolationFactor),
- Vector4::Lerp(
- Vector4(spark->oldShade / 255.0f, spark->oldShade / 255.0f, spark->oldShade / 255.0f, 1.0f),
- Vector4(spark->shade / 255.0f, spark->shade / 255.0f, spark->shade / 255.0f, 1.0f),
- _interpolationFactor),
- TO_RAD(Lerp(spark->oldRotAng << 4, spark->rotAng << 4, _interpolationFactor)),
- Lerp(spark->oldScalar, spark->scalar, _interpolationFactor),
- {
- Lerp(spark->oldSize, spark->size, _interpolationFactor) * 4.0f,
- Lerp(spark->oldSize, spark->size, _interpolationFactor) * 4.0f
- },
- BlendMode::Additive,
- true,
- view);
- }
+ AddSpriteBillboard(
+ &_sprites[smoke.def],
+ Vector3::Lerp(
+ Vector3(smoke.oldPosition.x, smoke.oldPosition.y, smoke.oldPosition.z),
+ Vector3(smoke.position.x, smoke.position.y, smoke.position.z),
+ _interpolationFactor),
+ Vector4::Lerp(
+ Vector4(smoke.oldShade / 255.0f, smoke.oldShade / 255.0f, smoke.oldShade / 255.0f, 1.0f),
+ Vector4(smoke.shade / 255.0f, smoke.shade / 255.0f, smoke.shade / 255.0f, 1.0f),
+ _interpolationFactor),
+ TO_RAD(Lerp(smoke.oldRotAng << 4, smoke.rotAng << 4, _interpolationFactor)),
+ Lerp(smoke.oldScalar, smoke.scalar, _interpolationFactor),
+ {
+ Lerp(smoke.oldSize, smoke.size, _interpolationFactor) * 4.0f,
+ Lerp(smoke.oldSize, smoke.size, _interpolationFactor) * 4.0f
+ },
+ BlendMode::Additive, true, view);
}
}
-
void Renderer::PrepareFires(RenderView& view)
{
for (int k = 0; k < MAX_FIRE_LIST; k++)
@@ -385,43 +356,41 @@ namespace TEN::Renderer
for (int i = 0; i < MAX_SPARKS_FIRE; i++)
{
- auto* spark = &FireSparks[i];
+ auto* fire = &FireSparks[i];
- if (spark->on)
+ if (fire->on)
{
AddSpriteBillboard(
- &_sprites[spark->def],
+ &_sprites[fire->def],
Vector3::Lerp(
Vector3(
- fire->oldPosition.x + spark->oldPosition.x * fire->oldSize / 2,
- fire->oldPosition.y + spark->oldPosition.y * fire->oldSize / 2,
- fire->oldPosition.z + spark->oldPosition.z * fire->oldSize / 2),
+ fire->oldPosition.x + fire->oldPosition.x * fire->oldSize / 2,
+ fire->oldPosition.y + fire->oldPosition.y * fire->oldSize / 2,
+ fire->oldPosition.z + fire->oldPosition.z * fire->oldSize / 2),
Vector3(
- fire->position.x + spark->position.x * fire->size / 2,
- fire->position.y + spark->position.y * fire->size / 2,
- fire->position.z + spark->position.z * fire->size / 2),
+ fire->position.x + fire->position.x * fire->size / 2,
+ fire->position.y + fire->position.y * fire->size / 2,
+ fire->position.z + fire->position.z * fire->size / 2),
_interpolationFactor),
Vector4::Lerp(
Vector4(
- spark->oldColor.x / 255.0f * fade,
- spark->oldColor.y / 255.0f * fade,
- spark->oldColor.z / 255.0f * fade,
+ fire->oldColor.x / 255.0f * fade,
+ fire->oldColor.y / 255.0f * fade,
+ fire->oldColor.z / 255.0f * fade,
1.0f),
Vector4(
- spark->color.x / 255.0f * fade,
- spark->color.y / 255.0f * fade,
- spark->color.z / 255.0f * fade,
+ fire->color.x / 255.0f * fade,
+ fire->color.y / 255.0f * fade,
+ fire->color.z / 255.0f * fade,
1.0f),
_interpolationFactor),
- TO_RAD(Lerp(spark->oldRotAng << 4, spark->rotAng << 4, _interpolationFactor)),
- Lerp(spark->oldScalar, spark->scalar, _interpolationFactor),
+ TO_RAD(Lerp(fire->oldRotAng << 4, fire->rotAng << 4, _interpolationFactor)),
+ Lerp(fire->oldScalar, fire->scalar, _interpolationFactor),
Vector2::Lerp(
- Vector2(spark->oldSize * fire->oldSize, spark->oldSize * fire->oldSize),
- Vector2(spark->size * fire->size, spark->size * fire->size),
+ Vector2(fire->oldSize * fire->oldSize, fire->oldSize * fire->oldSize),
+ Vector2(fire->size * fire->size, fire->size * fire->size),
_interpolationFactor),
- BlendMode::Additive,
- true,
- view);
+ BlendMode::Additive, true, view);
}
}
}
@@ -481,9 +450,13 @@ namespace TEN::Renderer
int meshIndex = NodeOffsets[particle.nodeNumber].meshNum;
if (meshIndex >= 0)
+ {
nodePos = GetJointPosition(item, meshIndex, nodePos);
+ }
else
+ {
nodePos = GetJointPosition(LaraItem, -meshIndex, nodePos);
+ }
NodeOffsets[particle.nodeNumber].gotIt = true;
NodeVectors[particle.nodeNumber] = nodePos;
@@ -511,7 +484,7 @@ namespace TEN::Renderer
AddSpriteBillboard(
&_sprites[spriteIndex],
pos,
- Vector4(particle.r / (float)UCHAR_MAX, particle.g / (float)UCHAR_MAX, particle.b / (float)UCHAR_MAX, 1.0f),
+ Color(particle.r / (float)UCHAR_MAX, particle.g / (float)UCHAR_MAX, particle.b / (float)UCHAR_MAX, 1.0f),
TO_RAD(particle.rotAng << 4), particle.scalar,
Vector2(particle.size, particle.size),
particle.blendMode, true, view);
@@ -562,18 +535,18 @@ namespace TEN::Renderer
}
}
- byte oldColor = (splash.oldLife >= 32 ? 128 : (byte)((splash.oldLife / 32.0f) * 128));
+ byte prevColor = (splash.oldLife >= 32 ? 128 : (byte)((splash.oldLife / 32.0f) * 128));
if (!splash.isRipple)
{
if (splash.oldHeightSpeed < 0 && splash.oldHeight < 1024)
{
float multiplier = splash.oldHeight / 1024.0f;
- oldColor = (float)oldColor * multiplier;
+ prevColor = (float)prevColor * multiplier;
}
}
- color = (byte)Lerp(oldColor, color, _interpolationFactor);
+ color = (byte)Lerp(prevColor, color, _interpolationFactor);
float xInner;
float zInner;
@@ -610,17 +583,13 @@ namespace TEN::Renderer
z2Outer += splash.z;
AddQuad(&_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + splash.spriteSequenceStart + (int)splash.animationPhase],
- Vector3(xOuter, yOuter, zOuter),
- Vector3(x2Outer, yOuter, z2Outer),
- Vector3(x2Inner, yInner, z2Inner),
- Vector3(xInner, yInner, zInner),
- Vector4(color / 255.0f, color / 255.0f, color / 255.0f, 1.0f),
- 0,
- 1,
- { 0, 0 },
- BlendMode::Additive,
- false,
- view);
+ Vector3(xOuter, yOuter, zOuter),
+ Vector3(x2Outer, yOuter, z2Outer),
+ Vector3(x2Inner, yInner, z2Inner),
+ Vector3(xInner, yInner, zInner),
+ Vector4(color / 255.0f, color / 255.0f, color / 255.0f, 1.0f),
+ 0, 1, Vector2::Zero,
+ BlendMode::Additive, false, view);
}
}
}
@@ -643,11 +612,9 @@ namespace TEN::Renderer
Vector3::Lerp(bubble.PrevPosition, bubble.Position, _interpolationFactor),
Vector4::Lerp(bubble.PrevColor, bubble.Color, _interpolationFactor),
0.0f,
- 1.0f,
+ 1.0f,
Vector2::Lerp(bubble.PrevSize, bubble.Size, _interpolationFactor) / 2,
- BlendMode::Additive,
- true,
- view);
+ BlendMode::Additive, true, view);
}
}
@@ -667,20 +634,15 @@ namespace TEN::Renderer
auto axis = drip.Velocity;
drip.Velocity.Normalize(axis);
- auto oldAxis = drip.OldVelocity;
- drip.OldVelocity.Normalize(oldAxis);
+ auto prevAxis = drip.OldVelocity;
+ drip.OldVelocity.Normalize(prevAxis);
AddSpriteBillboardConstrained(
&_sprites[Objects[ID_DRIP_SPRITE].meshIndex],
Vector3::Lerp(drip.OldPosition, drip.Position, _interpolationFactor),
Vector4::Lerp(drip.OldColor, drip.Color, _interpolationFactor),
- 0.0f,
- 1.0f,
- Vector2::Lerp(drip.OldSize, drip.Size, _interpolationFactor),
- BlendMode::Additive,
- -Vector3::Lerp(oldAxis, axis, _interpolationFactor),
- false,
- view);
+ 0.0f, 1.0f, Vector2::Lerp(drip.OldSize, drip.Size, _interpolationFactor),
+ BlendMode::Additive, -Vector3::Lerp(prevAxis, axis, _interpolationFactor), false, view);
}
}
@@ -706,13 +668,8 @@ namespace TEN::Renderer
&_sprites[ripple.SpriteIndex],
Vector3::Lerp(ripple.PrevPosition, ripple.Position, _interpolationFactor),
Vector4::Lerp(oldColor, color, _interpolationFactor),
- 0.0f,
- 1.0f,
- Vector2(Lerp(ripple.PrevSize, ripple.Size, _interpolationFactor) * 2),
- BlendMode::Additive,
- ripple.Normal,
- true,
- view);
+ 0.0f, 1.0f, Vector2(Lerp(ripple.PrevSize, ripple.Size, _interpolationFactor) * 2),
+ BlendMode::Additive, ripple.Normal, true, view);
}
}
@@ -728,9 +685,13 @@ namespace TEN::Renderer
auto color = Vector4::Zero;
if (uwBlood.Init)
+ {
color = Vector4(uwBlood.Init / 2, 0, uwBlood.Init / 16, UCHAR_MAX);
+ }
else
+ {
color = Vector4(uwBlood.Life / 2, 0, uwBlood.Life / 16, UCHAR_MAX);
+ }
color.x = (int)std::clamp((int)color.x, 0, UCHAR_MAX);
color.y = (int)std::clamp((int)color.y, 0, UCHAR_MAX);
@@ -752,15 +713,11 @@ namespace TEN::Renderer
&_sprites[uwBlood.SpriteIndex],
Vector3::Lerp(uwBlood.PrevPosition, uwBlood.Position, _interpolationFactor),
Vector4::Lerp(oldColor, color, _interpolationFactor),
- 0.0f,
- 1.0f,
+ 0.0f, 1.0f,
Vector2(
Lerp(uwBlood.PrevSize, uwBlood.Size, _interpolationFactor),
- Lerp(uwBlood.PrevSize, uwBlood.Size, _interpolationFactor)
- ) * 2,
- BlendMode::Additive,
- true,
- view);
+ Lerp(uwBlood.PrevSize, uwBlood.Size, _interpolationFactor)) * 2,
+ BlendMode::Additive, true, view);
}
}
@@ -775,7 +732,7 @@ namespace TEN::Renderer
for (int i = 0; i < MAX_SHOCKWAVE; i++)
{
- SHOCKWAVE_STRUCT* shockwave = &ShockWaves[i];
+ auto* shockwave = &ShockWaves[i];
if (!shockwave->life)
continue;
@@ -836,7 +793,6 @@ namespace TEN::Renderer
r = shockwave->r * shockwave->life / 255.0f;
}
-
if (shockwave->sg < shockwave->g)
{
shockwave->sg += shockwave->g / 18;
@@ -847,7 +803,6 @@ namespace TEN::Renderer
g = shockwave->g * shockwave->life / 255.0f;
}
-
if (shockwave->sb < shockwave->b)
{
shockwave->sb += shockwave->b / 18;
@@ -916,7 +871,7 @@ namespace TEN::Renderer
g / 16.0f,
b / 16.0f,
1.0f),
- 0, 1, { 0,0 }, BlendMode::Additive, true, view);
+ 0, 1, Vector2::Zero, BlendMode::Additive, true, view);
}
else if (shockwave->style == (int)ShockwaveStyle::Knockback)
@@ -933,7 +888,7 @@ namespace TEN::Renderer
g / 16.0f,
b / 16.0f,
1.0f),
- 0, 1, { 0,0 }, BlendMode::Additive, true, view);
+ 0, 1, Vector2::Zero, BlendMode::Additive, true, view);
}
p1 = p2;
@@ -946,7 +901,7 @@ namespace TEN::Renderer
{
for (int i = 0; i < 32; i++)
{
- BLOOD_STRUCT* blood = &Blood[i];
+ auto* blood = &Blood[i];
if (blood->on)
{
@@ -962,16 +917,13 @@ namespace TEN::Renderer
Vector4::Lerp(
Vector4(blood->oldShade / 255.0f, blood->oldShade * 0, blood->oldShade * 0, 1.0f),
Vector4(blood->shade / 255.0f, blood->shade * 0, blood->shade * 0, 1.0f),
- _interpolationFactor
- ),
- TO_RAD(Lerp(blood->oldRotAng << 4, blood->rotAng << 4, _interpolationFactor)),
- 1.0f,
- {
- Lerp(blood->oldSize, blood->size, _interpolationFactor) * 8.0f,
- Lerp(blood->oldSize, blood->size, _interpolationFactor) * 8.0f },
- BlendMode::Additive,
- true,
- view);
+ _interpolationFactor),
+ TO_RAD(Lerp(blood->oldRotAng << 4, blood->rotAng << 4, _interpolationFactor)),
+ 1.0f,
+ Vector2(
+ Lerp(blood->oldSize, blood->size, _interpolationFactor) * 8.0f,
+ Lerp(blood->oldSize, blood->size, _interpolationFactor) * 8.0f),
+ BlendMode::Additive, true, view);
}
}
}
@@ -980,12 +932,12 @@ namespace TEN::Renderer
{
constexpr auto RAIN_WIDTH = 4.0f;
- for (auto& p : Weather.GetParticles())
+ for (const auto& part : Weather.GetParticles())
{
- if (!p.Enabled)
+ if (!part.Enabled)
continue;
- switch (p.Type)
+ switch (part.Type)
{
case WeatherType::None:
@@ -994,14 +946,10 @@ namespace TEN::Renderer
AddSpriteBillboard(
&_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_UNDERWATERDUST],
- Vector3::Lerp(p.PrevPosition, p.Position, _interpolationFactor),
- Vector4(1.0f, 1.0f, 1.0f, p.Transparency()),
- 0.0f,
- 1.0f,
- Vector2(Lerp(p.PrevSize, p.Size, _interpolationFactor)),
- BlendMode::Additive,
- true,
- view);
+ Vector3::Lerp(part.PrevPosition, part.Position, _interpolationFactor),
+ Color(1.0f, 1.0f, 1.0f, part.Transparency()),
+ 0.0f, 1.0f, Vector2(Lerp(part.PrevSize, part.Size, _interpolationFactor)),
+ BlendMode::Additive, true, view);
break;
@@ -1012,14 +960,10 @@ namespace TEN::Renderer
AddSpriteBillboard(
&_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_UNDERWATERDUST],
- Vector3::Lerp(p.PrevPosition, p.Position, _interpolationFactor),
- Vector4(1.0f, 1.0f, 1.0f, p.Transparency()),
- 0.0f,
- 1.0f,
- Vector2(Lerp(p.PrevSize, p.Size, _interpolationFactor)),
- BlendMode::Additive,
- true,
- view);
+ Vector3::Lerp(part.PrevPosition, part.Position, _interpolationFactor),
+ Color(1.0f, 1.0f, 1.0f, part.Transparency()),
+ 0.0f, 1.0f, Vector2(Lerp(part.PrevSize, part.Size, _interpolationFactor)),
+ BlendMode::Additive, true, view);
break;
@@ -1029,19 +973,15 @@ namespace TEN::Renderer
return;
Vector3 v;
- p.Velocity.Normalize(v);
+ part.Velocity.Normalize(v);
AddSpriteBillboardConstrained(
&_sprites[Objects[ID_DRIP_SPRITE].meshIndex],
- Vector3::Lerp(p.PrevPosition, p.Position, _interpolationFactor),
- Vector4(0.8f, 1.0f, 1.0f, p.Transparency()),
- 0.0f,
- 1.0f,
- Vector2(RAIN_WIDTH, Lerp(p.PrevSize, p.Size, _interpolationFactor)),
- BlendMode::Additive,
- -v,
- true,
- view);
+ Vector3::Lerp(part.PrevPosition, part.Position, _interpolationFactor),
+ Color(0.8f, 1.0f, 1.0f, part.Transparency()),
+ 0.0f, 1.0f,
+ Vector2(RAIN_WIDTH, Lerp(part.PrevSize, part.Size, _interpolationFactor)),
+ BlendMode::Additive, -v, true, view);
break;
}
@@ -1053,8 +993,8 @@ namespace TEN::Renderer
_context->VSSetShader(_vsStatics.Get(), nullptr, 0);
_context->PSSetShader(_psStatics.Get(), nullptr, 0);
- UINT stride = sizeof(Vertex);
- UINT offset = 0;
+ unsigned int stride = sizeof(Vertex);
+ unsigned int offset = 0;
_context->IASetVertexBuffers(0, 1, _moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
@@ -1178,8 +1118,8 @@ namespace TEN::Renderer
_context->VSSetShader(_vsStatics.Get(), nullptr, 0);
_context->PSSetShader(_psStatics.Get(), nullptr, 0);
- UINT stride = sizeof(Vertex);
- UINT offset = 0;
+ unsigned int stride = sizeof(Vertex);
+ unsigned int offset = 0;
_context->IASetVertexBuffers(0, 1, _moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
_context->IASetIndexBuffer(_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
@@ -1291,7 +1231,7 @@ namespace TEN::Renderer
Texture2D Renderer::CreateDefaultNormalTexture()
{
- std::vector data = { 128, 128, 255, 1 };
+ auto data = std::vector{ 128, 128, 255, 1 };
return Texture2D(_device.Get(), 1, 1, data.data());
}
@@ -1375,9 +1315,7 @@ namespace TEN::Renderer
for (int p = 0; p < passes; p++)
{
if (!SetupBlendModeAndAlphaTest(bucket.BlendMode, rendererPass, p))
- {
continue;
- }
BindTexture(TextureRegister::ColorMap, &std::get<0>(_moveablesTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp);
BindTexture(TextureRegister::NormalMap, &std::get<1>(_moveablesTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp);
@@ -1394,8 +1332,8 @@ namespace TEN::Renderer
_context->VSSetShader(_vsStatics.Get(), nullptr, 0);
_context->PSSetShader(_psStatics.Get(), nullptr, 0);
- UINT stride = sizeof(Vertex);
- UINT offset = 0;
+ unsigned int stride = sizeof(Vertex);
+ unsigned int offset = 0;
_context->IASetVertexBuffers(0, 1, _moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
_context->IASetIndexBuffer(_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
@@ -1415,8 +1353,6 @@ namespace TEN::Renderer
void Renderer::DrawDebris(RenderView& view, RendererPass rendererPass)
{
- std::vector vertices;
-
bool activeDebrisExist = false;
for (auto& deb : DebrisFragments)
{
@@ -1439,9 +1375,7 @@ namespace TEN::Renderer
if (deb.active)
{
if (!SetupBlendModeAndAlphaTest(deb.mesh.blendMode, rendererPass, 0))
- {
continue;
- }
if (deb.isStatic)
{
@@ -1513,15 +1447,12 @@ namespace TEN::Renderer
&_sprites[Objects[ID_SMOKE_SPRITES].meshIndex + smoke.sprite],
Vector3::Lerp(smoke.oldPosition, smoke.position, _interpolationFactor),
Vector4::Lerp(smoke.oldColor, smoke.color, _interpolationFactor),
- Lerp(smoke.oldRotation, smoke.rotation, _interpolationFactor),
- 1.0f,
- {
+ Lerp(smoke.oldRotation, smoke.rotation, _interpolationFactor),
+ 1.0f,
+ Vector2(
Lerp(smoke.oldSize, smoke.size, _interpolationFactor),
- Lerp(smoke.oldSize, smoke.size, _interpolationFactor)
- },
- BlendMode::AlphaBlend,
- true,
- view);
+ Lerp(smoke.oldSize, smoke.size, _interpolationFactor)),
+ BlendMode::AlphaBlend, true, view);
}
}
@@ -1534,20 +1465,18 @@ namespace TEN::Renderer
for (int i = 0; i < SparkParticles.size(); i++)
{
- SparkParticle& s = SparkParticles[i];
+ auto& s = SparkParticles[i];
if (!s.active) continue;
if (!CheckIfSlotExists(ID_SPARK_SPRITE, "Spark particle rendering"))
- {
return;
- }
- Vector3 oldVelocity;
+ Vector3 prevVelocity;
Vector3 velocity;
- s.oldVelocity.Normalize(oldVelocity);
+ s.oldVelocity.Normalize(prevVelocity);
s.velocity.Normalize(velocity);
- velocity = Vector3::Lerp(oldVelocity, velocity, _interpolationFactor);
+ velocity = Vector3::Lerp(prevVelocity, velocity, _interpolationFactor);
velocity.Normalize();
float normalizedLife = s.age / s.life;
@@ -1558,16 +1487,11 @@ namespace TEN::Renderer
&_sprites[Objects[ID_SPARK_SPRITE].meshIndex],
Vector3::Lerp(s.oldPos, s.pos, _interpolationFactor),
color,
- 0,
- 1,
- {
+ 0, 1,
+ Vector2(
s.width,
- s.height * height
- },
- BlendMode::Additive,
- -velocity,
- false,
- view);
+ s.height * height),
+ BlendMode::Additive, -velocity, false, view);
}
}
@@ -1578,25 +1502,22 @@ namespace TEN::Renderer
for (int i = 0; i < explosionParticles.size(); i++)
{
- ExplosionParticle& e = explosionParticles[i];
- if (!e.active) continue;
+ auto& exp = explosionParticles[i];
+ if (!exp.active) continue;
if (!CheckIfSlotExists(ID_EXPLOSION_SPRITES, "Explosion particles rendering"))
return;
AddSpriteBillboard(
- &_sprites[Objects[ID_EXPLOSION_SPRITES].meshIndex + e.sprite],
- Vector3::Lerp(e.oldPos, e.pos, _interpolationFactor),
- Vector4::Lerp(e.oldTint, e.tint, _interpolationFactor),
- Lerp(e.oldRotation, e.rotation, _interpolationFactor),
+ &_sprites[Objects[ID_EXPLOSION_SPRITES].meshIndex + exp.sprite],
+ Vector3::Lerp(exp.oldPos, exp.pos, _interpolationFactor),
+ Vector4::Lerp(exp.oldTint, exp.tint, _interpolationFactor),
+ Lerp(exp.oldRotation, exp.rotation, _interpolationFactor),
1.0f,
- {
- Lerp(e.oldSize, e.size, _interpolationFactor),
- Lerp(e.oldSize, e.size, _interpolationFactor)
- },
- BlendMode::Additive,
- true,
- view);
+ Vector2(
+ Lerp(exp.oldSize, exp.size, _interpolationFactor),
+ Lerp(exp.oldSize, exp.size, _interpolationFactor)),
+ BlendMode::Additive, true, view);
}
}
@@ -1604,26 +1525,22 @@ namespace TEN::Renderer
{
using namespace TEN::Effects;
- for (SimpleParticle& s : simpleParticles)
+ for (const auto& part : simpleParticles)
{
- if (!s.active) continue;
+ if (!part.active)
+ continue;
- if (!CheckIfSlotExists(s.sequence, "Particle rendering"))
+ if (!CheckIfSlotExists(part.sequence, "Particle rendering"))
continue;
AddSpriteBillboard(
- &_sprites[Objects[s.sequence].meshIndex + s.sprite],
- Vector3::Lerp(s.oldWorldPosition, s.worldPosition, _interpolationFactor),
- Vector4(1.0f),
- 0,
- 1.0f,
- {
- Lerp(s.oldSize, s.size, _interpolationFactor),
- Lerp(s.oldSize, s.size, _interpolationFactor) / 2
- },
- BlendMode::AlphaBlend,
- true,
- view);
+ &_sprites[Objects[part.sequence].meshIndex + part.sprite],
+ Vector3::Lerp(part.oldWorldPosition, part.worldPosition, _interpolationFactor),
+ Color(1.0f, 1.0f, 1.0f), 0, 1.0f,
+ Vector2(
+ Lerp(part.oldSize, part.size, _interpolationFactor),
+ Lerp(part.oldSize, part.size, _interpolationFactor) / 2),
+ BlendMode::AlphaBlend, true, view);
}
}
}
diff --git a/TombEngine/Renderer/RendererSprites.cpp b/TombEngine/Renderer/RendererSprites.cpp
index 28d3cc8ad..272b06884 100644
--- a/TombEngine/Renderer/RendererSprites.cpp
+++ b/TombEngine/Renderer/RendererSprites.cpp
@@ -39,7 +39,7 @@ namespace TEN::Renderer
void Renderer::AddSpriteBillboardConstrained(RendererSprite* sprite, const Vector3& pos, const Vector4& color, float orient2D,
float scale, Vector2 size, BlendMode blendMode, const Vector3& constrainAxis,
- bool softParticles, RenderView& view, SpriteRenderType renderType)
+ bool isSoft, RenderView& view, SpriteRenderType renderType)
{
if (scale <= 0.0f)
scale = 1.0f;
@@ -58,7 +58,7 @@ namespace TEN::Renderer
spr.Height = size.y;
spr.BlendMode = blendMode;
spr.ConstrainAxis = constrainAxis;
- spr.SoftParticle = softParticles;
+ spr.SoftParticle = isSoft;
spr.c1 = color;
spr.c2 = color;
spr.c3 = color;
From 460d2d9edbe96518084190b200395a25546291b4 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 8 May 2024 19:49:52 +1000
Subject: [PATCH 149/410] Add interpolation for pickup summary; more clean up
---
TombEngine/Game/Hud/PickupSummary.cpp | 2 ++
TombEngine/Game/Hud/PickupSummary.h | 13 +++++++++
TombEngine/Renderer/RendererDraw.cpp | 33 ++++++++++------------
TombEngine/Renderer/RendererDrawEffect.cpp | 10 ++-----
TombEngine/Renderer/RendererDrawMenu.cpp | 7 ++++-
TombEngine/Renderer/RendererSprites.cpp | 23 ++++-----------
6 files changed, 45 insertions(+), 43 deletions(-)
diff --git a/TombEngine/Game/Hud/PickupSummary.cpp b/TombEngine/Game/Hud/PickupSummary.cpp
index bc816aafc..137d54233 100644
--- a/TombEngine/Game/Hud/PickupSummary.cpp
+++ b/TombEngine/Game/Hud/PickupSummary.cpp
@@ -39,6 +39,8 @@ namespace TEN::Hud
constexpr auto ROT_RATE = ANGLE(360.0f / (LIFE_MAX * FPS));
constexpr auto ROT = EulerAngles(0, ROT_RATE, 0);
+ StoreInterpolationData();
+
// Move offscreen.
if (Life <= 0.0f && isHead)
{
diff --git a/TombEngine/Game/Hud/PickupSummary.h b/TombEngine/Game/Hud/PickupSummary.h
index a1c0b012f..6a68d50b5 100644
--- a/TombEngine/Game/Hud/PickupSummary.h
+++ b/TombEngine/Game/Hud/PickupSummary.h
@@ -25,8 +25,21 @@ namespace TEN::Hud
float StringScale = 0.0f;
float StringScalar = 0.0f;
+ Vector2 PrevPosition = Vector2::Zero;
+ EulerAngles PrevOrientation = EulerAngles::Identity;
+ float PrevScale = 0.0f;
+ float PrevOpacity = 0.0f;
+
bool IsOffscreen() const;
void Update(bool isHead);
+
+ void StoreInterpolationData()
+ {
+ PrevPosition = Position;
+ PrevOrientation = Orientation;
+ PrevScale = Scale;
+ PrevOpacity = Opacity;
+ }
};
class PickupSummaryController
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index 2af4157dd..2ce60496a 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -1714,7 +1714,7 @@ namespace TEN::Renderer
PrepareLaserBarriers(view);
PrepareSingleLaserBeam(view);
- // Sprites grouped in buckets for instancing. Non-commutative sprites are collected for a later stage.
+ // Sprites grouped in buckets for instancing. Non-commutative sprites are collected at a later stage.
SortAndPrepareSprites(view);
auto time2 = std::chrono::high_resolution_clock::now();
@@ -1726,7 +1726,7 @@ namespace TEN::Renderer
SetDepthState(DepthState::Write, true);
SetCullMode(CullMode::CounterClockwise, true);
- // Bind constant buffers
+ // Bind constant buffers.
BindConstantBufferVS(ConstantBufferRegister::Camera, _cbCameraMatrices.get());
BindConstantBufferVS(ConstantBufferRegister::Item, _cbItem.get());
BindConstantBufferVS(ConstantBufferRegister::InstancedStatics, _cbInstancedStaticMeshBuffer.get());
@@ -1763,7 +1763,7 @@ namespace TEN::Renderer
_context->ClearRenderTargetView(_renderTarget.RenderTargetView.Get(), _debugPage == RendererDebugPage::WireframeMode ? Colors::White : Colors::Black);
_context->ClearDepthStencilView(_renderTarget.DepthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
- // Reset viewport and scissor
+ // Reset viewport and scissor.
_context->RSSetViewports(1, &view.Viewport);
ResetScissor();
@@ -1812,7 +1812,7 @@ namespace TEN::Renderer
// Draw horizon and sky.
DrawHorizonAndSky(view, _renderTarget.DepthStencilView.Get());
- // Build G-Buffer (Normals + Depth).
+ // Build G-Buffer (normals + depth).
_context->ClearRenderTargetView(_normalsRenderTarget.RenderTargetView.Get(), Colors::Black);
_context->ClearRenderTargetView(_depthRenderTarget.RenderTargetView.Get(), Colors::White);
@@ -1831,7 +1831,7 @@ namespace TEN::Renderer
DrawRats(view, RendererPass::GBuffer);
DrawLocusts(view, RendererPass::GBuffer);
- // Calculate ambient occlusion
+ // Calculate ambient occlusion.
if (g_Configuration.EnableAmbientOcclusion)
{
_doingFullscreenPass = true;
@@ -1849,8 +1849,7 @@ namespace TEN::Renderer
_context->RSSetViewports(1, &view.Viewport);
ResetScissor();
- // Bind main render target again.
- // At this point, main depth buffer is already filled and avoids overdraw in following steps.
+ // Bind main render target again. Main depth buffer is already filled and avoids overdraw in following steps.
_context->OMSetRenderTargets(1, _renderTarget.RenderTargetView.GetAddressOf(), _renderTarget.DepthStencilView.Get());
// Draw opaque, alpha test, and fast alpha blend faces.
@@ -1883,7 +1882,7 @@ namespace TEN::Renderer
DrawFishSwarm(view, RendererPass::Additive);
// Collect all non-commutative transparent faces.
- // NOTE: Sorted sprites are already collected at the beginning of the frame.
+ // NOTE: Sorted sprites already collected at beginning of frame.
DrawRooms(view, RendererPass::CollectTransparentFaces);
DrawItems(view, RendererPass::CollectTransparentFaces);
DrawStatics(view, RendererPass::CollectTransparentFaces);
@@ -1896,11 +1895,11 @@ namespace TEN::Renderer
// Draw sorted faces.
DrawSortedFaces(view);
- // HACK: Draw gunflashes after everything because they are very near the camera.
+ // HACK: Gunflashes drawn after everything because they are very near the camera.
DrawGunFlashes(view);
DrawBaddyGunflashes(view);
- // Draw 3D debug lines and trianges.
+ // Draw 3D debug lines and triangles.
DrawLines3D(view);
DrawTriangles3D(view);
@@ -2000,7 +1999,7 @@ namespace TEN::Renderer
SetCullMode(CullMode::Clockwise);
}
- RenderView view = RenderView(&Camera, 0, PI / 2.0f, 32, DEFAULT_FAR_VIEW, ROOM_AMBIENT_MAP_SIZE, ROOM_AMBIENT_MAP_SIZE);
+ auto view = RenderView(&Camera, 0, PI / 2.0f, 32, DEFAULT_FAR_VIEW, ROOM_AMBIENT_MAP_SIZE, ROOM_AMBIENT_MAP_SIZE);
CCameraMatrixBuffer cameraConstantBuffer;
cameraConstantBuffer.DualParaboloidView = Matrix::CreateLookAt(position, position + Vector3(0, 0, 1024), -Vector3::UnitY);
@@ -2016,12 +2015,10 @@ namespace TEN::Renderer
_context->VSSetShader(_vsRoomAmbientSky.Get(), nullptr, 0);
if (Lara.Control.Look.OpticRange != 0)
- {
AlterFOV(ANGLE(DEFAULT_FOV) - Lara.Control.Look.OpticRange, false);
- }
- UINT stride = sizeof(Vertex);
- UINT offset = 0;
+ unsigned int stride = sizeof(Vertex);
+ unsigned int offset = 0;
// Draw sky.
auto rotation = Matrix::CreateRotationX(PI);
@@ -2220,13 +2217,13 @@ namespace TEN::Renderer
void Renderer::DrawItems(RenderView& view, RendererPass rendererPass)
{
- UINT stride = sizeof(Vertex);
- UINT offset = 0;
+ unsigned int stride = sizeof(Vertex);
+ unsigned int offset = 0;
_context->IASetVertexBuffers(0, 1, _moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
_context->IASetIndexBuffer(_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
- // Set shaders
+ // Set shaders.
if (rendererPass == RendererPass::GBuffer)
{
_context->VSSetShader(_vsGBufferItems.Get(), nullptr, 0);
diff --git a/TombEngine/Renderer/RendererDrawEffect.cpp b/TombEngine/Renderer/RendererDrawEffect.cpp
index 34bbb36c5..6cbcbd011 100644
--- a/TombEngine/Renderer/RendererDrawEffect.cpp
+++ b/TombEngine/Renderer/RendererDrawEffect.cpp
@@ -1300,17 +1300,13 @@ namespace TEN::Renderer
BindStaticLights(effect->LightsToDraw);
_cbStatic.UpdateData(_stStatic, _context.Get());
- auto* meshPtr = effect->Mesh;
- auto m_lastBlendMode = BlendMode::Unknown;
-
- for (auto& bucket : meshPtr->Buckets)
+ auto& mesh = *effect->Mesh;
+ for (auto& bucket : mesh.Buckets)
{
if (bucket.NumVertices == 0)
- {
continue;
- }
- int passes = rendererPass == RendererPass::Opaque && bucket.BlendMode == BlendMode::AlphaTest ? 2 : 1;
+ int passes = (rendererPass == RendererPass::Opaque && bucket.BlendMode == BlendMode::AlphaTest) ? 2 : 1;
for (int p = 0; p < passes; p++)
{
diff --git a/TombEngine/Renderer/RendererDrawMenu.cpp b/TombEngine/Renderer/RendererDrawMenu.cpp
index f38ba9add..69dfe4271 100644
--- a/TombEngine/Renderer/RendererDrawMenu.cpp
+++ b/TombEngine/Renderer/RendererDrawMenu.cpp
@@ -718,8 +718,13 @@ namespace TEN::Renderer
constexpr auto COUNT_STRING_INF = "Inf";
constexpr auto COUNT_STRING_OFFSET = Vector2(DISPLAY_SPACE_RES.x / 40, 0.0f);
+ auto pos = Vector2::Lerp(pickup.PrevPosition, pickup.Position, _interpolationFactor);
+ auto orient = EulerAngles::Lerp(pickup.PrevOrientation, pickup.Orientation, _interpolationFactor);
+ float scale = Lerp(pickup.PrevScale, pickup.Scale, _interpolationFactor);
+ float opacity = Lerp(pickup.PrevOpacity, pickup.Opacity, _interpolationFactor);
+
// Draw display pickup.
- DrawObjectIn2DSpace(pickup.ObjectID, pickup.Position, pickup.Orientation, pickup.Scale);
+ DrawObjectIn2DSpace(pickup.ObjectID, pos, orient, scale);
// Draw count string.
if (pickup.Count != 1)
diff --git a/TombEngine/Renderer/RendererSprites.cpp b/TombEngine/Renderer/RendererSprites.cpp
index 272b06884..417155097 100644
--- a/TombEngine/Renderer/RendererSprites.cpp
+++ b/TombEngine/Renderer/RendererSprites.cpp
@@ -39,7 +39,7 @@ namespace TEN::Renderer
void Renderer::AddSpriteBillboardConstrained(RendererSprite* sprite, const Vector3& pos, const Vector4& color, float orient2D,
float scale, Vector2 size, BlendMode blendMode, const Vector3& constrainAxis,
- bool isSoft, RenderView& view, SpriteRenderType renderType)
+ bool isSoftParticle, RenderView& view, SpriteRenderType renderType)
{
if (scale <= 0.0f)
scale = 1.0f;
@@ -58,7 +58,7 @@ namespace TEN::Renderer
spr.Height = size.y;
spr.BlendMode = blendMode;
spr.ConstrainAxis = constrainAxis;
- spr.SoftParticle = isSoft;
+ spr.SoftParticle = isSoftParticle;
spr.c1 = color;
spr.c2 = color;
spr.c3 = color;
@@ -259,24 +259,17 @@ namespace TEN::Renderer
void Renderer::DrawSprites(RenderView& view, RendererPass rendererPass)
{
if (view.SpritesToDraw.empty())
- {
return;
- }
- // Draw instanced sprites
+ // Draw instanced sprites.
bool wasGPUSet = false;
-
for (auto& spriteBucket : _spriteBuckets)
{
if (spriteBucket.SpritesToDraw.size() == 0 || !spriteBucket.IsBillboard)
- {
continue;
- }
if (!SetupBlendModeAndAlphaTest(spriteBucket.BlendMode, rendererPass, 0))
- {
continue;
- }
if (!wasGPUSet)
{
@@ -291,8 +284,8 @@ namespace TEN::Renderer
_context->PSSetShader(_psInstancedSprites.Get(), nullptr, 0);
// Set up vertex buffer and parameters.
- UINT stride = sizeof(Vertex);
- UINT offset = 0;
+ unsigned int stride = sizeof(Vertex);
+ unsigned int offset = 0;
_context->IASetVertexBuffers(0, 1, _quadVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
wasGPUSet = true;
@@ -329,20 +322,16 @@ namespace TEN::Renderer
_numInstancedSpritesDrawCalls++;
}
- // Draw 3D non instanced sprites
+ // Draw 3D non-instanced sprites.
wasGPUSet = false;
for (auto& spriteBucket : _spriteBuckets)
{
if (spriteBucket.SpritesToDraw.empty() || spriteBucket.IsBillboard)
- {
continue;
- }
if (!SetupBlendModeAndAlphaTest(spriteBucket.BlendMode, rendererPass, 0))
- {
continue;
- }
if (!wasGPUSet)
{
From 272db667727614c906e396931774b4e7cb0c63ca Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 8 May 2024 20:37:41 +1000
Subject: [PATCH 150/410] Interpolate crosshairs (partial solution)
---
TombEngine/Game/Hud/PickupSummary.cpp | 5 ++++-
TombEngine/Game/Hud/TargetHighlighter.cpp | 22 ++++++++++++++++------
TombEngine/Game/Hud/TargetHighlighter.h | 15 +++++++++++++++
TombEngine/Game/gui.cpp | 2 +-
TombEngine/Renderer/Renderer.h | 14 ++++++++------
TombEngine/Renderer/RendererDraw.cpp | 12 ++++++------
TombEngine/Renderer/RendererDrawMenu.cpp | 14 +++++++-------
TombEngine/Renderer/RendererHelper.cpp | 5 +++++
8 files changed, 62 insertions(+), 27 deletions(-)
diff --git a/TombEngine/Game/Hud/PickupSummary.cpp b/TombEngine/Game/Hud/PickupSummary.cpp
index 137d54233..810226208 100644
--- a/TombEngine/Game/Hud/PickupSummary.cpp
+++ b/TombEngine/Game/Hud/PickupSummary.cpp
@@ -215,7 +215,10 @@ namespace TEN::Hud
_displayPickups.erase(
std::remove_if(
_displayPickups.begin(), _displayPickups.end(),
- [](const DisplayPickup& pickup) { return ((pickup.Life <= 0.0f) && pickup.IsOffscreen()); }),
+ [](const DisplayPickup& pickup)
+ {
+ return ((pickup.Life <= 0.0f) && pickup.IsOffscreen());
+ }),
_displayPickups.end());
}
diff --git a/TombEngine/Game/Hud/TargetHighlighter.cpp b/TombEngine/Game/Hud/TargetHighlighter.cpp
index 166dc66a8..cd52b5825 100644
--- a/TombEngine/Game/Hud/TargetHighlighter.cpp
+++ b/TombEngine/Game/Hud/TargetHighlighter.cpp
@@ -74,6 +74,9 @@ namespace TEN::Hud
constexpr auto ORIENT_LERP_ALPHA = 0.1f;
constexpr auto RADIUS_LERP_ALPHA = 0.2f;
+ if (Position.has_value())
+ StoreInterpolationData();
+
// Update active status.
IsActive = isActive;
@@ -137,23 +140,30 @@ namespace TEN::Hud
if (!Position.has_value())
return;
+ auto pos0 = Vector2::Lerp(*Position, PrevPosition, g_Renderer.GetInterpolationFactor());
+ short orient0 = (short)Lerp(PrevOrientation, Orientation, g_Renderer.GetInterpolationFactor()); // TODO: use Geometry::GetShortestAngle()
+ float scale = Lerp(PrevScale, Scale, g_Renderer.GetInterpolationFactor());
+ auto color = Color::Lerp(PrevColor, Color, g_Renderer.GetInterpolationFactor());
+
// Draw main static element.
AddDisplaySprite(
SPRITE_SEQUENCE_OBJECT_ID, STATIC_ELEMENT_SPRITE_ID,
- *Position, Orientation, Vector2(Scale), Color,
+ pos0, orient0, Vector2(scale), color,
PRIORITY, DisplaySpriteAlignMode::Center, DisplaySpriteScaleMode::Fill,
BlendMode::Additive, DisplaySpritePhase::Draw);
// Draw animated outer segment elements.
- for (const auto& segment : Segments)
+ for (int i = 0; i < Segments.size(); i++)
{
- auto pos = *Position + segment.PosOffset;
- short orient = Orientation + segment.OrientOffset;
- auto scale = Vector2(Scale / 2);
+ const auto& segment = Segments[i];
+ const auto& prevSegment = PrevSegments[i];
+
+ auto pos1 = pos0 + Vector2::Lerp(prevSegment.PosOffset, segment.PosOffset, g_Renderer.GetInterpolationFactor());
+ short orient1 = orient0 + (short)Lerp(prevSegment.OrientOffset, segment.OrientOffset, g_Renderer.GetInterpolationFactor()); // TODO: use Geometry::GetShortestAngle()
AddDisplaySprite(
SPRITE_SEQUENCE_OBJECT_ID, SEGMENT_ELEMENT_SPRITE_ID,
- pos, orient, scale, Color,
+ pos1, orient1, Vector2(scale / 2), color,
PRIORITY, DisplaySpriteAlignMode::Center, DisplaySpriteScaleMode::Fill,
BlendMode::Additive, DisplaySpritePhase::Draw);
}
diff --git a/TombEngine/Game/Hud/TargetHighlighter.h b/TombEngine/Game/Hud/TargetHighlighter.h
index b62c5b3df..9108137b4 100644
--- a/TombEngine/Game/Hud/TargetHighlighter.h
+++ b/TombEngine/Game/Hud/TargetHighlighter.h
@@ -46,6 +46,21 @@ namespace TEN::Hud
// Utilities
void Update(const Vector3& targetPos, bool isActive, bool doPulse);
void Draw() const;
+
+ Vector2 PrevPosition = Vector2::Zero;
+ short PrevOrientation = 0;
+ float PrevScale = 0.0f;
+ Vector4 PrevColor = Vector4::Zero;
+ std::array PrevSegments = {};
+
+ void StoreInterpolationData()
+ {
+ PrevPosition = *Position;
+ PrevOrientation = Orientation;
+ PrevScale = Scale;
+ PrevColor = Color;
+ PrevSegments = Segments;
+ }
};
class TargetHighlighterController
diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp
index 7767da684..45162341c 100644
--- a/TombEngine/Game/gui.cpp
+++ b/TombEngine/Game/gui.cpp
@@ -3448,7 +3448,7 @@ namespace TEN::Gui
needleOrient.Lerp(EulerAngles(0, item->Pose.Orientation.y, 0), LERP_ALPHA);
float wibble = std::sin(((float)(GameTimer & 0x3F) / (float)0x3F) * PI_MUL_2);
- this->CompassNeedleAngle = needleOrient.y + ANGLE(wibble);
+ CompassNeedleAngle = needleOrient.y + ANGLE(wibble);
// HACK: Needle is rotated in the draw function.
const auto& invObject = InventoryObjectTable[INV_OBJECT_COMPASS];
diff --git a/TombEngine/Renderer/Renderer.h b/TombEngine/Renderer/Renderer.h
index 527c7a33d..6890825d0 100644
--- a/TombEngine/Renderer/Renderer.h
+++ b/TombEngine/Renderer/Renderer.h
@@ -377,7 +377,7 @@ namespace TEN::Renderer
VertexBuffer _sortedPolygonsVertexBuffer;
IndexBuffer _sortedPolygonsIndexBuffer;
- // Used for variable framerate
+ // Variable framerate.
float _interpolationFactor = 0.0f;
// Private functions
@@ -587,8 +587,8 @@ namespace TEN::Renderer
void DrawBar(float percent, const RendererHudBar& bar, GAME_OBJECT_ID textureSlot, int frame, bool poison);
void Create();
void Initialize(int w, int h, bool windowed, HWND handle);
- void Render(float interpolationFactor);
- void RenderTitle(float interpolationFactor);
+ void Render(float interpFactor);
+ void RenderTitle(float interpFactor);
void Lock();
bool PrepareDataForTheRenderer();
void UpdateCameraMatrices(CAMERA_INFO* cam, float roll, float fov, float farView);
@@ -641,9 +641,11 @@ namespace TEN::Renderer
void SetTextureOrDefault(Texture2D& texture, std::wstring path);
std::string GetDefaultAdapterName();
void SaveOldState();
- Vector2i GetScreenResolution() const;
- std::optional Get2DPosition(const Vector3& pos) const;
- Vector3 GetAbsEntityBonePosition(int itemNumber, int jointIndex, const Vector3& relOffset = Vector3::Zero);
+
+ float GetInterpolationFactor() const;
+ Vector2i GetScreenResolution() const;
+ std::optional Get2DPosition(const Vector3& pos) const;
+ Vector3 GetAbsEntityBonePosition(int itemNumber, int jointIndex, const Vector3& relOffset = Vector3::Zero);
std::pair GetRay(const Vector2& pos) const;
void AddDisplaySprite(const RendererSprite& sprite, const Vector2& pos2D, short orient, const Vector2& size, const Vector4& color,
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index 2ce60496a..8b131c80e 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -3074,15 +3074,15 @@ namespace TEN::Renderer
SetCullMode(CullMode::CounterClockwise);
}
- void Renderer::Render(float interpolationFactor)
+ void Renderer::Render(float interpFactor)
{
//RenderToCubemap(reflectionCubemap, Vector3(LaraItem->pos.xPos, LaraItem->pos.yPos - 1024, LaraItem->pos.zPos), LaraItem->roomNumber);
// Interpolate camera.
- _gameCamera.Camera.WorldPosition = Vector3::Lerp(_oldGameCamera.Camera.WorldPosition, _currentGameCamera.Camera.WorldPosition, interpolationFactor);
- _gameCamera.Camera.WorldDirection = Vector3::Lerp(_oldGameCamera.Camera.WorldDirection, _currentGameCamera.Camera.WorldDirection, interpolationFactor);
- _gameCamera.Camera.View = Matrix::Lerp(_oldGameCamera.Camera.View, _currentGameCamera.Camera.View, interpolationFactor);
- _gameCamera.Camera.Projection = Matrix::Lerp(_oldGameCamera.Camera.Projection, _currentGameCamera.Camera.Projection, interpolationFactor);
+ _gameCamera.Camera.WorldPosition = Vector3::Lerp(_oldGameCamera.Camera.WorldPosition, _currentGameCamera.Camera.WorldPosition, interpFactor);
+ _gameCamera.Camera.WorldDirection = Vector3::Lerp(_oldGameCamera.Camera.WorldDirection, _currentGameCamera.Camera.WorldDirection, interpFactor);
+ _gameCamera.Camera.View = Matrix::Lerp(_oldGameCamera.Camera.View, _currentGameCamera.Camera.View, interpFactor);
+ _gameCamera.Camera.Projection = Matrix::Lerp(_oldGameCamera.Camera.Projection, _currentGameCamera.Camera.Projection, interpFactor);
_gameCamera.Camera.ViewProjection = _gameCamera.Camera.View * _gameCamera.Camera.Projection;
_gameCamera.Camera.FOV = _currentGameCamera.Camera.FOV;
_gameCamera.Camera.Frustum=_currentGameCamera.Camera.Frustum;
@@ -3091,7 +3091,7 @@ namespace TEN::Renderer
_gameCamera.Camera.NearPlane = _currentGameCamera.Camera.NearPlane;
_gameCamera.Camera.FarPlane = _currentGameCamera.Camera.FarPlane;
- _interpolationFactor = interpolationFactor;
+ _interpolationFactor = interpFactor;
RenderScene(&_backBuffer, true, _gameCamera);
diff --git a/TombEngine/Renderer/RendererDrawMenu.cpp b/TombEngine/Renderer/RendererDrawMenu.cpp
index 69dfe4271..8ac86c306 100644
--- a/TombEngine/Renderer/RendererDrawMenu.cpp
+++ b/TombEngine/Renderer/RendererDrawMenu.cpp
@@ -729,7 +729,7 @@ namespace TEN::Renderer
// Draw count string.
if (pickup.Count != 1)
{
- auto countString = (pickup.Count != -1) ? std::to_string(pickup.Count) : COUNT_STRING_INF;
+ auto countString = (pickup.Count != NO_VALUE) ? std::to_string(pickup.Count) : COUNT_STRING_INF;
auto countStringPos = pickup.Position + COUNT_STRING_OFFSET;
AddString(countString, countStringPos, Color(PRINTSTRING_COLOR_WHITE), pickup.StringScale, SF());
@@ -1118,12 +1118,12 @@ namespace TEN::Renderer
_swapChain->Present(1, 0);
}
- void Renderer::RenderTitle(float interpolationFactor)
+ void Renderer::RenderTitle(float interpFactor)
{
- _gameCamera.Camera.WorldPosition = Vector3::Lerp(_oldGameCamera.Camera.WorldPosition, _currentGameCamera.Camera.WorldPosition, interpolationFactor);
- _gameCamera.Camera.WorldDirection = Vector3::Lerp(_oldGameCamera.Camera.WorldDirection, _currentGameCamera.Camera.WorldDirection, interpolationFactor);
- _gameCamera.Camera.View = Matrix::Lerp(_oldGameCamera.Camera.View, _currentGameCamera.Camera.View, interpolationFactor);
- _gameCamera.Camera.Projection = Matrix::Lerp(_oldGameCamera.Camera.Projection, _currentGameCamera.Camera.Projection, interpolationFactor);
+ _gameCamera.Camera.WorldPosition = Vector3::Lerp(_oldGameCamera.Camera.WorldPosition, _currentGameCamera.Camera.WorldPosition, interpFactor);
+ _gameCamera.Camera.WorldDirection = Vector3::Lerp(_oldGameCamera.Camera.WorldDirection, _currentGameCamera.Camera.WorldDirection, interpFactor);
+ _gameCamera.Camera.View = Matrix::Lerp(_oldGameCamera.Camera.View, _currentGameCamera.Camera.View, interpFactor);
+ _gameCamera.Camera.Projection = Matrix::Lerp(_oldGameCamera.Camera.Projection, _currentGameCamera.Camera.Projection, interpFactor);
_gameCamera.Camera.ViewProjection = _gameCamera.Camera.View * _gameCamera.Camera.Projection;
_gameCamera.Camera.FOV = _currentGameCamera.Camera.FOV;
_gameCamera.Camera.Frustum = _currentGameCamera.Camera.Frustum;
@@ -1132,7 +1132,7 @@ namespace TEN::Renderer
_gameCamera.Camera.NearPlane = _currentGameCamera.Camera.NearPlane;
_gameCamera.Camera.FarPlane = _currentGameCamera.Camera.FarPlane;
- _interpolationFactor = interpolationFactor;
+ _interpolationFactor = interpFactor;
RenderScene(&_dumpScreenRenderTarget, false, _gameCamera);
diff --git a/TombEngine/Renderer/RendererHelper.cpp b/TombEngine/Renderer/RendererHelper.cpp
index 4ef1310fc..7a0ae86c7 100644
--- a/TombEngine/Renderer/RendererHelper.cpp
+++ b/TombEngine/Renderer/RendererHelper.cpp
@@ -519,6 +519,11 @@ namespace TEN::Renderer
return s;
}
+ float Renderer::GetInterpolationFactor() const
+ {
+ return _interpolationFactor;
+ }
+
Vector2i Renderer::GetScreenResolution() const
{
return Vector2i(_screenWidth, _screenHeight);
From c398f4ae58c34a3b743c023e404c593afaa8798d Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 8 May 2024 20:46:17 +1000
Subject: [PATCH 151/410] Prepare interpolation data for speedometer
---
TombEngine/Game/Hud/Speedometer.cpp | 4 ++++
TombEngine/Game/Hud/Speedometer.h | 9 +++++++++
2 files changed, 13 insertions(+)
diff --git a/TombEngine/Game/Hud/Speedometer.cpp b/TombEngine/Game/Hud/Speedometer.cpp
index dbfa3044d..cc3d0fe69 100644
--- a/TombEngine/Game/Hud/Speedometer.cpp
+++ b/TombEngine/Game/Hud/Speedometer.cpp
@@ -30,6 +30,8 @@ namespace TEN::Hud
return;
}
+ StoreInterpolationData();
+
// Update life and updated value status.
_life = std::clamp(_life + (_hasValueUpdated ? 1.0f : -1.0f), 0.0f, LIFE_MAX * FPS);
_hasValueUpdated = false;
@@ -58,6 +60,8 @@ namespace TEN::Hud
if (_life <= 0.0f)
return;
+ // TODO: Interpolation.
+
auto color = Color(1.0f, 1.0f, 1.0f, _opacity);
// Draw dial.
diff --git a/TombEngine/Game/Hud/Speedometer.h b/TombEngine/Game/Hud/Speedometer.h
index 164d652a2..bcc770234 100644
--- a/TombEngine/Game/Hud/Speedometer.h
+++ b/TombEngine/Game/Hud/Speedometer.h
@@ -16,6 +16,15 @@ namespace TEN::Hud
float _opacity = 0.0f;
float _life = 0.0f;
+ short _prevPointerAngle = 0;
+ float _prevOpacity = 0.0f;
+
+ void StoreInterpolationData()
+ {
+ _prevPointerAngle = _pointerAngle;
+ _prevOpacity = _opacity;
+ }
+
public:
// Utilities
void UpdateValue(float value);
From ce723b5a7eaa18b8a0ab479df9f88d6c354f2ede Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 8 May 2024 22:59:14 +1000
Subject: [PATCH 152/410] Clean up more effects
---
TombEngine/Game/effects/Streamer.cpp | 5 +-
TombEngine/Game/effects/Streamer.h | 11 ++--
TombEngine/Game/effects/debris.h | 5 +-
TombEngine/Game/effects/drip.h | 20 +++---
TombEngine/Game/effects/hair.cpp | 6 +-
TombEngine/Game/effects/hair.h | 8 +--
TombEngine/Game/effects/simple_particle.cpp | 70 +++++++++++----------
TombEngine/Game/effects/simple_particle.h | 8 +--
TombEngine/Game/effects/smoke.h | 16 ++---
TombEngine/Game/effects/spark.h | 8 +--
TombEngine/Renderer/RendererDrawEffect.cpp | 32 +++++-----
TombEngine/Renderer/RendererLara.cpp | 4 +-
12 files changed, 99 insertions(+), 94 deletions(-)
diff --git a/TombEngine/Game/effects/Streamer.cpp b/TombEngine/Game/effects/Streamer.cpp
index 8e346db3d..0a77723b6 100644
--- a/TombEngine/Game/effects/Streamer.cpp
+++ b/TombEngine/Game/effects/Streamer.cpp
@@ -192,7 +192,10 @@ namespace TEN::Effects::Streamer
pool.erase(
std::remove_if(
pool.begin(), pool.end(),
- [](const auto& streamer) { return streamer.Segments.empty(); }),
+ [](const auto& streamer)
+ {
+ return streamer.Segments.empty();
+ }),
pool.end());
}
diff --git a/TombEngine/Game/effects/Streamer.h b/TombEngine/Game/effects/Streamer.h
index 39db32d22..57df932d2 100644
--- a/TombEngine/Game/effects/Streamer.h
+++ b/TombEngine/Game/effects/Streamer.h
@@ -9,10 +9,9 @@ namespace TEN::Effects::Streamer
{
enum class StreamerFlags
{
- FadeLeft = (1 << 0),
- FadeRight = (1 << 1),
-
- BlendModeAdditive = (1 << 2)
+ FadeLeft = 1 << 0,
+ FadeRight = 1 << 1,
+ BlendModeAdditive = 1 << 2
};
class Streamer
@@ -39,8 +38,8 @@ namespace TEN::Effects::Streamer
std::array Vertices = {};
- std::array PrevVertices = {};
Vector4 PrevColor = Vector4::Zero;
+ std::array PrevVertices = {};
void InitializeVertices(const Vector3& pos, float width);
void Update();
@@ -50,9 +49,9 @@ namespace TEN::Effects::Streamer
void StoreInterpolationData()
{
+ PrevColor = Color;
PrevVertices[0] = Vertices[0];
PrevVertices[1] = Vertices[1];
- PrevColor = Color;
}
};
diff --git a/TombEngine/Game/effects/debris.h b/TombEngine/Game/effects/debris.h
index 513d096ed..bffb68871 100644
--- a/TombEngine/Game/effects/debris.h
+++ b/TombEngine/Game/effects/debris.h
@@ -71,11 +71,12 @@ struct DebrisFragment
bool active;
bool isStatic;
Matrix Transform;
- Matrix OldTransform;
+
+ Matrix PrevTransform = Matrix::Identity;
void StoreInterpolationData()
{
- OldTransform = Transform;
+ PrevTransform = Transform;
}
};
diff --git a/TombEngine/Game/effects/drip.h b/TombEngine/Game/effects/drip.h
index bb6946ab1..31c428a74 100644
--- a/TombEngine/Game/effects/drip.h
+++ b/TombEngine/Game/effects/drip.h
@@ -16,19 +16,19 @@ namespace TEN::Effects::Drip
float LifeMax = 0.0f;
float Gravity = 0.0f;
- Vector3 OldPosition = Vector3::Zero;
- Vector4 OldColor = Vector4::Zero;
- Vector2 OldSize = Vector2::Zero;
- float OldLife = 0.0f;
- Vector3 OldVelocity = Vector3::Zero;
+ Vector3 PrevPosition = Vector3::Zero;
+ Vector3 PrevVelocity = Vector3::Zero;
+ Vector2 PrevSize = Vector2::Zero;
+ Vector4 PrevColor = Vector4::Zero;
+ float PrevLife = 0.0f;
void StoreInterpolationData()
{
- OldPosition = Position;
- OldColor = Color;
- OldSize = Size;
- OldLife = Life;
- OldVelocity = Velocity;
+ PrevPosition = Position;
+ PrevColor = Color;
+ PrevSize = Size;
+ PrevLife = Life;
+ PrevVelocity = Velocity;
}
};
diff --git a/TombEngine/Game/effects/hair.cpp b/TombEngine/Game/effects/hair.cpp
index 20576a9fd..1d633a849 100644
--- a/TombEngine/Game/effects/hair.cpp
+++ b/TombEngine/Game/effects/hair.cpp
@@ -25,10 +25,8 @@ namespace TEN::Effects::Hair
void HairUnit::Update(const ItemInfo& item, int hairUnitIndex)
{
- for (int i = 0; i < Segments.size(); i++)
- {
- Segments[i].StoreInterpolationData();
- }
+ for (auto& segment : Segments)
+ segment.StoreInterpolationData();
const auto& player = GetLaraInfo(item);
diff --git a/TombEngine/Game/effects/hair.h b/TombEngine/Game/effects/hair.h
index dde5d3b3c..1e89aa3b3 100644
--- a/TombEngine/Game/effects/hair.h
+++ b/TombEngine/Game/effects/hair.h
@@ -16,13 +16,13 @@ namespace TEN::Effects::Hair
Vector3 Velocity = Vector3::Zero;
Quaternion Orientation = Quaternion::Identity;
- Vector3 OldPosition = Vector3::Zero;
- Quaternion OldOrientation = Quaternion::Identity;
+ Vector3 PrevPosition = Vector3::Zero;
+ Quaternion PrevOrientation = Quaternion::Identity;
void StoreInterpolationData()
{
- OldPosition = Position;
- OldOrientation = Orientation;
+ PrevPosition = Position;
+ PrevOrientation = Orientation;
}
};
diff --git a/TombEngine/Game/effects/simple_particle.cpp b/TombEngine/Game/effects/simple_particle.cpp
index 867f0da63..850c1b98b 100644
--- a/TombEngine/Game/effects/simple_particle.cpp
+++ b/TombEngine/Game/effects/simple_particle.cpp
@@ -13,9 +13,11 @@ namespace TEN::Effects
SimpleParticle& GetFreeSimpleParticle()
{
- for (auto& p : simpleParticles)
- if (!p.active)
- return p;
+ for (auto& part : simpleParticles)
+ {
+ if (!part.active)
+ return part;
+ }
return simpleParticles[0];
}
@@ -28,17 +30,18 @@ namespace TEN::Effects
float z = std::cos(angle + angleVariation);
x = x* -500 + snowMobile->Pose.Position.x;
z = z* -500 + snowMobile->Pose.Position.z;
- SimpleParticle& p = GetFreeSimpleParticle();
- p = {};
- p.active = true;
- p.life = Random::GenerateFloat(8, 14);
- p.room = snowMobile->RoomNumber;
- p.ageRate = Random::GenerateFloat(0.9f, 1.3f);
+
+ SimpleParticle& part = GetFreeSimpleParticle();
+ part = {};
+ part.active = true;
+ part.life = Random::GenerateFloat(8, 14);
+ part.room = snowMobile->RoomNumber;
+ part.ageRate = Random::GenerateFloat(0.9f, 1.3f);
float size = Random::GenerateFloat(96, 128);
- p.worldPosition = {x, float(snowMobile->Pose.Position.y) - size / 2 , z};
- p.sequence = ID_SKIDOO_SNOW_TRAIL_SPRITES;
- p.size = Random::GenerateFloat(256, 512);
- p.blendMode = BlendMode::AlphaBlend;
+ part.worldPosition = {x, float(snowMobile->Pose.Position.y) - size / 2 , z};
+ part.sequence = ID_SKIDOO_SNOW_TRAIL_SPRITES;
+ part.size = Random::GenerateFloat(256, 512);
+ part.blendMode = BlendMode::AlphaBlend;
}
void TriggerSpeedboatFoam(ItemInfo* boat, Vector3 offset)
@@ -47,41 +50,42 @@ namespace TEN::Effects
{
float size = Random::GenerateFloat(96, 128);
float angle = TO_RAD(boat->Pose.Orientation.y);
- float angleVariation = i*2*10 * RADIAN;
+ float angleVariation = i * 2 * 10 * RADIAN;
float y = float(boat->Pose.Position.y) - size / 2 + offset.y;
float x = std::sin(angle + angleVariation);
float z = std::cos(angle + angleVariation);
x = x * offset.z + z * offset.x + boat->Pose.Position.x;
z = z * offset.z + x * offset.x + boat->Pose.Position.z;
- SimpleParticle& p = GetFreeSimpleParticle();
- p = {};
- p.active = true;
- p.life = Random::GenerateFloat(5, 9);
- p.room = boat->RoomNumber;
- p.ageRate = Random::GenerateFloat(0.9f, 1.3f);
- p.worldPosition = { x, y, z };
- p.sequence = ID_MOTORBOAT_FOAM_SPRITES;
- p.size = Random::GenerateFloat(256, 512);
- p.blendMode = BlendMode::Additive;
+
+ auto& part = GetFreeSimpleParticle();
+ part = {};
+ part.active = true;
+ part.life = Random::GenerateFloat(5, 9);
+ part.room = boat->RoomNumber;
+ part.ageRate = Random::GenerateFloat(0.9f, 1.3f);
+ part.worldPosition = { x, y, z };
+ part.sequence = ID_MOTORBOAT_FOAM_SPRITES;
+ part.size = Random::GenerateFloat(256, 512);
+ part.blendMode = BlendMode::Additive;
}
}
void UpdateSimpleParticles()
{
- for (auto& p : simpleParticles)
+ for (auto& part : simpleParticles)
{
- if (!p.active)
+ if (!part.active)
continue;
- p.StoreInterpolationData();
+ part.StoreInterpolationData();
- p.age+= p.ageRate;
- if (p.life < p.age)
- p.active = false;
+ part.age+= part.ageRate;
+ if (part.life < part.age)
+ part.active = false;
- int numSprites = -Objects[p.sequence].nmeshes - 1;
- float normalizedAge = p.age / p.life;
- p.sprite = Lerp(0.0f, numSprites, normalizedAge);
+ int spriteCount = -Objects[part.sequence].nmeshes - 1;
+ float normalizedAge = part.age / part.life;
+ part.sprite = Lerp(0.0f, spriteCount, normalizedAge);
}
}
}
diff --git a/TombEngine/Game/effects/simple_particle.h b/TombEngine/Game/effects/simple_particle.h
index 592c23154..42811cf23 100644
--- a/TombEngine/Game/effects/simple_particle.h
+++ b/TombEngine/Game/effects/simple_particle.h
@@ -22,13 +22,13 @@ namespace TEN::Effects
bool active;
BlendMode blendMode;
- Vector3 oldWorldPosition;
- float oldSize;
+ Vector3 PrevWorldPosition = Vector3::Zero;
+ float PrevSize = 0.0f;
void StoreInterpolationData()
{
- oldWorldPosition = worldPosition;
- oldSize = size;
+ PrevWorldPosition = worldPosition;
+ PrevSize = size;
}
};
extern std::array simpleParticles;
diff --git a/TombEngine/Game/effects/smoke.h b/TombEngine/Game/effects/smoke.h
index fb0dfb7ab..5386fe12e 100644
--- a/TombEngine/Game/effects/smoke.h
+++ b/TombEngine/Game/effects/smoke.h
@@ -28,17 +28,17 @@ namespace TEN::Effects::Smoke
bool affectedByWind;
bool active;
- Vector4 oldColor;
- Vector3 oldPosition;
- float oldRotation;
- float oldSize;
+ Vector3 PrevPosition = Vector3::Zero;
+ float PrevRotation = 0.0f;
+ Vector4 PrevColor = Vector4::Zero;
+ float PrevSize = 0.0f;
void StoreInterpolationData()
{
- oldColor = color;
- oldPosition = position;
- oldRotation = rotation;
- oldSize = size;
+ PrevPosition = position;
+ PrevRotation = rotation;
+ PrevColor = color;
+ PrevSize = size;
}
};
extern std::array SmokeParticles;
diff --git a/TombEngine/Game/effects/spark.h b/TombEngine/Game/effects/spark.h
index 34fe6b386..d925ae26e 100644
--- a/TombEngine/Game/effects/spark.h
+++ b/TombEngine/Game/effects/spark.h
@@ -23,13 +23,13 @@ namespace TEN::Effects::Spark
float height;
bool active;
- Vector3 oldPos;
- Vector3 oldVelocity;
+ Vector3 PrevPosition = Vector3::Zero;
+ Vector3 PrevVelocity = Vector3::Zero;
void StoreInterpolationData()
{
- oldPos = pos;
- oldVelocity = velocity;
+ PrevPosition = pos;
+ PrevVelocity = velocity;
}
};
extern std::array SparkParticles;
diff --git a/TombEngine/Renderer/RendererDrawEffect.cpp b/TombEngine/Renderer/RendererDrawEffect.cpp
index 6cbcbd011..1b9d8d069 100644
--- a/TombEngine/Renderer/RendererDrawEffect.cpp
+++ b/TombEngine/Renderer/RendererDrawEffect.cpp
@@ -634,14 +634,14 @@ namespace TEN::Renderer
auto axis = drip.Velocity;
drip.Velocity.Normalize(axis);
- auto prevAxis = drip.OldVelocity;
- drip.OldVelocity.Normalize(prevAxis);
+ auto prevAxis = drip.PrevVelocity;
+ drip.PrevVelocity.Normalize(prevAxis);
AddSpriteBillboardConstrained(
&_sprites[Objects[ID_DRIP_SPRITE].meshIndex],
- Vector3::Lerp(drip.OldPosition, drip.Position, _interpolationFactor),
- Vector4::Lerp(drip.OldColor, drip.Color, _interpolationFactor),
- 0.0f, 1.0f, Vector2::Lerp(drip.OldSize, drip.Size, _interpolationFactor),
+ Vector3::Lerp(drip.PrevPosition, drip.Position, _interpolationFactor),
+ Vector4::Lerp(drip.PrevColor, drip.Color, _interpolationFactor),
+ 0.0f, 1.0f, Vector2::Lerp(drip.PrevSize, drip.Size, _interpolationFactor),
BlendMode::Additive, -Vector3::Lerp(prevAxis, axis, _interpolationFactor), false, view);
}
}
@@ -1382,7 +1382,7 @@ namespace TEN::Renderer
BindTexture(TextureRegister::ColorMap, &std::get<0>(_moveablesTextures[deb.mesh.tex]), SamplerStateRegister::LinearClamp);
}
- _stStatic.World = Matrix::Lerp(deb.OldTransform, deb.Transform, _interpolationFactor);
+ _stStatic.World = Matrix::Lerp(deb.PrevTransform, deb.Transform, _interpolationFactor);
_stStatic.Color = deb.color;
_stStatic.AmbientLight = _rooms[deb.roomNumber].AmbientLight;
_stStatic.LightMode = (int)deb.lightMode;
@@ -1441,13 +1441,13 @@ namespace TEN::Renderer
AddSpriteBillboard(
&_sprites[Objects[ID_SMOKE_SPRITES].meshIndex + smoke.sprite],
- Vector3::Lerp(smoke.oldPosition, smoke.position, _interpolationFactor),
- Vector4::Lerp(smoke.oldColor, smoke.color, _interpolationFactor),
- Lerp(smoke.oldRotation, smoke.rotation, _interpolationFactor),
+ Vector3::Lerp(smoke.PrevPosition, smoke.position, _interpolationFactor),
+ Vector4::Lerp(smoke.PrevColor, smoke.color, _interpolationFactor),
+ Lerp(smoke.PrevRotation, smoke.rotation, _interpolationFactor),
1.0f,
Vector2(
- Lerp(smoke.oldSize, smoke.size, _interpolationFactor),
- Lerp(smoke.oldSize, smoke.size, _interpolationFactor)),
+ Lerp(smoke.PrevSize, smoke.size, _interpolationFactor),
+ Lerp(smoke.PrevSize, smoke.size, _interpolationFactor)),
BlendMode::AlphaBlend, true, view);
}
}
@@ -1469,7 +1469,7 @@ namespace TEN::Renderer
Vector3 prevVelocity;
Vector3 velocity;
- s.oldVelocity.Normalize(prevVelocity);
+ s.PrevVelocity.Normalize(prevVelocity);
s.velocity.Normalize(velocity);
velocity = Vector3::Lerp(prevVelocity, velocity, _interpolationFactor);
@@ -1481,7 +1481,7 @@ namespace TEN::Renderer
AddSpriteBillboardConstrained(
&_sprites[Objects[ID_SPARK_SPRITE].meshIndex],
- Vector3::Lerp(s.oldPos, s.pos, _interpolationFactor),
+ Vector3::Lerp(s.PrevPosition, s.pos, _interpolationFactor),
color,
0, 1,
Vector2(
@@ -1531,11 +1531,11 @@ namespace TEN::Renderer
AddSpriteBillboard(
&_sprites[Objects[part.sequence].meshIndex + part.sprite],
- Vector3::Lerp(part.oldWorldPosition, part.worldPosition, _interpolationFactor),
+ Vector3::Lerp(part.PrevWorldPosition, part.worldPosition, _interpolationFactor),
Color(1.0f, 1.0f, 1.0f), 0, 1.0f,
Vector2(
- Lerp(part.oldSize, part.size, _interpolationFactor),
- Lerp(part.oldSize, part.size, _interpolationFactor) / 2),
+ Lerp(part.PrevSize, part.size, _interpolationFactor),
+ Lerp(part.PrevSize, part.size, _interpolationFactor) / 2),
BlendMode::AlphaBlend, true, view);
}
}
diff --git a/TombEngine/Renderer/RendererLara.cpp b/TombEngine/Renderer/RendererLara.cpp
index 2685390bc..f12ab25f0 100644
--- a/TombEngine/Renderer/RendererLara.cpp
+++ b/TombEngine/Renderer/RendererLara.cpp
@@ -352,9 +352,9 @@ void Renderer::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, Render
const auto& segment = unit.Segments[i];
auto worldMatrix =
Matrix::CreateFromQuaternion(
- Quaternion::Lerp(segment.OldOrientation, segment.Orientation, _interpolationFactor)) *
+ Quaternion::Lerp(segment.PrevOrientation, segment.Orientation, _interpolationFactor)) *
Matrix::CreateTranslation(
- Vector3::Lerp(segment.OldPosition, segment.Position, _interpolationFactor));
+ Vector3::Lerp(segment.PrevPosition, segment.Position, _interpolationFactor));
_stItem.BonesMatrices[i + 1] = worldMatrix;
_stItem.BoneLightModes[i] = (int)LightMode::Dynamic;
From 367cb777588eb9a5b4f48e0a021a92442a70cbba Mon Sep 17 00:00:00 2001
From: Sezz
Date: Thu, 9 May 2024 01:43:20 +1000
Subject: [PATCH 153/410] Fix doc comments
---
.../Internal/TEN/Flow/LensFlare/LensFlare.cpp | 15 ++++++---------
.../Internal/TEN/Flow/Starfield/Starfield.cpp | 5 +----
2 files changed, 7 insertions(+), 13 deletions(-)
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.cpp b/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.cpp
index aab754268..138c5eced 100644
--- a/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.cpp
@@ -19,10 +19,7 @@ namespace TEN::Scripting
// Register type.
parent.new_usertype(
- "LensFlare",
- ctors(),
- sol::call_constructor, ctors(),
-
+ "LensFlare", ctors(), sol::call_constructor, ctors(),
"GetEnabled", &LensFlare::GetEnabled,
"GetSunSpriteID", &LensFlare::GetSunSpriteID,
"GetRotation", &LensFlare::GetRotation,
@@ -60,7 +57,7 @@ namespace TEN::Scripting
return _sunSpriteID;
}
- // Get the lens flare's euler rotation.
+ /// Get the lens flare's euler rotation.
// @function LensFlare:GetRotation()
// @treturn Rotation Rotation.
Rotation LensFlare::GetRotation() const
@@ -68,14 +65,14 @@ namespace TEN::Scripting
return _rotation;
}
- // Get the lens flare's color.
+ /// Get the lens flare's color.
// @function LensFlare:SetColor()
ScriptColor LensFlare::GetColor() const
{
return _color;
}
- // Set the lens flare's sun sprite ID.
+ /// Set the lens flare's sun sprite ID.
// @function LensFlare:SetSunbjectID()
// @tparam int New sprite ID.
void LensFlare::SetSunSpriteID(int spriteID)
@@ -90,7 +87,7 @@ namespace TEN::Scripting
_sunSpriteID = spriteID;
}
- // Set the lens flare's euler rotation.
+ /// Set the lens flare's euler rotation.
// @function LensFlare:SetRotation(Rotation)
// @tparam Rotation New euler rotation.
void LensFlare::SetRotation(const Rotation& rot)
@@ -98,7 +95,7 @@ namespace TEN::Scripting
_rotation = rot;
}
- // Set the lens flare's color.
+ /// Set the lens flare's color.
// @function LensFlare:SetColor(Color)
// @tparam Color New color.
void LensFlare::SetColor(const ScriptColor& color)
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.cpp b/TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.cpp
index a2f030a6e..b37703135 100644
--- a/TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.cpp
@@ -21,10 +21,7 @@ namespace TEN::Scripting
// Register type.
parent.new_usertype(
- "Starfield",
- ctors(),
- sol::call_constructor, ctors(),
-
+ "Starfield", ctors(), sol::call_constructor, ctors(),
"GetStarsEnabled", &Starfield::GetStarsEnabled,
"GetMeteorsEnabled", &Starfield::GetMeteorsEnabled,
"GetStarCount", &Starfield::GetStarCount,
From caa13a659c9459e38d841b296a667396d935757c Mon Sep 17 00:00:00 2001
From: Sezz
Date: Thu, 9 May 2024 03:33:11 +1000
Subject: [PATCH 154/410] Update TombEngine.vcxproj
---
TombEngine/TombEngine.vcxproj | 1 +
1 file changed, 1 insertion(+)
diff --git a/TombEngine/TombEngine.vcxproj b/TombEngine/TombEngine.vcxproj
index 24ff002ab..48697de84 100644
--- a/TombEngine/TombEngine.vcxproj
+++ b/TombEngine/TombEngine.vcxproj
@@ -300,6 +300,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x86\*.dll" "$(TargetDir)"
/Zc:__cplusplus /experimental:external /external:anglebrackets
4018;4244;4996;%(DisableSpecificWarnings)
true
+ $(IntDir)/%(RelativeDir)/
Console
From 1bd183203748d3c2357f7d8afd373ac6da408056 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Thu, 9 May 2024 05:42:36 +0200
Subject: [PATCH 155/410] WIP solution for variable monitor refresh rates
---
.../doc/2 classes/Flow.LensFlare.html | 122 ++++++++++++++++++
TombEngine/Game/gui.cpp | 2 +-
TombEngine/Renderer/Renderer.h | 2 +
TombEngine/Renderer/RendererDrawMenu.cpp | 13 +-
TombEngine/Renderer/RendererHelper.cpp | 5 +
TombEngine/Renderer/RendererInit.cpp | 10 +-
TombEngine/Specific/winmain.cpp | 16 +++
TombEngine/Specific/winmain.h | 3 +-
8 files changed, 164 insertions(+), 9 deletions(-)
diff --git a/Documentation/doc/2 classes/Flow.LensFlare.html b/Documentation/doc/2 classes/Flow.LensFlare.html
index 574b42065..5ce8350f1 100644
--- a/Documentation/doc/2 classes/Flow.LensFlare.html
+++ b/Documentation/doc/2 classes/Flow.LensFlare.html
@@ -122,6 +122,26 @@
LensFlare:GetObjectID()
Get the sun's sprite ID.
+
+ LensFlare:GetRotation()
+ Get the lens flare's euler rotation.
+
+
+ LensFlare:SetColor()
+ Get the lens flare's color.
+
+
+ LensFlare:SetSunbjectID(New)
+ Set the lens flare's sun sprite ID.
+
+
+ LensFlare:SetRotation(New)
+ Set the lens flare's euler rotation.
+
+
+ LensFlare:SetColor(New)
+ Set the lens flare's color.
+
@@ -208,6 +228,108 @@
+
+
+
+ LensFlare:GetRotation()
+
+
+ Get the lens flare's euler rotation. ()
+
+
+
+
+ Returns:
+
+
+ Rotation
+ Rotation.
+
+
+
+
+
+
+
+
+ LensFlare:SetColor()
+
+
+ Get the lens flare's color. ()
+
+
+
+
+
+
+
+
+
+
+
+ LensFlare:SetSunbjectID(New)
+
+
+ Set the lens flare's sun sprite ID. ()
+
+
+
+ Parameters:
+
+ New
+ int
+ sprite ID.
+
+
+
+
+
+
+
+
+
+
+ LensFlare:SetRotation(New)
+
+
+ Set the lens flare's euler rotation. (Rotation)
+
+
+
+ Parameters:
+
+
+
+
+
+
+
+
+
+ LensFlare:SetColor(New)
+
+
+ Set the lens flare's color. (Color)
+
+
+
+ Parameters:
+
+ New
+ Color
+ color.
+
+
+
+
+
+
+
diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp
index 45162341c..6b8ce4bf5 100644
--- a/TombEngine/Game/gui.cpp
+++ b/TombEngine/Game/gui.cpp
@@ -2806,7 +2806,7 @@ namespace TEN::Gui
const auto& player = GetLaraInfo(*item);
auto& ring = Rings[(int)ringType];
- float multiplier = g_Configuration.EnableVariableFramerate ? 2.0f : 1.0f;
+ float multiplier = g_Configuration.EnableVariableFramerate ? g_Renderer.GetScreenRefreshRate() / 30.0f : 1.0f;
if (ring.CurrentObjectList <= 0)
return;
diff --git a/TombEngine/Renderer/Renderer.h b/TombEngine/Renderer/Renderer.h
index 6890825d0..8d058514d 100644
--- a/TombEngine/Renderer/Renderer.h
+++ b/TombEngine/Renderer/Renderer.h
@@ -305,6 +305,7 @@ namespace TEN::Renderer
// Screen settings
int _screenWidth;
int _screenHeight;
+ int _refreshRate;
bool _isWindowed;
float _farView = DEFAULT_FAR_VIEW;
@@ -644,6 +645,7 @@ namespace TEN::Renderer
float GetInterpolationFactor() const;
Vector2i GetScreenResolution() const;
+ int GetScreenRefreshRate() const;
std::optional Get2DPosition(const Vector3& pos) const;
Vector3 GetAbsEntityBonePosition(int itemNumber, int jointIndex, const Vector3& relOffset = Vector3::Zero);
std::pair GetRay(const Vector2& pos) const;
diff --git a/TombEngine/Renderer/RendererDrawMenu.cpp b/TombEngine/Renderer/RendererDrawMenu.cpp
index 8ac86c306..d27af4d35 100644
--- a/TombEngine/Renderer/RendererDrawMenu.cpp
+++ b/TombEngine/Renderer/RendererDrawMenu.cpp
@@ -892,28 +892,29 @@ namespace TEN::Renderer
static EulerAngles orient = EulerAngles::Identity;
static float scaler = 1.2f;
+ float multiplier = g_Configuration.EnableVariableFramerate ? g_Renderer.GetScreenRefreshRate() / 30.0f : 1.0f;
short invItem = g_Gui.GetRing(RingTypes::Inventory).CurrentObjectList[g_Gui.GetRing(RingTypes::Inventory).CurrentObjectInList].InventoryItem;
auto& object = InventoryObjectTable[invItem];
if (IsHeld(In::Forward))
- orient.x += ANGLE(3.0f);
+ orient.x += ANGLE(3.0f / multiplier);
if (IsHeld(In::Back))
- orient.x -= ANGLE(3.0f);
+ orient.x -= ANGLE(3.0f / multiplier);
if (IsHeld(In::Left))
- orient.y += ANGLE(3.0f);
+ orient.y += ANGLE(3.0f / multiplier);
if (IsHeld(In::Right))
- orient.y -= ANGLE(3.0f);
+ orient.y -= ANGLE(3.0f / multiplier);
if (IsHeld(In::Sprint))
- scaler += 0.03f;
+ scaler += 0.03f / multiplier;
if (IsHeld(In::Crouch))
- scaler -= 0.03f;
+ scaler -= 0.03f / multiplier;
if (scaler > 1.6f)
scaler = 1.6f;
diff --git a/TombEngine/Renderer/RendererHelper.cpp b/TombEngine/Renderer/RendererHelper.cpp
index 7a0ae86c7..7c69bf102 100644
--- a/TombEngine/Renderer/RendererHelper.cpp
+++ b/TombEngine/Renderer/RendererHelper.cpp
@@ -529,6 +529,11 @@ namespace TEN::Renderer
return Vector2i(_screenWidth, _screenHeight);
}
+ int Renderer::GetScreenRefreshRate() const
+ {
+ return _refreshRate;
+ }
+
std::optional Renderer::Get2DPosition(const Vector3& pos) const
{
auto point = Vector4(pos.x, pos.y, pos.z, 1.0f);
diff --git a/TombEngine/Renderer/RendererInit.cpp b/TombEngine/Renderer/RendererInit.cpp
index 9eb926176..d382d191d 100644
--- a/TombEngine/Renderer/RendererInit.cpp
+++ b/TombEngine/Renderer/RendererInit.cpp
@@ -465,12 +465,20 @@ namespace TEN::Renderer
sd.BufferDesc.Height = h;
if (!g_Configuration.EnableVariableFramerate)
{
+ _refreshRate = 30;
+
sd.BufferDesc.RefreshRate.Numerator = 0;
sd.BufferDesc.RefreshRate.Denominator = 0;
}
else
{
- sd.BufferDesc.RefreshRate.Numerator = 60;
+ _refreshRate = GetCurrentScreenRefreshRate();
+ if (_refreshRate == 0)
+ {
+ _refreshRate = 60;
+ }
+
+ sd.BufferDesc.RefreshRate.Numerator = _refreshRate;
sd.BufferDesc.RefreshRate.Denominator = 1;
}
sd.BufferDesc.RefreshRate.Numerator = 60;
diff --git a/TombEngine/Specific/winmain.cpp b/TombEngine/Specific/winmain.cpp
index 3a3d7438b..3e2e7ed5b 100644
--- a/TombEngine/Specific/winmain.cpp
+++ b/TombEngine/Specific/winmain.cpp
@@ -60,6 +60,22 @@ Vector2i GetScreenResolution()
return resolution;
}
+int GetCurrentScreenRefreshRate()
+{
+ DEVMODE devmode;
+ memset(&devmode, 0, sizeof(devmode));
+ devmode.dmSize = sizeof(devmode);
+
+ if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devmode))
+ {
+ return devmode.dmDisplayFrequency;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
std::vector GetAllSupportedScreenResolutions()
{
auto resList = std::vector{};
diff --git a/TombEngine/Specific/winmain.h b/TombEngine/Specific/winmain.h
index 80427898b..14158adb5 100644
--- a/TombEngine/Specific/winmain.h
+++ b/TombEngine/Specific/winmain.h
@@ -39,4 +39,5 @@ void WinClose();
LRESULT CALLBACK WinAppProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
void CALLBACK HandleWmCommand(unsigned short wParam);
Vector2i GetScreenResolution();
-std::vector GetAllSupportedScreenResolutions();
\ No newline at end of file
+std::vector GetAllSupportedScreenResolutions();
+int GetCurrentScreenRefreshRate();
\ No newline at end of file
From afab268a133e2765216024d5621426b6e13f47c0 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Thu, 9 May 2024 13:38:08 +0200
Subject: [PATCH 156/410] Fixed ammos ring speed
---
TombEngine/Game/gui.cpp | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp
index 6b8ce4bf5..a6a48b75c 100644
--- a/TombEngine/Game/gui.cpp
+++ b/TombEngine/Game/gui.cpp
@@ -2028,6 +2028,8 @@ namespace TEN::Gui
void GuiController::FadeAmmoSelector()
{
+ float multiplier = g_Configuration.EnableVariableFramerate ? g_Renderer.GetScreenRefreshRate() / 30.0f : 1.0f;
+
if (Rings[(int)RingTypes::Inventory].RingActive)
{
AmmoSelectorFadeVal = 0;
@@ -2035,7 +2037,7 @@ namespace TEN::Gui
else if (AmmoSelectorFadeDir == 1)
{
if (AmmoSelectorFadeVal < 128)
- AmmoSelectorFadeVal += 32;
+ AmmoSelectorFadeVal += 32 / multiplier;
if (AmmoSelectorFadeVal > 128)
{
@@ -2046,7 +2048,7 @@ namespace TEN::Gui
else if (AmmoSelectorFadeDir == 2)
{
if (AmmoSelectorFadeVal > 0)
- AmmoSelectorFadeVal -= 32;
+ AmmoSelectorFadeVal -= 32 / multiplier;
if (AmmoSelectorFadeVal < 0)
{
@@ -2737,6 +2739,8 @@ namespace TEN::Gui
{
if (!AmmoSelectorFlag)
return;
+
+ float multiplier = g_Configuration.EnableVariableFramerate ? g_Renderer.GetScreenRefreshRate() / 30.0f : 1.0f;
int xPos = (2 * PHD_CENTER_X - OBJLIST_SPACING) / 2;
if (NumAmmoSlots == 2)
@@ -2753,13 +2757,13 @@ namespace TEN::Gui
if (n == *CurrentAmmoType)
{
if (invObject->RotFlags & INV_ROT_X)
- AmmoObjectList[n].Orientation.x += ANGLE(5.0f);
+ AmmoObjectList[n].Orientation.x += ANGLE(5.0f / multiplier);
if (invObject->RotFlags & INV_ROT_Y)
- AmmoObjectList[n].Orientation.y += ANGLE(5.0f);
+ AmmoObjectList[n].Orientation.y += ANGLE(5.0f / multiplier);
if (invObject->RotFlags & INV_ROT_Z)
- AmmoObjectList[n].Orientation.z += ANGLE(5.0f);
+ AmmoObjectList[n].Orientation.z += ANGLE(5.0f / multiplier);
}
else
SpinBack(AmmoObjectList[n].Orientation);
From fa697cc26e7e3bd0ad92e093e6aff1ee91389cb8 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Fri, 10 May 2024 22:19:36 +1000
Subject: [PATCH 157/410] Update lens flare Lua API
---
.../doc/2 classes/Flow.LensFlare.html | 107 +++++++++++++-----
.../doc/3 primitive classes/Rotation.html | 2 +-
TombEngine/Game/control/control.cpp | 2 +-
.../Scripting/Include/ScriptInterfaceLevel.h | 9 +-
.../Internal/TEN/Flow/LensFlare/LensFlare.cpp | 57 ++++++----
.../Internal/TEN/Flow/LensFlare/LensFlare.h | 8 +-
.../Internal/TEN/Flow/Level/FlowLevel.cpp | 9 +-
.../Internal/TEN/Flow/Level/FlowLevel.h | 9 +-
.../Internal/TEN/Rotation/Rotation.cpp | 35 +++---
9 files changed, 157 insertions(+), 81 deletions(-)
diff --git a/Documentation/doc/2 classes/Flow.LensFlare.html b/Documentation/doc/2 classes/Flow.LensFlare.html
index 5ce8350f1..825fe070e 100644
--- a/Documentation/doc/2 classes/Flow.LensFlare.html
+++ b/Documentation/doc/2 classes/Flow.LensFlare.html
@@ -111,7 +111,7 @@
- LensFlare(Rotation., Color.)
+ LensFlare(Pitch, Yaw, Color.)
Create a LensFlare object.
@@ -119,24 +119,32 @@
Get the lens flare's enabled status.
- LensFlare:GetObjectID()
+ LensFlare:GetSunSpriteID()
Get the sun's sprite ID.
- LensFlare:GetRotation()
- Get the lens flare's euler rotation.
+ LensFlare:GetPitch()
+ Get the lens flare's pitch angle in degrees.
+
+
+ LensFlare:GetYaw()
+ Get the lens flare's yaw angle in degrees.
LensFlare:SetColor()
Get the lens flare's color.
- LensFlare:SetSunbjectID(New)
+ LensFlare:SetSunSpriteID(New)
Set the lens flare's sun sprite ID.
- LensFlare:SetRotation(New)
- Set the lens flare's euler rotation.
+ LensFlare:SetPitch(New)
+ Set the lens flare's pitch angle.
+
+
+ LensFlare:SetYaw(New)
+ Set the lens flare's yaw angle.
LensFlare:SetColor(New)
@@ -153,7 +161,7 @@
- LensFlare(Rotation., Color.)
+ LensFlare(Pitch, Yaw, Color.)
Create a LensFlare object. ()
@@ -162,11 +170,13 @@
Parameters:
- Rotation.
- Rotation
-
-
-
+ Pitch
+ float
+ angle.
+
+ Yaw
+ float
+ angle.
Color.
Color
@@ -209,8 +219,8 @@
-
- LensFlare:GetObjectID()
+
+ LensFlare:GetSunSpriteID()
Get the sun's sprite ID. ()
@@ -230,11 +240,11 @@
-
- LensFlare:GetRotation()
+
+ LensFlare:GetPitch()
- Get the lens flare's euler rotation. ()
+ Get the lens flare's pitch angle in degrees. ()
@@ -242,8 +252,29 @@
Returns:
- Rotation
- Rotation.
+ float
+ Pitch angle in degrees.
+
+
+
+
+
+
+
+
+ LensFlare:GetYaw()
+
+
+ Get the lens flare's yaw angle in degrees. ()
+
+
+
+
+ Returns:
+
+
+ float
+ Yaw angle in degrees.
@@ -266,8 +297,8 @@
-
- LensFlare:SetSunbjectID(New)
+
+ LensFlare:SetSunSpriteID(New)
Set the lens flare's sun sprite ID. ()
@@ -288,19 +319,41 @@
-
- LensFlare:SetRotation(New)
+
+ LensFlare:SetPitch(New)
- Set the lens flare's euler rotation. (Rotation)
+ Set the lens flare's pitch angle. (float)
Parameters:
New
- Rotation
- euler rotation.
+ float
+ pitch angle in degrees.
+
+
+
+
+
+
+
+
+
+
+ LensFlare:SetYaw(New)
+
+
+ Set the lens flare's yaw angle. (float)
+
+
+
+ Parameters:
+
+ New
+ float
+ yaw angle in degrees.
diff --git a/Documentation/doc/3 primitive classes/Rotation.html b/Documentation/doc/3 primitive classes/Rotation.html
index 81269805f..b163bc9de 100644
--- a/Documentation/doc/3 primitive classes/Rotation.html
+++ b/Documentation/doc/3 primitive classes/Rotation.html
@@ -103,7 +103,7 @@
Primitive Class Rotation
Represents a degree-based 3D rotation.
-All values are clamped to the range [0.0, 360.0].
+ All values are clamped to the range [0.0, 360.0].
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index 23f028319..f8666c90f 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -247,7 +247,7 @@ GameStatus ControlPhase()
if (g_GameFlow->GetLevel(CurrentLevel)->GetLensFlareEnabled())
{
SetupGlobalLensFlare(
- g_GameFlow->GetLevel(CurrentLevel)->GetLensFlareRotation(),
+ EulerAngles(g_GameFlow->GetLevel(CurrentLevel)->GetLensFlarePitch(), g_GameFlow->GetLevel(CurrentLevel)->GetLensFlareYaw(), 0),
g_GameFlow->GetLevel(CurrentLevel)->GetLensFlareColor(),
g_GameFlow->GetLevel(CurrentLevel)->GetLensFlareSunSpriteID());
}
diff --git a/TombEngine/Scripting/Include/ScriptInterfaceLevel.h b/TombEngine/Scripting/Include/ScriptInterfaceLevel.h
index b96635db7..f1c442cca 100644
--- a/TombEngine/Scripting/Include/ScriptInterfaceLevel.h
+++ b/TombEngine/Scripting/Include/ScriptInterfaceLevel.h
@@ -50,10 +50,11 @@ public:
virtual bool GetResetHubEnabled() const = 0;
// Lens flare getters
- virtual bool GetLensFlareEnabled() const = 0;
- virtual int GetLensFlareSunSpriteID() const = 0;
- virtual EulerAngles GetLensFlareRotation() const = 0;
- virtual Color GetLensFlareColor() const = 0;
+ virtual bool GetLensFlareEnabled() const = 0;
+ virtual int GetLensFlareSunSpriteID() const = 0;
+ virtual short GetLensFlarePitch() const = 0;
+ virtual short GetLensFlareYaw() const = 0;
+ virtual Color GetLensFlareColor() const = 0;
// Starfield getters
virtual bool GetStarfieldStarsEnabled() const = 0;
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.cpp b/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.cpp
index 138c5eced..8b9664593 100644
--- a/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.cpp
@@ -15,30 +15,33 @@ namespace TEN::Scripting
void LensFlare::Register(sol::table& parent)
{
using ctors = sol::constructors<
- LensFlare(const Rotation& rot, const ScriptColor& color)>;
+ LensFlare(float pitch, float yaw, const ScriptColor& color)>;
// Register type.
parent.new_usertype(
"LensFlare", ctors(), sol::call_constructor, ctors(),
"GetEnabled", &LensFlare::GetEnabled,
"GetSunSpriteID", &LensFlare::GetSunSpriteID,
- "GetRotation", &LensFlare::GetRotation,
+ "GetPitch", &LensFlare::GetPitch,
+ "GetYaw", &LensFlare::GetYaw,
"GetColor", &LensFlare::GetColor,
"SetSunSpriteID", &LensFlare::SetSunSpriteID,
- "SetRotation", &LensFlare::SetRotation,
+ "SetPitch", &LensFlare::SetPitch,
+ "SetYaw", &LensFlare::SetYaw,
"SetColor", &LensFlare::SetColor);
}
/// Create a LensFlare object.
// @function LensFlare()
- // @tparam Rotation Rotation.
+ // @tparam float Pitch angle in degrees.
+ // @tparam float Yaw angle in degrees.
// @tparam Color Color.
// @treturn LensFlare A new LensFlare object.
- LensFlare::LensFlare(const Rotation& rot, const ScriptColor& color)
+ LensFlare::LensFlare(float pitch, float yaw, const ScriptColor& color)
{
_isEnabled = true;
_color = color;
- _rotation = rot;
+ _rotation = Rotation(pitch, yaw, 0.0f);
}
/// Get the lens flare's enabled status.
@@ -50,19 +53,27 @@ namespace TEN::Scripting
}
/// Get the sun's sprite ID.
- // @function LensFlare:GetObjectID()
+ // @function LensFlare:GetSunSpriteID()
// @treturn int Sprite ID.
int LensFlare::GetSunSpriteID() const
{
return _sunSpriteID;
}
- /// Get the lens flare's euler rotation.
- // @function LensFlare:GetRotation()
- // @treturn Rotation Rotation.
- Rotation LensFlare::GetRotation() const
+ /// Get the lens flare's pitch angle in degrees.
+ // @function LensFlare:GetPitch()
+ // @treturn float Pitch angle in degrees.
+ float LensFlare::GetPitch() const
{
- return _rotation;
+ return _rotation.x;
+ }
+
+ /// Get the lens flare's yaw angle in degrees.
+ // @function LensFlare:GetYaw()
+ // @treturn float Yaw angle in degrees.
+ float LensFlare::GetYaw() const
+ {
+ return _rotation.y;
}
/// Get the lens flare's color.
@@ -73,28 +84,36 @@ namespace TEN::Scripting
}
/// Set the lens flare's sun sprite ID.
- // @function LensFlare:SetSunbjectID()
+ // @function LensFlare:SetSunSpriteID()
// @tparam int New sprite ID.
void LensFlare::SetSunSpriteID(int spriteID)
{
// Sprite ID out of range; return early.
if (spriteID < 0 || g_Level.Sprites.size() > spriteID)
{
- TENLog("Sub sprite ID out of range.");
+ TENLog("Sun sprite ID out of range.");
return;
}
_sunSpriteID = spriteID;
}
- /// Set the lens flare's euler rotation.
- // @function LensFlare:SetRotation(Rotation)
- // @tparam Rotation New euler rotation.
- void LensFlare::SetRotation(const Rotation& rot)
+ /// Set the lens flare's pitch angle.
+ // @function LensFlare:SetPitch(float)
+ // @tparam float New pitch angle in degrees.
+ void LensFlare::SetPitch(float pitch)
{
- _rotation = rot;
+ _rotation.x = pitch;
}
+ /// Set the lens flare's yaw angle.
+ // @function LensFlare:SetYaw(float)
+ // @tparam float New yaw angle in degrees.
+ void LensFlare::SetYaw(float yaw)
+ {
+ _rotation.y = yaw;
+ }
+
/// Set the lens flare's color.
// @function LensFlare:SetColor(Color)
// @tparam Color New color.
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.h b/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.h
index 8b034b9f0..e13f97d40 100644
--- a/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.h
+++ b/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.h
@@ -23,17 +23,19 @@ namespace TEN::Scripting
// Constructors
LensFlare() = default;
- LensFlare(const Rotation& rot, const ScriptColor& color);
+ LensFlare(float pitch, float yaw, const ScriptColor& color);
// Getters
bool GetEnabled() const;
int GetSunSpriteID() const;
- Rotation GetRotation() const;
+ float GetPitch() const;
+ float GetYaw() const;
ScriptColor GetColor() const;
// Setters
void SetSunSpriteID(int spriteID);
- void SetRotation(const Rotation& rot);
+ void SetPitch(float pitch);
+ void SetYaw(float yaw);
void SetColor(const ScriptColor& color);
};
}
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp b/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp
index 2f419cf1d..f9c92fc6f 100644
--- a/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp
@@ -301,9 +301,14 @@ int Level::GetLensFlareSunSpriteID() const
return LensFlare.GetSunSpriteID();
}
-EulerAngles Level::GetLensFlareRotation() const
+short Level::GetLensFlarePitch() const
{
- return LensFlare.GetRotation().ToEulerAngles();
+ return ANGLE(LensFlare.GetPitch());
+}
+
+short Level::GetLensFlareYaw() const
+{
+ return ANGLE(LensFlare.GetYaw());
}
Color Level::GetLensFlareColor() const
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.h b/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.h
index 4b8610f5c..18d52df5b 100644
--- a/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.h
+++ b/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.h
@@ -72,10 +72,11 @@ struct Level : public ScriptInterfaceLevel
bool GetResetHubEnabled() const override;
// Lens flare getters
- bool GetLensFlareEnabled() const override;
- int GetLensFlareSunSpriteID() const override;
- EulerAngles GetLensFlareRotation() const override;
- Color GetLensFlareColor() const override;
+ bool GetLensFlareEnabled() const override;
+ int GetLensFlareSunSpriteID() const override;
+ short GetLensFlarePitch() const override;
+ short GetLensFlareYaw() const override;
+ Color GetLensFlareColor() const override;
// Starfield getters
bool GetStarfieldStarsEnabled() const override;
diff --git a/TombEngine/Scripting/Internal/TEN/Rotation/Rotation.cpp b/TombEngine/Scripting/Internal/TEN/Rotation/Rotation.cpp
index 1fad9a411..3a2cdf881 100644
--- a/TombEngine/Scripting/Internal/TEN/Rotation/Rotation.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Rotation/Rotation.cpp
@@ -6,11 +6,10 @@
using namespace TEN::Math;
-/*** Represents a degree-based 3D rotation.
-All values are clamped to the range [0.0, 360.0].
-@tenprimitive Rotation
-@pragma nostrip
-*/
+/// Represents a degree-based 3D rotation.
+// All values are clamped to the range [0.0, 360.0].
+// @tenprimitive Rotation
+// @pragma nostrip
void Rotation::Register(sol::table& parent)
{
@@ -21,25 +20,23 @@ void Rotation::Register(sol::table& parent)
sol::meta_function::to_string, &Rotation::ToString,
/// (float) X angle component.
- //@mem x
+ // @mem x
"x", &Rotation::x,
/// (float) Y angle component.
- //@mem y
+ // @mem y
"y", &Rotation::y,
/// (float) Z angle component.
- //@mem z
+ // @mem z
"z", &Rotation::z);
}
-/***
-@tparam float x X angle component.
-@tparam float y Y angle component.
-@tparam float z Z angle component.
-@treturn Rotation A Rotation.
-@function Rotation
-*/
+/// @tparam float x X angle component.
+// @tparam float y Y angle component.
+// @tparam float z Z angle component.
+// @treturn Rotation A Rotation.
+// @function Rotation
Rotation::Rotation(float x, float y, float z)
{
this->x = x;
@@ -80,11 +77,9 @@ Rotation::operator Vector3() const
return Vector3(x, y, z);
};
-/***
-@tparam Rotation rotation this Rotation.
-@treturn string A string showing the X, Y, and Z angle components of the Rotation.
-@function __tostring
-*/
+/// @tparam Rotation rotation this Rotation.
+// @treturn string A string showing the X, Y, and Z angle components of the Rotation.
+// @function __tostring
std::string Rotation::ToString() const
{
return ("{ " + std::to_string(x) + ", " + std::to_string(y) + ", " + std::to_string(z) + " }");
From 52398927439ea3b361a46f5e4be68d51ce8c4beb Mon Sep 17 00:00:00 2001
From: Sezz
Date: Fri, 10 May 2024 23:33:55 +1000
Subject: [PATCH 158/410] Update starfield error handling
---
TombEngine/Objects/Effects/LensFlare.cpp | 22 ++++++++---------
TombEngine/Objects/Effects/LensFlare.h | 3 ++-
.../Internal/TEN/Flow/LensFlare/LensFlare.h | 4 ++--
.../Internal/TEN/Flow/Starfield/Starfield.cpp | 24 ++++++++-----------
4 files changed, 25 insertions(+), 28 deletions(-)
diff --git a/TombEngine/Objects/Effects/LensFlare.cpp b/TombEngine/Objects/Effects/LensFlare.cpp
index 080605a63..6e0677fe0 100644
--- a/TombEngine/Objects/Effects/LensFlare.cpp
+++ b/TombEngine/Objects/Effects/LensFlare.cpp
@@ -75,6 +75,17 @@ namespace TEN::Entities::Effects
LensFlares.push_back(lensFlare);
}
+ void SetupGlobalLensFlare(const EulerAngles& orient, const Color& color, int spriteID)
+ {
+ constexpr auto BASE_POS = Vector3(0.0f, 0.0f, BLOCK(256));
+
+ auto pos = Camera.pos.ToVector3();
+ auto rotMatrix = orient.ToRotationMatrix();
+
+ pos += Vector3::Transform(BASE_POS, rotMatrix);
+ SetupLensFlare(pos, NO_VALUE, color, true, spriteID);
+ }
+
void ControlLensFlare(int itemNumber)
{
auto& item = g_Level.Items[itemNumber];
@@ -87,15 +98,4 @@ namespace TEN::Entities::Effects
{
LensFlares.clear();
}
-
- void SetupGlobalLensFlare(const EulerAngles& orient, const Color& color, int spriteID)
- {
- constexpr auto BASE_POS = Vector3(0.0f, 0.0f, BLOCK(256));
-
- auto pos = Camera.pos.ToVector3();
- auto rotMatrix = orient.ToRotationMatrix();
-
- pos += Vector3::Transform(BASE_POS, rotMatrix);
- SetupLensFlare(pos, NO_VALUE, color, true, spriteID);
- }
}
diff --git a/TombEngine/Objects/Effects/LensFlare.h b/TombEngine/Objects/Effects/LensFlare.h
index be1e88f8f..3440e5ad8 100644
--- a/TombEngine/Objects/Effects/LensFlare.h
+++ b/TombEngine/Objects/Effects/LensFlare.h
@@ -17,7 +17,8 @@ namespace TEN::Entities::Effects
extern std::vector LensFlares;
+ void SetupGlobalLensFlare(const EulerAngles& orient, const Color& color, int spriteID);
+
void ControlLensFlare(int itemNumber);
void ClearLensFlares();
- void SetupGlobalLensFlare(const EulerAngles& orient, const Color& color, int spriteID);
}
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.h b/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.h
index e13f97d40..ab450b6e1 100644
--- a/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.h
+++ b/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.h
@@ -12,8 +12,8 @@ namespace TEN::Scripting
{
private:
// Members
- int _sunSpriteID = SPRITE_TYPES::SPR_LENS_FLARE_3;
- bool _isEnabled;
+ int _sunSpriteID = SPRITE_TYPES::SPR_LENS_FLARE_3;
+ bool _isEnabled = false;
Rotation _rotation = {};
ScriptColor _color = 0;
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.cpp b/TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.cpp
index b37703135..15cfde18b 100644
--- a/TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.cpp
@@ -50,8 +50,14 @@ namespace TEN::Scripting
// @treturn Starfield A new Starfield object.
Starfield::Starfield(int starCount, int meteorCount, int meteorSpawnDensity, float meteorVel)
{
- _starCount = starCount;
- _meteorCount = meteorCount;
+ if (starCount < 0 || starCount > STAR_COUNT_MAX)
+ TENLog("Star count must be in range [0, " + std::to_string(STAR_COUNT_MAX) + "].", LogLevel::Warning);
+
+ if (meteorCount < 0 || meteorCount > METEOR_COUNT_MAX)
+ TENLog("Meteor count must be in range [0, " + std::to_string(METEOR_COUNT_MAX) + "].", LogLevel::Warning);
+
+ _starCount = std::clamp(starCount, 0, STAR_COUNT_MAX);
+ _meteorCount = std::clamp(meteorCount, 0, METEOR_COUNT_MAX);
_meteorSpawnDensity = meteorSpawnDensity;
_meteorVelocity = meteorVel;
}
@@ -109,15 +115,10 @@ namespace TEN::Scripting
// @tparam int New count.
void Starfield::SetStarCount(int count)
{
- // Star count out of range; set max.
if (count < 0 || count > STAR_COUNT_MAX)
- {
TENLog("Star count must be in range [0, " + std::to_string(STAR_COUNT_MAX) + "].", LogLevel::Warning);
- _starCount = STAR_COUNT_MAX;
- return;
- }
- _starCount = count;
+ _starCount = std::clamp(count, 0, STAR_COUNT_MAX);
}
/// Set the starfield's number of meteors.
@@ -125,15 +126,10 @@ namespace TEN::Scripting
// @tparam int New count.
void Starfield::SetMeteorCount(int count)
{
- // Meteor count out of range; set max.
if (count < 0 || count > METEOR_COUNT_MAX)
- {
TENLog("Meteor count must be in range [0, " + std::to_string(METEOR_COUNT_MAX) + "].", LogLevel::Warning);
- _meteorCount = METEOR_COUNT_MAX;
- return;
- }
- _meteorCount = count;
+ _meteorCount = std::clamp(count, 0, METEOR_COUNT_MAX);
}
/// Set the starfield's meteor spawn density.
From af5bce3cf85ce142adb48d81319d967af7aec07c Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sat, 11 May 2024 00:29:21 +1000
Subject: [PATCH 159/410] Update TargetHighlighter.h
---
TombEngine/Game/Hud/TargetHighlighter.h | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/TombEngine/Game/Hud/TargetHighlighter.h b/TombEngine/Game/Hud/TargetHighlighter.h
index 9108137b4..f3be870a5 100644
--- a/TombEngine/Game/Hud/TargetHighlighter.h
+++ b/TombEngine/Game/Hud/TargetHighlighter.h
@@ -34,6 +34,12 @@ namespace TEN::Hud
std::array Segments = {};
+ Vector2 PrevPosition = Vector2::Zero;
+ short PrevOrientation = 0;
+ float PrevScale = 0.0f;
+ Vector4 PrevColor = Vector4::Zero;
+ std::array PrevSegments = {};
+
// Getters
float GetScale(float cameraDist) const;
float GetRadius() const;
@@ -47,12 +53,6 @@ namespace TEN::Hud
void Update(const Vector3& targetPos, bool isActive, bool doPulse);
void Draw() const;
- Vector2 PrevPosition = Vector2::Zero;
- short PrevOrientation = 0;
- float PrevScale = 0.0f;
- Vector4 PrevColor = Vector4::Zero;
- std::array PrevSegments = {};
-
void StoreInterpolationData()
{
PrevPosition = *Position;
From 715df20e1faab1cb86c0a9bbf568cb28c9ebc2e2 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sat, 11 May 2024 01:51:48 +1000
Subject: [PATCH 160/410] Fix crosshair angle interpolation
---
Documentation/doc/2 classes/Flow.LensFlare.html | 4 ++--
TombEngine/Game/Hud/TargetHighlighter.cpp | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/Documentation/doc/2 classes/Flow.LensFlare.html b/Documentation/doc/2 classes/Flow.LensFlare.html
index 825fe070e..4f972ab32 100644
--- a/Documentation/doc/2 classes/Flow.LensFlare.html
+++ b/Documentation/doc/2 classes/Flow.LensFlare.html
@@ -172,11 +172,11 @@
Pitch
float
- angle.
+ angle in degrees.
Yaw
float
- angle.
+ angle in degrees.
Color.
Color
diff --git a/TombEngine/Game/Hud/TargetHighlighter.cpp b/TombEngine/Game/Hud/TargetHighlighter.cpp
index cd52b5825..7cd768ba4 100644
--- a/TombEngine/Game/Hud/TargetHighlighter.cpp
+++ b/TombEngine/Game/Hud/TargetHighlighter.cpp
@@ -141,7 +141,7 @@ namespace TEN::Hud
return;
auto pos0 = Vector2::Lerp(*Position, PrevPosition, g_Renderer.GetInterpolationFactor());
- short orient0 = (short)Lerp(PrevOrientation, Orientation, g_Renderer.GetInterpolationFactor()); // TODO: use Geometry::GetShortestAngle()
+ short orient0 = PrevOrientation + (Geometry::GetShortestAngle(PrevOrientation, Orientation) * g_Renderer.GetInterpolationFactor());
float scale = Lerp(PrevScale, Scale, g_Renderer.GetInterpolationFactor());
auto color = Color::Lerp(PrevColor, Color, g_Renderer.GetInterpolationFactor());
@@ -159,7 +159,7 @@ namespace TEN::Hud
const auto& prevSegment = PrevSegments[i];
auto pos1 = pos0 + Vector2::Lerp(prevSegment.PosOffset, segment.PosOffset, g_Renderer.GetInterpolationFactor());
- short orient1 = orient0 + (short)Lerp(prevSegment.OrientOffset, segment.OrientOffset, g_Renderer.GetInterpolationFactor()); // TODO: use Geometry::GetShortestAngle()
+ short orient1 = orient0 + (prevSegment.OrientOffset + (Geometry::GetShortestAngle(prevSegment.OrientOffset, segment.OrientOffset) * g_Renderer.GetInterpolationFactor()));
AddDisplaySprite(
SPRITE_SEQUENCE_OBJECT_ID, SEGMENT_ELEMENT_SPRITE_ID,
From 895660fe5a2df006b0a0eb92fffd2acbecf268d0 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Sat, 11 May 2024 05:54:25 +0200
Subject: [PATCH 161/410] Fixed look at camera;
---
TombEngine/Game/camera.cpp | 2 +-
TombEngine/Renderer/ConstantBuffers/CameraMatrixBuffer.h | 3 ++-
TombEngine/Renderer/RendererDraw.cpp | 3 +++
TombEngine/Renderer/RendererHelper.cpp | 3 ---
TombEngine/Shaders/AnimatedTextures.hlsli | 2 +-
TombEngine/Shaders/CBCamera.hlsli | 3 ++-
6 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/TombEngine/Game/camera.cpp b/TombEngine/Game/camera.cpp
index e0863e650..722d1db91 100644
--- a/TombEngine/Game/camera.cpp
+++ b/TombEngine/Game/camera.cpp
@@ -202,7 +202,7 @@ void LookAt(CAMERA_INFO* cam, short roll)
float levelFarView = g_GameFlow->GetLevel(CurrentLevel)->GetFarView() * float(BLOCK(1));
- g_Renderer.UpdateCameraMatrices(cam, r, fov, levelFarView);
+ g_Renderer.UpdateCameraMatrices(cam, r, fov, levelFarView);
}
void AlterFOV(short value, bool store)
diff --git a/TombEngine/Renderer/ConstantBuffers/CameraMatrixBuffer.h b/TombEngine/Renderer/ConstantBuffers/CameraMatrixBuffer.h
index ed29faa40..9be9b953b 100644
--- a/TombEngine/Renderer/ConstantBuffers/CameraMatrixBuffer.h
+++ b/TombEngine/Renderer/ConstantBuffers/CameraMatrixBuffer.h
@@ -42,8 +42,9 @@ namespace TEN::Renderer::ConstantBuffers
float NearPlane;
float FarPlane;
//--
+ int RefreshRate;
int NumFogBulbs;
- Vector3 Padding2;
+ Vector2 Padding2;
//--
ShaderFogBulb FogBulbs[MAX_FOG_BULBS_DRAW];
};
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index 8b131c80e..9d0c992a4 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -1652,6 +1652,8 @@ namespace TEN::Renderer
if (_blinkTime > PI_MUL_2)
_blinkTime -= PI_MUL_2;
+ _oldGameCamera = _currentGameCamera;
+
_isLocked = false;
}
@@ -1771,6 +1773,7 @@ namespace TEN::Renderer
CCameraMatrixBuffer cameraConstantBuffer;
view.FillConstantBuffer(cameraConstantBuffer);
cameraConstantBuffer.Frame = GlobalCounter;
+ cameraConstantBuffer.RefreshRate = _refreshRate;
cameraConstantBuffer.CameraUnderwater = g_Level.Rooms[cameraConstantBuffer.RoomNumber].flags & ENV_FLAG_WATER;
cameraConstantBuffer.DualParaboloidView = Matrix::CreateLookAt(LaraItem->Pose.Position.ToVector3(), LaraItem->Pose.Position.ToVector3() + Vector3(0, 0, 1024), -Vector3::UnitY);
diff --git a/TombEngine/Renderer/RendererHelper.cpp b/TombEngine/Renderer/RendererHelper.cpp
index 7c69bf102..8dd9814bb 100644
--- a/TombEngine/Renderer/RendererHelper.cpp
+++ b/TombEngine/Renderer/RendererHelper.cpp
@@ -361,9 +361,6 @@ namespace TEN::Renderer
if (farView < MIN_FAR_VIEW)
farView = DEFAULT_FAR_VIEW;
- farView = farView;
-
- _oldGameCamera = _currentGameCamera;
_currentGameCamera = RenderView(cam, roll, fov, 32, farView, g_Configuration.ScreenWidth, g_Configuration.ScreenHeight);
_gameCamera = RenderView(cam, roll, fov, 32, farView, g_Configuration.ScreenWidth, g_Configuration.ScreenHeight);
}
diff --git a/TombEngine/Shaders/AnimatedTextures.hlsli b/TombEngine/Shaders/AnimatedTextures.hlsli
index bf733d74a..f43de521b 100644
--- a/TombEngine/Shaders/AnimatedTextures.hlsli
+++ b/TombEngine/Shaders/AnimatedTextures.hlsli
@@ -36,7 +36,7 @@ float2 CalculateUVRotate(float2 uv, unsigned int frame)
float2 GetFrame(unsigned int index, unsigned int offset)
{
- float speed = FPS / 30.0f;
+ float speed = (float)FPS / 30.0f;
int frame = int(Frame * speed + offset) % NumAnimFrames;
float2 result = 0;
diff --git a/TombEngine/Shaders/CBCamera.hlsli b/TombEngine/Shaders/CBCamera.hlsli
index 85dc4ac3d..2c627acb5 100644
--- a/TombEngine/Shaders/CBCamera.hlsli
+++ b/TombEngine/Shaders/CBCamera.hlsli
@@ -33,8 +33,9 @@ cbuffer CBCamera : register(b0)
float NearPlane;
float FarPlane;
//--
+ int RefreshRate;
int NumFogBulbs;
- float3 Padding2;
+ float2 Padding2;
//--
ShaderFogBulb FogBulbs[MAX_FOG_BULBS];
};
From 48d1c9ca10062e907528dc8aa039d46564a2437f Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Sat, 11 May 2024 06:02:24 +0200
Subject: [PATCH 162/410] Better handling of legacy 30 fps
---
TombEngine/Game/control/control.cpp | 27 +++++++++++++++++----------
1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index f8666c90f..eae248add 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -598,6 +598,8 @@ GameStatus DoGameLoop(int levelIndex)
controlLag += frameTime;
}
+ bool legacy30FPSdoneDraw = false;
+
while (controlLag >= controlFrameTime)
{
#if _DEBUG
@@ -615,22 +617,27 @@ GameStatus DoGameLoop(int levelIndex)
controlLag -= controlFrameTime;
controlCalls++;
- if (!g_Configuration.EnableVariableFramerate)
- {
- DrawPhase(!levelIndex, 0.0f);
- drawCalls++;
- }
+ legacy30FPSdoneDraw = false;
}
if (status != GameStatus::Normal)
break;
if (!g_Configuration.EnableVariableFramerate)
- continue;
-
- float interpolationFactor = std::min((float)controlLag / (float)controlFrameTime, 1.0f);
- DrawPhase(!levelIndex, interpolationFactor);
- drawCalls++;
+ {
+ if (!legacy30FPSdoneDraw)
+ {
+ DrawPhase(!levelIndex, 0.0f);
+ drawCalls++;
+ legacy30FPSdoneDraw = true;
+ }
+ }
+ else
+ {
+ float interpolationFactor = std::min((float)controlLag / (float)controlFrameTime, 1.0f);
+ DrawPhase(!levelIndex, interpolationFactor);
+ drawCalls++;
+ }
}
EndGameLoop(levelIndex, status);
From 8aa34857e045db30cf351efaf17304d67a54c015 Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Sat, 11 May 2024 10:12:42 +0200
Subject: [PATCH 163/410] Fix inventory spinback
---
TombEngine/Game/gui.cpp | 37 ++++++++++++++++++-------------------
TombEngine/Game/gui.h | 3 +++
2 files changed, 21 insertions(+), 19 deletions(-)
diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp
index a6a48b75c..953a9961b 100644
--- a/TombEngine/Game/gui.cpp
+++ b/TombEngine/Game/gui.cpp
@@ -193,6 +193,11 @@ namespace TEN::Gui
return false;
}
+ float GuiController::GetSpinSpeed()
+ {
+ return g_Configuration.EnableVariableFramerate ? (g_Renderer.GetScreenRefreshRate() / 30.0f) : 1.0f;
+ }
+
bool GuiController::CanDeselect() const
{
return !(IsHeld(In::Select) || IsHeld(In::Action));
@@ -2028,8 +2033,6 @@ namespace TEN::Gui
void GuiController::FadeAmmoSelector()
{
- float multiplier = g_Configuration.EnableVariableFramerate ? g_Renderer.GetScreenRefreshRate() / 30.0f : 1.0f;
-
if (Rings[(int)RingTypes::Inventory].RingActive)
{
AmmoSelectorFadeVal = 0;
@@ -2037,7 +2040,7 @@ namespace TEN::Gui
else if (AmmoSelectorFadeDir == 1)
{
if (AmmoSelectorFadeVal < 128)
- AmmoSelectorFadeVal += 32 / multiplier;
+ AmmoSelectorFadeVal += 32 / GetSpinSpeed();
if (AmmoSelectorFadeVal > 128)
{
@@ -2048,7 +2051,7 @@ namespace TEN::Gui
else if (AmmoSelectorFadeDir == 2)
{
if (AmmoSelectorFadeVal > 0)
- AmmoSelectorFadeVal -= 32 / multiplier;
+ AmmoSelectorFadeVal -= 32 / GetSpinSpeed();
if (AmmoSelectorFadeVal < 0)
{
@@ -2732,15 +2735,13 @@ namespace TEN::Gui
void GuiController::SpinBack(EulerAngles& orient)
{
- orient.Lerp(EulerAngles::Identity, 1.0f / 8);
+ orient.Lerp(EulerAngles::Identity, 1.0f / (8.0f * GetSpinSpeed()));
}
void GuiController::DrawAmmoSelector()
{
if (!AmmoSelectorFlag)
return;
-
- float multiplier = g_Configuration.EnableVariableFramerate ? g_Renderer.GetScreenRefreshRate() / 30.0f : 1.0f;
int xPos = (2 * PHD_CENTER_X - OBJLIST_SPACING) / 2;
if (NumAmmoSlots == 2)
@@ -2757,13 +2758,13 @@ namespace TEN::Gui
if (n == *CurrentAmmoType)
{
if (invObject->RotFlags & INV_ROT_X)
- AmmoObjectList[n].Orientation.x += ANGLE(5.0f / multiplier);
+ AmmoObjectList[n].Orientation.x += ANGLE(5.0f / GetSpinSpeed());
if (invObject->RotFlags & INV_ROT_Y)
- AmmoObjectList[n].Orientation.y += ANGLE(5.0f / multiplier);
+ AmmoObjectList[n].Orientation.y += ANGLE(5.0f / GetSpinSpeed());
if (invObject->RotFlags & INV_ROT_Z)
- AmmoObjectList[n].Orientation.z += ANGLE(5.0f / multiplier);
+ AmmoObjectList[n].Orientation.z += ANGLE(5.0f / GetSpinSpeed());
}
else
SpinBack(AmmoObjectList[n].Orientation);
@@ -2810,8 +2811,6 @@ namespace TEN::Gui
const auto& player = GetLaraInfo(*item);
auto& ring = Rings[(int)ringType];
- float multiplier = g_Configuration.EnableVariableFramerate ? g_Renderer.GetScreenRefreshRate() / 30.0f : 1.0f;
-
if (ring.CurrentObjectList <= 0)
return;
@@ -3137,13 +3136,13 @@ namespace TEN::Gui
if (!i && !ring.ObjectListMovement)
{
if (invObject.RotFlags & INV_ROT_X)
- listObject.Orientation.x += ANGLE(5.0f / multiplier);
+ listObject.Orientation.x += ANGLE(5.0f / GetSpinSpeed());
if (invObject.RotFlags & INV_ROT_Y)
- listObject.Orientation.y += ANGLE(5.0f / multiplier);
+ listObject.Orientation.y += ANGLE(5.0f / GetSpinSpeed());
if (invObject.RotFlags & INV_ROT_Z)
- listObject.Orientation.z += ANGLE(5.0f / multiplier);
+ listObject.Orientation.z += ANGLE(5.0f / GetSpinSpeed());
}
else
{
@@ -3199,17 +3198,17 @@ namespace TEN::Gui
if (ring.NumObjectsInList != 1 && (ringType != RingTypes::Ammo || CombineRingFadeVal == 128))
{
if (ring.ObjectListMovement > 0)
- ring.ObjectListMovement += ANGLE(45.0f / multiplier);
+ ring.ObjectListMovement += ANGLE(45.0f / GetSpinSpeed());
if (ring.ObjectListMovement < 0)
- ring.ObjectListMovement -= ANGLE(45.0f / multiplier);
+ ring.ObjectListMovement -= ANGLE(45.0f / GetSpinSpeed());
if (IsHeld(In::Left))
{
if (!ring.ObjectListMovement)
{
SoundEffect(SFX_TR4_MENU_ROTATE, nullptr, SoundEnvironment::Always);
- ring.ObjectListMovement += ANGLE(45.0f / multiplier);
+ ring.ObjectListMovement += ANGLE(45.0f / GetSpinSpeed());
if (AmmoSelectorFlag)
AmmoSelectorFadeDir = 2;
@@ -3221,7 +3220,7 @@ namespace TEN::Gui
if (!ring.ObjectListMovement)
{
SoundEffect(SFX_TR4_MENU_ROTATE, nullptr, SoundEnvironment::Always);
- ring.ObjectListMovement -= ANGLE(45.0f / multiplier);
+ ring.ObjectListMovement -= ANGLE(45.0f / GetSpinSpeed());
if (AmmoSelectorFlag)
AmmoSelectorFadeDir = 2;
diff --git a/TombEngine/Game/gui.h b/TombEngine/Game/gui.h
index bf4a4baea..f63e35b0e 100644
--- a/TombEngine/Game/gui.h
+++ b/TombEngine/Game/gui.h
@@ -127,6 +127,9 @@ namespace TEN::Gui
bool CanSelect() const;
bool CanDeselect() const;
+ // Variable FPS
+ float GetSpinSpeed();
+
// GUI variables
Menu MenuToDisplay = Menu::Title;
int SelectedOption;
From 09d756a75f6c13f03ec7042bcc632842c5e1dbe8 Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Sat, 11 May 2024 10:38:35 +0200
Subject: [PATCH 164/410] Only disable interpolation in scripting method if
difference is big enough
---
.../TEN/Objects/Moveable/MoveableObject.cpp | 22 +++++++++++--------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp
index 4e5a62952..90ca4bdd7 100644
--- a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp
@@ -580,8 +580,10 @@ Vec3 Moveable::GetPos() const
// @bool[opt] updateRoom Will room changes be automatically detected? Set to false if you are using overlapping rooms (default: true)
void Moveable::SetPos(const Vec3& pos, sol::optional updateRoom)
{
- auto prevPos = m_item->Pose.Position.ToVector3();
- m_item->Pose.Position = pos.ToVector3i();
+ auto newPos = pos.ToVector3i();
+ bool bigDistance = Vector3i::Distance(newPos, m_item->Pose.Position) > CLICK(1);
+
+ m_item->Pose.Position = newPos;
bool willUpdate = !updateRoom.has_value() || updateRoom.value();
@@ -590,8 +592,7 @@ void Moveable::SetPos(const Vec3& pos, sol::optional updateRoom)
bool isRoomUpdated = m_item->IsLara() ? UpdateLaraRoom(m_item, pos.y) : UpdateItemRoom(m_item->Index);
// In case direct portal room update didn't happen and distance between old and new points is significant, do predictive room update.
- if (!isRoomUpdated &&
- (willUpdate || Vector3::Distance(prevPos, m_item->Pose.Position.ToVector3()) > BLOCK(1)))
+ if (!isRoomUpdated && (willUpdate || bigDistance))
{
int potentialNewRoom = FindRoomNumber(m_item->Pose.Position, m_item->RoomNumber);
if (potentialNewRoom != m_item->RoomNumber)
@@ -602,7 +603,8 @@ void Moveable::SetPos(const Vec3& pos, sol::optional updateRoom)
if (m_item->IsBridge())
UpdateBridgeItem(*m_item);
- m_item->DisableInterpolation = true;
+ if (bigDistance)
+ m_item->DisableInterpolation = true;
}
Vec3 Moveable::GetJointPos(int jointIndex) const
@@ -627,14 +629,16 @@ Rotation Moveable::GetRot() const
void Moveable::SetRot(const Rotation& rot)
{
- m_item->Pose.Orientation.x = ANGLE(rot.x);
- m_item->Pose.Orientation.y = ANGLE(rot.y);
- m_item->Pose.Orientation.z = ANGLE(rot.z);
+ auto newRot = rot.ToEulerAngles();
+ bool bigRotation = EulerAngles::Compare(newRot, m_item->Pose.Orientation, ANGLE(30.0f));
+
+ m_item->Pose.Orientation = newRot;
if (m_item->IsBridge())
UpdateBridgeItem(*m_item);
- m_item->DisableInterpolation = true;
+ if (bigRotation)
+ m_item->DisableInterpolation = true;
}
short Moveable::GetHP() const
From 796354e67af3aff4cdcb7dcdf9171193dabe562e Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Sat, 11 May 2024 10:59:07 +0200
Subject: [PATCH 165/410] Invert SetRot interpolation condition
---
.../Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp
index 90ca4bdd7..7987d2366 100644
--- a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp
@@ -630,7 +630,7 @@ Rotation Moveable::GetRot() const
void Moveable::SetRot(const Rotation& rot)
{
auto newRot = rot.ToEulerAngles();
- bool bigRotation = EulerAngles::Compare(newRot, m_item->Pose.Orientation, ANGLE(30.0f));
+ bool bigRotation = !EulerAngles::Compare(newRot, m_item->Pose.Orientation, ANGLE(30.0f));
m_item->Pose.Orientation = newRot;
From 98f4caec8045226c1c2ac82c8a775e03f0cba2f3 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Sun, 12 May 2024 05:42:08 +0200
Subject: [PATCH 166/410] Fixed missing strings in inventory
---
TombEngine/Game/gui.cpp | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp
index 953a9961b..42411c31d 100644
--- a/TombEngine/Game/gui.cpp
+++ b/TombEngine/Game/gui.cpp
@@ -279,7 +279,6 @@ namespace TEN::Gui
void GuiController::DrawInventory()
{
- g_Renderer.PrepareScene();
g_Renderer.RenderInventory();
g_Renderer.Lock(); // TODO: When inventory is converted to 60 FPS, move this lock call outside of render loop.
}
@@ -3273,8 +3272,13 @@ namespace TEN::Gui
while (g_Gui.GetInventoryMode() == InventoryMode::Pause)
{
- g_Gui.DrawInventory();
- g_Renderer.Synchronize();
+ g_Renderer.PrepareScene();
+ g_Renderer.RenderInventory();
+ g_Renderer.Lock();
+ if (!g_Configuration.EnableVariableFramerate)
+ {
+ g_Renderer.Synchronize();
+ }
if (g_Gui.DoPauseMenu(LaraItem) == InventoryResult::ExitToTitle)
{
@@ -3329,7 +3333,7 @@ namespace TEN::Gui
exitLoop = true;
}
- DrawInventory();
+ g_Renderer.PrepareScene();
switch (InvMode)
{
@@ -3387,6 +3391,8 @@ namespace TEN::Gui
SetEnterInventory(NO_VALUE);
+ g_Renderer.RenderInventory();
+ g_Renderer.Lock();
if (!g_Configuration.EnableVariableFramerate)
{
g_Renderer.Synchronize();
From 5bd68efc108f2ea23fc3d64c2919629a52b8d24c Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Sun, 12 May 2024 06:02:09 +0200
Subject: [PATCH 167/410] WIP better inventory game loop
---
TombEngine/Game/gui.cpp | 154 ++++++++++++++++++++++++++--------------
1 file changed, 100 insertions(+), 54 deletions(-)
diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp
index 42411c31d..b86f1de38 100644
--- a/TombEngine/Game/gui.cpp
+++ b/TombEngine/Game/gui.cpp
@@ -3313,6 +3313,19 @@ namespace TEN::Gui
InitializeInventory(item);
Camera.numberFrames = 2;
+ LARGE_INTEGER lastTime;
+ LARGE_INTEGER currentTime;
+ double controlLag = 0;
+ double frameTime = 0;
+ constexpr auto controlFrameTime = 1000.0f / 30.0f;
+
+ LARGE_INTEGER frequency;
+ QueryPerformanceFrequency(&frequency);
+ QueryPerformanceCounter(&lastTime);
+
+ int controlCalls = 0;
+ int drawCalls = 0;
+
bool exitLoop = false;
while (!exitLoop)
{
@@ -3322,81 +3335,114 @@ namespace TEN::Gui
return false;
}
- TimeInMenu++;
- GameTimer++;
-
- UpdateInputActions(item);
-
- if (GuiIsDeselected() || IsClicked(In::Inventory))
+ if (App.ResetClock)
{
- SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always);
- exitLoop = true;
+ App.ResetClock = false;
+ QueryPerformanceCounter(&lastTime);
+ currentTime = lastTime;
+ controlLag = 0;
+ frameTime = 0;
+ }
+ else
+ {
+ QueryPerformanceCounter(¤tTime);
+ frameTime = (currentTime.QuadPart - lastTime.QuadPart) * 1000.0 / frequency.QuadPart;
+ lastTime = currentTime;
+ controlLag += frameTime;
}
- g_Renderer.PrepareScene();
-
- switch (InvMode)
+ while (controlLag >= controlFrameTime)
{
- case InventoryMode::InGame:
- DoInventory(item);
- break;
+#if _DEBUG
+ constexpr auto DEBUG_SKIP_FRAMES = 10;
- case InventoryMode::Statistics:
- DoStatisticsMode();
- break;
-
- case InventoryMode::Examine:
- DoExamineMode();
- break;
-
- case InventoryMode::Diary:
- DoDiary(item);
- break;
-
- case InventoryMode::Load:
- switch (DoLoad())
+ if (controlLag >= DEBUG_SKIP_FRAMES * controlFrameTime)
{
- case LoadResult::Load:
- doLoad = true;
+ TENLog("Game loop is running too slow!", LogLevel::Warning);
+ App.ResetClock = true;
+ break;
+ }
+#endif
+ TimeInMenu++;
+ GameTimer++;
+
+ UpdateInputActions(item);
+
+ if (GuiIsDeselected() || IsClicked(In::Inventory))
+ {
+ SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always);
exitLoop = true;
- break;
-
- case LoadResult::Cancel:
- exitLoop = !resetMode;
-
- if (resetMode)
- SetInventoryMode(InventoryMode::InGame);
-
- break;
-
- case LoadResult::None:
- break;
}
- break;
+ g_Renderer.PrepareScene();
- case InventoryMode::Save:
- if (DoSave())
+ switch (InvMode)
{
- exitLoop = !resetMode;
- if (resetMode)
- SetInventoryMode(InventoryMode::InGame);
+ case InventoryMode::InGame:
+ DoInventory(item);
+ break;
+
+ case InventoryMode::Statistics:
+ DoStatisticsMode();
+ break;
+
+ case InventoryMode::Examine:
+ DoExamineMode();
+ break;
+
+ case InventoryMode::Diary:
+ DoDiary(item);
+ break;
+
+ case InventoryMode::Load:
+ switch (DoLoad())
+ {
+ case LoadResult::Load:
+ doLoad = true;
+ exitLoop = true;
+ break;
+
+ case LoadResult::Cancel:
+ exitLoop = !resetMode;
+
+ if (resetMode)
+ SetInventoryMode(InventoryMode::InGame);
+
+ break;
+
+ case LoadResult::None:
+ break;
+ }
+
+ break;
+
+ case InventoryMode::Save:
+ if (DoSave())
+ {
+ exitLoop = !resetMode;
+ if (resetMode)
+ SetInventoryMode(InventoryMode::InGame);
+ }
+
+ break;
}
- break;
+ if (ItemUsed && NoAction())
+ exitLoop = true;
+
+ SetEnterInventory(NO_VALUE);
+ controlLag -= controlFrameTime;
+ controlCalls++;
}
- if (ItemUsed && NoAction())
- exitLoop = true;
-
- SetEnterInventory(NO_VALUE);
-
g_Renderer.RenderInventory();
g_Renderer.Lock();
if (!g_Configuration.EnableVariableFramerate)
{
g_Renderer.Synchronize();
}
+
+ drawCalls++;
}
LastInvItem = Rings[(int)RingTypes::Inventory].CurrentObjectList[Rings[(int)RingTypes::Inventory].CurrentObjectInList].InventoryItem;
From bb4e64812122d3420c9156aa69e3db08e341084a Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Sun, 12 May 2024 15:45:44 +0200
Subject: [PATCH 168/410] WIP fixes for other menus
---
TombEngine/Game/gui.cpp | 113 +++++++++++++++++++++++----
TombEngine/Renderer/Renderer.h | 1 +
TombEngine/Renderer/RendererDraw.cpp | 2 +-
3 files changed, 99 insertions(+), 17 deletions(-)
diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp
index b86f1de38..5f1afb82d 100644
--- a/TombEngine/Game/gui.cpp
+++ b/TombEngine/Game/gui.cpp
@@ -1191,7 +1191,6 @@ namespace TEN::Gui
case Menu::Display:
HandleDisplaySettingsInput(true);
- App.ResetClock = true;
return InventoryResult::None;
case Menu::GeneralActions:
@@ -1199,12 +1198,10 @@ namespace TEN::Gui
case Menu::QuickActions:
case Menu::MenuActions:
HandleControlSettingsInput(item, true);
- App.ResetClock = true;
return InventoryResult::None;
case Menu::OtherSettings:
HandleOtherSettingsInput(true);
- App.ResetClock = true;
return InventoryResult::None;
}
@@ -1288,7 +1285,6 @@ namespace TEN::Gui
}
}
- App.ResetClock = true;
return InventoryResult::None;
}
@@ -3270,21 +3266,93 @@ namespace TEN::Gui
bool doExitToTitle = false;
+ LARGE_INTEGER lastTime;
+ LARGE_INTEGER currentTime;
+ double controlLag = 0;
+ double frameTime = 0;
+ constexpr auto controlFrameTime = 1000.0f / 30.0f;
+
+ LARGE_INTEGER frequency;
+ QueryPerformanceFrequency(&frequency);
+ QueryPerformanceCounter(&lastTime);
+
+ int controlCalls = 0;
+ int drawCalls = 0;
+
while (g_Gui.GetInventoryMode() == InventoryMode::Pause)
{
- g_Renderer.PrepareScene();
- g_Renderer.RenderInventory();
- g_Renderer.Lock();
- if (!g_Configuration.EnableVariableFramerate)
+ if (ThreadEnded)
{
- g_Renderer.Synchronize();
+ App.ResetClock = true;
+ return false;
}
- if (g_Gui.DoPauseMenu(LaraItem) == InventoryResult::ExitToTitle)
+ if (App.ResetClock)
+ {
+ App.ResetClock = false;
+ QueryPerformanceCounter(&lastTime);
+ currentTime = lastTime;
+ controlLag = 0;
+ frameTime = 0;
+ }
+ else
+ {
+ QueryPerformanceCounter(¤tTime);
+ frameTime = (currentTime.QuadPart - lastTime.QuadPart) * 1000.0 / frequency.QuadPart;
+ lastTime = currentTime;
+ controlLag += frameTime;
+ }
+
+ bool legacy30FPSdoneDraw = false;
+
+ while (controlLag >= controlFrameTime)
+ {
+#if _DEBUG
+ constexpr auto DEBUG_SKIP_FRAMES = 10;
+
+ if (controlLag >= DEBUG_SKIP_FRAMES * controlFrameTime)
+ {
+ TENLog("Game loop is running too slow!", LogLevel::Warning);
+ App.ResetClock = true;
+ break;
+ }
+#endif
+ g_Renderer.PrepareScene();
+
+ if (g_Gui.DoPauseMenu(LaraItem) == InventoryResult::ExitToTitle)
+ {
+ doExitToTitle = true;
+ break;
+ }
+
+ controlLag -= controlFrameTime;
+ controlCalls++;
+
+ legacy30FPSdoneDraw = false;
+ }
+
+ if (doExitToTitle)
{
- doExitToTitle = true;
break;
}
+
+ if (!g_Configuration.EnableVariableFramerate)
+ {
+ if (!legacy30FPSdoneDraw)
+ {
+ g_Renderer.RenderInventory();
+ g_Renderer.Lock();
+ g_Renderer.Synchronize();
+ drawCalls++;
+ legacy30FPSdoneDraw = true;
+ }
+ }
+ else
+ {
+ g_Renderer.RenderInventory();
+ g_Renderer.Lock();
+ drawCalls++;
+ }
}
if (doExitToTitle)
@@ -3351,6 +3419,8 @@ namespace TEN::Gui
controlLag += frameTime;
}
+ bool legacy30FPSdoneDraw = false;
+
while (controlLag >= controlFrameTime)
{
#if _DEBUG
@@ -3433,16 +3503,27 @@ namespace TEN::Gui
SetEnterInventory(NO_VALUE);
controlLag -= controlFrameTime;
controlCalls++;
+
+ legacy30FPSdoneDraw = false;
}
- g_Renderer.RenderInventory();
- g_Renderer.Lock();
if (!g_Configuration.EnableVariableFramerate)
{
- g_Renderer.Synchronize();
+ if (!legacy30FPSdoneDraw)
+ {
+ g_Renderer.RenderInventory();
+ g_Renderer.Lock();
+ g_Renderer.Synchronize();
+ drawCalls++;
+ legacy30FPSdoneDraw = true;
+ }
+ }
+ else
+ {
+ g_Renderer.RenderInventory();
+ g_Renderer.Lock();
+ drawCalls++;
}
-
- drawCalls++;
}
LastInvItem = Rings[(int)RingTypes::Inventory].CurrentObjectList[Rings[(int)RingTypes::Inventory].CurrentObjectInList].InventoryItem;
diff --git a/TombEngine/Renderer/Renderer.h b/TombEngine/Renderer/Renderer.h
index 8d058514d..41ed018ce 100644
--- a/TombEngine/Renderer/Renderer.h
+++ b/TombEngine/Renderer/Renderer.h
@@ -202,6 +202,7 @@ namespace TEN::Renderer
std::vector _stringsToDraw;
float _blinkColorValue = 0.0f;
float _blinkTime = 0.0f;
+ float _oldBlinkTime = 0.0f;
// Graphics resources
Texture2D _logo;
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index 9d0c992a4..78cb5ef4e 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -1648,7 +1648,7 @@ namespace TEN::Renderer
_blinkColorValue = ((sin(_blinkTime) + BLINK_VALUE_MAX) * 0.5f) + BLINK_VALUE_MIN;
// Update blink time.
- _blinkTime += BLINK_TIME_STEP;
+ _blinkTime += BLINK_TIME_STEP / (g_Configuration.EnableVariableFramerate ? (g_Renderer.GetScreenRefreshRate() / 30.0f) : 1.0f);
if (_blinkTime > PI_MUL_2)
_blinkTime -= PI_MUL_2;
From a7b697e75640c96e50055b507eb93015249c30f3 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Mon, 13 May 2024 00:16:07 +1000
Subject: [PATCH 169/410] Minor formatting
---
TombEngine/Game/gui.cpp | 46 ++++++++++++++++++++++-------------------
1 file changed, 25 insertions(+), 21 deletions(-)
diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp
index 5f1afb82d..628e799a6 100644
--- a/TombEngine/Game/gui.cpp
+++ b/TombEngine/Game/gui.cpp
@@ -3256,6 +3256,8 @@ namespace TEN::Gui
bool GuiController::CallPause()
{
+ constexpr auto CONTROL_FRAME_TIME = 1000.0f / 30.0f;
+
g_Renderer.DumpGameScene();
PauseAllSounds(SoundPauseMode::Pause);
SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always);
@@ -3270,7 +3272,6 @@ namespace TEN::Gui
LARGE_INTEGER currentTime;
double controlLag = 0;
double frameTime = 0;
- constexpr auto controlFrameTime = 1000.0f / 30.0f;
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
@@ -3303,16 +3304,16 @@ namespace TEN::Gui
controlLag += frameTime;
}
- bool legacy30FPSdoneDraw = false;
+ bool legacy30FpsDoneDraw = false;
- while (controlLag >= controlFrameTime)
+ while (controlLag >= CONTROL_FRAME_TIME)
{
#if _DEBUG
constexpr auto DEBUG_SKIP_FRAMES = 10;
- if (controlLag >= DEBUG_SKIP_FRAMES * controlFrameTime)
+ if (controlLag >= (DEBUG_SKIP_FRAMES * CONTROL_FRAME_TIME))
{
- TENLog("Game loop is running too slow!", LogLevel::Warning);
+ TENLog("Game loop is running too slow.", LogLevel::Warning);
App.ResetClock = true;
break;
}
@@ -3325,26 +3326,24 @@ namespace TEN::Gui
break;
}
- controlLag -= controlFrameTime;
+ controlLag -= CONTROL_FRAME_TIME;
controlCalls++;
- legacy30FPSdoneDraw = false;
+ legacy30FpsDoneDraw = false;
}
if (doExitToTitle)
- {
break;
- }
if (!g_Configuration.EnableVariableFramerate)
{
- if (!legacy30FPSdoneDraw)
+ if (!legacy30FpsDoneDraw)
{
g_Renderer.RenderInventory();
g_Renderer.Lock();
g_Renderer.Synchronize();
drawCalls++;
- legacy30FPSdoneDraw = true;
+ legacy30FpsDoneDraw = true;
}
}
else
@@ -3356,15 +3355,21 @@ namespace TEN::Gui
}
if (doExitToTitle)
+ {
StopAllSounds();
+ }
else
+ {
ResumeAllSounds(SoundPauseMode::Pause);
+ }
return doExitToTitle;
}
bool GuiController::CallInventory(ItemInfo* item, bool resetMode)
{
+ constexpr auto CONTROL_FRAME_TIME = 1000.0f / 30.0f;
+
auto* lara = GetLaraInfo(item);
bool doLoad = false;
@@ -3385,7 +3390,6 @@ namespace TEN::Gui
LARGE_INTEGER currentTime;
double controlLag = 0;
double frameTime = 0;
- constexpr auto controlFrameTime = 1000.0f / 30.0f;
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
@@ -3419,16 +3423,16 @@ namespace TEN::Gui
controlLag += frameTime;
}
- bool legacy30FPSdoneDraw = false;
+ bool legacy30FpsDoneDraw = false;
- while (controlLag >= controlFrameTime)
+ while (controlLag >= CONTROL_FRAME_TIME)
{
#if _DEBUG
- constexpr auto DEBUG_SKIP_FRAMES = 10;
+ constexpr auto DEBUG_SKIP_FRAME_COUNT = 10;
- if (controlLag >= DEBUG_SKIP_FRAMES * controlFrameTime)
+ if (controlLag >= (DEBUG_SKIP_FRAME_COUNT * CONTROL_FRAME_TIME))
{
- TENLog("Game loop is running too slow!", LogLevel::Warning);
+ TENLog("Game loop is running too slow.", LogLevel::Warning);
App.ResetClock = true;
break;
}
@@ -3501,21 +3505,21 @@ namespace TEN::Gui
exitLoop = true;
SetEnterInventory(NO_VALUE);
- controlLag -= controlFrameTime;
+ controlLag -= CONTROL_FRAME_TIME;
controlCalls++;
- legacy30FPSdoneDraw = false;
+ legacy30FpsDoneDraw = false;
}
if (!g_Configuration.EnableVariableFramerate)
{
- if (!legacy30FPSdoneDraw)
+ if (!legacy30FpsDoneDraw)
{
g_Renderer.RenderInventory();
g_Renderer.Lock();
g_Renderer.Synchronize();
drawCalls++;
- legacy30FPSdoneDraw = true;
+ legacy30FpsDoneDraw = true;
}
}
else
From 24a8dd3b47b0ec7c79738f1a3b350c614bea89a8 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Mon, 13 May 2024 06:06:17 +0200
Subject: [PATCH 170/410] Fix occasional freeze after calling pause menu
---
TombEngine/Game/gui.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp
index 5f1afb82d..ea88f039f 100644
--- a/TombEngine/Game/gui.cpp
+++ b/TombEngine/Game/gui.cpp
@@ -3360,6 +3360,8 @@ namespace TEN::Gui
else
ResumeAllSounds(SoundPauseMode::Pause);
+ App.ResetClock = true;
+
return doExitToTitle;
}
From 46b3b383a63514d73f8ff5e0a10859ab9ea3a00f Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Tue, 14 May 2024 11:53:54 +0200
Subject: [PATCH 171/410] Added animated textures support in G-Buffer creation
for rooms
---
TombEngine/Renderer/Renderer.h | 1 +
TombEngine/Renderer/RendererDraw.cpp | 12 +++++++++++-
TombEngine/Renderer/RendererInit.cpp | 1 +
TombEngine/Shaders/GBuffer.fx | 12 +++++++++++-
4 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/TombEngine/Renderer/Renderer.h b/TombEngine/Renderer/Renderer.h
index 41ed018ce..7bc8a35a0 100644
--- a/TombEngine/Renderer/Renderer.h
+++ b/TombEngine/Renderer/Renderer.h
@@ -151,6 +151,7 @@ namespace TEN::Renderer
ComPtr _psHUDTexture;
ComPtr _psHUDBarColor;
ComPtr _vsGBufferRooms;
+ ComPtr _vsGBufferRoomsAnimated;
ComPtr _vsGBufferItems;
ComPtr _vsGBufferStatics;
ComPtr _vsGBufferInstancedStatics;
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index 78cb5ef4e..401b1ec0d 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -2630,7 +2630,6 @@ namespace TEN::Renderer
{
if (rendererPass == RendererPass::GBuffer)
{
- _context->VSSetShader(_vsGBufferRooms.Get(), nullptr, 0);
_context->PSSetShader(_psGBuffer.Get(), nullptr, 0);
}
else
@@ -2709,6 +2708,17 @@ namespace TEN::Renderer
_context->VSSetShader(_vsRoomsAnimatedTextures.Get(), nullptr, 0);
}
}
+ else
+ {
+ if (animated == 0)
+ {
+ _context->VSSetShader(_vsGBufferRooms.Get(), nullptr, 0);
+ }
+ else
+ {
+ _context->VSSetShader(_vsGBufferRoomsAnimated.Get(), nullptr, 0);
+ }
+ }
for (auto& bucket : room->Buckets)
{
diff --git a/TombEngine/Renderer/RendererInit.cpp b/TombEngine/Renderer/RendererInit.cpp
index d382d191d..78f714ed0 100644
--- a/TombEngine/Renderer/RendererInit.cpp
+++ b/TombEngine/Renderer/RendererInit.cpp
@@ -86,6 +86,7 @@ namespace TEN::Renderer
_vsInstancedSprites = Utils::compileVertexShader(_device.Get(), GetAssetPath(L"Shaders\\InstancedSprites.fx"), "VS", "vs_5_0", nullptr, blob);
_psInstancedSprites = Utils::compilePixelShader(_device.Get(), GetAssetPath(L"Shaders\\InstancedSprites.fx"), "PS", "ps_5_0", nullptr, blob);
_vsGBufferRooms = Utils::compileVertexShader(_device.Get(), GetAssetPath(L"Shaders\\GBuffer.fx"), "VSRooms", "vs_5_0", nullptr, blob);
+ _vsGBufferRoomsAnimated = Utils::compileVertexShader(_device.Get(), GetAssetPath(L"Shaders\\GBuffer.fx"), "VSRooms", "vs_5_0", &roomDefinesAnimated[0], blob);
_vsGBufferItems = Utils::compileVertexShader(_device.Get(), GetAssetPath(L"Shaders\\GBuffer.fx"), "VSItems", "vs_5_0", nullptr, blob);
_vsGBufferStatics = Utils::compileVertexShader(_device.Get(), GetAssetPath(L"Shaders\\GBuffer.fx"), "VSStatics", "vs_5_0", nullptr, blob);
_vsGBufferInstancedStatics = Utils::compileVertexShader(_device.Get(), GetAssetPath(L"Shaders\\GBuffer.fx"), "VSInstancedStatics", "vs_5_0", nullptr, blob);
diff --git a/TombEngine/Shaders/GBuffer.fx b/TombEngine/Shaders/GBuffer.fx
index 830ed1c33..566ca6518 100644
--- a/TombEngine/Shaders/GBuffer.fx
+++ b/TombEngine/Shaders/GBuffer.fx
@@ -1,6 +1,7 @@
#include "./CBCamera.hlsli"
#include "./VertexInput.hlsli"
#include "./VertexEffects.hlsli"
+#include "./AnimatedTextures.hlsli"
#include "./Blending.hlsli"
#include "./Math.hlsli"
@@ -102,7 +103,16 @@ PixelShaderInput VSRooms(VertexShaderInput input)
output.Tangent = input.Tangent;
output.Binormal = input.Binormal;
output.PositionCopy = screenPos;
- output.UV = input.UV;
+
+#ifdef ANIMATED
+
+ if (Type == 0)
+ output.UV = GetFrame(input.PolyIndex, input.AnimationFrameOffset);
+ else
+ output.UV = input.UV; // TODO: true UVRotate in future?
+#else
+ output.UV = input.UV;
+#endif
return output;
}
From 2a0f01824765bc9096371027a430111975aa15e3 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Tue, 14 May 2024 12:15:06 +0200
Subject: [PATCH 172/410] Fixed flickering transparent sorted faces; Fixed
variable framerate always on even if disabled in settings;
---
TombEngine/Game/control/control.cpp | 4 ++--
TombEngine/Game/gui.cpp | 8 ++++----
TombEngine/Renderer/RenderView.cpp | 1 +
3 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index eae248add..813d29b12 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -579,6 +579,8 @@ GameStatus DoGameLoop(int levelIndex)
int controlCalls = 0;
int drawCalls = 0;
+
+ bool legacy30FPSdoneDraw = false;
while (DoTheGame)
{
@@ -598,8 +600,6 @@ GameStatus DoGameLoop(int levelIndex)
controlLag += frameTime;
}
- bool legacy30FPSdoneDraw = false;
-
while (controlLag >= controlFrameTime)
{
#if _DEBUG
diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp
index 83e875041..31efc000f 100644
--- a/TombEngine/Game/gui.cpp
+++ b/TombEngine/Game/gui.cpp
@@ -3280,6 +3280,8 @@ namespace TEN::Gui
int controlCalls = 0;
int drawCalls = 0;
+ bool legacy30FpsDoneDraw = false;
+
while (g_Gui.GetInventoryMode() == InventoryMode::Pause)
{
if (ThreadEnded)
@@ -3304,8 +3306,6 @@ namespace TEN::Gui
controlLag += frameTime;
}
- bool legacy30FpsDoneDraw = false;
-
while (controlLag >= CONTROL_FRAME_TIME)
{
#if _DEBUG
@@ -3400,7 +3400,9 @@ namespace TEN::Gui
int controlCalls = 0;
int drawCalls = 0;
+ bool legacy30FpsDoneDraw = false;
bool exitLoop = false;
+
while (!exitLoop)
{
if (ThreadEnded)
@@ -3425,8 +3427,6 @@ namespace TEN::Gui
controlLag += frameTime;
}
- bool legacy30FpsDoneDraw = false;
-
while (controlLag >= CONTROL_FRAME_TIME)
{
#if _DEBUG
diff --git a/TombEngine/Renderer/RenderView.cpp b/TombEngine/Renderer/RenderView.cpp
index 6558d062c..1f02db401 100644
--- a/TombEngine/Renderer/RenderView.cpp
+++ b/TombEngine/Renderer/RenderView.cpp
@@ -52,6 +52,7 @@ namespace TEN::Renderer
SortedStaticsToDraw.clear();
FogBulbsToDraw.clear();
LensFlaresToDraw.clear();
+ TransparentObjectsToDraw.clear();
}
RenderViewCamera::RenderViewCamera(CAMERA_INFO* cam, float roll, float fov, float n, float f, int w, int h)
From f9963f7940804910d20a834ae3a33afdb7463d9e Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Tue, 14 May 2024 22:51:47 +0200
Subject: [PATCH 173/410] Fix slow text fade
---
TombEngine/Renderer/RendererDraw.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index 401b1ec0d..a1c0966b7 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -1648,7 +1648,7 @@ namespace TEN::Renderer
_blinkColorValue = ((sin(_blinkTime) + BLINK_VALUE_MAX) * 0.5f) + BLINK_VALUE_MIN;
// Update blink time.
- _blinkTime += BLINK_TIME_STEP / (g_Configuration.EnableVariableFramerate ? (g_Renderer.GetScreenRefreshRate() / 30.0f) : 1.0f);
+ _blinkTime += BLINK_TIME_STEP;
if (_blinkTime > PI_MUL_2)
_blinkTime -= PI_MUL_2;
From 15da2fcc874b5b7e06420f87dc780e806a307abf Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Wed, 15 May 2024 09:01:03 +0200
Subject: [PATCH 174/410] Removed old numberFrames field from camera
---
TombEngine/Game/camera.cpp | 1 -
TombEngine/Game/camera.h | 1 -
TombEngine/Game/gui.cpp | 1 -
3 files changed, 3 deletions(-)
diff --git a/TombEngine/Game/camera.cpp b/TombEngine/Game/camera.cpp
index 722d1db91..b3733f0d1 100644
--- a/TombEngine/Game/camera.cpp
+++ b/TombEngine/Game/camera.cpp
@@ -248,7 +248,6 @@ void InitializeCamera()
Camera.targetDistance = BLOCK(1.5f);
Camera.item = nullptr;
- Camera.numberFrames = 1;
Camera.type = CameraType::Chase;
Camera.speed = 1;
Camera.flags = CF_NONE;
diff --git a/TombEngine/Game/camera.h b/TombEngine/Game/camera.h
index 504a59ed4..969dec236 100644
--- a/TombEngine/Game/camera.h
+++ b/TombEngine/Game/camera.h
@@ -28,7 +28,6 @@ struct CAMERA_INFO
int flags;
bool fixedCamera;
bool underwater;
- int numberFrames;
int bounce;
int targetDistance;
short targetAngle;
diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp
index 31efc000f..6af798543 100644
--- a/TombEngine/Game/gui.cpp
+++ b/TombEngine/Game/gui.cpp
@@ -3386,7 +3386,6 @@ namespace TEN::Gui
SetInventoryMode(InventoryMode::InGame);
InitializeInventory(item);
- Camera.numberFrames = 2;
LARGE_INTEGER lastTime;
LARGE_INTEGER currentTime;
From 359df969e1e6748607d81012ffbc898275b5c13e Mon Sep 17 00:00:00 2001
From: Sezz
Date: Thu, 16 May 2024 06:58:21 +1000
Subject: [PATCH 175/410] Update doc comments; minor formatting
---
TombEngine/Game/control/control.cpp | 8 +--
TombEngine/Renderer/RendererDraw.cpp | 53 ++++++-------------
.../Internal/TEN/Flow/Starfield/Starfield.cpp | 8 +--
3 files changed, 25 insertions(+), 44 deletions(-)
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index 813d29b12..504a55a9f 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -580,7 +580,7 @@ GameStatus DoGameLoop(int levelIndex)
int controlCalls = 0;
int drawCalls = 0;
- bool legacy30FPSdoneDraw = false;
+ bool legacy30FpsDoneDraw = false;
while (DoTheGame)
{
@@ -617,7 +617,7 @@ GameStatus DoGameLoop(int levelIndex)
controlLag -= controlFrameTime;
controlCalls++;
- legacy30FPSdoneDraw = false;
+ legacy30FpsDoneDraw = false;
}
if (status != GameStatus::Normal)
@@ -625,11 +625,11 @@ GameStatus DoGameLoop(int levelIndex)
if (!g_Configuration.EnableVariableFramerate)
{
- if (!legacy30FPSdoneDraw)
+ if (!legacy30FpsDoneDraw)
{
DrawPhase(!levelIndex, 0.0f);
drawCalls++;
- legacy30FPSdoneDraw = true;
+ legacy30FpsDoneDraw = true;
}
}
else
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index a1c0966b7..ebf7a04b3 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -2679,69 +2679,48 @@ namespace TEN::Renderer
for (int i = (int)view.RoomsToDraw.size() - 1; i >= 0; i--)
{
- int index = i;
- RendererRoom* room = view.RoomsToDraw[index];
- ROOM_INFO* nativeRoom = &g_Level.Rooms[room->RoomNumber];
+ const auto& room = *view.RoomsToDraw[i];
+ const auto& nativeRoom = g_Level.Rooms[room.RoomNumber];
if (rendererPass != RendererPass::GBuffer)
{
- _stRoom.Caustics = (int)(g_Configuration.EnableCaustics && (nativeRoom->flags & ENV_FLAG_WATER));
- _stRoom.AmbientColor = room->AmbientLight;
+ _stRoom.Caustics = int(g_Configuration.EnableCaustics && (nativeRoom.flags & ENV_FLAG_WATER));
+ _stRoom.AmbientColor = room.AmbientLight;
BindRoomLights(view.LightsToDraw);
}
- _stRoom.Water = (nativeRoom->flags & ENV_FLAG_WATER) != 0 ? 1 : 0;
+ _stRoom.Water = (nativeRoom.flags & ENV_FLAG_WATER) != 0 ? 1 : 0;
_cbRoom.UpdateData(_stRoom, _context.Get());
- SetScissor(room->ClipBounds);
+ SetScissor(room.ClipBounds);
for (int animated = 0; animated < 2; animated++)
{
if (rendererPass != RendererPass::GBuffer)
{
- if (animated == 0)
- {
- _context->VSSetShader(_vsRooms.Get(), nullptr, 0);
- }
- else
- {
- _context->VSSetShader(_vsRoomsAnimatedTextures.Get(), nullptr, 0);
- }
+ _context->VSSetShader((animated == 0) ? _vsRooms.Get() : _vsRoomsAnimatedTextures.Get(), nullptr, 0);
}
else
{
- if (animated == 0)
- {
- _context->VSSetShader(_vsGBufferRooms.Get(), nullptr, 0);
- }
- else
- {
- _context->VSSetShader(_vsGBufferRoomsAnimated.Get(), nullptr, 0);
- }
+ _context->VSSetShader((animated == 0) ? _vsGBufferRooms.Get() : _vsGBufferRoomsAnimated.Get(), nullptr, 0);
}
- for (auto& bucket : room->Buckets)
+ for (const auto& bucket : room.Buckets)
{
if ((animated == 1) ^ bucket.Animated)
- {
continue;
- }
if (bucket.NumVertices == 0)
- {
continue;
- }
int passes = rendererPass == RendererPass::Opaque && bucket.BlendMode == BlendMode::AlphaTest ? 2 : 1;
for (int p = 0; p < passes; p++)
{
if (!SetupBlendModeAndAlphaTest(bucket.BlendMode, rendererPass, p))
- {
continue;
- }
- // Draw geometry
+ // Draw geometry.
if (animated)
{
BindTexture(TextureRegister::ColorMap,
@@ -2750,7 +2729,7 @@ namespace TEN::Renderer
BindTexture(TextureRegister::NormalMap,
&std::get<1>(_animatedTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp);
- RendererAnimatedTextureSet& set = _animatedTextureSets[bucket.Texture];
+ const auto& set = _animatedTextureSets[bucket.Texture];
_stAnimated.NumFrames = set.NumTextures;
_stAnimated.Type = 0;
_stAnimated.Fps = set.Fps;
@@ -2759,7 +2738,7 @@ namespace TEN::Renderer
{
if (j >= _stAnimated.Textures.size())
{
- TENLog("Animated frame " + std::to_string(j) + " is out of bounds, too many frames in sequence.");
+ TENLog("Animated frame " + std::to_string(j) + " out of bounds. Too many frames in sequence.");
break;
}
@@ -2772,10 +2751,12 @@ namespace TEN::Renderer
}
else
{
- BindTexture(TextureRegister::ColorMap, &std::get<0>(_roomTextures[bucket.Texture]),
+ BindTexture(
+ TextureRegister::ColorMap, &std::get<0>(_roomTextures[bucket.Texture]),
+ SamplerStateRegister::AnisotropicClamp);
+ BindTexture(
+ TextureRegister::NormalMap, &std::get<1>(_roomTextures[bucket.Texture]),
SamplerStateRegister::AnisotropicClamp);
- BindTexture(TextureRegister::NormalMap,
- &std::get<1>(_roomTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp);
}
DrawIndexedTriangles(bucket.NumIndices, bucket.StartIndex, 0);
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.cpp b/TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.cpp
index 15cfde18b..60d277a17 100644
--- a/TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Flow/Starfield/Starfield.cpp
@@ -45,8 +45,8 @@ namespace TEN::Scripting
/// Create a starfield object with stars and meteors.
// @function Starfield()
- // @tparam int starCount Star count.
- // @tparam int meteorCount Meteor count.
+ // @tparam int starCount Star count (6000 max).
+ // @tparam int meteorCount Meteor count (100 max).
// @treturn Starfield A new Starfield object.
Starfield::Starfield(int starCount, int meteorCount, int meteorSpawnDensity, float meteorVel)
{
@@ -110,7 +110,7 @@ namespace TEN::Scripting
return _meteorVelocity;
}
- /// Set the starfield's number of stars.
+ /// Set the starfield's number of stars (6000 max).
// @function Starfield:SetStarCount(int)
// @tparam int New count.
void Starfield::SetStarCount(int count)
@@ -121,7 +121,7 @@ namespace TEN::Scripting
_starCount = std::clamp(count, 0, STAR_COUNT_MAX);
}
- /// Set the starfield's number of meteors.
+ /// Set the starfield's number of meteors (100 max).
// @function Starfield:SetMeteorCount(int)
// @tparam int New count.
void Starfield::SetMeteorCount(int count)
From 93549b7b07a3ec59dc4abebb75cf3e27ccb9e326 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Thu, 16 May 2024 07:02:38 +1000
Subject: [PATCH 176/410] Revert "Remove unnecessary string constants"
This reverts commit 3ff70b29153791ae81fe7744f9e7416bee4b3da6.
---
.../Scripting/Internal/ReservedScriptNames.h | 16 +++++++++++
.../TEN/DisplaySprite/ScriptDisplaySprite.cpp | 28 +++++++++----------
2 files changed, 30 insertions(+), 14 deletions(-)
diff --git a/TombEngine/Scripting/Internal/ReservedScriptNames.h b/TombEngine/Scripting/Internal/ReservedScriptNames.h
index ba1134907..8d0e58181 100644
--- a/TombEngine/Scripting/Internal/ReservedScriptNames.h
+++ b/TombEngine/Scripting/Internal/ReservedScriptNames.h
@@ -37,6 +37,22 @@ static constexpr char ScriptReserved_MoveableStatus[] = "MoveableStatus";
static constexpr char ScriptReserved_Lara[] = "Lara";
static constexpr char ScriptReserved_GetPlayerInteractedMoveable[] = "GetInteractedMoveable";
+// DisplaySprite object
+static constexpr char ScriptReserved_DisplaySprite[] = "DisplaySprite";
+static constexpr char ScriptReserved_DisplayStringGetObjectID[] = "GetObjectID";
+static constexpr char ScriptReserved_DisplayStringGetSpriteID[] = "GetSpriteID";
+static constexpr char ScriptReserved_DisplayStringGetPosition[] = "GetPosition";
+static constexpr char ScriptReserved_DisplayStringGetRotation[] = "GetRotation";
+static constexpr char ScriptReserved_DisplayStringGetScale[] = "GetScale";
+static constexpr char ScriptReserved_DisplayStringGetColor[] = "GetColor";
+static constexpr char ScriptReserved_DisplayStringSetObjectID[] = "SetObjectID";
+static constexpr char ScriptReserved_DisplayStringSetSpriteID[] = "SetSpriteID";
+static constexpr char ScriptReserved_DisplayStringSetPosition[] = "SetPosition";
+static constexpr char ScriptReserved_DisplayStringSetRotation[] = "SetRotation";
+static constexpr char ScriptReserved_DisplayStringSetScale[] = "SetScale";
+static constexpr char ScriptReserved_DisplayStringSetColor[] = "SetColor";
+static constexpr char ScriptReserved_DisplaySpriteDraw[] = "Draw";
+
static constexpr char ScriptReserved_EndReasonExitToTitle[] = "EXITTOTITLE";
static constexpr char ScriptReserved_EndReasonLevelComplete[] = "LEVELCOMPLETE";
static constexpr char ScriptReserved_EndReasonLoadGame[] = "LOADGAME";
diff --git a/TombEngine/Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.cpp b/TombEngine/Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.cpp
index aed2f4908..12529806d 100644
--- a/TombEngine/Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.cpp
+++ b/TombEngine/Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.cpp
@@ -30,23 +30,23 @@ namespace TEN::Scripting::DisplaySprite
// Register type.
parent.new_usertype(
- "DisplaySprite",
+ ScriptReserved_DisplaySprite,
ctors(),
sol::call_constructor, ctors(),
- "GetObjectID", & ScriptDisplaySprite::GetObjectID,
- "GetSpriteID", &ScriptDisplaySprite::GetSpriteID,
- "GetPosition", &ScriptDisplaySprite::GetPosition,
- "GetRotation", &ScriptDisplaySprite::GetRotation,
- "GetScale", &ScriptDisplaySprite::GetScale,
- "GetColor", &ScriptDisplaySprite::GetColor,
- "SetObjectID", &ScriptDisplaySprite::SetObjectID,
- "SetSpriteID", &ScriptDisplaySprite::SetSpriteID,
- "SetPosition", &ScriptDisplaySprite::SetPosition,
- "SetRotation", &ScriptDisplaySprite::SetRotation,
- "SetScale", &ScriptDisplaySprite::SetScale,
- "SetColor", &ScriptDisplaySprite::SetColor,
- "Draw", &ScriptDisplaySprite::Draw);
+ ScriptReserved_DisplayStringGetObjectID, &ScriptDisplaySprite::GetObjectID,
+ ScriptReserved_DisplayStringGetSpriteID, &ScriptDisplaySprite::GetSpriteID,
+ ScriptReserved_DisplayStringGetPosition, &ScriptDisplaySprite::GetPosition,
+ ScriptReserved_DisplayStringGetRotation, &ScriptDisplaySprite::GetRotation,
+ ScriptReserved_DisplayStringGetScale, &ScriptDisplaySprite::GetScale,
+ ScriptReserved_DisplayStringGetColor, &ScriptDisplaySprite::GetColor,
+ ScriptReserved_DisplayStringSetObjectID, &ScriptDisplaySprite::SetObjectID,
+ ScriptReserved_DisplayStringSetSpriteID, &ScriptDisplaySprite::SetSpriteID,
+ ScriptReserved_DisplayStringSetPosition, &ScriptDisplaySprite::SetPosition,
+ ScriptReserved_DisplayStringSetRotation, &ScriptDisplaySprite::SetRotation,
+ ScriptReserved_DisplayStringSetScale, &ScriptDisplaySprite::SetScale,
+ ScriptReserved_DisplayStringSetColor, &ScriptDisplaySprite::SetColor,
+ ScriptReserved_DisplaySpriteDraw, &ScriptDisplaySprite::Draw);
}
/// Create a DisplaySprite object.
From eb7163a4729ff753e0b959937d6b32d80516f536 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Thu, 16 May 2024 05:43:54 +0200
Subject: [PATCH 177/410] Fixed meteors drawing
---
TombEngine/Game/effects/weather.cpp | 12 ++--
TombEngine/Renderer/RendererDraw.cpp | 89 ++++++++++++++++------------
2 files changed, 59 insertions(+), 42 deletions(-)
diff --git a/TombEngine/Game/effects/weather.cpp b/TombEngine/Game/effects/weather.cpp
index f8ad60ac7..e4e2c95f6 100644
--- a/TombEngine/Game/effects/weather.cpp
+++ b/TombEngine/Game/effects/weather.cpp
@@ -645,10 +645,12 @@ namespace TEN::Effects::Environment
int density = level.GetStarfieldMeteorSpawnDensity();
if (density > 0)
- {
- for (int i = 0; i < level.GetStarfieldMeteorCount(); i++)
+ {
+ int newParticlesCount = 0;
+
+ while (Meteors.size() < level.GetStarfieldMeteorCount())
{
- if (i > density)
+ if (newParticlesCount > density)
break;
auto horizontalDir = Random::GenerateDirection2D();
@@ -658,7 +660,7 @@ namespace TEN::Effects::Environment
part.Active = true;
part.Life = METEOR_PARTICLE_LIFE_MAX;
part.StartPosition =
- part.Position = Random::GenerateDirectionInCone(-Vector3::UnitY, 40.0f) * BLOCK(1.5f);
+ part.Position = Random::GenerateDirectionInCone(-Vector3::UnitY, 40.0f) * BLOCK(1.5f);
part.Fade = 0.0f;
part.Color = Vector3(
Random::GenerateFloat(0.6f, 1.0f),
@@ -670,6 +672,8 @@ namespace TEN::Effects::Environment
part.Direction.y = -part.Direction.y;
Meteors.push_back(part);
+
+ newParticlesCount++;
}
}
}
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index a1c0966b7..b1adaed7c 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -2878,7 +2878,10 @@ namespace TEN::Renderer
while (drawnStars < starCount)
{
- int starsToDraw = (starCount - drawnStars) > 100 ? 100 : (starCount - drawnStars);
+ int starsToDraw =
+ (starCount - drawnStars) > INSTANCED_SPRITES_BUCKET_SIZE ?
+ INSTANCED_SPRITES_BUCKET_SIZE :
+ (starCount - drawnStars);
int i = 0;
for (int i = 0; i < starsToDraw; i++)
@@ -2930,51 +2933,61 @@ namespace TEN::Renderer
rDrawSprite.Sprite = &_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_LENS_FLARE_3];
BindTexture(TextureRegister::ColorMap, rDrawSprite.Sprite->Texture, SamplerStateRegister::LinearClamp);
- int meteorCount = 0;
+ int drawnMeteors = 0;
+ int meteorsCount = (int)Weather.GetMeteors().size();
- for (int i = 0; i < Weather.GetMeteors().size(); i++)
+ while (drawnMeteors < meteorsCount)
{
- auto meteor = Weather.GetMeteors()[i];
+ int meteorsToDraw =
+ (meteorsCount - drawnMeteors) > INSTANCED_SPRITES_BUCKET_SIZE ?
+ INSTANCED_SPRITES_BUCKET_SIZE :
+ (meteorsCount - drawnMeteors);
+ int i = 0;
- if (meteor.Active == false)
- continue;
+ for (int i = 0; i < meteorsToDraw; i++)
+ {
+ auto meteor = Weather.GetMeteors()[drawnMeteors + i];
- rDrawSprite.Type = SpriteType::CustomBillboard;
- rDrawSprite.pos =
- renderView.Camera.WorldPosition +
- Vector3::Lerp(meteor.PrevPosition, meteor.Position, _interpolationFactor);
- rDrawSprite.Rotation = 0;
- rDrawSprite.Scale = 1;
- rDrawSprite.Width = 2;
- rDrawSprite.Height = 192;
- rDrawSprite.ConstrainAxis = meteor.Direction;
+ if (meteor.Active == false)
+ continue;
- _stInstancedSpriteBuffer.Sprites[meteorCount].World = GetWorldMatrixForSprite(&rDrawSprite, renderView);
- _stInstancedSpriteBuffer.Sprites[meteorCount].Color = Vector4(
- meteor.Color.x,
- meteor.Color.y,
- meteor.Color.z,
- Lerp(meteor.PrevFade, meteor.Fade, _interpolationFactor));
- _stInstancedSpriteBuffer.Sprites[meteorCount].IsBillboard = 1;
- _stInstancedSpriteBuffer.Sprites[i].IsSoftParticle = 0;
+ rDrawSprite.Type = SpriteType::CustomBillboard;
+ rDrawSprite.pos =
+ renderView.Camera.WorldPosition +
+ Vector3::Lerp(meteor.PrevPosition, meteor.Position, _interpolationFactor);
+ rDrawSprite.Rotation = 0;
+ rDrawSprite.Scale = 1;
+ rDrawSprite.Width = 2;
+ rDrawSprite.Height = 192;
+ rDrawSprite.ConstrainAxis = meteor.Direction;
- // NOTE: Strange packing due to particular HLSL 16 byte alignment requirements.
- _stInstancedSpriteBuffer.Sprites[meteorCount].UV[0].x = rDrawSprite.Sprite->UV[0].x;
- _stInstancedSpriteBuffer.Sprites[meteorCount].UV[0].y = rDrawSprite.Sprite->UV[1].x;
- _stInstancedSpriteBuffer.Sprites[meteorCount].UV[0].z = rDrawSprite.Sprite->UV[2].x;
- _stInstancedSpriteBuffer.Sprites[meteorCount].UV[0].w = rDrawSprite.Sprite->UV[3].x;
- _stInstancedSpriteBuffer.Sprites[meteorCount].UV[1].x = rDrawSprite.Sprite->UV[0].y;
- _stInstancedSpriteBuffer.Sprites[meteorCount].UV[1].y = rDrawSprite.Sprite->UV[1].y;
- _stInstancedSpriteBuffer.Sprites[meteorCount].UV[1].z = rDrawSprite.Sprite->UV[2].y;
- _stInstancedSpriteBuffer.Sprites[meteorCount].UV[1].w = rDrawSprite.Sprite->UV[3].y;
+ _stInstancedSpriteBuffer.Sprites[i].World = GetWorldMatrixForSprite(&rDrawSprite, renderView);
+ _stInstancedSpriteBuffer.Sprites[i].Color = Vector4(
+ meteor.Color.x,
+ meteor.Color.y,
+ meteor.Color.z,
+ Lerp(meteor.PrevFade, meteor.Fade, _interpolationFactor));
+ _stInstancedSpriteBuffer.Sprites[i].IsBillboard = 1;
+ _stInstancedSpriteBuffer.Sprites[i].IsSoftParticle = 0;
- meteorCount++;
+ // NOTE: Strange packing due to particular HLSL 16 byte alignment requirements.
+ _stInstancedSpriteBuffer.Sprites[i].UV[0].x = rDrawSprite.Sprite->UV[0].x;
+ _stInstancedSpriteBuffer.Sprites[i].UV[0].y = rDrawSprite.Sprite->UV[1].x;
+ _stInstancedSpriteBuffer.Sprites[i].UV[0].z = rDrawSprite.Sprite->UV[2].x;
+ _stInstancedSpriteBuffer.Sprites[i].UV[0].w = rDrawSprite.Sprite->UV[3].x;
+ _stInstancedSpriteBuffer.Sprites[i].UV[1].x = rDrawSprite.Sprite->UV[0].y;
+ _stInstancedSpriteBuffer.Sprites[i].UV[1].y = rDrawSprite.Sprite->UV[1].y;
+ _stInstancedSpriteBuffer.Sprites[i].UV[1].z = rDrawSprite.Sprite->UV[2].y;
+ _stInstancedSpriteBuffer.Sprites[i].UV[1].w = rDrawSprite.Sprite->UV[3].y;
+ }
+
+ _cbInstancedSpriteBuffer.UpdateData(_stInstancedSpriteBuffer, _context.Get());
+
+ // Draw sprites with instancing.
+ DrawInstancedTriangles(4, meteorsToDraw, 0);
+
+ drawnMeteors += meteorsToDraw;
}
-
- _cbInstancedSpriteBuffer.UpdateData(_stInstancedSpriteBuffer, _context.Get());
-
- // Draw sprites with instancing.
- DrawInstancedTriangles(4, meteorCount, 0);
}
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
From 20d591b74fd46a7ea09ccee8fb404ff1c0193fc4 Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Wed, 15 May 2024 21:53:40 +0200
Subject: [PATCH 178/410] Increase maximum interpolated distance change
---
.../Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp
index 7987d2366..2f1dd3e2b 100644
--- a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp
@@ -581,7 +581,7 @@ Vec3 Moveable::GetPos() const
void Moveable::SetPos(const Vec3& pos, sol::optional updateRoom)
{
auto newPos = pos.ToVector3i();
- bool bigDistance = Vector3i::Distance(newPos, m_item->Pose.Position) > CLICK(1);
+ bool bigDistance = Vector3i::Distance(newPos, m_item->Pose.Position) > BLOCK(1);
m_item->Pose.Position = newPos;
From 09445ad0ba554fdbd107713a40b52b2db4445f08 Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Thu, 16 May 2024 09:13:36 +0300
Subject: [PATCH 179/410] Update README.md
---
README.md | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/README.md b/README.md
index 58288e125..c5799ecab 100644
--- a/README.md
+++ b/README.md
@@ -2,13 +2,7 @@

-In the year 2000, Core Design granted us a great gift: their TR4-based Level Editor, which allowed people to create custom levels. It was, unfortunately, quite limited, hence why over the decades it was upgraded massively with fan projects such as Tomb Raider Engine Patcher (TREP) and Tomb Raider Next Generation (TRNG).
-- TREP was a tool which allowed modification of the executable to expand certain limits and implement new features.
-- TRNG built upon TREP and provided many new tools, including a scripting language, expanding even more limits with its own .DLL.
-
-Unfortunately, TRNG's toolset is poorly documented and not user-friendly; the program remains closed-source to this day and is in all practicality an abandonware. As a direct consequence, no one is able to fix the countless well-known bugs and issues extant in TRNG, rendering implementation of new features is impossible without an in-depth knowledge of C++ plugin creation and a solid understanding of the classic Tomb Raider engine's many idiosyncrasies.
-
-TombEngine (TEN) is a new, open-source engine which aims to abolish all limits, fix bugs from the original games, introduce new features while refining old ones, and provide for a refined, user-friendly level creation process. Current support includes:
+In the year 2000, Core Design granted us a great gift: their TR4-based Level Editor, which allowed people to create custom levels. It was, unfortunately, quite limited, hence why over the decades it was upgraded massively with fan patcher projects such as Tomb Raider Engine Patcher (TREP) and Tomb Raider Next Generation (TRNG). TombEngine (TEN) is a new, open-source engine which aims to abolish all limits, fix bugs from the original games, introduce new features while refining old ones, and provide for a refined, user-friendly level creation process. Current support includes:
- Lua (as the native scripting language)
- All objects from the classic series (1-5)
- Many more exciting gameplay functionalities such as diagonal shimmying and expanded crawlspace flexibility
@@ -22,7 +16,7 @@ Tomb Engine should be used in conjuction with Tomb Editor. Tomb Editor is also o
# Compiling TombEngine
To compile TEN, ensure you have installed:
- Microsoft Visual Studio
-- TombEditor (if you would like to create and test levels)
+- Tomb Editor (if you would like to create and test levels)
Steps:
1) Clone the repository to your GitHub Desktop
From 0b59e4f7241f7a9c4b5032cbda7ed4799e4e1da6 Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Thu, 16 May 2024 09:14:09 +0300
Subject: [PATCH 180/410] Update README.md
---
README.md | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index c5799ecab..fd3834ff5 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,9 @@

-In the year 2000, Core Design granted us a great gift: their TR4-based Level Editor, which allowed people to create custom levels. It was, unfortunately, quite limited, hence why over the decades it was upgraded massively with fan patcher projects such as Tomb Raider Engine Patcher (TREP) and Tomb Raider Next Generation (TRNG). TombEngine (TEN) is a new, open-source engine which aims to abolish all limits, fix bugs from the original games, introduce new features while refining old ones, and provide for a refined, user-friendly level creation process. Current support includes:
+In the year 2000, Core Design granted us a great gift: their TR4-based Level Editor, which allowed people to create custom levels. It was, unfortunately, quite limited, hence why over the decades it was upgraded massively with fan patcher projects such as Tomb Raider Engine Patcher (TREP) and Tomb Raider Next Generation (TRNG).
+
+TombEngine (TEN) is a new, open-source engine which aims to abolish all limits, fix bugs from the original games, introduce new features while refining old ones, and provide for a refined, user-friendly level creation process. Current support includes:
- Lua (as the native scripting language)
- All objects from the classic series (1-5)
- Many more exciting gameplay functionalities such as diagonal shimmying and expanded crawlspace flexibility
From 9124b3129ec468d64f38abec745163efe5d221a9 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Thu, 16 May 2024 18:26:20 +1000
Subject: [PATCH 181/410] Squishy blocks aren't bridges
---
TombEngine/Specific/level.cpp | 2 --
1 file changed, 2 deletions(-)
diff --git a/TombEngine/Specific/level.cpp b/TombEngine/Specific/level.cpp
index d3e4e1fbc..88596ddc4 100644
--- a/TombEngine/Specific/level.cpp
+++ b/TombEngine/Specific/level.cpp
@@ -38,8 +38,6 @@ using namespace TEN::Utils;
const std::vector BRIDGE_OBJECT_IDS =
{
ID_EXPANDING_PLATFORM,
- ID_SQUISHY_BLOCK_HORIZONTAL,
- ID_SQUISHY_BLOCK_VERTICAL,
ID_FALLING_BLOCK,
ID_FALLING_BLOCK2,
From cec6e744757768a2b584fef712eac53e450c7428 Mon Sep 17 00:00:00 2001
From: Jakub <80340234+Jakub768@users.noreply.github.com>
Date: Thu, 16 May 2024 09:30:23 +0100
Subject: [PATCH 182/410] Update CHANGELOG.md
---
CHANGELOG.md | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 287a40f15..aac358b80 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,21 @@ Here you will find the full changelog of TEN's releases from Version 1.0 and up
The dates are in European standard format where date is presented as **YYYY-MM-DD**
+## Version 1.5 - xxxx-xx-xx
+
+### Bug fixes
+* Fixed original issue with classic switch off trigger wrongly activating some trigger actions.
+* Fixed incorrect diving animation when swandiving from a high place.
+* Fixed camera rotating with Lara's hips when climbing out of water.
+* Fixed AI for skidoo driver and worker with shotgun TR2 enemies.
+* Fixed Ember emitter crashing when ocb is between -1 and -10
+* Fixed Electric cleaner and Squishy block not detecting collision with certain block heights.
+
+### Features/Amendments
+
+### Lua API changes
+* Added Inventory.GetUsedItem(), Inventory.SetUsedItem() and Inventory.ClearUsedItem() functions.
+
## Version 1.4 - 2024-04-21
### Bug Fixes
From 654e3a0381a953cd0de6af9dbe4de261df6928a7 Mon Sep 17 00:00:00 2001
From: Jakub
Date: Thu, 16 May 2024 09:31:38 +0100
Subject: [PATCH 183/410] remove changes.txt (changelog is now in CHANGELOG.md)
---
Documentation/Changes.txt | 707 --------------------------------------
1 file changed, 707 deletions(-)
delete mode 100644 Documentation/Changes.txt
diff --git a/Documentation/Changes.txt b/Documentation/Changes.txt
deleted file mode 100644
index 61d2938c7..000000000
--- a/Documentation/Changes.txt
+++ /dev/null
@@ -1,707 +0,0 @@
-Version 1.5
-===========
-
-* Fixed original issue with classic switch off trigger wrongly activating some trigger actions.
-* Fixed incorrect diving animation when swandiving from a high place.
-* Fixed camera rotating with Lara's hips when climbing out of water.
-* Fixed AI for skidoo driver and worker with shotgun TR2 enemies.
-* Fixed Ember emitter crashing when ocb is between -1 and -10
-* Fixed Electric cleaner and Squishy block not detecting collision with certain block heights.
-
-Lua API changes:
-* Added Inventory.GetUsedItem(), Inventory.SetUsedItem() and Inventory.ClearUsedItem() functions.
-
-Version 1.4
-===========
-
-* Fixed drawing of display sprites in title level.
-* Fixed drawing of smoke sprites and various other sprites.
-* Fixed drawing of transparent surfaces when debris are present in scene.
-* Fixed player holster state and current vehicle not preserved correctly on level jump.
-* Fixed diving when swimming over sinks.
-* Fixed fire item effect not extinguishing in water.
-* Fixed fade-in and fade-out effects not canceling correctly when next level is loaded.
-* Fixed shadows still being visible after shattering a moveable.
-* Fixed FOV interpolation at the end of the flyby sequence.
-* Fixed sounds resuming in pause mode while switching between apps.
-* Fixed slide directions.
-* Fixed occasional collision warnings in a log when teeth spikes object was activated.
-* Fixed climbable pushables collision during continuous pulling action.
-* Fixed collision for solid static meshes with zero collision box.
-* Fixed bottom collision for solid static meshes.
-* Fixed T-Rex's head rotation.
-* Auto-switch to a crawl state if player start position is in a crawlspace.
-* Allow directional flame emitter (negative OCBs) to be rotated at any angle.
-* Revise wall spikes:
- - Wall spikes now stop when they touch a pushable, another spike wall or a normal wall.
- - Wall spikes will shatter any shatter in its path.
- - Wall spikes can be stopped by normal antitrigger or with a volume.
-* Added hub system to preserve level state on level jumps.
-* Added ember emitter.
-* Added fish emitter.
-* Added laser beam object.
-* Added TR2 dragon.
-* Added TR3 Winston (requires updated TEN .wad2 on TombEngine.com).
-* Added TR4 squishy blocks (requires updated TEN .wad2 on TombEngine.com).
-
-Lua API changes:
-* Added resetHub flag to Flow.Level, which allows to reset hub data.
-* Added Flow.GetFlipMapStatus() function to get current flipmap status.
-* Added Moveable:GetMeshCount() function to get number of moveable meshes.
-* Added timeout parameter for Moveable:Enable() function.
-* Added Static:GetHP() and Static:SetHP() functions to change shatterable static mesh hit points.
-* Fixed Moveable:SetOnCollidedWithObject() callback.
-
-Version 1.3
-===========
-
-* Fixed crash if title logo is removed from Textures folder.
-* Fixed crash if unknown player state ID is encountered.
-* Fixed bug with OCB 2 on pushables, and some other pushable bugs.
-* Fixed pushable camera bug during edge slip.
-* Fixed lever switch turn off alignment animation.
-* Fixed lack of water splash in certain scenarios.
-* Fixed hydra flame not showing when charging.
-* Fixed shockwave light for hammer god.
-* Fixed camera shaking in some cases when the player is in quicksand room.
-* Fixed certain flame emitter OCBs emitting fire in wrong directions.
-* Fixed player not being able to pick up a torch when crouching.
-* Fixed jittery camera when performing crawl-to-hang.
-* Fixed several issues with limited pistol ammo.
-* Fixed player not being able to crawl if two-handed weapon is currently equipped.
-* Fixed playback issues with audio tracks placed in subfolders.
-* Fixed thin caustics outline on the edge of the blocks.
-* Fixed big static objects affected wrongly by dynamic lights.
-* Fixed legacy trigger leveljumps ignoring provided level index.
-* Fixed incorrect light collection in some cases.
-* Fixed normal mapping for rooms, items, and statics.
-* Added ambient occlusion (SSAO).
-* Added new post-process workflow (monochrome, negative, exclusion) with tinting.
-* Added SMAA antialiasing instead of MSAA.
-* Added previously missing player start position object functionality.
-* Added fast speed for fly cheat by holding Sprint input action.
-* Added speedometer to vehicles.
-* Added global node events.
-* Totally revised transparency handling.
-* Increased the maximum frames for animated sequences from 128 to 256.
-* Optimized the renderer.
-* Separate underwater wall and ceiling switch objects into two slots each.
-* Accurately rotate display sprites around the pivot defined by the align mode.
-* Allow walking on slopes when wading in water (similar to quicksand).
-* Allow player to pull certain levers with both hands when holding a flare.
-* Ported twin auto gun from TR3.
-* Revised keyhole OCBs to account for keeping or losing keys:
- - OCB 0: Play default animation and lose key.
- - Positive OCB: Play anim number and keep key.
- - Negative OCB: Play anim number and lose key.
-* Revised Wolf OCBs:
- - OCB 0: Wolf starts in walking animation, ready to chase Lara.
- - OCB 1: Wolf starts in sleeping animation.
-
-Lua API changes:
-* Added Lara:GetInteractedMoveable() which returns currently interacted moveable by Lara.
-* Added Moveable:SetStatus() to set the current status of the moveable.
-* Added Room:GetColor() to get room's ambient light color.
-* Added Util.PickMoveableByDisplayPosition() and Util.PickStaticByDisplayPosition() functions.
-* Added View.GetCameraPosition(), View.GetCameraTarget() and View.GetCameraRoom() functions.
-* Added View.SetPostProcessMode(), View.SetPostProcessStrength() and View.SetPostProcessTint() functions.
-
-Version 1.2
-===========
-
-* Fix burning torch not working properly if there are more than 256 objects in a level.
-* Fix grenade and rocket projectiles smoke offset in certain directions.
-* Fix projectiles flying through animating objects.
-* Fix harpoon gun doing enormous damage on enemies.
-* Fix train death animation.
-* Fix various camera issues with unique death animations.
-* Fix zipline not following correct trajectory.
-* Fix TR1 wolf damage value inflicted on a close bite attack.
-* Fix TR1 bear various original AI issues.
-* Fix TR2 knife thrower AI.
-* Fix TR2 doberman crashing the game when killed by explosive weapons.
-* Fix random crashes when killing exploding enemies.
-* Fix random crashes in battle with more than 8 enemies.
-* Fix volume change in settings not affecting voice track.
-* Fix several lighting bugs.
-* Fix double drawing additive faces.
-* Fix savegame count not properly increasing.
-* Fix regeneration of non-ammo pickups with OCB 128.
-* Fix vault bug preventing the player from climbing onto ledges out of deeper sections of wade-depth water.
-* Fix cold exposure status not recovering in non-cold wade-depth water.
-* Fix non-elevated combat camera.
-* Fix camera snap when disengaging the look-around mode.
-* Fix TR4 mapper not being visible.
-* Improve head-on wall collision.
-* Overhaul pushables:
- - Separate climbable and non-climbable pushable object slots.
- - Add new pushable OCB to manipulate pushable properties.
- - Add new animations for pushing pushables off edgees (TR1-3 and TR4-5 versions).
- - Fix pushables not working with raising blocks.
- - Fix miscellaneous pushable bugs.
-* Overhaul look-around feature:
- - Allow for more consistent and wider viewing angles while crawling, crouching, and hanging.
- - Improve look camera movement and control.
- - Re-enable looking while performing up jump, backward jump, or backward crawl.
- - Add functionality to rotate slowly when holding Walk while using binoculars or lasersight.
-* Add target highlighter system with toggle in Sound and Gameplay settings.
-* Add sprint slide state 191.
-* Add swinging blade.
-* Add crumbling platform and add new OCBs for behaviour:
- - OCB 0: Default behaviour. When the player steps on the platform, it will shake and crumble after 1.2 seconds.
- - OCB > 0: When the player steps on the platform, it will crumble after the number of frames set in the OCB.
- - A positive value results in activation via player collision.
- - A negative value requires a trigger to activate.
-* Add basic mouse input handling. Allows for binding of mouse inputs in control settings.
-* Add settings for Mouse Sensitivity and Mouse Smoothing (not used in-game yet).
-
-Lua API changes:
-* Split and organize functions in `Misc` namespace to appropriate new namespaces.
-* Make Vec2 and Vec3 objects float-based instead of integer-based.
-* Add DisplaySprite object.
-* Add Flow.EnableLoadSave() function to disable savegames.
-* Add Flow.EnablePointFilter() function to disable bilinear filtering.
-* Add View.GetAspectRatio() function to get the screen resolution's aspect ratio.
-* Add Logic.HandleEvent() function to call node events.
-* Add Input.GetCursorDisplayPosition() function to get the cursor's position.
-* Add functions to load, save, delete and check existence of savegames.
-* Add Lara:GetAmmoType() function to read the ammo that player is using.
-* Add Moveable:GetEndFrame() function to get the end frame number of a moveable's current animation.
-* Add extra parameter to GiveItem() function to optionally display an inventory item given to the player in the pickup summary.
-* Add DisplayStringOption.RIGHT and DisplayStringOption.BLINK flags for DisplayString.
-* Add log messages warnings to functions AddCallback and RemoveCallback.
-* Add Vec2 and Vec3 arithmetic for division with a number and multiplication with another Vec2 or Vec3.
-* Add various Vec2 and Vec3 operators and methods, such as Normalize() and Lerp().
-* Fix InventoryItem constructor, now it will accept compound values in Item Action parameter.
-* Fix Moveable constructor forcing initial animation to 0 and hit points to 10, even if not specified.
-* Fix activation of a flipped room when using SetPos() script command or position change node.
-* Fix Sound:PlaySoundEffect() function when used without optional position argument.
-* Update DisplayString constructor to take a "scale" parameter, allowing for the resizing of text.
-* Make DisplayString constructor's "color" parameter optional.
-* Add DisplayString::SetScale() function to resize text.
-* Add DisplayString::GetScale() function to get text scale.
-
-Version 1.1.0
-==============
-
-* Fix enemies shooting Lara through static meshes and moveables.
-* Fix skeletons and mummies not being affected by explosive weapons.
-* Fix crash on loading if static meshes with IDs above maximum are present.
-* Fix various crashes specific to 64-bit build.
-* Fix random crashes when playing audio tracks with names longer than 15 symbols.
-* Fix crashes when trying to play .wav audio tracks on some Windows 11 systems.
-* Fix last selected gun type not preserved after level jump.
-* Fix incorrect vertical position after reloading a savegame made while standing on a bridge.
-* Fix sprint value going below zero.
-* Fix fog bulb density formula.
-* Fix clockwork beetle activation crashing the game.
-* Fix corrupted vehicle positions after savegame reload.
-* Fix default ambience overlapping current one when loading a savegame.
-* Fix doppelganger being limited to a single room.
-* Fix bat AI, damage value, and incorrect collision after death.
-* Fix regeneration for pickups with OCB 128.
-* Fix raising blocks still shaking without OCB.
-* Fix spiky ceiling, improve collision, and allow setting velocity via OCB.
-* Fix TR1 winged mutant pathfinding and damage issues and add new OCBs.
-* Fix TR1 Natla facing angle, bomb and shard projectiles, shooting anim in the second phase.
-* Fix last inventory item position not being saved.
-* Fix some puzzle hole objects crashing the game on item insertion.
-* Fix incorrect harpoon bolt speed and angle when shooting vertically.
-* Fix black shatter debris.
-* Fix Lara's shadow projecting only her joints on some occasions.
-* Fix sun and spot bulbs direction and sheen casts.
-* Fix room collector freezing game on some occasions.
-* Fix incorrect culling for scaled static meshes.
-* Fix normal mapping.
-* Add ability to save screenshot in the "Screenshots" subfolder by pressing the "Print screen" key.
-* Implement separate audio track channel for playing voiceovers with subtitles in .srt format.
-* Don't stop ambience when Lara dies.
-* Pause all sounds when entering inventory or pause menu.
-* Preserve hit points on level jump.
-* Improve deflection against slopes.
-* Move and rotate Lara and activated pickups together with dynamic bridge objects.
-* Reduce camera bounce.
-* Improve spiky wall collision accuracy.
-* Expand control settings page.
-* Allow key bindings for previously hardcoded actions (weapon hotkeys, vehicle controls).
-* Add input actions for weapon scroll.
-* Add splash effect to rockets and grenades when they enter water.
-* Allow multiple doppelgangers by using the same OCB for the origin nullmesh and doppelganger.
-* Add TR1 skateboard kid.
-* Add TR1 Kold.
-
-Lua API changes:
-* Add soundtrack functions:
- - Misc::GetAudioTrackLoudness() for getting current loudness of a given track type.
- - Misc::IsAudioTrackPlaying() for checking if a given track type is playing.
- - Misc::GetCurrentSubtitle() for getting current subtitle string for the voice track.
-
-Version 1.0.9
-=============
-
-* Fix cold bar triggered in non-water rooms.
-* Fix spiky wall speed value and change it via OCB number or Lua (Moveable::SetItemFlags[0]).
-* Fix bats emitter crashing the game if little beetle object does not exist in wad.
-* Fix gunflash rendering and position for entities.
-* Fix snowmobile driver crashing the game.
-* Fix knifethrower not throwing knife.
-* Fix classic rollingball rolling in place into some closed doors.
-* Fix zipline not working properly.
-* Fix missing heavytrigger checks for node events activated from classic triggers.
-* Fix death flag burning enemies underwater.
-* Fix pickups and object collision not working properly in flipped rooms without portals.
-* Fix footprints not being cleared after level change.
-* Fix thumbstick camera option sometimes producing jerky camera movements during object interaction.
-* Fix soundtrack position not restoring if same track is already playing.
-* Fix inventory input interference when entering inventory via puzzle.
-* Fix gamepad still vibrating if Lara was poisoned prior to death.
-* Fix flare brightness.
-* Fix grenade firing angle.
-* Fix rendering for static meshes with custom blending modes and alpha transparency.
-* Fix inconsistent multiline string spacing on different display modes.
-* Remove search object 4 hardcoded meshswap activated with a flipmap.
-* Add TR1 cowboy.
-* Add TR3 wall mounted blade.
-* Add TR3 claw mutant.
-* Add TR5 lasers:
- - Choose colour for the lasers via tint menu.
- - Laser OCB means width of the laser in sectors.
- - Negative OCB laser will trigger heavy trigger.
- - Positive OCB kills Lara.
-* Add removable puzzles from puzzle holes and puzzle dones:
- - Employed by setting the trigger type as "Switch" for either puzzle hole or puzzle done.
- - Can be mixed with puzzle done and puzzle holes of the same or different type.
-* Add reusable keys for key holes:
- - Employed by setting the trigger type as "Switch" for key hole.
-* Allow key hole animation to be played via OCB number:
- - Default OCB 0 will play Lara use key animation.
- - Any positive OCB number will play the animation according to the OCB number.
-* Reimplement fog bulbs.
-* Add missing gunflash for some entities, also include dynamic light and smoke to all gunflashes.
-* Add ability to pick up a single inactive flare as an inventory item.
-* Add log reports if title level or other levels don't exist.
-* Add better error handling for missing font, sprites or shaders.
-* Add "Reset to defaults" entry to controls menu and automatically bind XBOX gamepad profile if connected.
-* Add 64-bit executable and place both 32-bit and 64-bit versions into /Bin subdirectory.
-
-Lua API changes:
-* Add Vec2 class.
-* Add function String::SetTranslated().
-* Add function Misc::IsStringDisplaying().
-* Add the following for use in AddCallback and RemoveCallback:
- - PRESTART, POSTSTART
- - PREEND, POSTEND
- - PRESAVE, POSTSAVE
- - PRELOAD, POSTLOAD
-
-Version 1.0.8
-=============
-
-* Fix bubbles phasing through ceilings.
-* Fix object camera not clearing at level end.
-* Fix double breath sound effect when coming up for air.
-* Fix flickering hair.
-* Fix harpoon gun triggering water and dry sounds when shooting and reholstering.
-* Fix Z-fighting in inventory rendering.
-* Fix transparent objects not displaying correctly in the Inventory.
-* Fix dozy cheat always giving uzi weapons even if not present in WAD.
-* Fix player getting launched when landing close to an edge.
-* Fix player going through trapdoor/bridge while climbing up a climbable wall.
-* Fix TR3 Sophia's charge ring drawing below floor.
-* Fix TR5 imp collision handling and animations:
- - OCB 1: Climbs up to player when triggered.
- - OCB 2: Starts rolling on the floor when triggered.
- - OCB 3: Will throw stones at player.
- - Imp is also scared of of the player if holding a lit torch.
- - Please note you must use the patched version found here: https://github.com/TombEngine/Resources/blob/main/Wad2%20Objects/tr5_Imp.wad2
-* Fix and improve wraith tails.
-* Add dedicated WRAITH_TRAP object with enhanced effects.
- - OCB 0: Effect disabled.
- - OCB 1: Effect enabled.
-* Add TR1 slamming doors.
-* Add TR3 mutant wasp (AI_MODIFY object won't allow it to land, the wasp will always fly).
-* Add TR3 Corpse
- - OCB 0: used for coprses targeted by the compsognathus dinosaur.
- - OCB 1: used for corpses hung in the air to be used as piranha bait. Will fall when shot.
- - Please note you must use the patched version found here: https://github.com/TombEngine/Resources/blob/main/Wad2%20Objects/tr3_Compsognathus_Cadavar.wad2
-* Add cold exposure bar (employed by setting the "cold" flag in water rooms in Tomb Editor).
-* Add water wakes for vehicles.
-* Restored light effect nullmeshes (color, electrical, pulse, and strobe):
- - Select the light color as object tint in the OCB menu in Tomb Editor.
- - ELECTRICAL_LIGHT:
- - Can have multiple meshes. Add mesh number to OCB to be renderd with the light.
- - OCB + (mesh number): Light behaves like a neon light.
- - OCB – (mesh number): Light flickers.
-* Restored inventory compass.
-* Allow dynamic segment count for hair object.
-
-Lua API changes:
-* Add function Misc::IsSoundPlaying()
-* Add function DisplayString::SetFlags()
-
-Version 1.0.7
-=============
-
-* Fix spark particles not being cleared on level reload.
-* Fix visible but inactive enemies (e.g. Shiva or Xian guardians) taking damage.
-* Fix blockable LOT type enemies (e.g. T-Rex and Shiva) not being able to step up 1 click or drop 2 clicks.
-* Fix valve switch unable to untrigger objects.
-* Fix valve and wall hole switches (OCB 5 and 6) not working as a timed switches.
-* Fix incorrect Lara alignment on monkeyswing autojump.
-* Fix silent crash if hair object or skin joints are missing.
-* Fix holster meshes not displaying for Lara's shadow.
-* Use Lara object's own meshes if Lara skin object does not exist in level file.
-* Fix TR3 Shiva not taking explosive damage (should still block it with the sword).
-* Fix TR3 Puna boss not blocking projectiles (grenade, rocket, harpoon, bolt) with the shield.
-* Fix TR3 Puna boss and TR5 Roman statue taking fire when shot by explosive ammo.
-* Fix TR2 sword and spear guardian:
- - Not doing transition from alive to stone and stone to alive.
- - Taking damage in stone mode.
- - Wrong joint index for rotating the head and torso.
- - Spear guardian not using left and right spear attack when walking (had wrong state ID set as target).
- - Killing move for spear used wrong value.
-* Fix TR3 big gun spawning rocket with 0 life which caused an immediate explosion.
-* Fix TR3 Tony and add boss effect for him.
-* Add TR3 civvy.
-* Add TR3 electric cleaner.
-* Add TR3 Sophia Leigh with following OCBs:
- - 0 – Normal mode. Sophia behaves like a regular enemy.
- - 1 – Tower mode. Behaviour matched from Tomb Raider III.
- - 2 – Tower mode with volumes. Same as tower mode, but Sophia's ascent can be controlled using volumes in Tomb Editor.
-* Add airlock switch object. Achieved by putting valve switch trigger and door trigger on the same sector (TR5 submarine door setup).
-* Add OCB 7 for switches to be used with SetItemFlags Lua commands for customizing on/off animations and reachable distance.
-* Add instant headshot to guards.
-* Polish the distance position between Lara and switch objects.
-* Adjust rocket ammo pickup from 10 to 1.
-* Improve behaviour of tiger and lion enemies.
-* Implement more realistic water bubble effects.
-* Implement a new stacked pickup display inspired by OpenLara.
-* Prevent Lara from drawing weapons during parallel bar swinging.
-* Further renderer performance optimizations and bugfixes.
-
-Lua API changes:
-* Fix Camera:SetPosition not updating camera position when it is played simultaneously.
-* Add Moveable:GetAirborne and Moveable:SetAirborne.
-* Add Moveable:GetLocationAI and Moveable:SetLocationAI.
-
-Version 1.0.6
-=============
-
-* Fix major pathfinding bug which could have caused lots of issues with enemy behaviour.
-* Fix potential random crashes due to incorrect rendering behaviour.
-* Fix savegame crash for disabled enemies with partially set activation mask.
-* Fix certain enemies not damaging Lara if binoculars or lasersight mode is active.
-* Fix invisible Lara after starting a new game from title flyby with hidden Lara.
-* Fix backholster weapons not updating their sound position together with player.
-* Fix black screen bug when there was an obstacle between the fixed camera and the target.
-* Fix underwater caustics not appearing without visiting options menu beforehand.
-* Fix TR1 ape climbing.
-* Fix TR1 rat which crashed the game when it was killed.
-* Fix TR2 small spider climbing and pathfinding.
-* Fix TR3 Shiva and TR4 baddy 2 not blocking bullets.
-* Fix TR4 harpy's sting attack which was neither hurting nor poisoning Lara.
-* Fix TR4 SAS teleporting over the blocks he walks by.
-* Fix TR4 seth blades that were doing a double activation when used an OCB different than 0.
-* Fix TR4 skeleton spawn when used with OCB 3.
-* Fix TR4 sphinx solving his bugged behaviour that happened if it received a lot of damage.
-* Fix TR5 Roman statue and its meshswap.
-* Fix TR5 twogun laser guard.
-* Fix enemy projectile effect colours.
-* Fix enemy shadow position.
-* Fix sound positions not updated during flybys.
-* Fix grenade launcher super ammo emitting too many fragments.
-* Fix grenade and rocket launcher lighting.
-* Fix ceiling trapdoor and floor trapdoor that Lara couldn't open manually.
-* Make enemies drop pickups at first available bounding box corner point, not centerpoint.
-* Restore original volumetric explosion effects.
-* Add TR3 lizard and Puna.
-* Add TR3 boss effects in ID_BOSS_SHIELD and ID_BOSS_SHOCKWAVE_EXPLOSION slots.
-* Add an option to activate Lua or node events from legacy triggers.
-* Add more warnings in logs to enemies which animation or required slot is missing.
-* Antitriggering an enemy will now cause it to vanish and pause.
-* Re-triggering an enemy will cause it to reappear and unpause.
-* Lua Moveable functions Enable and Disable now correctly trigger and antitrigger the moveable.
-* Improve level loading speed a lot.
-
-Lua API changes:
-* Moveable:SetVisible has been added. MakeInvisible is now an alias for SetVisible(false).
-* Moveable:MeshIsVisible is now GetMeshVisible.
-* Moveable:SetMeshVisible has been added to replace ShowMesh/HideMesh.
-* Moveable:MeshIsSwapped is now GetMeshSwapped
-* Camera:SetPosition now updates the position if it's called while it's being played.
-* Primitive Classes (Color, Rotation, Vec3) can now be saved via Levelvars and Gamevars variables.
-* OnSave function now gets called just before data is saved, rather than just after.
-* Add new function CameraObject::PlayCamera()
-* Add new function Misc::GetCameraType()
-* Add new functions Moveable:GetAirborne() and Moveable:SetAirborne(bool input)
-
-Version 1.0.5
-=============
-
-* Fix combined items not existing in inventory upon game reload.
-* Fix classic rollingball not behaving properly in rooms beyond the distance of 32 blocks.
-* Fix rollingball not killing Lara under certain movement angles.
-* Fix savegame crashes when rooms with static meshes are flipped.
-* Fix discrepancies between statistics and save / load game time units.
-* Fix draw key incorrectly working in binoculars / lasersight mode.
-* Fix incorrect picking up from plinths concealed by raising blocks.
-* Fix reversed grenade rotation.
-* Fix flame emitter 3 not burning player.
-* Fix TR2 yeti, TR3 civvy and MP with stick vault bugs.
-* Fix TR2 worker with flamethrower and TR3 flamethrower baddy attack ranges and aiming issues.
-* Fix TR3 tribeman with axe not attacking Lara.
-* Fix TR3 tribeman with dart not shooting at Lara's direction.
-* Fix TR3 crow and TR4 harpy death animations not performing correctly.
-* Fix TR4 crocodile attack range and joint rotation speed.
-* Fix TR4 Von Croy not using animation for 2 and 3 step down vaults.
-* Fix TR4 baddies not using animation for 3 step down vaults.
-* Fix TR5 laserhead guardian.
-* Fix crash, water death and meshswap issues for TR5 cyborg.
-* Fix pathfinding problems for first initialized enemy of every slot.
-* Fix pathfinding of flying and water creatures (partial).
-* Fix rare crash when smash item is inside a wall and add warning log for the scenario.
-* Fix bone rotations of some entities.
-* Fix Lara's animation for cog switch release.
-* Added new OCB to cog switch object:
- - Use OCB 0 to have the traditional behaviour.
- - Use any other OCB to can use the Cog Switch without need of any door linked.
-* Allow to freely rotate dart emitter in all directions.
-* Customize dart emitter damage with OCB. Negative number will additionally poison Lara.
-* Draw real mesh for darts.
-* Added warning log when one slot requires another slot which is missing.
-
-Lua API changes:
-* Add new Room class and several methods for it.
-
-Version 1.0.4
-=============
-
-* Add generic assignable effects for moveables - fire, sparks, smoke and laser / electric ignite.
-* Add ability to burn enemies with FLAME_EMITTER_1 and death blocks.
-* Add wireframe mode and other visual debug information (switch by F10/F11 debug page scroll hotkeys).
-* Activate Lara-bound volume triggers with mounted vehicles.
-* Allow multiple individual activators for the same volume at the same time.
-* Remove TRC remnant which added HK to inventory if pistols weren't available.
-* Change default shatter sound to TR4_SMASH_ROCK (tomb4 default).
-* Reduce idle pose time from 30 to 20 seconds.
-* Automatically align pickups to floor surface.
-* Minecart enhancements:
- - Add landing / jump sound.
- - Add falldamage.
- - Explode in water below 2 click surface.
- - Fix jump.
-* Templar Knight enhancements:
- - Restored spark effects.
- - Can destroy statics in shatter slots.
- - Fix crash when attacking.
-* SAS enhancements:
- - Fix grenade shooting.
- - Fix AI_MODIFY and AI_GUARD behaviour.
-* Fix choppy camera movement in several cases.
-* Fix Lara's vertical position when shimmying around steep slope corners.
-* Fix legacy pickup triggers not working in certain cases.
-* Fix crawl pickup not actually doing any pickups.
-* Fix demigod and harpy shooting in incorrect directions.
-* Fix particle effects for seth and harpy magic attacks.
-* Fix lasersight always displaying with HK, revolver and crossbow.
-* Fix rapid ammo spending in HK lasersight mode.
-* Fix incorrect string IDs for item combine, HK and revolver with lasersight.
-* Fix puzzle holes not swapping to puzzle done objects.
-* Fix several collision and sound source issues in flipped rooms.
-* Fix several pushable sound and object collision bugs.
-* Fix original bug with incorrect climb up behaviour on ladders under sloped ceilings.
-* Fix original bug with reassigned control keys still triggering default events.
-* Fix TR1 centaur bubble targeting.
-* Fix TR5 autogun rotation.
-* Fix occasional wrong rollingball collision in narrow pits.
-* Fix classic rollingball and big rollingball not behaving properly.
-* Fix caustics not turning off in display settings.
-* Fix windowed mode not using real resolution when DPI scaling is active.
-* Fix control lock not working in flyby sequences.
-* Fix empty inventory when using build and play feature in TE.
-* Fix non-pickupable thrown flares.
-* Fix throwing flare without drawing any weapons if there are no weapons present.
-* Fix several incorrect FOV reset issues.
-* Fix current soundtrack fading into silence if incoming one doesn't exist.
-* Fix crash if there is an attempt to display a string with missing characters.
-
-Lua API changes:
-* Add new Volume class and several methods for it.
-* Add new Moveable functions: GetEffect, SetEffect and SetCustomEffect (for colored fire).
-* Add new Lara functions: GetTarget, GetVehicle and TorchIsLit.
-* Remove Lara functions: SetOnFire and GetOnFire (replaced with GetEffect and SetEffect).
-* Add Gameflow.lua options:
- - Flow.EnableMassPickup for mass pickup functionality.
- - Flow.EnableLaraInTitle for displaying Lara in title flyby.
- - Flow.EnableLevelSelect for title flyby level selection.
- - level.secrets for level-specific secret count.
-
-* Fix level.ambientTrack property not working for title flyby.
-* Fix action key script functions not fully working in some cases.
-* Fix mounted vehicles ignoring Disable, Shatter and Explode script commands.
-* Fix SetPosition command not updating room number correctly.
-* Fix Rotation class using integers under the hood which prevented using fractional rotation values.
-* Fix distance tests failing on a very high distances.
-
-Version 1.0.3
-=============
-
-* Add ledge jumps (Lara object must be updated with new animations to make it work).
-* Allow any object slot to be used as a meshswap.
-* Add OCB 1 for rollingball to make it silent.
-* Customize waterfall mist colour and OCB (XXYY, where XX is width, and YY is size).
-* Implement HK shooting modes from TR5.
-* Implement sprite instancing to speed up rendering.
-* Enable dynamic lights for swarm enemies (beetles, rats and bats).
-* Re-enable underwater caustics.
-* Increase amount of maximum secrets per level from 8 to 32.
-* Improve game and inventory input handling.
-* Adjust sprint jump timing.
-* Backport DAMOCLES_SWORD from TR1.
-* Fix going into inventory and load/save dialogs during fade-ins and fade-outs.
-* Fix savegames not preserving save number and game timer.
-* Fix dodgy weapon lock angle constraints.
-* Fix wrong shotgun ammo pickup amount.
-* Fix shotgun using 6 units of ammo with each shot.
-* Fix rocket explosions near statics.
-* Fix explosive crossbow bolts not damaging player.
-* Fix poisoned crossbow bolts not damaging enemies.
-* Fix TR3 monkey level crash.
-* Fix occasional ejections when landing on a slope.
-* Fix occasional ejections when climbing up on a ledge under a slope.
-* Fix pushables not being pushable on top of bridges and other pushables.
-* Fix pushables having incorrect collision when bounding box is bigger than 1 sector.
-* Fix grabbing narrow ledges below ceilings.
-* Fix slow centaur projectile velocity.
-* Fix search animations - allow chest and shelf animations to play properly.
-* Fix sarcophagus and its item pickup.
-* Fix underwater door and double doors continuing to be interactable after opening.
-* Fix underwater door being interactable when underwater switch is on the same square.
-* Fix ability to turn when aligning to an object while standing.
-* Fix left arm lock while picking up an item with a flare in hand.
-* Fix potential crashes when exiting game.
-* Fix secret soundtrack (which filename number should be the last) not playing.
-* Fix distance fog not applying properly to additive and subtractive surfaces.
-* Fix swarm enemies and projectiles occasionally drawn using incorrect meshes.
-* Fix single-hand weapons not having a sound on draw and undraw.
-* Fix waterfall mist - it can now be disabled with antitrigger.
-* Fix underwater lever pull animation playing after interacting with underwater ceiling switch.
-* Fix SAS_DRAG_BLOKE object interaction.
-* Fix KILLER_STATUE not triggering.
-
-Lua API changes:
-* A new class has been added, LaraObject, for Lara-specific functions. The built-in "Lara" variable now uses this class.
-* Add functions for Lara object:
- - GetPoison / SetPoison
- - GetAir / SetAir
- - GetOnFire / SetOnFire
- - GetSprintEnergy / SetSprintEnergy
- - GetWet / SetWet
- - GetWeaponType / SetWeaponType
- - UndrawWeapon
- - GetAmmoCount
- - GetHandStatus
- - ThrowAwayTorch
-
-* Add FlipMap and PlayFlyBy script commands and node functions.
-* Add GetMoveablesBySlot and GetStaticsBySlot script commands to select groups of items.
-* Add FlyCheat option to gameflow script for disabling dozy mode.
-* Add SetTotalSecretCount option to gameflow script to set overall amount of secrets.
-* Raised the maximum value on Moveable.SetHP to 32767 (its internal numeric maximum).
-
-Version 1.0.2
-=============
-
-* Fix removing Pistols with TakeItem and SetItemCount.
-* Allow saving and loading of Vec3s in LevelVars and GameVars.
-* Support volume triggers made with node editor.
-* Adjust max turn rate of idle state.
-* Align Lara on slopes when crouching, crawling, and dying.
-* Better slope alignment for large, flat enemies (i.e. big scorpion and crocodile).
-* Lock turn rate when automatically aligning Lara to objects.
-* Don't play Lara alignment animations if the interacted object is too close.
-* Allow vertical pole mounts only when facing one directly.
-* Allow vertical pole mounts while turning, walking, or running.
-* Update monkey swing 180 turn animation.
-* Update backward monkey swing animations.
-* Added standing 180 turn. Activated with WALK+ROLL on dry ground, automatic when in wade-height water or swamp.
-* Added crouch turn and crawl turn animations.
-* Added new switch OCBs:
- - 0 for wall switch
- - 1 for small wall switch
- - 2 for small button
- - 3 for big button
- - 4 for giant button (sequence switch)
- - 5 for valve turn
- - 6 for hole switch
- - any other OCBs play corresponding switch on anim or OCB+1 switch off anim.
-
-* Fix incorrect pole mounting.
-* Fix zeroed forward velocity upon landing.
-* Fix incorrect behaviour when falling on statics from the top after monkeyswing.
-* Fix missing animcommand calls on first animation frame.
-* Fix 1-frame turn rate delays.
-* Fix occasional leave event calls when moving closer to volumes.
-* Fix incorrect viewport size in windowed mode.
-* Fix late landing animation dispatch in rare cases.
-* Fix incorrect velocity calculations for death animations.
-* Fix horseman's axe attack using his left foot as the damaging joint.
-* Fix stargate blades needlessly pushing the player around while hardly doing any damage.
-* Fix weapon hotkeys and add missing crossbow hotkey.
-
-Lua API changes:
-* Util.ShortenTENCalls no longer needs to be called; it is now automatic for both level scripts and Gameflow.lua.
-* Flow.InvID has been removed; any function taking a pickup (e.g. GiveItem) now takes an Objects.ObjID instead.
-* Add Enable, Disable, GetActive, Get/SetSolid functions for static meshes.
-* Add FadeOutComplete, StopAudioTrack and StopAudioTracks functions.
-* Account for objects in HasLineOfSight tests.
-* Move Timer.lua, EventSequence.lua and Util.lua to a subfolder named "Engine".
-* LevelFuncs can now contain tables as well as functions. These tables can contain functions and other tables, and so forth.
-* Moveable functions SetOnHit, SetOnKilled, SetOnCollidedWithObject and SetOnCollidedWithRoom no longer take strings, and instead take function objects themselves.
-* Don't require EventSequence and Timer to call Timer.UpdateAll in OnControlPhase.
-* Add TEN.Logic.AddCallback and TEN.Logic.RemoveCallback.
-* Rework GiveItem, TakeItem, and SetItemCount (e.g. SetItemCount with a value of -1 can give infinite ammo/consumables).
-
-
-Version 1.0.1
-=============
-
-* Added antialiasing support.
-* Added static mesh scaling support.
-* Added free rotation for teeth spikes instead of using OCB codes.
-* Fix some issues with shimmying between diagonal ledges and walls.
-* Fix rope transparency.
-* Fix objects disappearing under certain angles at the edges of the screen.
-* Fix incorrect polerope and jumpswitch grabbing.
-* Fix camera behaviour with pushable blocks.
-* Fix minecart unduck on inclines.
-* Fix quadbike dismount with jump key and allow to shoot big gun with action key.
-* Fix static meshes having wrong colors on savegame reload.
-* Fix rollingball incorrectly killing Lara in water and in jump.
-* Fix resurfacing on underwater death.
-* Fix water to ladder animation not activating in all cases.
-* Fix ripples not appearing on water connections higher than room bottom.
-* Fix several problems with ropes (stumbling, rope length, etc).
-* Fix several problems with teeth spikes.
-* Fix falling through twoblock platform on room number change.
-* Fix falling block breaking too early if placed on a vertical portal.
-* Fix crashes when loading image files are missing.
-* Disable trigger check for puzzle holes.
-* Clear locusts and other swarm enemies on level reload.
-* Enhance cobra AI and fix targeting.
-* Fully decompile HAMMER object from TR4.
-* Prevent title music audio from starting in a random place.
-* Update harpoon speed on room change.
-* Enable second sky layer rendering.
-* Preserve inventory and flare on level jumps.
-* Timer.Create now lets you choose the units to display remaining time.
-* Fatal script errors now boot you to the title (it will crash if the title itself has these errors).
-* SetFarView has been removed, and Flow.Level.farView is now uncapped.
-* DisplayString text will now be cleared when a level is exited or reloaded.
-* EventSequence.lua has been added and documented.
-
-
-Version 1.0
-===========
-
-First beta release.
From 2d670175b48a2f1187e4dcd96ff3d0049a524144 Mon Sep 17 00:00:00 2001
From: Jakub <80340234+Jakub768@users.noreply.github.com>
Date: Thu, 16 May 2024 09:41:48 +0100
Subject: [PATCH 184/410] Update CHANGELOG.md
---
CHANGELOG.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index aac358b80..f511bfbe0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,8 @@ Here you will find the full changelog of TEN's releases from Version 1.0 and up
The dates are in European standard format where date is presented as **YYYY-MM-DD**
+TombEngine releases are located in this repository (alongside with Tomb Editor): https://github.com/TombEngine/TombEditorReleases
+
## Version 1.5 - xxxx-xx-xx
### Bug fixes
From 23254c87eaeeb0a0a224ed2bbc918ab95d8cf1e4 Mon Sep 17 00:00:00 2001
From: Jakub <80340234+Jakub768@users.noreply.github.com>
Date: Thu, 16 May 2024 10:14:26 +0100
Subject: [PATCH 185/410] Update CHANGELOG.md
---
CHANGELOG.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f511bfbe0..545c4f5e9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor):
* Fixed AI for skidoo driver and worker with shotgun TR2 enemies.
* Fixed Ember emitter crashing when ocb is between -1 and -10
* Fixed Electric cleaner and Squishy block not detecting collision with certain block heights.
+* Fixed Squishy blocks crashing the level.
### Features/Amendments
From d5ed115d507e8438c136bfa5b83eac3d7a72ef95 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Thu, 16 May 2024 11:49:58 +0200
Subject: [PATCH 186/410] Fixed wrong positions for transparent faces in
moveable items
---
Documentation/doc/2 classes/Flow.Starfield.html | 12 ++++++------
TombEngine/Renderer/RendererDraw.cpp | 6 +++---
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/Documentation/doc/2 classes/Flow.Starfield.html b/Documentation/doc/2 classes/Flow.Starfield.html
index 07749c388..a0d3880c4 100644
--- a/Documentation/doc/2 classes/Flow.Starfield.html
+++ b/Documentation/doc/2 classes/Flow.Starfield.html
@@ -144,11 +144,11 @@
Starfield:SetStarCount(New)
- Set the starfield's number of stars.
+ Set the starfield's number of stars (6000 max).
Starfield:SetMeteorCount(New)
- Set the starfield's number of meteors.
+ Set the starfield's number of meteors (100 max).
Starfield:SetMeteorSpawnDensity(New)
@@ -208,11 +208,11 @@
starCount
int
- Star count.
+ Star count (6000 max).
meteorCount
int
- Meteor count.
+ Meteor count (100 max).
@@ -358,7 +358,7 @@
Starfield:SetStarCount(New)
- Set the starfield's number of stars. (int)
+ Set the starfield's number of stars (6000 max). (int)
@@ -380,7 +380,7 @@
Starfield:SetMeteorCount(New)
- Set the starfield's number of meteors. (int)
+ Set the starfield's number of meteors (100 max). (int)
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index cede3ccbf..137143413 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -3123,7 +3123,7 @@ namespace TEN::Renderer
for (int p = 0; p < bucket.Polygons.size(); p++)
{
auto centre = Vector3::Transform(
- bucket.Polygons[p].Centre, itemToDraw->AnimationTransforms[boneIndex] * itemToDraw->World);
+ bucket.Polygons[p].Centre, itemToDraw->InterpolatedAnimationTransforms[boneIndex] * itemToDraw->InterpolatedWorld);
int distance = (centre - cameraPos).Length();
RendererSortableObject object;
@@ -3566,10 +3566,10 @@ namespace TEN::Renderer
RendererObject& moveableObj = *_moveableObjects[objectInfo->Item->ObjectNumber];
// Bind item main properties
- _stItem.World = objectInfo->Item->World;
+ _stItem.World = objectInfo->Item->InterpolatedWorld;
_stItem.Color = objectInfo->Item->Color;
_stItem.AmbientLight = objectInfo->Item->AmbientLight;
- memcpy(_stItem.BonesMatrices, objectInfo->Item->AnimationTransforms, sizeof(Matrix) * MAX_BONES);
+ memcpy(_stItem.BonesMatrices, objectInfo->Item->InterpolatedAnimationTransforms, sizeof(Matrix) * MAX_BONES);
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
_stItem.BoneLightModes[k] = (int)moveableObj.ObjectMeshes[k]->LightMode;
From a39f7ccd2c3e9a9f2ea4266a5dc9a8436e6b3298 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Thu, 16 May 2024 12:01:33 +0200
Subject: [PATCH 187/410] Disabled interpolation on PuzzleDone
---
TombEngine/Objects/Generic/puzzles_keys.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/TombEngine/Objects/Generic/puzzles_keys.cpp b/TombEngine/Objects/Generic/puzzles_keys.cpp
index 811896ad1..31733b631 100644
--- a/TombEngine/Objects/Generic/puzzles_keys.cpp
+++ b/TombEngine/Objects/Generic/puzzles_keys.cpp
@@ -339,6 +339,7 @@ void PuzzleDone(ItemInfo* item, short itemNumber)
item->ObjectNumber += GAME_OBJECT_ID{ ID_PUZZLE_DONE1 - ID_PUZZLE_HOLE1 };
item->ItemFlags[5] = (int)ReusableReceptacleState::Done;
SetAnimation(item, 0);
+ item->DisableInterpolation = true;
item->ResetModelToDefault();
}
else
@@ -349,6 +350,7 @@ void PuzzleDone(ItemInfo* item, short itemNumber)
item->Animation.ActiveState = GetAnimData(item).ActiveState;
item->Animation.TargetState = GetAnimData(item).ActiveState;
item->Animation.RequiredState = NO_VALUE;
+ item->DisableInterpolation = true;
item->ResetModelToDefault();
AddActiveItem(itemNumber);
From 411c397027f9d6f30ffe2d40fe538491f6aa6ba4 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Fri, 17 May 2024 18:52:26 +1000
Subject: [PATCH 188/410] Minor formatting
---
Scripts/SystemStrings.lua | 2 +-
TombEngine/Renderer/RendererDraw.cpp | 17 ++++++++---------
2 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/Scripts/SystemStrings.lua b/Scripts/SystemStrings.lua
index 69009d8eb..73caa9386 100644
--- a/Scripts/SystemStrings.lua
+++ b/Scripts/SystemStrings.lua
@@ -110,10 +110,10 @@ local strings =
total_secrets_found = { "Secrets Found Total" },
use = { "Use" },
used_medipacks = { "Medipacks Used" },
+ variable_framerate = { "Variable Framerate" },
vehicle_actions = { "Vehicle Actions" },
view = { "View" },
volumetric_fog = { "Volumetric Fog" },
- variable_framerate = { "Variable Framerate" },
waiting_for_input = { "Waiting For Input" },
window_title = { "TombEngine" },
windowed = { "Windowed" },
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index 137143413..364ad3156 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -3547,8 +3547,8 @@ namespace TEN::Renderer
void Renderer::DrawItemSorted(RendererSortableObject* objectInfo, RendererObjectType lastObjectType, RenderView& view)
{
- UINT stride = sizeof(Vertex);
- UINT offset = 0;
+ unsigned int stride = sizeof(Vertex);
+ unsigned int offset = 0;
_context->IASetVertexBuffers(0, 1, _moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
_context->IASetInputLayout(_inputLayout.Get());
@@ -3561,25 +3561,24 @@ namespace TEN::Renderer
_context->VSSetShader(_vsItems.Get(), nullptr, 0);
_context->PSSetShader(_psItems.Get(), nullptr, 0);
- ItemInfo* nativeItem = &g_Level.Items[objectInfo->Item->ItemNumber];
- RendererRoom* room = &_rooms[objectInfo->Item->RoomNumber];
- RendererObject& moveableObj = *_moveableObjects[objectInfo->Item->ObjectNumber];
-
- // Bind item main properties
+ // Bind main item properties.
_stItem.World = objectInfo->Item->InterpolatedWorld;
_stItem.Color = objectInfo->Item->Color;
_stItem.AmbientLight = objectInfo->Item->AmbientLight;
memcpy(_stItem.BonesMatrices, objectInfo->Item->InterpolatedAnimationTransforms, sizeof(Matrix) * MAX_BONES);
+ const auto& moveableObj = *_moveableObjects[objectInfo->Item->ObjectNumber];
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
_stItem.BoneLightModes[k] = (int)moveableObj.ObjectMeshes[k]->LightMode;
BindMoveableLights(objectInfo->Item->LightsToDraw, objectInfo->Item->RoomNumber, objectInfo->Item->PrevRoomNumber, objectInfo->Item->LightFade);
_cbItem.UpdateData(_stItem, _context.Get());
- BindTexture(TextureRegister::ColorMap, &std::get<0>(_moveablesTextures[objectInfo->Bucket->Texture]),
+ BindTexture(
+ TextureRegister::ColorMap, &std::get<0>(_moveablesTextures[objectInfo->Bucket->Texture]),
SamplerStateRegister::AnisotropicClamp);
- BindTexture(TextureRegister::NormalMap, &std::get<1>(_moveablesTextures[objectInfo->Bucket->Texture]),
+ BindTexture(
+ TextureRegister::NormalMap, &std::get<1>(_moveablesTextures[objectInfo->Bucket->Texture]),
SamplerStateRegister::AnisotropicClamp);
_sortedPolygonsIndexBuffer.Update(_context.Get(), _sortedPolygonsIndices, 0, (int)_sortedPolygonsIndices.size());
From 206fd59e55fbcef30069feee2d4ff8cebc588463 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Fri, 17 May 2024 18:57:22 +1000
Subject: [PATCH 189/410] Interpolate speedometer
---
TombEngine/Game/Hud/Speedometer.cpp | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/TombEngine/Game/Hud/Speedometer.cpp b/TombEngine/Game/Hud/Speedometer.cpp
index cc3d0fe69..9689c6d73 100644
--- a/TombEngine/Game/Hud/Speedometer.cpp
+++ b/TombEngine/Game/Hud/Speedometer.cpp
@@ -48,7 +48,7 @@ namespace TEN::Hud
void SpeedometerController::Draw() const
{
constexpr auto POS = Vector2(DISPLAY_SPACE_RES.x - (DISPLAY_SPACE_RES.x / 6), DISPLAY_SPACE_RES.y - (DISPLAY_SPACE_RES.y / 10));
- constexpr auto ORIENT_OFFSET = ANGLE(90.0f);
+ constexpr auto POINTER_ANGLE_OFFSET = ANGLE(90.0f);
constexpr auto SCALE = Vector2(0.35f);
constexpr auto DIAL_ELEMENT_SPRITE_ID = 0;
constexpr auto POINTER_ELEMENT_SPRITE_ID = 1;
@@ -60,9 +60,8 @@ namespace TEN::Hud
if (_life <= 0.0f)
return;
- // TODO: Interpolation.
-
- auto color = Color(1.0f, 1.0f, 1.0f, _opacity);
+ short pointerAngle = (short)Lerp(_prevPointerAngle, _pointerAngle, g_Renderer.GetInterpolationFactor());
+ auto color = Color(1.0f, 1.0f, 1.0f, Lerp(_prevOpacity, _opacity, g_Renderer.GetInterpolationFactor()));
// Draw dial.
AddDisplaySprite(
@@ -74,7 +73,7 @@ namespace TEN::Hud
// Draw pointer.
AddDisplaySprite(
ID_SPEEDOMETER, POINTER_ELEMENT_SPRITE_ID,
- POS, _pointerAngle + ORIENT_OFFSET, SCALE, color,
+ POS, pointerAngle + POINTER_ANGLE_OFFSET, SCALE, color,
POINTER_PRIORITY, DisplaySpriteAlignMode::Center, DisplaySpriteScaleMode::Fit, BlendMode::AlphaBlend,
DisplaySpritePhase::Draw);
}
From de91720fc9c6857bdaa7b7ac88c919a0155db715 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Fri, 17 May 2024 19:40:09 +1000
Subject: [PATCH 190/410] Formatting
---
TombEngine/Game/Lara/lara.cpp | 6 --
TombEngine/Game/Lara/lara.h | 6 +-
TombEngine/Game/camera.cpp | 2 +-
TombEngine/Game/control/control.cpp | 116 +++++++++++++++-------------
TombEngine/Game/gui.cpp | 4 +-
5 files changed, 68 insertions(+), 66 deletions(-)
diff --git a/TombEngine/Game/Lara/lara.cpp b/TombEngine/Game/Lara/lara.cpp
index b39f9c246..bc4465ce6 100644
--- a/TombEngine/Game/Lara/lara.cpp
+++ b/TombEngine/Game/Lara/lara.cpp
@@ -629,12 +629,6 @@ void UpdateLara(ItemInfo* item, bool isTitle)
// Control player.
InItemControlLoop = true;
-
- // Copy current state to old state for interpolation
- //memcpy(&item->OldPose, &item->Pose, sizeof(Pose));
- //memcpy(&item->OldLocation, &item->Location, sizeof(Vector3i));
- //memcpy(&item->OldAnimation, &item->Animation, sizeof(EntityAnimationData));
- //memcpy(&OldLara, &Lara, sizeof(LaraInfo));
LaraControl(item, &LaraCollision);
HandlePlayerFlyCheat(*item);
diff --git a/TombEngine/Game/Lara/lara.h b/TombEngine/Game/Lara/lara.h
index 223f47f77..fda62282c 100644
--- a/TombEngine/Game/Lara/lara.h
+++ b/TombEngine/Game/Lara/lara.h
@@ -93,9 +93,9 @@ constexpr auto WADE_WATER_DEPTH = STEPUP_HEIGHT;
constexpr auto SWIM_WATER_DEPTH = CLICK(2.75f);
constexpr auto SLOPE_DIFFERENCE = 60;
-extern LaraInfo Lara;
-extern LaraInfo PrevLara;
-extern ItemInfo* LaraItem;
+extern LaraInfo Lara;
+extern LaraInfo PrevLara;
+extern ItemInfo* LaraItem;
extern CollisionInfo LaraCollision;
void LaraControl(ItemInfo* item, CollisionInfo* coll);
diff --git a/TombEngine/Game/camera.cpp b/TombEngine/Game/camera.cpp
index b3733f0d1..a53123c16 100644
--- a/TombEngine/Game/camera.cpp
+++ b/TombEngine/Game/camera.cpp
@@ -202,7 +202,7 @@ void LookAt(CAMERA_INFO* cam, short roll)
float levelFarView = g_GameFlow->GetLevel(CurrentLevel)->GetFarView() * float(BLOCK(1));
- g_Renderer.UpdateCameraMatrices(cam, r, fov, levelFarView);
+ g_Renderer.UpdateCameraMatrices(cam, r, fov, levelFarView);
}
void AlterFOV(short value, bool store)
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index 504a55a9f..6fa9b355d 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -153,20 +153,18 @@ GameStatus ControlPhase()
SetupInterpolation();
g_Renderer.SaveOldState();
- // Controls are polled before OnLoop, so input data could be
- // overwritten by script API methods.
+ // Controls are polled before OnLoop to allow input data to be overwritten by script API methods.
HandleControls(isTitle);
// Pre-loop script and event handling.
g_GameScript->OnLoop(DELTA_TIME, false); // TODO: Don't use DELTA_TIME constant with variable framerate
HandleAllGlobalEvents(EventType::Loop, (Activator)LaraItem->Index);
- // Control lock is processed after handling scripts, because builder may want to
- // process input externally, while still locking Lara from input.
+ // Control lock is processed after handling scripts because builder may want to process input externally while locking player from input.
if (!isTitle && Lara.Control.IsLocked)
ClearAllActions();
- // Handle inventory / pause / load / save screens.
+ // Handle inventory, pause, load, save screens.
auto result = HandleMenuCalls(isTitle);
if (result != GameStatus::Normal)
return result;
@@ -176,9 +174,8 @@ GameStatus ControlPhase()
if (result != GameStatus::Normal)
return result;
- // Queued input actions are read again and cleared after UI
- // interrupts are processed, so first frame after exiting UI
- // will still register it.
+ // Queued input actions are read again and cleared after UI interrupts are processed,
+ // so first game frame after exiting UI will still register it.
ApplyActionQueue();
ClearActionQueue();
@@ -188,14 +185,14 @@ GameStatus ControlPhase()
g_GameScriptEntities->TestCollidingObjects();
+ // Draw flyby cameras.
if (UseSpotCam)
{
- // Draw flyby cameras.
CalculateSpotCameras();
}
+ // Do standard camera.
else
{
- // Do the standard camera.
TrackCameraInit = false;
CalculateCamera(LaraCollision);
}
@@ -206,11 +203,11 @@ GameStatus ControlPhase()
// Smash shatters and clear stopper flags under them.
UpdateShatters();
- // Clear last selected item in inventory (need to be after on loop event handling, so they can detect that).
+ // Clear last selected item in inventory (must be after on loop event handling, so they can detect that).
g_Gui.CancelInventorySelection();
- // Control lock is processed after handling scripts, because builder may want to
- // process input externally, while still locking Lara from input.
+ // Control lock is processed after handling scripts because builder may want to
+ // process input externally while locking player from input.
if (!isTitle && Lara.Control.IsLocked)
ClearAllActions();
@@ -286,22 +283,26 @@ GameStatus ControlPhase()
unsigned CALLBACK GameMain(void *)
{
- TENLog("Starting GameMain...", LogLevel::Info);
+ TENLog("Starting GameMain()...", LogLevel::Info);
TimeInit();
- // Do a fixed time title image.
+ // Do fixed-time title image.
if (g_GameFlow->IntroImagePath.empty())
- TENLog("Intro image path is not set.", LogLevel::Warning);
+ {
+ TENLog("Intro image path not set.", LogLevel::Warning);
+ }
else
+ {
g_Renderer.RenderTitleImage();
+ }
- // Execute the Lua gameflow and play the game.
+ // Execute Lua gameflow and play game.
g_GameFlow->DoFlow();
DoTheGame = false;
- // Finish the thread.
+ // Finish thread.
PostMessage(WindowsHandle, WM_CLOSE, NULL, NULL);
EndThread();
@@ -317,7 +318,7 @@ GameStatus DoLevel(int levelIndex, bool loadGame)
// Load level. Fall back to title if unsuccessful.
if (!LoadLevelFile(levelIndex))
- return isTitle ? GameStatus::ExitGame : GameStatus::ExitToTitle;
+ return (isTitle ? GameStatus::ExitGame : GameStatus::ExitToTitle);
// Initialize items, effects, lots, and cameras.
HairEffect.Initialize();
@@ -374,11 +375,15 @@ void KillMoveItems()
{
for (int i = 0; i < ItemNewRoomNo; i++)
{
- short itemNumber = ItemNewRooms[2 * i];
+ int itemNumber = ItemNewRooms[i * 2];
if (itemNumber >= 0)
- ItemNewRoom(itemNumber, ItemNewRooms[2 * i + 1]);
+ {
+ ItemNewRoom(itemNumber, ItemNewRooms[(i * 2) + 1]);
+ }
else
+ {
KillItem(itemNumber & 0x7FFF);
+ }
}
}
@@ -391,11 +396,15 @@ void KillMoveEffects()
{
for (int i = 0; i < ItemNewRoomNo; i++)
{
- short itemNumber = ItemNewRooms[2 * i];
+ int itemNumber = ItemNewRooms[i * 2];
if (itemNumber >= 0)
- EffectNewRoom(itemNumber, ItemNewRooms[2 * i + 1]);
+ {
+ EffectNewRoom(itemNumber, ItemNewRooms[(i * 2) + 1]);
+ }
else
+ {
KillEffect(itemNumber & 0x7FFF);
+ }
}
}
@@ -417,13 +426,13 @@ void CleanUp()
// Reset oscillator seed.
Wibble = 0;
- // Needs to be cleared, otherwise controls will lock if user exits to title while playing flyby with locked controls.
+ // Clear player lock, otherwise controls will lock if user exits to title while playing flyby with locked controls.
Lara.Control.IsLocked = false;
// Resets lightning and wind parameters to avoid holding over previous weather to new level.
Weather.Clear();
- // Needs to be cleared, otherwise a list of active creatures from previous level will spill into new level.
+ // Clear creatures, otherwise list of active creatures from previous level will spill into new level.
ActiveCreatures.clear();
// Clear ropes.
@@ -473,26 +482,27 @@ void InitializeScripting(int levelIndex, LevelLoadType type)
g_GameStringsHandler->ClearDisplayStrings();
g_GameScript->ResetScripts(!levelIndex || type != LevelLoadType::New);
- auto* level = g_GameFlow->GetLevel(levelIndex);
+ const auto& level = *g_GameFlow->GetLevel(levelIndex);
// Run level script if it exists.
- if (!level->ScriptFileName.empty())
+ if (!level.ScriptFileName.empty())
{
- g_GameScript->ExecuteScriptFile(g_GameFlow->GetGameDir() + level->ScriptFileName);
+ g_GameScript->ExecuteScriptFile(g_GameFlow->GetGameDir() + level.ScriptFileName);
g_GameScript->InitCallbacks();
g_GameStringsHandler->SetCallbackDrawString([](const std::string& key, D3DCOLOR color, const Vec2& pos, float scale, int flags)
{
g_Renderer.AddString(
key,
- Vector2(((float)pos.x / (float)g_Configuration.ScreenWidth * DISPLAY_SPACE_RES.x),
- ((float)pos.y / (float)g_Configuration.ScreenHeight * DISPLAY_SPACE_RES.y)),
+ Vector2(
+ (pos.x / g_Configuration.ScreenWidth) * DISPLAY_SPACE_RES.x,
+ (pos.y / g_Configuration.ScreenHeight) * DISPLAY_SPACE_RES.y),
Color(color), scale, flags);
});
}
// Play default background music.
if (type != LevelLoadType::Load)
- PlaySoundTrack(level->GetAmbientTrack(), SoundTrackType::BGM);
+ PlaySoundTrack(level.GetAmbientTrack(), SoundTrackType::BGM);
}
void DeInitializeScripting(int levelIndex, GameStatus reason)
@@ -503,7 +513,7 @@ void DeInitializeScripting(int levelIndex, GameStatus reason)
g_GameScript->FreeLevelScripts();
g_GameScriptEntities->FreeEntities();
- if (!levelIndex)
+ if (levelIndex == 0)
g_GameScript->ResetScripts(true);
}
@@ -512,7 +522,7 @@ void InitializeOrLoadGame(bool loadGame)
g_Gui.SetInventoryItemChosen(NO_VALUE);
g_Gui.SetEnterInventory(NO_VALUE);
- // Restore the game?
+ // Restore game?
if (loadGame)
{
SaveGame::Load(g_GameFlow->SelectedSaveGame);
@@ -533,7 +543,7 @@ void InitializeOrLoadGame(bool loadGame)
}
else
{
- // If not loading a savegame, clear all info.
+ // If not loading savegame, clear all info.
SaveGame::Statistics.Level = {};
if (InitializeGame)
@@ -559,19 +569,19 @@ void InitializeOrLoadGame(bool loadGame)
GameStatus DoGameLoop(int levelIndex)
{
- int numFrames = LOOP_FRAME_COUNT;
+ constexpr auto CONTROL_FRAME_TIME = 1000.0f / 30.0f;
+
+ int frameCount = LOOP_FRAME_COUNT;
auto& status = g_GameFlow->LastGameStatus;
- // Before entering actual game loop, ControlPhase must be
+ // Before entering actual game loop, ControlPhase() must be
// called once to sort out various runtime shenanigangs (e.g. hair).
-
status = ControlPhase();
LARGE_INTEGER lastTime;
LARGE_INTEGER currentTime;
double controlLag = 0;
double frameTime = 0;
- constexpr auto controlFrameTime = 1000.0f / 30.0f;
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
@@ -600,21 +610,21 @@ GameStatus DoGameLoop(int levelIndex)
controlLag += frameTime;
}
- while (controlLag >= controlFrameTime)
+ while (controlLag >= CONTROL_FRAME_TIME)
{
#if _DEBUG
constexpr auto DEBUG_SKIP_FRAMES = 10;
- if (controlLag >= DEBUG_SKIP_FRAMES * controlFrameTime)
+ if (controlLag >= DEBUG_SKIP_FRAMES * CONTROL_FRAME_TIME)
{
- TENLog("Game loop is running too slow!", LogLevel::Warning);
+ TENLog("Game loop is running too slow.", LogLevel::Warning);
App.ResetClock = true;
break;
}
#endif
status = ControlPhase();
- controlLag -= controlFrameTime;
+ controlLag -= CONTROL_FRAME_TIME;
controlCalls++;
legacy30FpsDoneDraw = false;
@@ -634,7 +644,7 @@ GameStatus DoGameLoop(int levelIndex)
}
else
{
- float interpolationFactor = std::min((float)controlLag / (float)controlFrameTime, 1.0f);
+ float interpolationFactor = std::min((float)controlLag / (float)CONTROL_FRAME_TIME, 1.0f);
DrawPhase(!levelIndex, interpolationFactor);
drawCalls++;
}
@@ -658,9 +668,7 @@ void EndGameLoop(int levelIndex, GameStatus reason)
void SetupInterpolation()
{
for (int i = 0; i < g_Level.Items.size(); i++)
- {
g_Level.Items[i].DisableInterpolation = false;
- }
}
void HandleControls(bool isTitle)
@@ -675,10 +683,10 @@ void HandleControls(bool isTitle)
GameStatus HandleMenuCalls(bool isTitle)
{
- auto result = GameStatus::Normal;
+ auto gameStatus = GameStatus::Normal;
if (ScreenFading)
- return result;
+ return gameStatus;
if (isTitle)
{
@@ -697,10 +705,10 @@ GameStatus HandleMenuCalls(bool isTitle)
return GameStatus::ExitGame;
}
- return result;
+ return gameStatus;
}
- // Does the player want to enter inventory?
+ // Handle inventory.
if (IsClicked(In::Save) && LaraItem->HitPoints > 0 &&
g_Gui.GetInventoryMode() != InventoryMode::Save &&
g_GameFlow->IsLoadSaveEnabled())
@@ -717,28 +725,28 @@ GameStatus HandleMenuCalls(bool isTitle)
g_Gui.SetInventoryMode(InventoryMode::Load);
if (g_Gui.CallInventory(LaraItem, false))
- result = GameStatus::LoadGame;
+ gameStatus = GameStatus::LoadGame;
}
else if (IsClicked(In::Pause) && LaraItem->HitPoints > 0 &&
g_Gui.GetInventoryMode() != InventoryMode::Pause)
{
if (g_Gui.CallPause())
- result = GameStatus::ExitToTitle;
+ gameStatus = GameStatus::ExitToTitle;
}
else if ((IsClicked(In::Inventory) || g_Gui.GetEnterInventory() != NO_VALUE) &&
LaraItem->HitPoints > 0 && !Lara.Control.Look.IsUsingBinoculars)
{
if (g_Gui.CallInventory(LaraItem, true))
- result = GameStatus::LoadGame;
+ gameStatus = GameStatus::LoadGame;
}
- if (result != GameStatus::Normal)
+ if (gameStatus != GameStatus::Normal)
{
StopAllSounds();
StopRumble();
}
- return result;
+ return gameStatus;
}
GameStatus HandleGlobalInputEvents(bool isTitle)
diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp
index 6af798543..16ef14da1 100644
--- a/TombEngine/Game/gui.cpp
+++ b/TombEngine/Game/gui.cpp
@@ -3588,8 +3588,8 @@ namespace TEN::Gui
auto needleOrient = EulerAngles(0, CompassNeedleAngle, 0);
needleOrient.Lerp(EulerAngles(0, item->Pose.Orientation.y, 0), LERP_ALPHA);
- float wibble = std::sin(((float)(GameTimer & 0x3F) / (float)0x3F) * PI_MUL_2);
- CompassNeedleAngle = needleOrient.y + ANGLE(wibble);
+ float wibble = std::sin((float(GameTimer & 0x3F) / (float)0x3F) * PI_MUL_2);
+ CompassNeedleAngle = needleOrient.y + ANGLE(wibble / 2);
// HACK: Needle is rotated in the draw function.
const auto& invObject = InventoryObjectTable[INV_OBJECT_COMPASS];
From b9d3f812536a240b77e3bb0bd216d537b1782301 Mon Sep 17 00:00:00 2001
From: Adngel
Date: Fri, 17 May 2024 12:30:14 +0200
Subject: [PATCH 191/410] Fix: Electric Cleaner crash
When it detected a sector with no box (a tile marked with "set non-walkable sector" editor flag) the game was crashing.
Changing the detection order solved the issue.
This issue was not happening in previous version (it was originated at some point of the past month) so I'm not registering in the changes.txt
---
TombEngine/Game/misc.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/TombEngine/Game/misc.cpp b/TombEngine/Game/misc.cpp
index 7468037c1..29fa3e945 100644
--- a/TombEngine/Game/misc.cpp
+++ b/TombEngine/Game/misc.cpp
@@ -131,6 +131,10 @@ bool IsNextSectorValid(const ItemInfo& item, const Vector3& dir, float dist, boo
return false;
}
+ // Check for inaccessible sector.
+ if (pointColl.GetSector().Box == NO_VALUE)
+ return false;
+
// Check for blocked grey box.
if (g_Level.Boxes[pointColl.GetSector().Box].flags & BLOCKABLE)
{
@@ -138,10 +142,6 @@ bool IsNextSectorValid(const ItemInfo& item, const Vector3& dir, float dist, boo
return false;
}
- // Check for inaccessible sector.
- if (pointColl.GetSector().Box == NO_VALUE)
- return false;
-
// Check for stopper flag.
if (pointColl.GetSector().Stopper)
return false;
From 815598f42528af7b7a34a3b936cb7ea9ffbf5ae3 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Fri, 17 May 2024 13:39:02 +0200
Subject: [PATCH 192/410] Fixed fire emitters
---
TombEngine/Renderer/RendererDrawEffect.cpp | 38 +++++++++++-----------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/TombEngine/Renderer/RendererDrawEffect.cpp b/TombEngine/Renderer/RendererDrawEffect.cpp
index 1b9d8d069..04a28d858 100644
--- a/TombEngine/Renderer/RendererDrawEffect.cpp
+++ b/TombEngine/Renderer/RendererDrawEffect.cpp
@@ -356,39 +356,39 @@ namespace TEN::Renderer
for (int i = 0; i < MAX_SPARKS_FIRE; i++)
{
- auto* fire = &FireSparks[i];
+ auto* spark = &FireSparks[i];
- if (fire->on)
+ if (spark->on)
{
AddSpriteBillboard(
- &_sprites[fire->def],
+ &_sprites[spark->def],
Vector3::Lerp(
Vector3(
- fire->oldPosition.x + fire->oldPosition.x * fire->oldSize / 2,
- fire->oldPosition.y + fire->oldPosition.y * fire->oldSize / 2,
- fire->oldPosition.z + fire->oldPosition.z * fire->oldSize / 2),
+ fire->oldPosition.x + spark->oldPosition.x * fire->oldSize / 2,
+ fire->oldPosition.y + spark->oldPosition.y * fire->oldSize / 2,
+ fire->oldPosition.z + spark->oldPosition.z * fire->oldSize / 2),
Vector3(
- fire->position.x + fire->position.x * fire->size / 2,
- fire->position.y + fire->position.y * fire->size / 2,
- fire->position.z + fire->position.z * fire->size / 2),
+ fire->position.x + spark->position.x * fire->size / 2,
+ fire->position.y + spark->position.y * fire->size / 2,
+ fire->position.z + spark->position.z * fire->size / 2),
_interpolationFactor),
Vector4::Lerp(
Vector4(
- fire->oldColor.x / 255.0f * fade,
- fire->oldColor.y / 255.0f * fade,
- fire->oldColor.z / 255.0f * fade,
+ spark->oldColor.x / 255.0f * fade,
+ spark->oldColor.y / 255.0f * fade,
+ spark->oldColor.z / 255.0f * fade,
1.0f),
Vector4(
- fire->color.x / 255.0f * fade,
- fire->color.y / 255.0f * fade,
- fire->color.z / 255.0f * fade,
+ spark->color.x / 255.0f * fade,
+ spark->color.y / 255.0f * fade,
+ spark->color.z / 255.0f * fade,
1.0f),
_interpolationFactor),
- TO_RAD(Lerp(fire->oldRotAng << 4, fire->rotAng << 4, _interpolationFactor)),
- Lerp(fire->oldScalar, fire->scalar, _interpolationFactor),
+ TO_RAD(Lerp(spark->oldRotAng << 4, spark->rotAng << 4, _interpolationFactor)),
+ Lerp(spark->oldScalar, spark->scalar, _interpolationFactor),
Vector2::Lerp(
- Vector2(fire->oldSize * fire->oldSize, fire->oldSize * fire->oldSize),
- Vector2(fire->size * fire->size, fire->size * fire->size),
+ Vector2(fire->oldSize * spark->oldSize, fire->oldSize * spark->oldSize),
+ Vector2(fire->size * spark->size, fire->size * spark->size),
_interpolationFactor),
BlendMode::Additive, true, view);
}
From 0b749b0c95c690a6cf58f671c4443048456d676c Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sat, 18 May 2024 01:37:41 +1000
Subject: [PATCH 193/410] Fix bridge push
---
TombEngine/Game/collision/collide_item.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/TombEngine/Game/collision/collide_item.cpp b/TombEngine/Game/collision/collide_item.cpp
index 8698d01df..0ae536fb2 100644
--- a/TombEngine/Game/collision/collide_item.cpp
+++ b/TombEngine/Game/collision/collide_item.cpp
@@ -920,7 +920,8 @@ void CollideBridgeItems(ItemInfo& item, CollisionInfo& coll, PointCollisionData&
}
}
// Push item.
- else if (Vector2(deltaPose.Position.x, deltaPose.Position.z).Length() <= coll.Setup.Radius &&
+ else if (TestBoundsCollide(&bridgeItem, &item, coll.Setup.Radius) &&
+ Vector2(deltaPose.Position.x, deltaPose.Position.z).Length() <= coll.Setup.Radius &&
(deltaPos != Vector3i::Zero || deltaOrient != EulerAngles::Identity))
{
ItemPushItem(&bridgeItem, &item);
From 4fd6cceecd9810ddc150851d6cc4ded699a6feca Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Sat, 18 May 2024 05:40:27 +0200
Subject: [PATCH 194/410] Added interpolation for scarabs, locusts, bats, rats,
spiders, fishes
---
TombEngine/Objects/Effects/tr4_locusts.cpp | 2 ++
TombEngine/Objects/Effects/tr4_locusts.h | 6 ++++
TombEngine/Objects/TR3/Entity/FishSwarm.cpp | 4 +++
TombEngine/Objects/TR3/Entity/FishSwarm.h | 8 +++++
.../Objects/TR4/Entity/tr4_beetle_swarm.cpp | 2 ++
.../Objects/TR4/Entity/tr4_beetle_swarm.h | 6 ++++
.../Objects/TR5/Emitter/tr5_bats_emitter.cpp | 2 ++
.../Objects/TR5/Emitter/tr5_bats_emitter.h | 6 ++++
.../Objects/TR5/Emitter/tr5_rats_emitter.cpp | 2 ++
.../Objects/TR5/Emitter/tr5_rats_emitter.h | 6 ++++
.../TR5/Emitter/tr5_spider_emitter.cpp | 6 ++++
.../Objects/TR5/Emitter/tr5_spider_emitter.h | 8 +++++
TombEngine/Renderer/RendererDraw.cpp | 32 ++++++++++++-------
13 files changed, 79 insertions(+), 11 deletions(-)
diff --git a/TombEngine/Objects/Effects/tr4_locusts.cpp b/TombEngine/Objects/Effects/tr4_locusts.cpp
index e828ce78b..0b8421507 100644
--- a/TombEngine/Objects/Effects/tr4_locusts.cpp
+++ b/TombEngine/Objects/Effects/tr4_locusts.cpp
@@ -111,6 +111,8 @@ namespace TEN::Entities::TR4
auto* locust = &Locusts[i];
if (locust->on)
{
+ locust->StoreInterpolationData();
+
// NOTE: not present in original TR4 code
//if (locust->target == nullptr)
// locust->target = LaraItem;
diff --git a/TombEngine/Objects/Effects/tr4_locusts.h b/TombEngine/Objects/Effects/tr4_locusts.h
index 2f2495a2b..ef1fb58f4 100644
--- a/TombEngine/Objects/Effects/tr4_locusts.h
+++ b/TombEngine/Objects/Effects/tr4_locusts.h
@@ -15,6 +15,12 @@ struct LOCUST_INFO
BYTE counter;
Matrix Transform;
+ Matrix OldTransform;
+
+ void StoreInterpolationData()
+ {
+ OldTransform = Transform;
+ }
};
namespace TEN::Entities::TR4
diff --git a/TombEngine/Objects/TR3/Entity/FishSwarm.cpp b/TombEngine/Objects/TR3/Entity/FishSwarm.cpp
index e9d5fedd5..abce85040 100644
--- a/TombEngine/Objects/TR3/Entity/FishSwarm.cpp
+++ b/TombEngine/Objects/TR3/Entity/FishSwarm.cpp
@@ -262,6 +262,8 @@ namespace TEN::Entities::Creatures::TR3
if (fish.Life <= 0.0f)
continue;
+ fish.StoreInterpolationData();
+
// Increase separation distance for each fish.
float separationDist = FISH_BASE_SEPARATION_DISTANCE + (fishID * 3);
fishID += 1;
@@ -417,6 +419,8 @@ namespace TEN::Entities::Creatures::TR3
fish.Undulation += std::clamp(movementValue / 2, 0.3f, 1.0f);
if (fish.Undulation > PI_MUL_2)
fish.Undulation -= PI_MUL_2;
+
+ fish.Transform = fish.Orientation.ToRotationMatrix() * Matrix::CreateTranslation(fish.Position);
}
}
diff --git a/TombEngine/Objects/TR3/Entity/FishSwarm.h b/TombEngine/Objects/TR3/Entity/FishSwarm.h
index 1a1dfe471..4f8cde15d 100644
--- a/TombEngine/Objects/TR3/Entity/FishSwarm.h
+++ b/TombEngine/Objects/TR3/Entity/FishSwarm.h
@@ -25,6 +25,14 @@ namespace TEN::Entities::Creatures::TR3
ItemInfo* TargetItemPtr = nullptr;
ItemInfo* LeaderItemPtr = nullptr;
+
+ Matrix Transform;
+ Matrix OldTransform;
+
+ void StoreInterpolationData()
+ {
+ OldTransform = Transform;
+ }
};
extern std::vector FishSwarm;
diff --git a/TombEngine/Objects/TR4/Entity/tr4_beetle_swarm.cpp b/TombEngine/Objects/TR4/Entity/tr4_beetle_swarm.cpp
index 9951cd441..910f2dbfb 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_beetle_swarm.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_beetle_swarm.cpp
@@ -143,6 +143,8 @@ namespace TEN::Entities::TR4
if (beetle->On)
{
+ beetle->StoreInterpolationData();
+
auto oldPos = beetle->Pose.Position;
beetle->Pose.Position.x += beetle->Velocity * phd_sin(beetle->Pose.Orientation.y);
diff --git a/TombEngine/Objects/TR4/Entity/tr4_beetle_swarm.h b/TombEngine/Objects/TR4/Entity/tr4_beetle_swarm.h
index 99f5cb88c..5a09712ff 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_beetle_swarm.h
+++ b/TombEngine/Objects/TR4/Entity/tr4_beetle_swarm.h
@@ -14,6 +14,12 @@ namespace TEN::Entities::TR4
byte Flags;
Matrix Transform;
+ Matrix OldTransform;
+
+ void StoreInterpolationData()
+ {
+ OldTransform = Transform;
+ }
};
constexpr auto NUM_BEETLES = 256;
diff --git a/TombEngine/Objects/TR5/Emitter/tr5_bats_emitter.cpp b/TombEngine/Objects/TR5/Emitter/tr5_bats_emitter.cpp
index a071909d9..865b71bd2 100644
--- a/TombEngine/Objects/TR5/Emitter/tr5_bats_emitter.cpp
+++ b/TombEngine/Objects/TR5/Emitter/tr5_bats_emitter.cpp
@@ -130,6 +130,8 @@ void UpdateBats()
if (!bat->On)
continue;
+ bat->StoreInterpolationData();
+
if ((LaraItem->Effect.Type != EffectType::None || LaraItem->HitPoints <= 0) &&
bat->Counter > 90 &&
!(GetRandomControl() & 7))
diff --git a/TombEngine/Objects/TR5/Emitter/tr5_bats_emitter.h b/TombEngine/Objects/TR5/Emitter/tr5_bats_emitter.h
index 9eeee5fb2..a380d0561 100644
--- a/TombEngine/Objects/TR5/Emitter/tr5_bats_emitter.h
+++ b/TombEngine/Objects/TR5/Emitter/tr5_bats_emitter.h
@@ -18,6 +18,12 @@ struct BatData
byte Flags;
Matrix Transform;
+ Matrix OldTransform;
+
+ void StoreInterpolationData()
+ {
+ OldTransform = Transform;
+ }
};
extern int NextBat;
diff --git a/TombEngine/Objects/TR5/Emitter/tr5_rats_emitter.cpp b/TombEngine/Objects/TR5/Emitter/tr5_rats_emitter.cpp
index bb1a1403a..ff4abf6e4 100644
--- a/TombEngine/Objects/TR5/Emitter/tr5_rats_emitter.cpp
+++ b/TombEngine/Objects/TR5/Emitter/tr5_rats_emitter.cpp
@@ -141,6 +141,8 @@ void UpdateRats()
if (rat->On)
{
+ rat->StoreInterpolationData();
+
int oldX = rat->Pose.Position.x;
int oldY = rat->Pose.Position.y;
int oldZ = rat->Pose.Position.z;
diff --git a/TombEngine/Objects/TR5/Emitter/tr5_rats_emitter.h b/TombEngine/Objects/TR5/Emitter/tr5_rats_emitter.h
index 306f5604e..6b5753990 100644
--- a/TombEngine/Objects/TR5/Emitter/tr5_rats_emitter.h
+++ b/TombEngine/Objects/TR5/Emitter/tr5_rats_emitter.h
@@ -15,6 +15,12 @@ struct RatData
byte Flags;
Matrix Transform;
+ Matrix OldTransform;
+
+ void StoreInterpolationData()
+ {
+ OldTransform = Transform;
+ }
};
extern int NextRat;
diff --git a/TombEngine/Objects/TR5/Emitter/tr5_spider_emitter.cpp b/TombEngine/Objects/TR5/Emitter/tr5_spider_emitter.cpp
index 8e201afe2..4723ee085 100644
--- a/TombEngine/Objects/TR5/Emitter/tr5_spider_emitter.cpp
+++ b/TombEngine/Objects/TR5/Emitter/tr5_spider_emitter.cpp
@@ -134,6 +134,8 @@ void UpdateSpiders()
if (spider->On)
{
+ spider->StoreInterpolationData();
+
int x = spider->Pose.Position.x;
int y = spider->Pose.Position.y;
int z = spider->Pose.Position.z;
@@ -241,6 +243,10 @@ void UpdateSpiders()
if (!i && !(GetRandomControl() & 4))
SoundEffect(SFX_TR5_INSECTS,&spider->Pose);
+
+ Matrix translation = Matrix::CreateTranslation(spider->Pose.Position.x, spider->Pose.Position.y, spider->Pose.Position.z);
+ Matrix rotation = spider->Pose.Orientation.ToRotationMatrix();
+ spider->Transform = rotation * translation;
}
}
}
diff --git a/TombEngine/Objects/TR5/Emitter/tr5_spider_emitter.h b/TombEngine/Objects/TR5/Emitter/tr5_spider_emitter.h
index d2064d187..0ed0900f4 100644
--- a/TombEngine/Objects/TR5/Emitter/tr5_spider_emitter.h
+++ b/TombEngine/Objects/TR5/Emitter/tr5_spider_emitter.h
@@ -13,6 +13,14 @@ struct SpiderData
short VerticalVelocity;
byte Flags;
+
+ Matrix Transform;
+ Matrix OldTransform;
+
+ void StoreInterpolationData()
+ {
+ OldTransform = Transform;
+ }
};
extern int NextSpider;
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index 364ad3156..c1fa453ec 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -646,7 +646,7 @@ namespace TEN::Renderer
for (auto& poly : bucket.Polygons)
{
- auto worldMatrix = fish.Orientation.ToRotationMatrix() * Matrix::CreateTranslation(fish.Position);
+ auto worldMatrix = Matrix::Lerp(fish.OldTransform, fish.Transform, _interpolationFactor);
auto center = Vector3::Transform(poly.Centre, worldMatrix);
float dist = Vector3::Distance(center, view.Camera.WorldPosition);
@@ -707,7 +707,7 @@ namespace TEN::Renderer
const auto& mesh = *GetMesh(Objects[ID_FISH_EMITTER].meshIndex + fish.MeshIndex);
- _stStatic.World = fish.Orientation.ToRotationMatrix() * Matrix::CreateTranslation(fish.Position);
+ _stStatic.World = Matrix::Lerp(fish.OldTransform, fish.Transform, _interpolationFactor);
_stStatic.Color = Vector4::One;
_stStatic.AmbientLight = _rooms[fish.RoomNumber].AmbientLight;
@@ -763,8 +763,10 @@ namespace TEN::Renderer
{
for (int p = 0; p < bucket.Polygons.size(); p++)
{
+ Matrix transform = Matrix::Lerp(bat->OldTransform, bat->Transform, _interpolationFactor);
+
auto centre = Vector3::Transform(
- bucket.Polygons[p].Centre, bat->Transform);
+ bucket.Polygons[p].Centre, transform);
int distance = (centre - view.Camera.WorldPosition).Length();
RendererSortableObject object;
@@ -774,7 +776,7 @@ namespace TEN::Renderer
object.Bucket = &bucket;
object.Mesh = mesh;
object.Polygon = &bucket.Polygons[p];
- object.World = bat->Transform;
+ object.World = transform;
object.Room = &_rooms[bat->RoomNumber];
view.TransparentObjectsToDraw.push_back(object);
@@ -794,9 +796,11 @@ namespace TEN::Renderer
if (bat->On)
{
+ Matrix transform = Matrix::Lerp(bat->OldTransform, bat->Transform, _interpolationFactor);
+
RendererRoom& room = _rooms[bat->RoomNumber];
- _stInstancedStaticMeshBuffer.StaticMeshes[batsCount].World = bat->Transform;
+ _stInstancedStaticMeshBuffer.StaticMeshes[batsCount].World = transform;
_stInstancedStaticMeshBuffer.StaticMeshes[batsCount].Ambient = room.AmbientLight;
_stInstancedStaticMeshBuffer.StaticMeshes[batsCount].Color = Vector4::One;
_stInstancedStaticMeshBuffer.StaticMeshes[batsCount].LightMode = (int)mesh->LightMode;
@@ -879,6 +883,8 @@ namespace TEN::Renderer
if (beetle->On)
{
+ Matrix transform = Matrix::Lerp(beetle->OldTransform, beetle->Transform, _interpolationFactor);
+
for (int j = 0; j < mesh->Buckets.size(); j++)
{
auto& bucket = mesh->Buckets[j];
@@ -888,7 +894,7 @@ namespace TEN::Renderer
for (int p = 0; p < bucket.Polygons.size(); p++)
{
auto centre = Vector3::Transform(
- bucket.Polygons[p].Centre, beetle->Transform);
+ bucket.Polygons[p].Centre, transform);
int distance = (centre - view.Camera.WorldPosition).Length();
RendererSortableObject object;
@@ -898,7 +904,7 @@ namespace TEN::Renderer
object.Bucket = &bucket;
object.Mesh = mesh;
object.Polygon = &bucket.Polygons[p];
- object.World = beetle->Transform;
+ object.World = transform;
object.Room = &_rooms[beetle->RoomNumber];
view.TransparentObjectsToDraw.push_back(object);
@@ -920,9 +926,11 @@ namespace TEN::Renderer
if (beetle.On)
{
+ Matrix transform = Matrix::Lerp(beetle.OldTransform, beetle.Transform, _interpolationFactor);
+
auto& room = _rooms[beetle.RoomNumber];
- _stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].World = beetle.Transform;
+ _stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].World = transform;
_stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].Ambient = room.AmbientLight;
_stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].Color = Vector4::One;
_stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].LightMode = (int)mesh->LightMode;
@@ -1021,8 +1029,10 @@ namespace TEN::Renderer
{
for (int p = 0; p < bucket.Polygons.size(); p++)
{
+ Matrix transform = Matrix::Lerp(locust->OldTransform, locust->Transform, _interpolationFactor);
+
auto centre = Vector3::Transform(
- bucket.Polygons[p].Centre, locust->Transform);
+ bucket.Polygons[p].Centre, transform);
int distance = (centre - view.Camera.WorldPosition).Length();
RendererSortableObject object;
@@ -1032,7 +1042,7 @@ namespace TEN::Renderer
object.Bucket = &bucket;
object.Mesh = mesh;
object.Polygon = &bucket.Polygons[p];
- object.World = locust->Transform;
+ object.World = transform;
object.Room = &_rooms[locust->roomNumber];
view.TransparentObjectsToDraw.push_back(object);
@@ -1088,7 +1098,7 @@ namespace TEN::Renderer
{
RendererMesh* mesh = GetMesh(Objects[ID_LOCUSTS].meshIndex + (-locust->counter & 3));
- _stStatic.World = locust->Transform;
+ _stStatic.World = Matrix::Lerp(locust->OldTransform, locust->Transform, _interpolationFactor);
_stStatic.Color = Vector4::One;
_stStatic.AmbientLight = _rooms[locust->roomNumber].AmbientLight;
_cbStatic.UpdateData(_stStatic, _context.Get());
From e50715bd319505b23a49baa5f23d895c47f1cc33 Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Sun, 19 May 2024 05:34:53 +0200
Subject: [PATCH 195/410] Fixed bad interpolation of crosshair position
---
TombEngine/Game/Hud/TargetHighlighter.cpp | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/TombEngine/Game/Hud/TargetHighlighter.cpp b/TombEngine/Game/Hud/TargetHighlighter.cpp
index 7cd768ba4..5d0d5b372 100644
--- a/TombEngine/Game/Hud/TargetHighlighter.cpp
+++ b/TombEngine/Game/Hud/TargetHighlighter.cpp
@@ -140,10 +140,25 @@ namespace TEN::Hud
if (!Position.has_value())
return;
- auto pos0 = Vector2::Lerp(*Position, PrevPosition, g_Renderer.GetInterpolationFactor());
- short orient0 = PrevOrientation + (Geometry::GetShortestAngle(PrevOrientation, Orientation) * g_Renderer.GetInterpolationFactor());
- float scale = Lerp(PrevScale, Scale, g_Renderer.GetInterpolationFactor());
- auto color = Color::Lerp(PrevColor, Color, g_Renderer.GetInterpolationFactor());
+ auto pos0 = Vector2::Lerp(
+ PrevPosition,
+ *Position,
+ g_Renderer.GetInterpolationFactor()
+ );
+
+ short orient0 = PrevOrientation + Geometry::GetShortestAngle(PrevOrientation, Orientation) * g_Renderer.GetInterpolationFactor();
+
+ float scale = Lerp(
+ PrevScale,
+ Scale,
+ g_Renderer.GetInterpolationFactor()
+ );
+
+ auto color = Color::Lerp(
+ PrevColor,
+ Color,
+ g_Renderer.GetInterpolationFactor()
+ );
// Draw main static element.
AddDisplaySprite(
From 978fa30d61dfa9940b28e8d99884720847d753ad Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sun, 19 May 2024 18:09:41 +1000
Subject: [PATCH 196/410] Formatting
---
TombEngine/Objects/Effects/tr4_locusts.h | 6 +-
TombEngine/Objects/TR3/Entity/FishSwarm.h | 6 +-
.../Objects/TR4/Entity/tr4_beetle_swarm.h | 6 +-
.../Objects/TR5/Emitter/tr5_bats_emitter.h | 8 +-
.../Objects/TR5/Emitter/tr5_rats_emitter.h | 6 +-
.../TR5/Emitter/tr5_spider_emitter.cpp | 6 +-
.../Objects/TR5/Emitter/tr5_spider_emitter.h | 8 +-
TombEngine/Renderer/RendererDraw.cpp | 305 ++++++++----------
8 files changed, 152 insertions(+), 199 deletions(-)
diff --git a/TombEngine/Objects/Effects/tr4_locusts.h b/TombEngine/Objects/Effects/tr4_locusts.h
index ef1fb58f4..6fd6530ea 100644
--- a/TombEngine/Objects/Effects/tr4_locusts.h
+++ b/TombEngine/Objects/Effects/tr4_locusts.h
@@ -14,12 +14,12 @@ struct LOCUST_INFO
short escapeZrot;
BYTE counter;
- Matrix Transform;
- Matrix OldTransform;
+ Matrix Transform = Matrix::Identity;
+ Matrix PrevTransform = Matrix::Identity;
void StoreInterpolationData()
{
- OldTransform = Transform;
+ PrevTransform = Transform;
}
};
diff --git a/TombEngine/Objects/TR3/Entity/FishSwarm.h b/TombEngine/Objects/TR3/Entity/FishSwarm.h
index 4f8cde15d..6aa4c6962 100644
--- a/TombEngine/Objects/TR3/Entity/FishSwarm.h
+++ b/TombEngine/Objects/TR3/Entity/FishSwarm.h
@@ -26,12 +26,12 @@ namespace TEN::Entities::Creatures::TR3
ItemInfo* TargetItemPtr = nullptr;
ItemInfo* LeaderItemPtr = nullptr;
- Matrix Transform;
- Matrix OldTransform;
+ Matrix Transform = Matrix::Identity;
+ Matrix PrevTransform = Matrix::Identity;
void StoreInterpolationData()
{
- OldTransform = Transform;
+ PrevTransform = Transform;
}
};
diff --git a/TombEngine/Objects/TR4/Entity/tr4_beetle_swarm.h b/TombEngine/Objects/TR4/Entity/tr4_beetle_swarm.h
index 5a09712ff..b4bd983e0 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_beetle_swarm.h
+++ b/TombEngine/Objects/TR4/Entity/tr4_beetle_swarm.h
@@ -13,12 +13,12 @@ namespace TEN::Entities::TR4
byte Flags;
- Matrix Transform;
- Matrix OldTransform;
+ Matrix Transform = Matrix::Identity;
+ Matrix PrevTransform = Matrix::Identity;
void StoreInterpolationData()
{
- OldTransform = Transform;
+ PrevTransform = Transform;
}
};
diff --git a/TombEngine/Objects/TR5/Emitter/tr5_bats_emitter.h b/TombEngine/Objects/TR5/Emitter/tr5_bats_emitter.h
index a380d0561..ab0a0b03c 100644
--- a/TombEngine/Objects/TR5/Emitter/tr5_bats_emitter.h
+++ b/TombEngine/Objects/TR5/Emitter/tr5_bats_emitter.h
@@ -16,13 +16,13 @@ struct BatData
byte ZTarget;
byte Flags;
-
- Matrix Transform;
- Matrix OldTransform;
+
+ Matrix Transform = Matrix::Identity;
+ Matrix PrevTransform = Matrix::Identity;
void StoreInterpolationData()
{
- OldTransform = Transform;
+ PrevTransform = Transform;
}
};
diff --git a/TombEngine/Objects/TR5/Emitter/tr5_rats_emitter.h b/TombEngine/Objects/TR5/Emitter/tr5_rats_emitter.h
index 6b5753990..3f57a8f9f 100644
--- a/TombEngine/Objects/TR5/Emitter/tr5_rats_emitter.h
+++ b/TombEngine/Objects/TR5/Emitter/tr5_rats_emitter.h
@@ -14,12 +14,12 @@ struct RatData
byte Flags;
- Matrix Transform;
- Matrix OldTransform;
+ Matrix Transform = Matrix::Identity;
+ Matrix PrevTransform = Matrix::Identity;
void StoreInterpolationData()
{
- OldTransform = Transform;
+ PrevTransform = Transform;
}
};
diff --git a/TombEngine/Objects/TR5/Emitter/tr5_spider_emitter.cpp b/TombEngine/Objects/TR5/Emitter/tr5_spider_emitter.cpp
index 4723ee085..2828ddaa7 100644
--- a/TombEngine/Objects/TR5/Emitter/tr5_spider_emitter.cpp
+++ b/TombEngine/Objects/TR5/Emitter/tr5_spider_emitter.cpp
@@ -244,9 +244,9 @@ void UpdateSpiders()
if (!i && !(GetRandomControl() & 4))
SoundEffect(SFX_TR5_INSECTS,&spider->Pose);
- Matrix translation = Matrix::CreateTranslation(spider->Pose.Position.x, spider->Pose.Position.y, spider->Pose.Position.z);
- Matrix rotation = spider->Pose.Orientation.ToRotationMatrix();
- spider->Transform = rotation * translation;
+ auto tMatrix = Matrix::CreateTranslation(spider->Pose.Position.ToVector3());
+ auto rotMatrix = spider->Pose.Orientation.ToRotationMatrix();
+ spider->Transform = rotMatrix * tMatrix;
}
}
}
diff --git a/TombEngine/Objects/TR5/Emitter/tr5_spider_emitter.h b/TombEngine/Objects/TR5/Emitter/tr5_spider_emitter.h
index 0ed0900f4..636868907 100644
--- a/TombEngine/Objects/TR5/Emitter/tr5_spider_emitter.h
+++ b/TombEngine/Objects/TR5/Emitter/tr5_spider_emitter.h
@@ -13,13 +13,13 @@ struct SpiderData
short VerticalVelocity;
byte Flags;
-
- Matrix Transform;
- Matrix OldTransform;
+
+ Matrix Transform = Matrix::Identity;
+ Matrix PrevTransform = Matrix::Identity;
void StoreInterpolationData()
{
- OldTransform = Transform;
+ PrevTransform = Transform;
}
};
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index c1fa453ec..fdc64e403 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -646,7 +646,7 @@ namespace TEN::Renderer
for (auto& poly : bucket.Polygons)
{
- auto worldMatrix = Matrix::Lerp(fish.OldTransform, fish.Transform, _interpolationFactor);
+ auto worldMatrix = Matrix::Lerp(fish.PrevTransform, fish.Transform, _interpolationFactor);
auto center = Vector3::Transform(poly.Centre, worldMatrix);
float dist = Vector3::Distance(center, view.Camera.WorldPosition);
@@ -707,7 +707,7 @@ namespace TEN::Renderer
const auto& mesh = *GetMesh(Objects[ID_FISH_EMITTER].meshIndex + fish.MeshIndex);
- _stStatic.World = Matrix::Lerp(fish.OldTransform, fish.Transform, _interpolationFactor);
+ _stStatic.World = Matrix::Lerp(fish.PrevTransform, fish.Transform, _interpolationFactor);
_stStatic.Color = Vector4::One;
_stStatic.AmbientLight = _rooms[fish.RoomNumber].AmbientLight;
@@ -745,76 +745,67 @@ namespace TEN::Renderer
if (!Objects[ID_BATS_EMITTER].loaded)
return;
- auto* mesh = GetMesh(Objects[ID_BATS_EMITTER].meshIndex + (GlobalCounter & 3));
+ auto& mesh = *GetMesh(Objects[ID_BATS_EMITTER].meshIndex + (GlobalCounter & 3));
if (rendererPass == RendererPass::CollectTransparentFaces)
{
- for (int i = 0; i < NUM_BATS; i++)
+ for (const auto& bat : Bats)
{
- auto* bat = &Bats[i];
+ if (!bat.On)
+ continue;
- if (bat->On)
+ for (auto& bucket : mesh.Buckets)
{
- for (int j = 0; j < mesh->Buckets.size(); j++)
+ if (!IsSortedBlendMode(bucket.BlendMode))
+ continue;
+
+ for (int p = 0; p < bucket.Polygons.size(); p++)
{
- auto& bucket = mesh->Buckets[j];
+ auto transformMatrix = Matrix::Lerp(bat.PrevTransform, bat.Transform, _interpolationFactor);
+ auto centre = Vector3::Transform(bucket.Polygons[p].Centre, transformMatrix);
+ float dist = (centre - view.Camera.WorldPosition).Length();
- if (IsSortedBlendMode(bucket.BlendMode))
- {
- for (int p = 0; p < bucket.Polygons.size(); p++)
- {
- Matrix transform = Matrix::Lerp(bat->OldTransform, bat->Transform, _interpolationFactor);
+ auto object = RendererSortableObject{};
+ object.ObjectType = RendererObjectType::MoveableAsStatic;
+ object.Centre = centre;
+ object.Distance = dist;
+ object.Bucket = &bucket;
+ object.Mesh = &mesh;
+ object.Polygon = &bucket.Polygons[p];
+ object.World = transformMatrix;
+ object.Room = &_rooms[bat.RoomNumber];
- auto centre = Vector3::Transform(
- bucket.Polygons[p].Centre, transform);
- int distance = (centre - view.Camera.WorldPosition).Length();
-
- RendererSortableObject object;
- object.ObjectType = RendererObjectType::MoveableAsStatic;
- object.Centre = centre;
- object.Distance = distance;
- object.Bucket = &bucket;
- object.Mesh = mesh;
- object.Polygon = &bucket.Polygons[p];
- object.World = transform;
- object.Room = &_rooms[bat->RoomNumber];
-
- view.TransparentObjectsToDraw.push_back(object);
- }
- }
+ view.TransparentObjectsToDraw.push_back(object);
}
}
}
}
else
{
- int batsCount = 0;
-
+ int batCount = 0;
for (int i = 0; i < NUM_BATS; i++)
{
- auto* bat = &Bats[i];
+ const auto& bat = Bats[i];
- if (bat->On)
+ if (bat.On)
{
- Matrix transform = Matrix::Lerp(bat->OldTransform, bat->Transform, _interpolationFactor);
+ auto& room = _rooms[bat.RoomNumber];
- RendererRoom& room = _rooms[bat->RoomNumber];
+ auto transformMatrix = Matrix::Lerp(bat.PrevTransform, bat.Transform, _interpolationFactor);
- _stInstancedStaticMeshBuffer.StaticMeshes[batsCount].World = transform;
- _stInstancedStaticMeshBuffer.StaticMeshes[batsCount].Ambient = room.AmbientLight;
- _stInstancedStaticMeshBuffer.StaticMeshes[batsCount].Color = Vector4::One;
- _stInstancedStaticMeshBuffer.StaticMeshes[batsCount].LightMode = (int)mesh->LightMode;
+ _stInstancedStaticMeshBuffer.StaticMeshes[batCount].World = transformMatrix;
+ _stInstancedStaticMeshBuffer.StaticMeshes[batCount].Ambient = room.AmbientLight;
+ _stInstancedStaticMeshBuffer.StaticMeshes[batCount].Color = Vector4::One;
+ _stInstancedStaticMeshBuffer.StaticMeshes[batCount].LightMode = (int)mesh.LightMode;
if (rendererPass != RendererPass::GBuffer)
- {
- BindInstancedStaticLights(room.LightsToDraw, batsCount);
- }
+ BindInstancedStaticLights(room.LightsToDraw, batCount);
- batsCount++;
+ batCount++;
}
- if (batsCount == INSTANCED_STATIC_MESH_BUCKET_SIZE ||
- (i == NUM_BATS - 1 && batsCount > 0))
+ if (batCount == INSTANCED_STATIC_MESH_BUCKET_SIZE ||
+ (i == (NUM_BATS - 1) && batCount > 0))
{
if (rendererPass == RendererPass::GBuffer)
{
@@ -827,40 +818,35 @@ namespace TEN::Renderer
_context->PSSetShader(_psInstancedStaticMeshes.Get(), nullptr, 0);
}
- UINT stride = sizeof(Vertex);
- UINT offset = 0;
+ unsigned int stride = sizeof(Vertex);
+ unsigned int offset = 0;
_context->IASetVertexBuffers(0, 1, _moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
_context->IASetIndexBuffer(_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
_cbInstancedStaticMeshBuffer.UpdateData(_stInstancedStaticMeshBuffer, _context.Get());
- for (auto& bucket : mesh->Buckets)
+ for (auto& bucket : mesh.Buckets)
{
if (bucket.NumVertices == 0)
- {
continue;
- }
- int passes = rendererPass == RendererPass::Opaque && bucket.BlendMode == BlendMode::AlphaTest ? 2 : 1;
-
- for (int p = 0; p < passes; p++)
+ int passCount = (rendererPass == RendererPass::Opaque && bucket.BlendMode == BlendMode::AlphaTest) ? 2 : 1;
+ for (int p = 0; p < passCount; p++)
{
if (!SetupBlendModeAndAlphaTest(bucket.BlendMode, rendererPass, p))
- {
continue;
- }
BindTexture(TextureRegister::ColorMap, &std::get<0>(_moveablesTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp);
BindTexture(TextureRegister::NormalMap, &std::get<1>(_moveablesTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp);
- DrawIndexedInstancedTriangles(bucket.NumIndices, batsCount, bucket.StartIndex, 0);
+ DrawIndexedInstancedTriangles(bucket.NumIndices, batCount, bucket.StartIndex, 0);
_numMoveablesDrawCalls++;
}
}
- batsCount = 0;
+ batCount = 0;
}
}
}
@@ -869,79 +855,68 @@ namespace TEN::Renderer
void Renderer::DrawScarabs(RenderView& view, RendererPass rendererPass)
{
if (!Objects[ID_LITTLE_BEETLE].loaded)
- {
return;
- }
- RendererMesh* mesh = GetMesh(Objects[ID_LITTLE_BEETLE].meshIndex + ((Wibble >> 2) % 2));
+ auto& mesh = *GetMesh(Objects[ID_LITTLE_BEETLE].meshIndex + ((Wibble >> 2) % 2));
if (rendererPass == RendererPass::CollectTransparentFaces)
{
- for (int i = 0; i < TEN::Entities::TR4::NUM_BEETLES; i++)
+ for (const auto& beetle : TEN::Entities::TR4::BeetleSwarm)
{
- auto beetle = &TEN::Entities::TR4::BeetleSwarm[i];
+ if (!beetle.On)
+ continue;
- if (beetle->On)
+ auto transformMatrix = Matrix::Lerp(beetle.PrevTransform, beetle.Transform, _interpolationFactor);
+
+ for (auto& bucket : mesh.Buckets)
{
- Matrix transform = Matrix::Lerp(beetle->OldTransform, beetle->Transform, _interpolationFactor);
+ if (!IsSortedBlendMode(bucket.BlendMode))
+ continue;
- for (int j = 0; j < mesh->Buckets.size(); j++)
+ for (int p = 0; p < bucket.Polygons.size(); p++)
{
- auto& bucket = mesh->Buckets[j];
+ auto centre = Vector3::Transform(bucket.Polygons[p].Centre, transformMatrix);
+ float dist = (centre - view.Camera.WorldPosition).Length();
- if (IsSortedBlendMode(bucket.BlendMode))
- {
- for (int p = 0; p < bucket.Polygons.size(); p++)
- {
- auto centre = Vector3::Transform(
- bucket.Polygons[p].Centre, transform);
- int distance = (centre - view.Camera.WorldPosition).Length();
+ auto object = RendererSortableObject{};
+ object.ObjectType = RendererObjectType::MoveableAsStatic;
+ object.Centre = centre;
+ object.Distance = dist;
+ object.Bucket = &bucket;
+ object.Mesh = &mesh;
+ object.Polygon = &bucket.Polygons[p];
+ object.World = transformMatrix;
+ object.Room = &_rooms[beetle.RoomNumber];
- RendererSortableObject object;
- object.ObjectType = RendererObjectType::MoveableAsStatic;
- object.Centre = centre;
- object.Distance = distance;
- object.Bucket = &bucket;
- object.Mesh = mesh;
- object.Polygon = &bucket.Polygons[p];
- object.World = transform;
- object.Room = &_rooms[beetle->RoomNumber];
-
- view.TransparentObjectsToDraw.push_back(object);
- }
- }
+ view.TransparentObjectsToDraw.push_back(object);
}
}
}
}
else
{
- std::vector> beetlesBuckets;
-
- unsigned int beetleCount = 0;
-
+ int beetleCount = 0;
for (int i = 0; i < TEN::Entities::TR4::NUM_BEETLES; i++)
{
const auto& beetle = TEN::Entities::TR4::BeetleSwarm[i];
if (beetle.On)
{
- Matrix transform = Matrix::Lerp(beetle.OldTransform, beetle.Transform, _interpolationFactor);
-
auto& room = _rooms[beetle.RoomNumber];
- _stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].World = transform;
+ auto transformMatrix = Matrix::Lerp(beetle.PrevTransform, beetle.Transform, _interpolationFactor);
+
+ _stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].World = transformMatrix;
_stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].Ambient = room.AmbientLight;
_stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].Color = Vector4::One;
- _stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].LightMode = (int)mesh->LightMode;
+ _stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].LightMode = (int)mesh.LightMode;
if (rendererPass != RendererPass::GBuffer)
{
- std::vector lights;
+ auto lights = std::vector{};
for (int i = 0; i < std::min((int)room.LightsToDraw.size(), MAX_LIGHTS_PER_ITEM); i++)
- {
lights.push_back(room.LightsToDraw[i]);
- }
+
BindInstancedStaticLights(lights, beetleCount);
}
@@ -970,21 +945,16 @@ namespace TEN::Renderer
_cbInstancedStaticMeshBuffer.UpdateData(_stInstancedStaticMeshBuffer, _context.Get());
- for (const auto& bucket : mesh->Buckets)
+ for (auto& bucket : mesh.Buckets)
{
if (bucket.NumVertices == 0)
- {
continue;
- }
- int passes = rendererPass == RendererPass::Opaque && bucket.BlendMode == BlendMode::AlphaTest ? 2 : 1;
-
- for (int p = 0; p < passes; p++)
+ int passCount = (rendererPass == RendererPass::Opaque && bucket.BlendMode == BlendMode::AlphaTest) ? 2 : 1;
+ for (int p = 0; p < passCount; p++)
{
if (!SetupBlendModeAndAlphaTest(bucket.BlendMode, rendererPass, p))
- {
continue;
- }
BindTexture(TextureRegister::ColorMap, &std::get<0>(_moveablesTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp);
BindTexture(TextureRegister::NormalMap, &std::get<1>(_moveablesTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp);
@@ -1004,50 +974,42 @@ namespace TEN::Renderer
void Renderer::DrawLocusts(RenderView& view, RendererPass rendererPass)
{
if (!Objects[ID_LOCUSTS].loaded)
- {
return;
- }
if (rendererPass == RendererPass::CollectTransparentFaces)
{
- ObjectInfo* obj = &Objects[ID_LOCUSTS];
- RendererObject& moveableObj = *_moveableObjects[ID_LOCUSTS];
+ auto* obj = &Objects[ID_LOCUSTS];
+ auto& moveableObj = *_moveableObjects[ID_LOCUSTS];
- for (int i = 0; i < TEN::Entities::TR4::MAX_LOCUSTS; i++)
+ for (const auto& locust : TEN::Entities::TR4::Locusts)
{
- LOCUST_INFO* locust = &TEN::Entities::TR4::Locusts[i];
+ if (!locust.on)
+ continue;
- if (locust->on)
+ auto& mesh = *GetMesh(Objects[ID_LOCUSTS].meshIndex + (-locust.counter & 3));
+
+ for (auto& bucket : mesh.Buckets)
{
- RendererMesh* mesh = GetMesh(Objects[ID_LOCUSTS].meshIndex + (-locust->counter & 3));
+ if (!IsSortedBlendMode(bucket.BlendMode))
+ continue;
- for (int j = 0; j < mesh->Buckets.size(); j++)
+ for (int p = 0; p < bucket.Polygons.size(); p++)
{
- auto& bucket = mesh->Buckets[j];
+ auto transformMatrix = Matrix::Lerp(locust.PrevTransform, locust.Transform, _interpolationFactor);
+ auto centre = Vector3::Transform(bucket.Polygons[p].Centre, transformMatrix);
+ float dist = (centre - view.Camera.WorldPosition).Length();
- if (IsSortedBlendMode(bucket.BlendMode))
- {
- for (int p = 0; p < bucket.Polygons.size(); p++)
- {
- Matrix transform = Matrix::Lerp(locust->OldTransform, locust->Transform, _interpolationFactor);
+ auto object = RendererSortableObject{};
+ object.ObjectType = RendererObjectType::MoveableAsStatic;
+ object.Centre = centre;
+ object.Distance = dist;
+ object.Bucket = &bucket;
+ object.Mesh = &mesh;
+ object.Polygon = &bucket.Polygons[p];
+ object.World = transformMatrix;
+ object.Room = &_rooms[locust.roomNumber];
- auto centre = Vector3::Transform(
- bucket.Polygons[p].Centre, transform);
- int distance = (centre - view.Camera.WorldPosition).Length();
-
- RendererSortableObject object;
- object.ObjectType = RendererObjectType::MoveableAsStatic;
- object.Centre = centre;
- object.Distance = distance;
- object.Bucket = &bucket;
- object.Mesh = mesh;
- object.Polygon = &bucket.Polygons[p];
- object.World = transform;
- object.Room = &_rooms[locust->roomNumber];
-
- view.TransparentObjectsToDraw.push_back(object);
- }
- }
+ view.TransparentObjectsToDraw.push_back(object);
}
}
}
@@ -1055,15 +1017,13 @@ namespace TEN::Renderer
else
{
int activeLocustsExist = false;
- for (int i = 0; i < TEN::Entities::TR4::MAX_LOCUSTS; i++)
+ for (const auto& locust : TEN::Entities::TR4::Locusts)
{
- LOCUST_INFO* locust = &TEN::Entities::TR4::Locusts[i];
+ if (!locust.on)
+ continue;
- if (locust->on)
- {
- activeLocustsExist = true;
- break;
- }
+ activeLocustsExist = true;
+ break;
}
if (activeLocustsExist)
@@ -1079,53 +1039,46 @@ namespace TEN::Renderer
_context->PSSetShader(_psStatics.Get(), nullptr, 0);
}
- UINT stride = sizeof(Vertex);
- UINT offset = 0;
+ unsigned int stride = sizeof(Vertex);
+ unsigned int offset = 0;
_context->IASetVertexBuffers(0, 1, _moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
_context->IASetIndexBuffer(_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
- ObjectInfo* obj = &Objects[ID_LOCUSTS];
- RendererObject& moveableObj = *_moveableObjects[ID_LOCUSTS];
+ auto* obj = &Objects[ID_LOCUSTS];
+ auto& moveableObj = *_moveableObjects[ID_LOCUSTS];
_stStatic.LightMode = (int)moveableObj.ObjectMeshes[0]->LightMode;
- for (int i = 0; i < TEN::Entities::TR4::MAX_LOCUSTS; i++)
+ for (const auto& locust : TEN::Entities::TR4::Locusts)
{
- LOCUST_INFO* locust = &TEN::Entities::TR4::Locusts[i];
+ if (!locust.on)
+ continue;
- if (locust->on)
+ auto& mesh = *GetMesh(Objects[ID_LOCUSTS].meshIndex + (-locust.counter & 3));
+
+ _stStatic.World = Matrix::Lerp(locust.PrevTransform, locust.Transform, _interpolationFactor);
+ _stStatic.Color = Vector4::One;
+ _stStatic.AmbientLight = _rooms[locust.roomNumber].AmbientLight;
+ _cbStatic.UpdateData(_stStatic, _context.Get());
+
+ for (auto& bucket : mesh.Buckets)
{
- RendererMesh* mesh = GetMesh(Objects[ID_LOCUSTS].meshIndex + (-locust->counter & 3));
+ if (bucket.NumVertices == 0)
+ continue;
- _stStatic.World = Matrix::Lerp(locust->OldTransform, locust->Transform, _interpolationFactor);
- _stStatic.Color = Vector4::One;
- _stStatic.AmbientLight = _rooms[locust->roomNumber].AmbientLight;
- _cbStatic.UpdateData(_stStatic, _context.Get());
-
- for (auto& bucket : mesh->Buckets)
+ int passes = (rendererPass == RendererPass::Opaque && bucket.BlendMode == BlendMode::AlphaTest ? 2 : 1);
+ for (int p = 0; p < passes; p++)
{
- if (bucket.NumVertices == 0)
- {
+ if (!SetupBlendModeAndAlphaTest(bucket.BlendMode, rendererPass, p))
continue;
- }
- int passes = rendererPass == RendererPass::Opaque && bucket.BlendMode == BlendMode::AlphaTest ? 2 : 1;
+ BindTexture(TextureRegister::ColorMap, &std::get<0>(_moveablesTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp);
+ BindTexture(TextureRegister::NormalMap, &std::get<1>(_moveablesTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp);
- for (int p = 0; p < passes; p++)
- {
- if (!SetupBlendModeAndAlphaTest(bucket.BlendMode, rendererPass, p))
- {
- continue;
- }
+ DrawIndexedTriangles(bucket.NumIndices, bucket.StartIndex, 0);
- BindTexture(TextureRegister::ColorMap, &std::get<0>(_moveablesTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp);
- BindTexture(TextureRegister::NormalMap, &std::get<1>(_moveablesTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp);
-
- DrawIndexedTriangles(bucket.NumIndices, bucket.StartIndex, 0);
-
- _numMoveablesDrawCalls++;
- }
+ _numMoveablesDrawCalls++;
}
}
}
From 36133ea5e957fa8cbf2b63415f0ce91fe16b7b52 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sun, 19 May 2024 18:10:45 +1000
Subject: [PATCH 197/410] Use parentheses
---
TombEngine/Renderer/RendererDraw.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index fdc64e403..75cd73de2 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -1067,8 +1067,8 @@ namespace TEN::Renderer
if (bucket.NumVertices == 0)
continue;
- int passes = (rendererPass == RendererPass::Opaque && bucket.BlendMode == BlendMode::AlphaTest ? 2 : 1);
- for (int p = 0; p < passes; p++)
+ int passCount = (rendererPass == RendererPass::Opaque && bucket.BlendMode == BlendMode::AlphaTest) ? 2 : 1;
+ for (int p = 0; p < passCount; p++)
{
if (!SetupBlendModeAndAlphaTest(bucket.BlendMode, rendererPass, p))
continue;
From 210cad57e1ee152409fc0f8d37b3028178d8afbc Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sun, 19 May 2024 18:12:00 +1000
Subject: [PATCH 198/410] Fix formatting
---
TombEngine/Game/Hud/TargetHighlighter.cpp | 21 +++------------------
1 file changed, 3 insertions(+), 18 deletions(-)
diff --git a/TombEngine/Game/Hud/TargetHighlighter.cpp b/TombEngine/Game/Hud/TargetHighlighter.cpp
index 5d0d5b372..ab2fbc398 100644
--- a/TombEngine/Game/Hud/TargetHighlighter.cpp
+++ b/TombEngine/Game/Hud/TargetHighlighter.cpp
@@ -140,25 +140,10 @@ namespace TEN::Hud
if (!Position.has_value())
return;
- auto pos0 = Vector2::Lerp(
- PrevPosition,
- *Position,
- g_Renderer.GetInterpolationFactor()
- );
-
+ auto pos0 = Vector2::Lerp(PrevPosition, *Position, g_Renderer.GetInterpolationFactor());
short orient0 = PrevOrientation + Geometry::GetShortestAngle(PrevOrientation, Orientation) * g_Renderer.GetInterpolationFactor();
-
- float scale = Lerp(
- PrevScale,
- Scale,
- g_Renderer.GetInterpolationFactor()
- );
-
- auto color = Color::Lerp(
- PrevColor,
- Color,
- g_Renderer.GetInterpolationFactor()
- );
+ float scale = Lerp(PrevScale, Scale, g_Renderer.GetInterpolationFactor());
+ auto color = Color::Lerp(PrevColor, Color, g_Renderer.GetInterpolationFactor());
// Draw main static element.
AddDisplaySprite(
From be5c525fa2f1f2ae5e3611b4c9526ed635cec92d Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sun, 19 May 2024 18:21:01 +1000
Subject: [PATCH 199/410] Remove Ptr suffix
---
TombEngine/Game/Hud/TargetHighlighter.cpp | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/TombEngine/Game/Hud/TargetHighlighter.cpp b/TombEngine/Game/Hud/TargetHighlighter.cpp
index ab2fbc398..fb863cef9 100644
--- a/TombEngine/Game/Hud/TargetHighlighter.cpp
+++ b/TombEngine/Game/Hud/TargetHighlighter.cpp
@@ -184,23 +184,23 @@ namespace TEN::Hud
// Loop over player targets.
auto itemNumbers = std::vector{};
- for (const auto* itemPtr : player.TargetList)
+ for (const auto* item : player.TargetList)
{
- if (itemPtr == nullptr)
+ if (item == nullptr)
continue;
// Collect item number.
- if (itemPtr->HitPoints != NOT_TARGETABLE)
- itemNumbers.push_back(itemPtr->Index);
+ if (item->HitPoints != NOT_TARGETABLE)
+ itemNumbers.push_back(item->Index);
// Find crosshair at item number key.
- auto it = _crosshairs.find(itemPtr->Index);
+ auto it = _crosshairs.find(item->Index);
if (it == _crosshairs.end())
continue;
// Set crosshair as primary or peripheral.
auto& crosshair = it->second;
- if (player.TargetEntity != nullptr && itemPtr->Index == player.TargetEntity->Index)
+ if (player.TargetEntity != nullptr && item->Index == player.TargetEntity->Index)
{
crosshair.SetPrimary();
}
From 40966147c9b841f2ee6167903e759813ac40b1d9 Mon Sep 17 00:00:00 2001
From: Jakub <80340234+Jakub768@users.noreply.github.com>
Date: Sun, 19 May 2024 22:42:03 +0100
Subject: [PATCH 200/410] Fix bullet points
---
CHANGELOG.md | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5e69120b4..d84194e1b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -151,24 +151,24 @@ TombEngine releases are located in this repository (alongside with Tomb Editor):
### Features/Amendments
* Improve head-on wall collision.
* Overhaul pushables:
- - Separate climbable and non-climbable pushable object slots.
- - Add new pushable OCB to manipulate pushable properties.
- - Add new animations for pushing pushables off edgees (TR1-3 and TR4-5 versions).
- - Fix pushables not working with raising blocks.
- - Fix miscellaneous pushable bugs.
+ - Separate climbable and non-climbable pushable object slots.
+ - Add new pushable OCB to manipulate pushable properties.
+ - Add new animations for pushing pushables off edgees (TR1-3 and TR4-5 versions).
+ - Fix pushables not working with raising blocks.
+ - Fix miscellaneous pushable bugs.
* Overhaul look-around feature:
- - Allow for more consistent and wider viewing angles while crawling, crouching, and hanging.
- - Improve look camera movement and control.
- - Re-enable looking while performing up jump, backward jump, or backward crawl.
- - Add functionality to rotate slowly when holding Walk while using binoculars or lasersight.
+ - Allow for more consistent and wider viewing angles while crawling, crouching, and hanging.
+ - Improve look camera movement and control.
+ - Re-enable looking while performing up jump, backward jump, or backward crawl.
+ - Add functionality to rotate slowly when holding Walk while using binoculars or lasersight.
* Add target highlighter system with toggle in Sound and Gameplay settings.
* Add sprint slide state 191.
* Add swinging blade.
* Add crumbling platform and add new OCBs for behaviour:
- - OCB 0: Default behaviour. When the player steps on the platform, it will shake and crumble after 1.2 seconds.
- - OCB > 0: When the player steps on the platform, it will crumble after the number of frames set in the OCB.
- - A positive value results in activation via player collision.
- - A negative value requires a trigger to activate.
+ - OCB 0: Default behaviour. When the player steps on the platform, it will shake and crumble after 1.2 seconds.
+ - OCB > 0: When the player steps on the platform, it will crumble after the number of frames set in the OCB.
+ - A positive value results in activation via player collision.
+ - A negative value requires a trigger to activate.
* Add basic mouse input handling. Allows for binding of mouse inputs in control settings.
* Add settings for Mouse Sensitivity and Mouse Smoothing (not used in-game yet).
From dd46927f6286a7c2765bdcca1a6b5407b25ebcad Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Mon, 20 May 2024 05:17:31 +0200
Subject: [PATCH 201/410] Fixed fish swarms not drawing
---
TombEngine/Game/control/control.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index 6fa9b355d..329b8f6be 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -240,6 +240,7 @@ GameStatus ControlPhase()
UpdateBeetleSwarm();
UpdateLocusts();
UpdateUnderwaterBloodParticles();
+ UpdateFishSwarm();
if (g_GameFlow->GetLevel(CurrentLevel)->GetLensFlareEnabled())
{
From 01a4b69168461c33dba7c8447776317dc010f7e8 Mon Sep 17 00:00:00 2001
From: Adngel
Date: Mon, 27 May 2024 10:29:09 +0200
Subject: [PATCH 202/410] Fix: Larson and Pierre zone.
Human LotType allows enemies to moves up and down of 2 and 4 clicks (like VCI guards) but Larson and Pierre hasn't got climbing animations, so they move over high steps just walking through.
That's why I'm changing them to obj->LotType = LotType::Basic; So they will do the correct path through 1 click steps.
---
TombEngine/Objects/TR5/tr5_objects.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/TombEngine/Objects/TR5/tr5_objects.cpp b/TombEngine/Objects/TR5/tr5_objects.cpp
index 686c9d28c..6a72a81b2 100644
--- a/TombEngine/Objects/TR5/tr5_objects.cpp
+++ b/TombEngine/Objects/TR5/tr5_objects.cpp
@@ -374,7 +374,7 @@ static void StartEntity(ObjectInfo *obj)
obj->pivotLength = 50;
obj->radius = 102;
obj->intelligent = true;
- obj->LotType = LotType::Human;
+ obj->LotType = LotType::Basic;
obj->SetBoneRotationFlags(6, ROT_X | ROT_Y);
obj->SetBoneRotationFlags(7, ROT_X | ROT_Y);
obj->SetHitEffect();
@@ -391,7 +391,7 @@ static void StartEntity(ObjectInfo *obj)
obj->pivotLength = 50;
obj->radius = 102;
obj->intelligent = true;
- obj->LotType = LotType::Human;
+ obj->LotType = LotType::Basic;
obj->SetBoneRotationFlags(6, ROT_X | ROT_Y);
obj->SetBoneRotationFlags(7, ROT_X | ROT_Y);
obj->SetHitEffect();
From 1f4404d76010c74e76bdcdccd593037c9c27975c Mon Sep 17 00:00:00 2001
From: Adngel
Date: Fri, 31 May 2024 20:52:57 +0200
Subject: [PATCH 203/410] Fix: Burning Torch, flame in hand
Changing the commands order to switch off the Lara's hand flame in the same frame when she throws or drops the torch.
(The command must still be after the torch flare has been created, otherwise the torch flare will be switched off when instantiated).
Issue: https://github.com/MontyTRC89/TombEngine/issues/1376
---
TombEngine/Objects/Generic/Object/burning_torch.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/TombEngine/Objects/Generic/Object/burning_torch.cpp b/TombEngine/Objects/Generic/Object/burning_torch.cpp
index 7d271b08d..a38b1e3a6 100644
--- a/TombEngine/Objects/Generic/Object/burning_torch.cpp
+++ b/TombEngine/Objects/Generic/Object/burning_torch.cpp
@@ -127,7 +127,6 @@ namespace TEN::Entities::Generic
lara->LeftArm.FrameNumber++;
if (lara->LeftArm.FrameNumber == 27)
{
- lara->Torch.IsLit = false;
lara->Flare.ControlLeft = false;
lara->LeftArm.Locked = false;
lara->Torch.State = TorchState::Holding;
@@ -139,6 +138,7 @@ namespace TEN::Entities::Generic
{
laraItem->Model.MeshIndex[LM_LHAND] = laraItem->Model.BaseMesh + LM_LHAND;
CreateFlare(*laraItem, ID_BURNING_TORCH_ITEM, true);
+ lara->Torch.IsLit = false;
}
}
}
@@ -147,7 +147,6 @@ namespace TEN::Entities::Generic
lara->LeftArm.FrameNumber++;
if (lara->LeftArm.FrameNumber == 41)
{
- lara->Torch.IsLit = false;
lara->Flare.ControlLeft = false;
lara->LeftArm.Locked = false;
lara->Torch.State = TorchState::Holding;
@@ -159,6 +158,7 @@ namespace TEN::Entities::Generic
{
laraItem->Model.MeshIndex[LM_LHAND] = laraItem->Model.BaseMesh + LM_LHAND;
CreateFlare(*laraItem, ID_BURNING_TORCH_ITEM, false);
+ lara->Torch.IsLit = false;
}
}
else if (lara->Torch.State == TorchState::JustLit)
From 838dab484bc0f55367f6742ad3d19dd20b03bd5c Mon Sep 17 00:00:00 2001
From: Adngel
Date: Fri, 31 May 2024 20:59:25 +0200
Subject: [PATCH 204/410] Update CHANGELOG.md
---
CHANGELOG.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d84194e1b..f8ffd5f17 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,6 +16,8 @@ TombEngine releases are located in this repository (alongside with Tomb Editor):
* Fixed Ember emitter crashing when ocb is between -1 and -10
* Fixed Electric cleaner and Squishy block not detecting collision with certain block heights.
* Fixed Squishy blocks crashing the level.
+* Fixed the path finding zones of Larson and Pierre.
+* Fixed the torch flame delay in disappearing when Lara threw or dropped the torch object.
### Features/Amendments
From 47e22abbe92d2a52b79a0df02db7e5eba6b2b584 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Thu, 6 Jun 2024 10:52:59 +1000
Subject: [PATCH 205/410] Remove Ptrs suffixes
---
TombEngine/Game/Lara/lara_one_gun.cpp | 4 ++--
TombEngine/Game/Lara/lara_tests.cpp | 2 +-
TombEngine/Game/collision/collide_item.cpp | 4 ++--
TombEngine/Game/collision/collide_item.h | 6 +++---
TombEngine/Game/pickup/pickup.cpp | 8 ++++----
TombEngine/Objects/Effects/flame_emitters.cpp | 2 +-
TombEngine/Objects/Effects/tr5_electricity.cpp | 2 +-
.../Generic/Object/Pushable/PushableCollision.cpp | 4 ++--
TombEngine/Objects/Generic/Object/burning_torch.cpp | 12 ++++++------
TombEngine/Objects/TR5/Trap/tr5_explosion.cpp | 2 +-
10 files changed, 23 insertions(+), 23 deletions(-)
diff --git a/TombEngine/Game/Lara/lara_one_gun.cpp b/TombEngine/Game/Lara/lara_one_gun.cpp
index a5a55a22f..41f841d9b 100644
--- a/TombEngine/Game/Lara/lara_one_gun.cpp
+++ b/TombEngine/Game/Lara/lara_one_gun.cpp
@@ -1563,7 +1563,7 @@ void HandleProjectile(ItemInfo& projectile, ItemInfo& emitter, const Vector3i& p
break;
// Run through statics.
- for (auto* staticPtr : collObjects.StaticPtrs)
+ for (auto* staticPtr : collObjects.Statics)
{
hasHit = hasHitNotByEmitter = doShatter = true;
doExplosion = isExplosive;
@@ -1584,7 +1584,7 @@ void HandleProjectile(ItemInfo& projectile, ItemInfo& emitter, const Vector3i& p
}
// Run through items.
- for (auto* itemPtr : collObjects.ItemPtrs)
+ for (auto* itemPtr : collObjects.Items)
{
// Object was already affected by collision, skip it.
if (std::find(affectedObjects.begin(), affectedObjects.end(), itemPtr->Index) != affectedObjects.end())
diff --git a/TombEngine/Game/Lara/lara_tests.cpp b/TombEngine/Game/Lara/lara_tests.cpp
index 9d24bc0ea..dc631857c 100644
--- a/TombEngine/Game/Lara/lara_tests.cpp
+++ b/TombEngine/Game/Lara/lara_tests.cpp
@@ -1795,7 +1795,7 @@ bool TestLaraPoleCollision(ItemInfo* item, CollisionInfo* coll, bool goingUp, fl
//g_Renderer.AddDebugSphere(sphere.Center, 16.0f, Vector4(1, 0, 0, 1), RendererDebugPage::CollisionStats);
- for (const auto* itemPtr : collObjects.ItemPtrs)
+ for (const auto* itemPtr : collObjects.Items)
{
if (itemPtr->ObjectNumber != ID_POLEROPE)
continue;
diff --git a/TombEngine/Game/collision/collide_item.cpp b/TombEngine/Game/collision/collide_item.cpp
index 0ae536fb2..b979c66eb 100644
--- a/TombEngine/Game/collision/collide_item.cpp
+++ b/TombEngine/Game/collision/collide_item.cpp
@@ -204,7 +204,7 @@ CollidedObjectData GetCollidedObjects(ItemInfo& collidingItem, bool onlyVisible,
// Test accurate box intersection.
if (box0.Intersects(box1))
- collObjects.ItemPtrs.push_back(&item);
+ collObjects.Items.push_back(&item);
}
while (itemNumber != NO_VALUE);
}
@@ -253,7 +253,7 @@ CollidedObjectData GetCollidedObjects(ItemInfo& collidingItem, bool onlyVisible,
// Test accurate box intersection.
if (box0.Intersects(box1))
- collObjects.StaticPtrs.push_back(&staticObj);
+ collObjects.Statics.push_back(&staticObj);
}
}
}
diff --git a/TombEngine/Game/collision/collide_item.h b/TombEngine/Game/collision/collide_item.h
index 5bd91e997..6c39f9abb 100644
--- a/TombEngine/Game/collision/collide_item.h
+++ b/TombEngine/Game/collision/collide_item.h
@@ -30,10 +30,10 @@ struct ObjectCollisionBounds
struct CollidedObjectData
{
- std::vector ItemPtrs = {};
- std::vector StaticPtrs = {};
+ std::vector Items = {};
+ std::vector Statics = {};
- bool IsEmpty() const { return (ItemPtrs.empty() && StaticPtrs.empty()); };
+ bool IsEmpty() const { return (Items.empty() && Statics.empty()); };
};
void GenericSphereBoxCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll);
diff --git a/TombEngine/Game/pickup/pickup.cpp b/TombEngine/Game/pickup/pickup.cpp
index 0dff72dda..d9d2a3dc0 100644
--- a/TombEngine/Game/pickup/pickup.cpp
+++ b/TombEngine/Game/pickup/pickup.cpp
@@ -234,8 +234,8 @@ void CollectMultiplePickups(int itemNumber)
auto& firstItem = g_Level.Items[itemNumber];
auto collObjects = GetCollidedObjects(firstItem, true, true, LARA_RADIUS, ObjectCollectionMode::Items);
- collObjects.ItemPtrs.push_back(&firstItem);
- for (auto* itemPtr : collObjects.ItemPtrs)
+ collObjects.Items.push_back(&firstItem);
+ for (auto* itemPtr : collObjects.Items)
{
if (!Objects[itemPtr->ObjectNumber].isPickup)
continue;
@@ -886,7 +886,7 @@ void DropPickups(ItemInfo* item)
// Iterate through all found items and statics around, and determine if dummy sphere
// intersects any of those. If so, try other corner.
- for (const auto* itemPtr : collObjects.ItemPtrs)
+ for (const auto* itemPtr : collObjects.Items)
{
auto box = GameBoundingBox(itemPtr).ToBoundingOrientedBox(itemPtr->Pose);
if (box.Intersects(sphere))
@@ -896,7 +896,7 @@ void DropPickups(ItemInfo* item)
}
}
- for (auto* staticPtr : collObjects.StaticPtrs)
+ for (auto* staticPtr : collObjects.Statics)
{
auto& object = StaticObjects[staticPtr->staticNumber];
diff --git a/TombEngine/Objects/Effects/flame_emitters.cpp b/TombEngine/Objects/Effects/flame_emitters.cpp
index 80fea9e67..d0040a6f7 100644
--- a/TombEngine/Objects/Effects/flame_emitters.cpp
+++ b/TombEngine/Objects/Effects/flame_emitters.cpp
@@ -65,7 +65,7 @@ namespace TEN::Entities::Effects
void BurnNearbyItems(ItemInfo* item, int radius)
{
auto collObjects = GetCollidedObjects(*item, true, false, radius, ObjectCollectionMode::Items);
- for (auto* itemPtr : collObjects.ItemPtrs)
+ for (auto* itemPtr : collObjects.Items)
{
if (TestEnvironment(ENV_FLAG_WATER, itemPtr->RoomNumber))
continue;
diff --git a/TombEngine/Objects/Effects/tr5_electricity.cpp b/TombEngine/Objects/Effects/tr5_electricity.cpp
index abfd748a3..1e79cb09f 100644
--- a/TombEngine/Objects/Effects/tr5_electricity.cpp
+++ b/TombEngine/Objects/Effects/tr5_electricity.cpp
@@ -180,7 +180,7 @@ void ElectricityWiresControl(short itemNumber)
return;
auto collObjects = GetCollidedObjects(*item, true, false, BLOCK(2), ObjectCollectionMode::Items);
- for (auto* itemPtr : collObjects.ItemPtrs)
+ for (auto* itemPtr : collObjects.Items)
{
const auto& object = Objects[itemPtr->ObjectNumber];
diff --git a/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp b/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
index bf526c49a..4494bc600 100644
--- a/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
+++ b/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
@@ -120,7 +120,7 @@ namespace TEN::Entities::Generic
auto collObjects = GetCollidedObjects(pushableItem, true, true);
pushableItem.Pose.Position = prevPos;
- if (!collObjects.StaticPtrs.empty())
+ if (!collObjects.Statics.empty())
return false;
for (const auto* itemPtr : collObjects.ItemPtrs)
@@ -191,7 +191,7 @@ namespace TEN::Entities::Generic
auto collObjects = GetCollidedObjects(*LaraItem, true, true);
LaraItem->Pose.Position = prevPos;
- if (!collObjects.StaticPtrs.empty())
+ if (!collObjects.Statics.empty())
return false;
for (const auto* itemPtr : collObjects.ItemPtrs)
diff --git a/TombEngine/Objects/Generic/Object/burning_torch.cpp b/TombEngine/Objects/Generic/Object/burning_torch.cpp
index a38b1e3a6..4c1da0297 100644
--- a/TombEngine/Objects/Generic/Object/burning_torch.cpp
+++ b/TombEngine/Objects/Generic/Object/burning_torch.cpp
@@ -261,19 +261,19 @@ namespace TEN::Entities::Generic
if (!collObjects.IsEmpty())
{
LaraCollision.Setup.EnableObjectPush = true;
- if (!collObjects.ItemPtrs.empty())
+ if (!collObjects.Items.empty())
{
- const auto& object = Objects[collObjects.ItemPtrs.front()->ObjectNumber];
+ const auto& object = Objects[collObjects.Items.front()->ObjectNumber];
if (!object.intelligent &&
- !collObjects.ItemPtrs.front()->IsLara())
+ !collObjects.Items.front()->IsLara())
{
- ObjectCollision(collObjects.ItemPtrs.front()->Index, item, &LaraCollision);
+ ObjectCollision(collObjects.Items.front()->Index, item, &LaraCollision);
}
}
- else if (!collObjects.StaticPtrs.empty())
+ else if (!collObjects.Statics.empty())
{
- ItemPushStatic(item, *collObjects.StaticPtrs.front(), &LaraCollision);
+ ItemPushStatic(item, *collObjects.Statics.front(), &LaraCollision);
}
item->Animation.Velocity.z = -int(item->Animation.Velocity.z / 1.5f);
diff --git a/TombEngine/Objects/TR5/Trap/tr5_explosion.cpp b/TombEngine/Objects/TR5/Trap/tr5_explosion.cpp
index 8b33196a2..1873979ad 100644
--- a/TombEngine/Objects/TR5/Trap/tr5_explosion.cpp
+++ b/TombEngine/Objects/TR5/Trap/tr5_explosion.cpp
@@ -155,7 +155,7 @@ void ExplosionControl(short itemNumber)
}
}
- for (auto* staticPtr : collObjects.StaticPtrs)
+ for (auto* staticPtr : collObjects.Statics)
{
if (StaticObjects[staticPtr->staticNumber].shatterType != ShatterType::None)
{
From d33d1ced19f7488e63ddda96abe3fbacc2990463 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Thu, 6 Jun 2024 11:15:43 +1000
Subject: [PATCH 206/410] Manually fix VS search and replace errors
---
.../Objects/Generic/Object/Pushable/PushableCollision.cpp | 4 ++--
TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp | 2 +-
TombEngine/Objects/TR4/Trap/SpikyWall.cpp | 2 +-
TombEngine/Objects/TR5/Trap/tr5_explosion.cpp | 2 +-
TombEngine/Scripting/Internal/TEN/Objects/ObjectsHandler.cpp | 2 +-
5 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp b/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
index 4494bc600..c1ffac6ce 100644
--- a/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
+++ b/TombEngine/Objects/Generic/Object/Pushable/PushableCollision.cpp
@@ -123,7 +123,7 @@ namespace TEN::Entities::Generic
if (!collObjects.Statics.empty())
return false;
- for (const auto* itemPtr : collObjects.ItemPtrs)
+ for (const auto* itemPtr : collObjects.Items)
{
const auto& object = Objects[itemPtr->ObjectNumber];
@@ -194,7 +194,7 @@ namespace TEN::Entities::Generic
if (!collObjects.Statics.empty())
return false;
- for (const auto* itemPtr : collObjects.ItemPtrs)
+ for (const auto* itemPtr : collObjects.Items)
{
const auto& object = Objects[itemPtr->ObjectNumber];
diff --git a/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp b/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp
index f25abbc09..436ade346 100644
--- a/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp
+++ b/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp
@@ -114,7 +114,7 @@ namespace TEN::Entities::Traps
auto collObjects = GetCollidedObjects(item, true, true);
if (!collObjects.IsEmpty())
{
- for (auto* itemPtr : collObjects.ItemPtrs)
+ for (auto* itemPtr : collObjects.Items)
{
const auto& object = Objects[itemPtr->ObjectNumber];
diff --git a/TombEngine/Objects/TR4/Trap/SpikyWall.cpp b/TombEngine/Objects/TR4/Trap/SpikyWall.cpp
index bd1f55d5e..7f707153f 100644
--- a/TombEngine/Objects/TR4/Trap/SpikyWall.cpp
+++ b/TombEngine/Objects/TR4/Trap/SpikyWall.cpp
@@ -55,7 +55,7 @@ namespace TEN::Entities::Traps
auto collObjects = GetCollidedObjects(item, true, true);
if (!collObjects.IsEmpty())
{
- for (auto* itemPtr : collObjects.ItemPtrs)
+ for (auto* itemPtr : collObjects.Items)
{
const auto& object = Objects[itemPtr->ObjectNumber];
diff --git a/TombEngine/Objects/TR5/Trap/tr5_explosion.cpp b/TombEngine/Objects/TR5/Trap/tr5_explosion.cpp
index 1873979ad..70bf86659 100644
--- a/TombEngine/Objects/TR5/Trap/tr5_explosion.cpp
+++ b/TombEngine/Objects/TR5/Trap/tr5_explosion.cpp
@@ -132,7 +132,7 @@ void ExplosionControl(short itemNumber)
auto collObjects = GetCollidedObjects(*item, true, true, BLOCK(2), ObjectCollectionMode::All);
if (!collObjects.IsEmpty())
{
- for (auto* itemPtr : collObjects.ItemPtrs)
+ for (auto* itemPtr : collObjects.Items)
{
if (itemPtr->ObjectNumber >= ID_SMASH_OBJECT1 && itemPtr->ObjectNumber <= ID_SMASH_OBJECT16)
{
diff --git a/TombEngine/Scripting/Internal/TEN/Objects/ObjectsHandler.cpp b/TombEngine/Scripting/Internal/TEN/Objects/ObjectsHandler.cpp
index 64b74ca70..df52b1c59 100644
--- a/TombEngine/Scripting/Internal/TEN/Objects/ObjectsHandler.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Objects/ObjectsHandler.cpp
@@ -184,7 +184,7 @@ void ObjectsHandler::TestCollidingObjects()
{
// Test against other moveables.
auto collObjects = GetCollidedObjects(item, true, false);
- for (const auto& collidedItemPtr : collObjects.ItemPtrs)
+ for (const auto& collidedItemPtr : collObjects.Items)
g_GameScript->ExecuteFunction(item.Callbacks.OnObjectCollided, itemNumber0, collidedItemPtr->Index);
}
From 6fa494b093861fc72620ca538fbde99862e1ab6c Mon Sep 17 00:00:00 2001
From: Sezz
Date: Thu, 6 Jun 2024 11:42:54 +1000
Subject: [PATCH 207/410] Make monkey swing auto jump a player setting; Lua
formatting
---
Scripts/Settings.lua | 1 -
Scripts/SystemStrings.lua | 3 +-
TombEngine/Game/Lara/lara_tests.cpp | 6 +--
TombEngine/Game/Lara/lara_tests.h | 2 +-
TombEngine/Game/gui.cpp | 15 +++++--
TombEngine/Renderer/RendererDrawMenu.cpp | 33 ++++++++------
.../Include/Flow/ScriptInterfaceFlowHandler.h | 2 +-
.../Scripting/Internal/LanguageScript.h | 3 +-
TombEngine/Scripting/Internal/LuaHandler.cpp | 16 +++----
TombEngine/Scripting/Internal/LuaHandler.h | 30 ++++++-------
.../TEN/Flow/Animations/Animations.cpp | 7 +--
.../Internal/TEN/Flow/Animations/Animations.h | 4 +-
.../Internal/TEN/Flow/FlowHandler.cpp | 44 +++++++++----------
.../Scripting/Internal/TEN/Flow/FlowHandler.h | 27 ++++++------
.../Internal/TEN/Strings/StringsHandler.cpp | 2 +-
TombEngine/Specific/configuration.cpp | 9 +++-
TombEngine/Specific/configuration.h | 2 +
17 files changed, 114 insertions(+), 92 deletions(-)
diff --git a/Scripts/Settings.lua b/Scripts/Settings.lua
index 4b7a4c226..f50976766 100644
--- a/Scripts/Settings.lua
+++ b/Scripts/Settings.lua
@@ -11,7 +11,6 @@ local anims = Flow.Animations.new()
anims.crawlExtended = true
anims.crouchRoll = true
anims.crawlspaceSwandive = true
-anims.monkeyAutoJump = false
anims.overhangClimb = false
anims.slideExtended = false
anims.sprintJump = false
diff --git a/Scripts/SystemStrings.lua b/Scripts/SystemStrings.lua
index 2bb0d2e47..23f4c749b 100644
--- a/Scripts/SystemStrings.lua
+++ b/Scripts/SystemStrings.lua
@@ -51,7 +51,8 @@ local strings =
ammo_used = { "Ammo Used" },
antialiasing = { "Antialiasing" },
apply = { "Apply" },
- automatic_targeting = { "Automatic Targeting" },
+ auto_monkey_swing_jump = { "Auto Monkey Jump" },
+ auto_targeting = { "Auto Targeting" },
back = { "Back" },
cancel = { "Cancel" },
caustics = { "Underwater Caustics" },
diff --git a/TombEngine/Game/Lara/lara_tests.cpp b/TombEngine/Game/Lara/lara_tests.cpp
index dc631857c..97cd5d730 100644
--- a/TombEngine/Game/Lara/lara_tests.cpp
+++ b/TombEngine/Game/Lara/lara_tests.cpp
@@ -1427,7 +1427,7 @@ std::optional TestLaraLadderMount(ItemInfo* item, CollisionInfo
return std::nullopt;
}
-std::optional TestLaraMonkeyAutoJump(ItemInfo* item, CollisionInfo* coll)
+std::optional TestLaraAutoMonkeySwingJump(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
@@ -1530,8 +1530,8 @@ std::optional TestLaraVault(ItemInfo* item, CollisionInfo* coll
// In this case, they fail due to a reliance on ShiftItem(). @Sezz 2021.02.05
// Auto jump to monkey swing.
- vaultResult = TestLaraMonkeyAutoJump(item, coll);
- if (vaultResult.has_value() && g_GameFlow->HasMonkeyAutoJump())
+ vaultResult = TestLaraAutoMonkeySwingJump(item, coll);
+ if (vaultResult.has_value() && g_Configuration.EnableAutoMonkeySwingJump)
{
vaultResult->TargetState = LS_AUTO_JUMP;
if (!HasStateDispatch(item, vaultResult->TargetState))
diff --git a/TombEngine/Game/Lara/lara_tests.h b/TombEngine/Game/Lara/lara_tests.h
index 1081a1d79..3777783a0 100644
--- a/TombEngine/Game/Lara/lara_tests.h
+++ b/TombEngine/Game/Lara/lara_tests.h
@@ -56,7 +56,7 @@ std::optional TestLaraVault3StepsToCrouch(ItemInfo* item, Colli
std::optional TestLaraLedgeAutoJump(ItemInfo* item, CollisionInfo* coll);
std::optional TestLaraLadderAutoJump(ItemInfo* item, CollisionInfo* coll);
std::optional TestLaraLadderMount(ItemInfo* item, CollisionInfo* coll);
-std::optional TestLaraMonkeyAutoJump(ItemInfo* item, CollisionInfo* coll);
+std::optional TestLaraAutoMonkeySwingJump(ItemInfo* item, CollisionInfo* coll);
std::optional TestLaraVault(ItemInfo* item, CollisionInfo* coll);
bool TestAndDoLaraLadderClimb(ItemInfo* item, CollisionInfo* coll);
diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp
index 2e2bf148d..baf36f0e6 100644
--- a/TombEngine/Game/gui.cpp
+++ b/TombEngine/Game/gui.cpp
@@ -886,7 +886,9 @@ namespace TEN::Gui
Reverb,
MusicVolume,
SfxVolume,
+
Subtitles,
+ AutoMonkeySwingJump,
AutoTargeting,
TargetHighlighter,
ToggleRumble,
@@ -895,12 +897,12 @@ namespace TEN::Gui
MouseSmoothing,
Apply,
- Cancel
+ Cancel,
+
+ Count
};
- static const auto numOtherSettingsOptions = 11;
-
- OptionCount = numOtherSettingsOptions;
+ OptionCount = (int)OtherSettingsOption::Count - 1;
if (GuiIsDeselected())
{
@@ -923,6 +925,11 @@ namespace TEN::Gui
CurrentSettings.Configuration.EnableReverb = !CurrentSettings.Configuration.EnableReverb;
break;
+ case OtherSettingsOption::AutoMonkeySwingJump:
+ SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
+ CurrentSettings.Configuration.EnableAutoMonkeySwingJump = !CurrentSettings.Configuration.EnableAutoMonkeySwingJump;
+ break;
+
case OtherSettingsOption::Subtitles:
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
CurrentSettings.Configuration.EnableSubtitles = !CurrentSettings.Configuration.EnableSubtitles;
diff --git a/TombEngine/Renderer/RendererDrawMenu.cpp b/TombEngine/Renderer/RendererDrawMenu.cpp
index 8289f1453..4553f5630 100644
--- a/TombEngine/Renderer/RendererDrawMenu.cpp
+++ b/TombEngine/Renderer/RendererDrawMenu.cpp
@@ -231,42 +231,47 @@ namespace TEN::Renderer
AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableSubtitles), PRINTSTRING_COLOR_WHITE, SF(titleOption == 3));
GetNextLinePosition(&y);
+ // Auto monkey swing jump
+ AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_AUTO_MONKEY_SWING_JUMP), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 4));
+ AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableAutoMonkeySwingJump), PRINTSTRING_COLOR_WHITE, SF(titleOption == 4));
+ GetNextLinePosition(&y);
+
// Auto targeting
- AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_AUTOMATIC_TARGETING), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 4));
- AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableAutoTargeting), PRINTSTRING_COLOR_WHITE, SF(titleOption == 4));
+ AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_AUTO_TARGETING), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 5));
+ AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableAutoTargeting), PRINTSTRING_COLOR_WHITE, SF(titleOption == 5));
GetNextLinePosition(&y);
// Target highlighter
- AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_TARGET_HIGHLIGHTER), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 5));
- AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableTargetHighlighter), PRINTSTRING_COLOR_WHITE, SF(titleOption == 5));
+ AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_TARGET_HIGHLIGHTER), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 6));
+ AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableTargetHighlighter), PRINTSTRING_COLOR_WHITE, SF(titleOption == 6));
GetNextLinePosition(&y);
// Vibration
- AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_RUMBLE), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 6));
- AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableRumble), PRINTSTRING_COLOR_WHITE, SF(titleOption == 6));
+ AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_RUMBLE), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 7));
+ AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableRumble), PRINTSTRING_COLOR_WHITE, SF(titleOption == 7));
GetNextLinePosition(&y);
// Thumbstick camera
- AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_THUMBSTICK_CAMERA), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 7));
- AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableThumbstickCamera), PRINTSTRING_COLOR_WHITE, SF(titleOption == 7));
+ AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_THUMBSTICK_CAMERA), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 8));
+ AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableThumbstickCamera), PRINTSTRING_COLOR_WHITE, SF(titleOption == 8));
GetNextBlockPosition(&y);
// Mouse sensitivity
- AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_MOUSE_SENSITIVITY), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 8));
- AddString(MenuRightSideEntry, y, std::to_string(g_Gui.GetCurrentSettings().Configuration.MouseSensitivity).c_str(), PRINTSTRING_COLOR_WHITE, SF(titleOption == 8));
+ AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_MOUSE_SENSITIVITY), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 9));
+ AddString(MenuRightSideEntry, y, std::to_string(g_Gui.GetCurrentSettings().Configuration.MouseSensitivity).c_str(), PRINTSTRING_COLOR_WHITE, SF(titleOption == 9));
GetNextLinePosition(&y);
// Mouse smoothing
- AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_MOUSE_SMOOTHING), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 9));
- AddString(MenuRightSideEntry, y, std::to_string(g_Gui.GetCurrentSettings().Configuration.MouseSmoothing).c_str(), PRINTSTRING_COLOR_WHITE, SF(titleOption == 9));
+ AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_MOUSE_SMOOTHING), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 10));
+ AddString(MenuRightSideEntry, y, std::to_string(g_Gui.GetCurrentSettings().Configuration.MouseSmoothing).c_str(), PRINTSTRING_COLOR_WHITE, SF(titleOption == 10));
GetNextBlockPosition(&y);
// Apply
- AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_APPLY), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == 10));
+ AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_APPLY), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == 11));
GetNextLinePosition(&y);
// Cancel
- AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CANCEL), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == 11));
+ AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CANCEL), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == 12));
break;
case Menu::GeneralActions:
diff --git a/TombEngine/Scripting/Include/Flow/ScriptInterfaceFlowHandler.h b/TombEngine/Scripting/Include/Flow/ScriptInterfaceFlowHandler.h
index ac3382e1c..5c679f359 100644
--- a/TombEngine/Scripting/Include/Flow/ScriptInterfaceFlowHandler.h
+++ b/TombEngine/Scripting/Include/Flow/ScriptInterfaceFlowHandler.h
@@ -39,7 +39,7 @@ public:
virtual bool HasCrawlExtended() const = 0;
virtual bool HasCrouchRoll() const = 0;
virtual bool HasCrawlspaceDive() const = 0;
- virtual bool HasMonkeyAutoJump() const = 0;
+ virtual bool HasAutoMonkeySwingJump() const = 0;
virtual bool HasSprintJump() const = 0;
virtual bool HasAFKPose() const = 0;
virtual bool HasOverhangClimb() const = 0;
diff --git a/TombEngine/Scripting/Internal/LanguageScript.h b/TombEngine/Scripting/Internal/LanguageScript.h
index a2c04feaf..5eb728917 100644
--- a/TombEngine/Scripting/Internal/LanguageScript.h
+++ b/TombEngine/Scripting/Internal/LanguageScript.h
@@ -80,7 +80,8 @@
#define STRING_SOUND "sound"
#define STRING_ENABLE_SOUND "enable_sound"
#define STRING_REVERB "reverb"
-#define STRING_AUTOMATIC_TARGETING "automatic_targeting"
+#define STRING_AUTO_MONKEY_SWING_JUMP "auto_monkey_swing_jump"
+#define STRING_AUTO_TARGETING "auto_targeting"
#define STRING_TARGET_HIGHLIGHTER "target_highlighter"
#define STRING_RUMBLE "rumble"
#define STRING_THUMBSTICK_CAMERA "thumbstick_camera"
diff --git a/TombEngine/Scripting/Internal/LuaHandler.cpp b/TombEngine/Scripting/Internal/LuaHandler.cpp
index acbb76621..1b3140f9a 100644
--- a/TombEngine/Scripting/Internal/LuaHandler.cpp
+++ b/TombEngine/Scripting/Internal/LuaHandler.cpp
@@ -4,18 +4,18 @@
#include
#include "Scripting/Internal/LuaHandler.h"
-LuaHandler::LuaHandler(sol::state* lua) : m_lua{ lua }
+LuaHandler::LuaHandler(sol::state* lua) : _lua{ lua }
{
}
void LuaHandler::ResetGlobals()
{
- auto mt = sol::table{ *m_lua, sol::create };
- m_globals = sol::table{ *m_lua, sol::create };
- mt.set(sol::meta_function::new_index, m_globals);
- mt.set(sol::meta_function::index, m_globals);
+ auto mt = sol::table{ *_lua, sol::create };
+ _globals = sol::table{ *_lua, sol::create };
+ mt.set(sol::meta_function::new_index, _globals);
+ mt.set(sol::meta_function::index, _globals);
- m_lua->set(sol::metatable_key, mt);
+ _lua->set(sol::metatable_key, mt);
}
void LuaHandler::ExecuteScript(const std::string& luaFilename, bool isOptional)
@@ -23,7 +23,7 @@ void LuaHandler::ExecuteScript(const std::string& luaFilename, bool isOptional)
if (isOptional && !std::filesystem::is_regular_file(luaFilename))
return;
- auto result = m_lua->safe_script_file(luaFilename, sol::script_pass_on_error);
+ auto result = _lua->safe_script_file(luaFilename, sol::script_pass_on_error);
if (!result.valid())
{
sol::error error = result;
@@ -33,7 +33,7 @@ void LuaHandler::ExecuteScript(const std::string& luaFilename, bool isOptional)
void LuaHandler::ExecuteString(const std::string& command)
{
- auto result = m_lua->safe_script(command, sol::environment(m_lua->lua_state(), sol::create, m_lua->globals()), sol::script_pass_on_error);
+ auto result = _lua->safe_script(command, sol::environment(_lua->lua_state(), sol::create, _lua->globals()), sol::script_pass_on_error);
if (!result.valid())
{
sol::error error = result;
diff --git a/TombEngine/Scripting/Internal/LuaHandler.h b/TombEngine/Scripting/Internal/LuaHandler.h
index 050e93dac..53e59eaba 100644
--- a/TombEngine/Scripting/Internal/LuaHandler.h
+++ b/TombEngine/Scripting/Internal/LuaHandler.h
@@ -6,8 +6,8 @@
class LuaHandler
{
protected:
- sol::state* m_lua;
- sol::table m_globals;
+ sol::state* _lua;
+ sol::table _globals;
public:
LuaHandler(sol::state* lua);
@@ -22,17 +22,17 @@ public:
sol::state* GetState()
{
- return m_lua;
+ return _lua;
};
template void MakeReadOnlyTable(sol::table parent, const std::string& tableName, const T& container)
{
// Put all data into metatable.
auto metatable = tableName + "Meta";
- m_lua->set(metatable, sol::as_table(container));
+ _lua->set(metatable, sol::as_table(container));
auto mtmt = tableName + "MetaMeta";
- auto mtmtTable = m_lua->create_named_table(mtmt);
+ auto mtmtTable = _lua->create_named_table(mtmt);
// Make metatable's metatable's __index fail an assert to generate warning/error when trying to use missing variable.
auto lam = [tableName](sol::table tab, std::string const& key)
@@ -41,29 +41,29 @@ public:
};
mtmtTable[sol::meta_method::index] = lam;
- m_lua->safe_script("setmetatable(" + metatable + ", " + mtmt + ")");
+ _lua->safe_script("setmetatable(" + metatable + ", " + mtmt + ")");
// Make metatable's __index refer to itself so that requests to main table will go through to metatable
// (and thus container's members).
- m_lua->safe_script(metatable + ".__index = " + metatable);
+ _lua->safe_script(metatable + ".__index = " + metatable);
- m_lua->safe_script(metatable + ".__type = \"readonly\"");
+ _lua->safe_script(metatable + ".__type = \"readonly\"");
// Don't allow table to have new elements put into it.
- m_lua->safe_script(metatable + ".__newindex = function() error('" + tableName + " is read-only') end");
+ _lua->safe_script(metatable + ".__newindex = function() error('" + tableName + " is read-only') end");
// Protect metatable.
- m_lua->safe_script(metatable + ".__metatable = 'metatable is protected'");
+ _lua->safe_script(metatable + ".__metatable = 'metatable is protected'");
- auto tab = m_lua->create_named_table(tableName);
+ auto tab = _lua->create_named_table(tableName);
- m_lua->safe_script("setmetatable(" + tableName + ", " + metatable + ")");
+ _lua->safe_script("setmetatable(" + tableName + ", " + metatable + ")");
// Point initial metatable variable away from its contents. This is just for cleanliness.
parent.set(tableName, tab);
- m_lua->safe_script(tableName + " = nil");
- m_lua->safe_script(metatable + " = nil");
- m_lua->safe_script(mtmt + " = nil");
+ _lua->safe_script(tableName + " = nil");
+ _lua->safe_script(metatable + " = nil");
+ _lua->safe_script(mtmt + " = nil");
}
};
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Animations/Animations.cpp b/TombEngine/Scripting/Internal/TEN/Flow/Animations/Animations.cpp
index 856472784..eb820fb21 100644
--- a/TombEngine/Scripting/Internal/TEN/Flow/Animations/Animations.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Flow/Animations/Animations.cpp
@@ -15,11 +15,12 @@ void Animations::Register(sol::table& parent)
"crawlExtended", &Animations::HasCrawlExtended,
"crouchRoll", &Animations::HasCrouchRoll,
"crawlspaceSwandive", &Animations::HasCrawlspaceDive,
- "monkeyAutoJump", &Animations::HasMonkeyAutoJump,
"overhangClimb", &Animations::HasOverhangClimb,
"slideExtended", &Animations::HasSlideExtended,
"sprintJump", &Animations::HasSprintJump,
"pose", &Animations::HasPose,
- "ledgeJumps", &Animations::HasLedgeJumps
- );
+ "ledgeJumps", &Animations::HasLedgeJumps,
+
+ // NOTE: Removed. Keep for now to maintain compatibility. -- Sezz 2024.06.06
+ "monkeyAutoJump", & Animations::HasAutoMonkeySwingJump);
}
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Animations/Animations.h b/TombEngine/Scripting/Internal/TEN/Flow/Animations/Animations.h
index 763fc789c..781f62653 100644
--- a/TombEngine/Scripting/Internal/TEN/Flow/Animations/Animations.h
+++ b/TombEngine/Scripting/Internal/TEN/Flow/Animations/Animations.h
@@ -13,12 +13,14 @@ struct Animations
bool HasPose; // Crossed arms AFK posing.
bool HasSlideExtended; // Extended slope sliding functionality (not ready yet).
bool HasSprintJump; // Sprint jump.
- bool HasMonkeyAutoJump; // Auto jump to monkey swing when pressing UP + ACTION. TODO: Make this a player setting.
bool HasCrawlspaceDive; // Dive into crawlspaces.
bool HasCrawlExtended; // Extended crawl moveset.
bool HasCrouchRoll; // Crouch roll.
bool HasOverhangClimb; // Overhang functionality.
bool HasLedgeJumps; // Jump up or back from a ledge.
+ // NOTE: Removed. Keep for now to maintain compatibility. -- Sezz 2024.06.06
+ bool HasAutoMonkeySwingJump;
+
static void Register(sol::table&);
};
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp
index 5240789f8..73dfe787c 100644
--- a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp
@@ -30,7 +30,7 @@ ScriptInterfaceStringsHandler* g_GameStringsHandler;
ScriptInterfaceFlowHandler* g_GameFlow;
FlowHandler::FlowHandler(sol::state* lua, sol::table& parent) :
- m_handler(lua)
+ _handler(lua)
{
/*** gameflow.lua.
These functions are called in gameflow.lua, a file loosely equivalent to winroomedit's SCRIPT.DAT.
@@ -38,7 +38,7 @@ They handle a game's 'metadata'; i.e., things such as level titles, loading scre
ambient tracks.
@section Flowlua
*/
- sol::table tableFlow{ m_handler.GetState()->lua_state(), sol::create };
+ sol::table tableFlow{ _handler.GetState()->lua_state(), sol::create };
parent.set(ScriptReserved_Flow, tableFlow);
/***
@@ -265,12 +265,12 @@ Specify which translations in the strings table correspond to which languages.
Settings::Register(tableFlow);
Fog::Register(tableFlow);
- m_handler.MakeReadOnlyTable(tableFlow, ScriptReserved_WeatherType, WEATHER_TYPES);
- m_handler.MakeReadOnlyTable(tableFlow, ScriptReserved_LaraType, PLAYER_TYPES);
- m_handler.MakeReadOnlyTable(tableFlow, ScriptReserved_RotationAxis, ROTATION_AXES);
- m_handler.MakeReadOnlyTable(tableFlow, ScriptReserved_ItemAction, ITEM_MENU_ACTIONS);
- m_handler.MakeReadOnlyTable(tableFlow, ScriptReserved_ErrorMode, ERROR_MODES);
- m_handler.MakeReadOnlyTable(tableFlow, ScriptReserved_GameStatus, GAME_STATUSES);
+ _handler.MakeReadOnlyTable(tableFlow, ScriptReserved_WeatherType, WEATHER_TYPES);
+ _handler.MakeReadOnlyTable(tableFlow, ScriptReserved_LaraType, PLAYER_TYPES);
+ _handler.MakeReadOnlyTable(tableFlow, ScriptReserved_RotationAxis, ROTATION_AXES);
+ _handler.MakeReadOnlyTable(tableFlow, ScriptReserved_ItemAction, ITEM_MENU_ACTIONS);
+ _handler.MakeReadOnlyTable(tableFlow, ScriptReserved_ErrorMode, ERROR_MODES);
+ _handler.MakeReadOnlyTable(tableFlow, ScriptReserved_GameStatus, GAME_STATUSES);
}
FlowHandler::~FlowHandler()
@@ -281,35 +281,35 @@ FlowHandler::~FlowHandler()
std::string FlowHandler::GetGameDir()
{
- return m_gameDir;
+ return _gameDir;
}
void FlowHandler::SetGameDir(const std::string& assetDir)
{
- m_gameDir = assetDir;
+ _gameDir = assetDir;
}
void FlowHandler::SetLanguageNames(sol::as_table_t>&& src)
{
- m_languageNames = std::move(src);
+ _languageNames = std::move(src);
}
void FlowHandler::SetStrings(sol::nested>>&& src)
{
- if (m_translationsMap.empty())
+ if (_translationMap.empty())
{
- m_translationsMap = std::move(src);
+ _translationMap = std::move(src);
}
else
{
for (auto& stringPair : src.value())
- m_translationsMap.insert_or_assign(stringPair.first, stringPair.second);
+ _translationMap.insert_or_assign(stringPair.first, stringPair.second);
}
}
void FlowHandler::SetSettings(Settings const & src)
{
- m_settings = src;
+ _settings = src;
}
void FlowHandler::SetAnimations(Animations const& src)
@@ -339,10 +339,10 @@ void FlowHandler::SetTotalSecretCount(int secretsNumber)
void FlowHandler::LoadFlowScript()
{
- m_handler.ExecuteScript(m_gameDir + "Scripts/Gameflow.lua");
- m_handler.ExecuteScript(m_gameDir + "Scripts/SystemStrings.lua", true);
- m_handler.ExecuteScript(m_gameDir + "Scripts/Strings.lua", true);
- m_handler.ExecuteScript(m_gameDir + "Scripts/Settings.lua", true);
+ _handler.ExecuteScript(_gameDir + "Scripts/Gameflow.lua");
+ _handler.ExecuteScript(_gameDir + "Scripts/SystemStrings.lua", true);
+ _handler.ExecuteScript(_gameDir + "Scripts/Strings.lua", true);
+ _handler.ExecuteScript(_gameDir + "Scripts/Settings.lua", true);
SetScriptErrorMode(GetSettings()->ErrorMode);
@@ -359,19 +359,19 @@ void FlowHandler::LoadFlowScript()
char const * FlowHandler::GetString(const char* id) const
{
- if (!ScriptAssert(m_translationsMap.find(id) != m_translationsMap.end(), std::string{ "Couldn't find string " } + id))
+ if (!ScriptAssert(_translationMap.find(id) != _translationMap.end(), std::string{ "Couldn't find string " } + id))
{
return id;
}
else
{
- return m_translationsMap.at(std::string(id)).at(0).c_str();
+ return _translationMap.at(std::string(id)).at(0).c_str();
}
}
Settings* FlowHandler::GetSettings()
{
- return &m_settings;
+ return &_settings;
}
Level* FlowHandler::GetLevel(int id)
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.h b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.h
index b6aa5a417..84b267d36 100644
--- a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.h
+++ b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.h
@@ -1,29 +1,27 @@
#pragma once
#include
+#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
+#include "Scripting/Include/ScriptInterfaceGame.h"
#include "Scripting/Internal/LanguageScript.h"
#include "Scripting/Internal/LuaHandler.h"
-#include "Scripting/Internal/TEN/Logic/LogicHandler.h"
#include "Scripting/Internal/TEN/Color/Color.h"
+#include "Scripting/Internal/TEN/Logic/LogicHandler.h"
+#include "Scripting/Internal/TEN/Flow/Animations/Animations.h"
#include "Scripting/Internal/TEN/Flow/Level/FlowLevel.h"
#include "Scripting/Internal/TEN/Flow/Settings/Settings.h"
-#include "Scripting/Internal/TEN/Flow/Animations/Animations.h"
-#include "Scripting/Include/ScriptInterfaceGame.h"
-#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
class FlowHandler : public ScriptInterfaceFlowHandler
{
private:
- Settings m_settings;
+ LuaHandler _handler;
+ Settings _settings = {};
+ std::string _gameDir = {};
- std::unordered_map> m_translationsMap;
- std::vector m_languageNames;
+ std::map _moveableMap = {};
- std::map m_itemsMap;
-
- std::string m_gameDir;
-
- LuaHandler m_handler;
+ std::unordered_map> _translationMap = {};
+ std::vector _languageNames = {};
void PrepareInventoryObjects();
@@ -91,12 +89,13 @@ public:
bool HasCrawlExtended() const override { return Anims.HasCrawlExtended; }
bool HasCrouchRoll() const override { return Anims.HasCrouchRoll; }
bool HasCrawlspaceDive() const override { return Anims.HasCrawlspaceDive; }
- bool HasMonkeyAutoJump() const override { return Anims.HasMonkeyAutoJump; }
bool HasAFKPose() const override { return Anims.HasPose; }
bool HasOverhangClimb() const override { return Anims.HasOverhangClimb; }
bool HasSlideExtended() const override { return Anims.HasSlideExtended; }
bool HasSprintJump() const override { return Anims.HasSprintJump; }
bool HasLedgeJumps() const override { return Anims.HasLedgeJumps; }
bool DoFlow() override;
-};
+ // NOTE: Removed. Keep for now to maintain compatibility. -- Sezz 2024.06.06
+ bool HasAutoMonkeySwingJump() const override { return Anims.HasAutoMonkeySwingJump; }
+};
diff --git a/TombEngine/Scripting/Internal/TEN/Strings/StringsHandler.cpp b/TombEngine/Scripting/Internal/TEN/Strings/StringsHandler.cpp
index 2f34efd13..e90ea50b6 100644
--- a/TombEngine/Scripting/Internal/TEN/Strings/StringsHandler.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Strings/StringsHandler.cpp
@@ -16,7 +16,7 @@ Display strings.
StringsHandler::StringsHandler(sol::state* lua, sol::table& parent) :
LuaHandler(lua)
{
- auto table = sol::table(m_lua->lua_state(), sol::create);
+ auto table = sol::table(_lua->lua_state(), sol::create);
parent.set(ScriptReserved_Strings, table);
/***
diff --git a/TombEngine/Specific/configuration.cpp b/TombEngine/Specific/configuration.cpp
index 6e0b39d26..8d479c44f 100644
--- a/TombEngine/Specific/configuration.cpp
+++ b/TombEngine/Specific/configuration.cpp
@@ -230,6 +230,7 @@ bool SaveConfiguration()
// Set Gameplay keys.
if (SetBoolRegKey(gameplayKey, REGKEY_ENABLE_SUBTITLES, g_Configuration.EnableSubtitles) != ERROR_SUCCESS ||
+ SetBoolRegKey(gameplayKey, REGKEY_ENABLE_AUTO_MONKEY_JUMP, g_Configuration.EnableAutoMonkeySwingJump) != ERROR_SUCCESS ||
SetBoolRegKey(gameplayKey, REGKEY_ENABLE_AUTO_TARGETING, g_Configuration.EnableAutoTargeting) != ERROR_SUCCESS ||
SetBoolRegKey(gameplayKey, REGKEY_ENABLE_TARGET_HIGHLIGHTER, g_Configuration.EnableTargetHighlighter) != ERROR_SUCCESS ||
SetBoolRegKey(gameplayKey, REGKEY_ENABLE_RUMBLE, g_Configuration.EnableRumble) != ERROR_SUCCESS ||
@@ -322,6 +323,7 @@ void InitDefaultConfiguration()
g_Configuration.SfxVolume = 100;
g_Configuration.EnableSubtitles = true;
+ g_Configuration.EnableAutoMonkeySwingJump = false;
g_Configuration.EnableAutoTargeting = true;
g_Configuration.EnableTargetHighlighter = true;
g_Configuration.EnableRumble = true;
@@ -419,6 +421,7 @@ bool LoadConfiguration()
return false;
}
+ bool enableAutoMonkeySwingJump = false;
bool enableSubtitles = true;
bool enableAutoTargeting = true;
bool enableTargetHighlighter = true;
@@ -426,7 +429,8 @@ bool LoadConfiguration()
bool enableThumbstickCamera = true;
// Load Gameplay keys.
- if (GetBoolRegKey(gameplayKey, REGKEY_ENABLE_SUBTITLES, &enableSubtitles, true) != ERROR_SUCCESS ||
+ if (GetBoolRegKey(gameplayKey, REGKEY_ENABLE_AUTO_MONKEY_JUMP, &enableAutoMonkeySwingJump, true) != ERROR_SUCCESS ||
+ GetBoolRegKey(gameplayKey, REGKEY_ENABLE_SUBTITLES, &enableSubtitles, true) != ERROR_SUCCESS ||
GetBoolRegKey(gameplayKey, REGKEY_ENABLE_AUTO_TARGETING, &enableAutoTargeting, true) != ERROR_SUCCESS ||
GetBoolRegKey(gameplayKey, REGKEY_ENABLE_TARGET_HIGHLIGHTER, &enableTargetHighlighter, true) != ERROR_SUCCESS ||
GetBoolRegKey(gameplayKey, REGKEY_ENABLE_RUMBLE, &enableRumble, true) != ERROR_SUCCESS ||
@@ -507,11 +511,12 @@ bool LoadConfiguration()
g_Configuration.SfxVolume = sfxVolume;
g_Configuration.SoundDevice = soundDevice;
+ g_Configuration.EnableSubtitles = enableSubtitles;
+ g_Configuration.EnableAutoMonkeySwingJump = enableAutoMonkeySwingJump;
g_Configuration.EnableAutoTargeting = enableAutoTargeting;
g_Configuration.EnableTargetHighlighter = enableTargetHighlighter;
g_Configuration.EnableRumble = enableRumble;
g_Configuration.EnableThumbstickCamera = enableThumbstickCamera;
- g_Configuration.EnableSubtitles = enableSubtitles;
g_Configuration.MouseSensitivity = mouseSensitivity;
g_Configuration.MouseSmoothing = mouseSmoothing;
diff --git a/TombEngine/Specific/configuration.h b/TombEngine/Specific/configuration.h
index cf10f970c..ab3694e01 100644
--- a/TombEngine/Specific/configuration.h
+++ b/TombEngine/Specific/configuration.h
@@ -33,6 +33,7 @@ constexpr auto REGKEY_SFX_VOLUME = "SfxVolume";
// Gameplay keys
constexpr auto REGKEY_ENABLE_SUBTITLES = "EnableSubtitles";
+constexpr auto REGKEY_ENABLE_AUTO_MONKEY_JUMP = "EnableAutoMonkeySwingJump";
constexpr auto REGKEY_ENABLE_AUTO_TARGETING = "EnableAutoTargeting";
constexpr auto REGKEY_ENABLE_TARGET_HIGHLIGHTER = "EnableTargetHighlighter";
constexpr auto REGKEY_ENABLE_RUMBLE = "EnableRumble";
@@ -69,6 +70,7 @@ struct GameConfiguration
// Gameplay
bool EnableSubtitles = false;
+ bool EnableAutoMonkeySwingJump = false;
bool EnableAutoTargeting = false;
bool EnableTargetHighlighter = false;
bool EnableRumble = false;
From 22176d05f5f8b33a9f9ab6a03bf291b6f099d6cd Mon Sep 17 00:00:00 2001
From: Sezz
Date: Thu, 6 Jun 2024 11:46:43 +1000
Subject: [PATCH 208/410] Update CHANGELOG.md
---
CHANGELOG.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f8ffd5f17..3bb3f8a02 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -23,6 +23,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor):
### Lua API changes
* Added Inventory.GetUsedItem(), Inventory.SetUsedItem() and Inventory.ClearUsedItem() functions.
+* Removed anims.monkeyAutoJump. It is now a player menu configuration.
## [Version 1.4](https://github.com/TombEngine/TombEditorReleases/releases/tag/v1.7.1) - 2024-04-21
From a34bfaa89b6d85998c3867e3a36e949e29ce80c5 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Tue, 11 Jun 2024 12:07:48 +1000
Subject: [PATCH 209/410] Fix project build paths again
---
TombEngine/TombEngine.vcxproj | 2 ++
1 file changed, 2 insertions(+)
diff --git a/TombEngine/TombEngine.vcxproj b/TombEngine/TombEngine.vcxproj
index 94bbf469b..c4de82af7 100644
--- a/TombEngine/TombEngine.vcxproj
+++ b/TombEngine/TombEngine.vcxproj
@@ -235,6 +235,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
/Zc:__cplusplus /experimental:external /external:anglebrackets
4018;4244;4996;%(DisableSpecificWarnings)
true
+ $(IntDir)/%(RelativeDir)/
Console
@@ -300,6 +301,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x86\*.dll" "$(TargetDir)"
/Zc:__cplusplus /experimental:external /external:anglebrackets
4018;4244;4996;%(DisableSpecificWarnings)
true
+ $(IntDir)/%(RelativeDir)/
Console
From 87b5e8390140c5b881613a1ed814525a705b6612 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 19 Jun 2024 15:03:33 +1000
Subject: [PATCH 210/410] Remove unnecessary framework define; add newlines
between label comments to avoid inappropriate tooltips
---
TombEngine/Game/Hud/PickupSummary.cpp | 5 ++++-
TombEngine/Game/Hud/PickupSummary.h | 4 ++++
TombEngine/Game/Hud/Speedometer.h | 3 +++
TombEngine/Game/Hud/StatusBars.h | 4 ++++
TombEngine/Game/Hud/TargetHighlighter.h | 9 +++++++++
TombEngine/Game/Lara/lara_jump.cpp | 20 ++++++++++----------
TombEngine/Game/Lara/lara_tests.cpp | 4 ++--
TombEngine/framework.h | 6 ------
8 files changed, 36 insertions(+), 19 deletions(-)
diff --git a/TombEngine/Game/Hud/PickupSummary.cpp b/TombEngine/Game/Hud/PickupSummary.cpp
index bc816aafc..8bd2fc4fd 100644
--- a/TombEngine/Game/Hud/PickupSummary.cpp
+++ b/TombEngine/Game/Hud/PickupSummary.cpp
@@ -213,7 +213,10 @@ namespace TEN::Hud
_displayPickups.erase(
std::remove_if(
_displayPickups.begin(), _displayPickups.end(),
- [](const DisplayPickup& pickup) { return ((pickup.Life <= 0.0f) && pickup.IsOffscreen()); }),
+ [](const DisplayPickup& pickup)
+ {
+ return ((pickup.Life <= 0.0f) && pickup.IsOffscreen());
+ }),
_displayPickups.end());
}
diff --git a/TombEngine/Game/Hud/PickupSummary.h b/TombEngine/Game/Hud/PickupSummary.h
index a1c0b012f..fc56e09f1 100644
--- a/TombEngine/Game/Hud/PickupSummary.h
+++ b/TombEngine/Game/Hud/PickupSummary.h
@@ -33,14 +33,17 @@ namespace TEN::Hud
{
private:
// Constants
+
static constexpr auto DISPLAY_PICKUP_COUNT_MAX = 64;
static constexpr auto DISPLAY_PICKUP_COUNT_ARG_DEFAULT = 1;
// Members
+
std::vector _displayPickups = {};
public:
// Utilities
+
void AddDisplayPickup(GAME_OBJECT_ID objectID, const Vector2& origin, unsigned int count = DISPLAY_PICKUP_COUNT_ARG_DEFAULT);
void AddDisplayPickup(GAME_OBJECT_ID objectID, const Vector3& pos, unsigned int count = DISPLAY_PICKUP_COUNT_ARG_DEFAULT);
@@ -50,6 +53,7 @@ namespace TEN::Hud
private:
// Helpers
+
std::vector GetStackPositions() const;
DisplayPickup& GetNewDisplayPickup();
void ClearInactiveDisplayPickups();
diff --git a/TombEngine/Game/Hud/Speedometer.h b/TombEngine/Game/Hud/Speedometer.h
index 164d652a2..8795311d0 100644
--- a/TombEngine/Game/Hud/Speedometer.h
+++ b/TombEngine/Game/Hud/Speedometer.h
@@ -6,9 +6,11 @@ namespace TEN::Hud
{
private:
// Constants
+
static constexpr auto LIFE_MAX = 0.75f;
// Members
+
bool _hasValueUpdated = false;
float _value = 0.0f;
@@ -18,6 +20,7 @@ namespace TEN::Hud
public:
// Utilities
+
void UpdateValue(float value);
void Update();
diff --git a/TombEngine/Game/Hud/StatusBars.h b/TombEngine/Game/Hud/StatusBars.h
index 8ba931cb2..783e4648f 100644
--- a/TombEngine/Game/Hud/StatusBars.h
+++ b/TombEngine/Game/Hud/StatusBars.h
@@ -26,6 +26,7 @@ namespace TEN::Hud
{
private:
// Members
+
StatusBar _airBar = {};
StatusBar _exposureBar = {};
StatusBar _healthBar = {};
@@ -35,6 +36,7 @@ namespace TEN::Hud
public:
// Utilities
+
void Initialize(const ItemInfo& item);
void Update(const ItemInfo& item);
void Draw(const ItemInfo& item) const;
@@ -42,12 +44,14 @@ namespace TEN::Hud
private:
// Update helpers
+
void UpdateAirBar(const ItemInfo& item);
void UpdateExposureBar(const ItemInfo& item);
void UpdateHealthBar(const ItemInfo& item);
void UpdateStaminaBar(const ItemInfo& item);
// Draw helpers
+
void DrawStatusBar(float value, float criticalValue, const RendererHudBar& rHudBar, GAME_OBJECT_ID textureID, int frame, bool isPoisoned) const;
void DrawAirBar() const;
void DrawExposureBar() const;
diff --git a/TombEngine/Game/Hud/TargetHighlighter.h b/TombEngine/Game/Hud/TargetHighlighter.h
index b62c5b3df..4059d1f5b 100644
--- a/TombEngine/Game/Hud/TargetHighlighter.h
+++ b/TombEngine/Game/Hud/TargetHighlighter.h
@@ -15,11 +15,13 @@ namespace TEN::Hud
public:
// Constants
+
static constexpr auto COLOR_RED = Color(1.0f, 0.2f, 0.2f);
static constexpr auto COLOR_GRAY = Color(0.7f, 0.7f, 0.7f, 0.7f);
static constexpr auto SEGMENT_COUNT = 4;
// Members
+
bool IsActive = false;
bool IsPrimary = false;
@@ -35,15 +37,18 @@ namespace TEN::Hud
std::array Segments = {};
// Getters
+
float GetScale(float cameraDist) const;
float GetRadius() const;
Vector2 GetPositionOffset(short orientOffset) const;
// Setters
+
void SetPrimary();
void SetPeripheral();
// Utilities
+
void Update(const Vector3& targetPos, bool isActive, bool doPulse);
void Draw() const;
};
@@ -52,19 +57,23 @@ namespace TEN::Hud
{
private:
// Members
+
std::unordered_map _crosshairs = {}; // Key = item number.
public:
// Utilities
+
void Update(const ItemInfo& playerItem);
void Draw() const;
void Clear();
private:
// Update helpers
+
void Update(const std::vector& itemNumbers);
// Object helpers
+
CrosshairData& GetNewCrosshair(int itemNumber);
void AddCrosshair(int itemNumber, const Vector3& targetPos);
void ClearInactiveCrosshairs();
diff --git a/TombEngine/Game/Lara/lara_jump.cpp b/TombEngine/Game/Lara/lara_jump.cpp
index b84506aac..5b940035f 100644
--- a/TombEngine/Game/Lara/lara_jump.cpp
+++ b/TombEngine/Game/Lara/lara_jump.cpp
@@ -64,7 +64,7 @@ void lara_as_jump_forward(ItemInfo* item, CollisionInfo* coll)
{
DoLaraFallDamage(item);
- if (item->HitPoints <= 0) USE_FEATURE_IF_CPP20([[unlikely]])
+ if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
else if (IsHeld(In::Forward) && !IsHeld(In::Walk) &&
player.Control.WaterStatus != WaterStatus::Wade)
@@ -146,7 +146,7 @@ void lara_as_freefall(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
- else USE_FEATURE_IF_CPP20([[likely]])
+ else
item->Animation.TargetState = LS_IDLE;
SetLaraLand(item, coll);
@@ -202,7 +202,7 @@ void lara_as_reach(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
- else USE_FEATURE_IF_CPP20([[likely]])
+ else
item->Animation.TargetState = LS_IDLE;
SetLaraLand(item, coll);
@@ -414,7 +414,7 @@ void lara_as_jump_back(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
- else USE_FEATURE_IF_CPP20([[likely]])
+ else
item->Animation.TargetState = LS_IDLE;
SetLaraLand(item, coll);
@@ -468,7 +468,7 @@ void lara_as_jump_right(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
- else USE_FEATURE_IF_CPP20([[likely]])
+ else
item->Animation.TargetState = LS_IDLE;
SetLaraLand(item, coll);
@@ -523,7 +523,7 @@ void lara_as_jump_left(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
- else USE_FEATURE_IF_CPP20([[likely]])
+ else
item->Animation.TargetState = LS_IDLE;
SetLaraLand(item, coll);
@@ -576,7 +576,7 @@ void lara_as_jump_up(ItemInfo* item, CollisionInfo* coll)
{
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
- else USE_FEATURE_IF_CPP20([[likely]])
+ else
item->Animation.TargetState = LS_IDLE;
SetLaraLand(item, coll);
@@ -673,7 +673,7 @@ void lara_as_fall_back(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
- else USE_FEATURE_IF_CPP20([[likely]])
+ else
item->Animation.TargetState = LS_IDLE;
SetLaraLand(item, coll);
@@ -749,7 +749,7 @@ void lara_as_swan_dive(ItemInfo* item, CollisionInfo* coll)
item->Animation.TargetState = LS_CROUCH_IDLE;
TranslateItem(item, coll->Setup.ForwardAngle, CLICK(0.5f)); // HACK: Move forward to avoid standing up or falling out on an edge.
}
- else USE_FEATURE_IF_CPP20([[likely]])
+ else
item->Animation.TargetState = LS_IDLE;
SetLaraLand(item, coll);
@@ -823,7 +823,7 @@ void lara_as_freefall_dive(ItemInfo* item, CollisionInfo* coll)
item->Animation.TargetState = LS_DEATH;
Rumble(0.5f, 0.2f);
}
- else USE_FEATURE_IF_CPP20([[likely]])
+ else
item->Animation.TargetState = LS_IDLE;
SetLaraLand(item, coll);
diff --git a/TombEngine/Game/Lara/lara_tests.cpp b/TombEngine/Game/Lara/lara_tests.cpp
index 97cd5d730..ee7b8d809 100644
--- a/TombEngine/Game/Lara/lara_tests.cpp
+++ b/TombEngine/Game/Lara/lara_tests.cpp
@@ -1710,7 +1710,7 @@ CrawlVaultTestResult TestLaraCrawlVault(ItemInfo* item, CollisionInfo* coll)
{
if (IsHeld(In::Crouch) && TestLaraCrawlDownStep(item, coll).Success)
crawlVaultResult.TargetState = LS_CRAWL_STEP_DOWN;
- else USE_FEATURE_IF_CPP20([[likely]])
+ else
crawlVaultResult.TargetState = LS_CRAWL_EXIT_STEP_DOWN;
crawlVaultResult.Success = HasStateDispatch(item, crawlVaultResult.TargetState);
@@ -1723,7 +1723,7 @@ CrawlVaultTestResult TestLaraCrawlVault(ItemInfo* item, CollisionInfo* coll)
{
if (IsHeld(In::Walk))
crawlVaultResult.TargetState = LS_CRAWL_EXIT_FLIP;
- else USE_FEATURE_IF_CPP20([[likely]])
+ else
crawlVaultResult.TargetState = LS_CRAWL_EXIT_JUMP;
crawlVaultResult.Success = HasStateDispatch(item, crawlVaultResult.TargetState);
diff --git a/TombEngine/framework.h b/TombEngine/framework.h
index 9f5b27cb4..133da0a80 100644
--- a/TombEngine/framework.h
+++ b/TombEngine/framework.h
@@ -23,10 +23,4 @@
using namespace DirectX;
using namespace DirectX::SimpleMath;
-#if __cplusplus >= 202002L
-#define USE_FEATURE_IF_CPP20(x) x
-#else
-#define USE_FEATURE_IF_CPP20(x)
-#endif
-
constexpr auto NO_VALUE = -1;
From 49b014bc88b3636925ee23528f2b986600fc33be Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 19 Jun 2024 15:05:03 +1000
Subject: [PATCH 211/410] Avoid inappropriate tooltips
---
TombEngine/Math/Constants.h | 2 ++
TombEngine/Math/Geometry.h | 8 ++++++++
TombEngine/Math/Random.h | 5 +++++
3 files changed, 15 insertions(+)
diff --git a/TombEngine/Math/Constants.h b/TombEngine/Math/Constants.h
index 2e2a1e26d..7147986d0 100644
--- a/TombEngine/Math/Constants.h
+++ b/TombEngine/Math/Constants.h
@@ -4,6 +4,7 @@
//namespace TEN::Math
//{
// Math constants
+
constexpr auto PI = 3.14159265358979323846264338327950288419716939937510f;
constexpr auto PI_MUL_2 = PI * 2;
constexpr auto PI_DIV_2 = PI / 2;
@@ -16,6 +17,7 @@
constexpr auto CUBE = [](auto x) { return (x * x * x); };
// World constants
+
constexpr auto BLOCK_UNIT = 1024;
constexpr auto NO_HEIGHT = INT_MIN + UCHAR_MAX;
constexpr auto MAX_HEIGHT = INT_MIN + 1; // NOTE: +1 prevents issues with sign change.
diff --git a/TombEngine/Math/Geometry.h b/TombEngine/Math/Geometry.h
index 25a00ed9a..f47482a01 100644
--- a/TombEngine/Math/Geometry.h
+++ b/TombEngine/Math/Geometry.h
@@ -8,6 +8,7 @@ class Vector3i;
namespace TEN::Math::Geometry
{
// Integer-based point translation
+
Vector3i TranslatePoint(const Vector3i& point, short headingAngle, float forward, float down = 0.0f, float right = 0.0f, const Vector3& axis = Vector3::UnitY);
Vector3i TranslatePoint(const Vector3i& point, short headingAngle, const Vector3i& relOffset, const Vector3& axis = Vector3::UnitY);
Vector3i TranslatePoint(const Vector3i& point, const EulerAngles& orient, const Vector3i& relOffset);
@@ -16,6 +17,7 @@ namespace TEN::Math::Geometry
Vector3i TranslatePoint(const Vector3i& point, const Vector3& dir, float dist);
// Float-based point translation
+
Vector3 TranslatePoint(const Vector3& point, short headingAngle, float forward, float down = 0.0f, float right = 0.0f, const Vector3& axis = Vector3::UnitY);
Vector3 TranslatePoint(const Vector3& point, short headingAngle, const Vector3& relOffset, const Vector3& axis = Vector3::UnitY);
Vector3 TranslatePoint(const Vector3& point, const EulerAngles& orient, const Vector3& relOffset);
@@ -24,15 +26,18 @@ namespace TEN::Math::Geometry
Vector3 TranslatePoint(const Vector3& point, const Vector3& dir, float dist);
// Rotation
+
Vector3 RotatePoint(const Vector3& point, const EulerAngles& rot);
Vector3 RotatePoint(const Vector3& point, const AxisAngle& rot);
// Angle getters
+
short GetShortestAngle(short fromAngle, short toAngle);
short GetSurfaceSlopeAngle(const Vector3& normal, const Vector3& axis = Vector3::UnitY);
short GetSurfaceAspectAngle(const Vector3& normal, const Vector3& axis = Vector3::UnitY);
// Misc. getters
+
float GetDistanceToLine(const Vector3& origin, const Vector3& linePoint0, const Vector3& linePoint1);
Vector3 GetClosestPointOnLine(const Vector3& origin, const Vector3& linePoint0, const Vector3& linePoint1);
Vector3 GetClosestPointOnLinePerp(const Vector3& origin, const Vector3& linePoint0, const Vector3& linePoint1, const Vector3& axis = Vector3::UnitY);
@@ -41,10 +46,12 @@ namespace TEN::Math::Geometry
BoundingBox GetBoundingBox(const std::vector& points);
// Converters
+
Quaternion ConvertDirectionToQuat(const Vector3& dir);
Vector3 ConvertQuatToDirection(const Quaternion& quat);
// Point relation inquirers
+
bool IsPointInFront(const Pose& pose, const Vector3& target);
bool IsPointInFront(const Vector3& origin, const Vector3& target, const EulerAngles& orient);
bool IsPointInFront(const Vector3& origin, const Vector3& target, const Vector3& refPoint);
@@ -56,5 +63,6 @@ namespace TEN::Math::Geometry
bool IsPointInSphere(const Vector3& point, const BoundingSphere& sphere);
// Intersection inquirers
+
bool CircleIntersects(const Vector3& circle0, const Vector3& circle1);
}
diff --git a/TombEngine/Math/Random.h b/TombEngine/Math/Random.h
index fd7508d35..97b783993 100644
--- a/TombEngine/Math/Random.h
+++ b/TombEngine/Math/Random.h
@@ -5,16 +5,19 @@ class EulerAngles;
namespace TEN::Math::Random
{
// Value generation
+
int GenerateInt(int low = 0, int high = SHRT_MAX);
float GenerateFloat(float low = 0.0f, float high = 1.0f);
short GenerateAngle(short low = SHRT_MIN, short high = SHRT_MAX);
// 2D geometric generation
+
Vector2 GenerateDirection2D();
Vector2 GeneratePoint2DInSquare(const Vector2& pos, short orient, float apothem);
Vector2 GeneratePoint2DInCircle(const Vector2& pos, float radius);
// 3D geometric generation
+
Vector3 GenerateDirection();
Vector3 GenerateDirectionInCone(const Vector3& dir, float semiangleInDeg);
Vector3 GeneratePointInBox(const BoundingOrientedBox& box);
@@ -22,5 +25,7 @@ namespace TEN::Math::Random
Vector3 GeneratePointOnSphere(const BoundingSphere& sphere);
Vector3 GeneratePointInSpheroid(const Vector3& center, const EulerAngles& orient, const Vector3& semiMajorAxis);
+ // Probability
+
bool TestProbability(float prob);
}
From 2e6db4e01ce871c47010c186c78c5a13b7e6128b Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 19 Jun 2024 15:29:46 +1000
Subject: [PATCH 212/410] Add TEN::Debug namespace
---
TombEngine/Game/Hud/PickupSummary.cpp | 2 +-
TombEngine/Game/Lara/lara_struct.h | 2 +-
TombEngine/Game/animation.cpp | 2 +-
TombEngine/Game/debug/debug.cpp | 103 +++++++++---------
TombEngine/Game/debug/debug.h | 63 ++++++-----
TombEngine/Game/effects/Streamer.cpp | 8 +-
TombEngine/Game/effects/effects.h | 2 +-
TombEngine/Game/savegame.cpp | 4 +-
TombEngine/Math/Solvers.cpp | 2 +-
TombEngine/Objects/TR5/Trap/LaserBarrier.cpp | 2 +-
.../Internal/TEN/Flow/Level/FlowLevel.cpp | 6 +-
TombEngine/TombEngine.vcxproj | 4 +-
TombEngine/framework.h | 2 +
13 files changed, 106 insertions(+), 96 deletions(-)
diff --git a/TombEngine/Game/Hud/PickupSummary.cpp b/TombEngine/Game/Hud/PickupSummary.cpp
index 8bd2fc4fd..f38c0f6b6 100644
--- a/TombEngine/Game/Hud/PickupSummary.cpp
+++ b/TombEngine/Game/Hud/PickupSummary.cpp
@@ -196,7 +196,7 @@ namespace TEN::Hud
DisplayPickup& PickupSummaryController::GetNewDisplayPickup()
{
- assertion(_displayPickups.size() <= DISPLAY_PICKUP_COUNT_MAX, "Display pickup overflow.");
+ TENAssert(_displayPickups.size() <= DISPLAY_PICKUP_COUNT_MAX, "Display pickup overflow.");
// Add and return new display pickup.
if (_displayPickups.size() < DISPLAY_PICKUP_COUNT_MAX)
diff --git a/TombEngine/Game/Lara/lara_struct.h b/TombEngine/Game/Lara/lara_struct.h
index fa21dd987..1f1758096 100644
--- a/TombEngine/Game/Lara/lara_struct.h
+++ b/TombEngine/Game/Lara/lara_struct.h
@@ -1025,7 +1025,7 @@ public:
Ammo& operator --()
{
- assertion(Count > 0, "Ammo count is already 0.");
+ TENAssert(Count > 0, "Ammo count is already 0.");
--Count;
return *this;
}
diff --git a/TombEngine/Game/animation.cpp b/TombEngine/Game/animation.cpp
index 3003f6292..d4f5cd6d1 100644
--- a/TombEngine/Game/animation.cpp
+++ b/TombEngine/Game/animation.cpp
@@ -506,7 +506,7 @@ const AnimFrame* GetFrame(GAME_OBJECT_ID objectID, int animNumber, int frameNumb
const auto& object = Objects[objectID];
int animIndex = object.animIndex + animNumber;
- assertion(animIndex < g_Level.Anims.size(), "GetFrame() attempted to access missing animation.");
+ TENAssert(animIndex < g_Level.Anims.size(), "GetFrame() attempted to access missing animation.");
const auto& anim = GetAnimData(object, animNumber);
diff --git a/TombEngine/Game/debug/debug.cpp b/TombEngine/Game/debug/debug.cpp
index a5102b454..a5cba1b3f 100644
--- a/TombEngine/Game/debug/debug.cpp
+++ b/TombEngine/Game/debug/debug.cpp
@@ -5,57 +5,62 @@
#include
#include
-void InitTENLog(const std::string& logDirContainingDir)
+namespace TEN::Debug
{
- // "true" means create new log file each time game is run.
- auto logPath = logDirContainingDir + "Logs/TENLog.txt";
- auto fileSink = std::make_shared(logPath, true);
-
- std::shared_ptr logger;
-
- // Set file and console log targets.
- auto consoleSink = std::make_shared();
- logger = std::make_shared(std::string{ "multi_sink" }, spdlog::sinks_init_list{ fileSink, consoleSink });
-
- spdlog::initialize_logger(logger);
- logger->set_level(spdlog::level::info);
- logger->flush_on(spdlog::level::info);
- logger->set_pattern("[%Y-%b-%d %T] [%^%l%$] %v");
-}
-
-void TENLog(std::string_view str, LogLevel level, LogConfig config, bool allowSpam)
-{
- static std::string lastString = {};
-
- if (lastString == str && !allowSpam)
- return;
-
- if constexpr (!DebugBuild)
+ void InitTENLog(const std::string& logDirContainingDir)
{
- if (LogConfig::Debug == config)
+ // "true" means create new log file each time game is run.
+ auto logPath = logDirContainingDir + "Logs/TENLog.txt";
+ auto fileSink = std::make_shared(logPath, true);
+
+ auto logger = std::shared_ptr();
+
+ // Set file and console log targets.
+ auto consoleSink = std::make_shared();
+ logger = std::make_shared(std::string("multi_sink"), spdlog::sinks_init_list{ fileSink, consoleSink });
+
+ spdlog::initialize_logger(logger);
+ logger->set_level(spdlog::level::info);
+ logger->flush_on(spdlog::level::info);
+ logger->set_pattern("[%Y-%b-%d %T] [%^%l%$] %v");
+ }
+
+ void ShutdownTENLog()
+ {
+ spdlog::shutdown();
+ }
+
+ void TENLog(const std::string_view& string, LogLevel level, LogConfig config, bool allowSpam)
+ {
+ static auto prevString = std::string();
+
+ if (prevString == string && !allowSpam)
return;
+
+ if constexpr (!DebugBuild)
+ {
+ if (config == LogConfig::Debug)
+ return;
+ }
+
+ auto logger = spdlog::get("multi_sink");
+ switch (level)
+ {
+ case LogLevel::Error:
+ logger->error(string);
+ break;
+
+ case LogLevel::Warning:
+ logger->warn(string);
+ break;
+
+ case LogLevel::Info:
+ logger->info(string);
+ break;
+ }
+
+ logger->flush();
+
+ prevString = std::string(string);
}
-
- auto logger = spdlog::get("multi_sink");
- switch (level)
- {
- case LogLevel::Error:
- logger->error(str);
- break;
- case LogLevel::Warning:
- logger->warn(str);
- break;
- case LogLevel::Info:
- logger->info(str);
- break;
- }
-
- logger->flush();
-
- lastString = std::string(str);
-}
-
-void ShutdownTENLog()
-{
- spdlog::shutdown();
}
diff --git a/TombEngine/Game/debug/debug.h b/TombEngine/Game/debug/debug.h
index c668d40e2..561a2d28a 100644
--- a/TombEngine/Game/debug/debug.h
+++ b/TombEngine/Game/debug/debug.h
@@ -9,37 +9,40 @@ constexpr bool DebugBuild = false;
#include
#include
-enum class LogLevel
+namespace TEN::Debug
{
- Error,
- Warning,
- Info
-};
-
-enum class LogConfig
-{
- Debug,
- All
-};
-
-void TENLog(std::string_view str, LogLevel level = LogLevel::Info, LogConfig config = LogConfig::All, bool allowSpam = false);
-void ShutdownTENLog();
-void InitTENLog(const std::string& logDirContainingDir);
-
-class TENScriptException : public std::runtime_error
-{
-public:
- using std::runtime_error::runtime_error;
-};
-
-inline void assertion(const bool& expr, const char* msg)
-{
- if constexpr (DebugBuild)
+ enum class LogLevel
{
- if (!expr)
+ Error,
+ Warning,
+ Info
+ };
+
+ enum class LogConfig
+ {
+ Debug,
+ All
+ };
+
+ class TENScriptException : public std::runtime_error
+ {
+ public:
+ using std::runtime_error::runtime_error;
+ };
+
+ void InitTENLog(const std::string& logDirContainingDir);
+ void ShutdownTENLog();
+ void TENLog(const std::string_view& string, LogLevel level = LogLevel::Info, LogConfig config = LogConfig::All, bool allowSpam = false);
+
+ inline void TENAssert(const bool& cond, const char* msg)
+ {
+ if constexpr (DebugBuild)
{
- TENLog(msg, LogLevel::Error);
- throw std::runtime_error(msg);
+ if (!cond)
+ {
+ TENLog(msg, LogLevel::Error);
+ throw std::runtime_error(msg);
+ }
}
- }
-};
+ };
+}
diff --git a/TombEngine/Game/effects/Streamer.cpp b/TombEngine/Game/effects/Streamer.cpp
index ec7bad158..ae9f8ed55 100644
--- a/TombEngine/Game/effects/Streamer.cpp
+++ b/TombEngine/Game/effects/Streamer.cpp
@@ -99,7 +99,7 @@ namespace TEN::Effects::Streamer
Streamer::StreamerSegment& Streamer::GetNewSegment()
{
- assertion(Segments.size() <= SEGMENT_COUNT_MAX, "Streamer segment count overflow.");
+ TENAssert(Segments.size() <= SEGMENT_COUNT_MAX, "Streamer segment count overflow.");
// Clear oldest segment if vector is full.
if (Segments.size() == SEGMENT_COUNT_MAX)
@@ -112,7 +112,7 @@ namespace TEN::Effects::Streamer
void StreamerModule::AddStreamer(int tag, const Vector3& pos, const Vector3& dir, short orient, const Vector4& color,
float width, float life, float vel, float scaleRate, short rot, int flags)
{
- assertion(Pools.size() <= POOL_COUNT_MAX, "Streamer pool count overflow.");
+ TENAssert(Pools.size() <= POOL_COUNT_MAX, "Streamer pool count overflow.");
// Return early if pool map is full and element with tag key doesn't already exist.
if (Pools.size() == POOL_COUNT_MAX && !Pools.count(tag))
@@ -150,7 +150,7 @@ namespace TEN::Effects::Streamer
Streamer& StreamerModule::GetStreamer(int tag)
{
auto& pool = GetPool(tag);
- assertion(pool.size() <= STREAMER_COUNT_MAX, "Streamer pool size overflow.");
+ TENAssert(pool.size() <= STREAMER_COUNT_MAX, "Streamer pool size overflow.");
// Return most recent streamer iteration if it exists and is unbroken.
if (!pool.empty())
@@ -197,7 +197,7 @@ namespace TEN::Effects::Streamer
void StreamerEffectController::Spawn(int itemNumber, int tag, const Vector3& pos, const Vector3& direction, short orient, const Vector4& color,
float width, float life, float vel, float scaleRate, short rot, int flags)
{
- assertion(Modules.size() <= MODULE_COUNT_MAX, "Streamer module count overflow.");
+ TENAssert(Modules.size() <= MODULE_COUNT_MAX, "Streamer module count overflow.");
// Return early if module map is full and element with itemNumber key doesn't already exist.
if (Modules.size() == MODULE_COUNT_MAX && !Modules.count(itemNumber))
diff --git a/TombEngine/Game/effects/effects.h b/TombEngine/Game/effects/effects.h
index 2b77640a0..0613feaf1 100644
--- a/TombEngine/Game/effects/effects.h
+++ b/TombEngine/Game/effects/effects.h
@@ -211,7 +211,7 @@ extern FX_INFO EffectList[NUM_EFFECTS];
template
TEffect& GetNewEffect(std::vector& effects, unsigned int countMax)
{
- assertion(effects.size() <= countMax, "Too many particle effects.");
+ TENAssert(effects.size() <= countMax, "Too many particle effects.");
// Add and return new effect.
if (effects.size() < countMax)
diff --git a/TombEngine/Game/savegame.cpp b/TombEngine/Game/savegame.cpp
index 98100796f..9c821dd10 100644
--- a/TombEngine/Game/savegame.cpp
+++ b/TombEngine/Game/savegame.cpp
@@ -2010,7 +2010,7 @@ static void ParseEffects(const Save::SaveGame* s)
// Restore soundtracks.
for (int i = 0; i < s->soundtracks()->size(); i++)
{
- assertion(i < (int)SoundTrackType::Count, "Soundtrack type count was changed");
+ TENAssert(i < (int)SoundTrackType::Count, "Soundtrack type count was changed");
auto track = s->soundtracks()->Get(i);
PlaySoundTrack(track->name()->str(), (SoundTrackType)i, track->position());
@@ -2228,7 +2228,7 @@ static void ParseLevel(const Save::SaveGame* s, bool hubMode)
// Restore action queue.
for (int i = 0; i < s->action_queue()->size(); i++)
{
- assertion(i < ActionQueue.size(), "Action queue size was changed");
+ TENAssert(i < ActionQueue.size(), "Action queue size was changed");
ActionQueue[i] = (QueueState)s->action_queue()->Get(i);
}
diff --git a/TombEngine/Math/Solvers.cpp b/TombEngine/Math/Solvers.cpp
index 017b70d15..0b6b3da43 100644
--- a/TombEngine/Math/Solvers.cpp
+++ b/TombEngine/Math/Solvers.cpp
@@ -56,7 +56,7 @@ namespace TEN::Math::Solvers
float a = flipXY ? (scaledTarget.y - origin.y) : (scaledTarget.x - origin.x);
float b = flipXY ? (scaledTarget.x - origin.x) : (scaledTarget.y - origin.y);
- assertion(abs(a) >= EPSILON, "SolveIK2D() failed.");
+ TENAssert(abs(a) >= EPSILON, "SolveIK2D() failed.");
float m = ((SQUARE(length0) - SQUARE(length1)) + (SQUARE(a) + SQUARE(b))) / (2.0f * a);
float n = b / a;
diff --git a/TombEngine/Objects/TR5/Trap/LaserBarrier.cpp b/TombEngine/Objects/TR5/Trap/LaserBarrier.cpp
index cf44a2b01..cece3c862 100644
--- a/TombEngine/Objects/TR5/Trap/LaserBarrier.cpp
+++ b/TombEngine/Objects/TR5/Trap/LaserBarrier.cpp
@@ -60,7 +60,7 @@ namespace TEN::Traps::TR5
auto beamOffset = Vector3(0.0f, -LaserBarrierBeam::HEIGHT, 0.0f);
for (auto& beam : Beams)
{
- assertion(beam.VertexPoints.size() == baseVertices.size(), "Laser barrier beam vertex count out of sync.");
+ TENAssert(beam.VertexPoints.size() == baseVertices.size(), "Laser barrier beam vertex count out of sync.");
for (int i = 0; i < beam.VertexPoints.size(); i++)
beam.VertexPoints[i] = baseVertices[i] + beamOffset;
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp b/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp
index 55067e76a..31cc26320 100644
--- a/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp
@@ -167,7 +167,7 @@ void Level::SetLevelFarView(short val)
RGBAColor8Byte Level::GetSkyLayerColor(int index) const
{
- assertion(index == 0 || index == 1, "Sky layer index must be 0 or 1.");
+ TENAssert(index == 0 || index == 1, "Sky layer index must be 0 or 1.");
if (index == 0)
{
@@ -181,7 +181,7 @@ RGBAColor8Byte Level::GetSkyLayerColor(int index) const
bool Level::GetSkyLayerEnabled(int index) const
{
- assertion(index == 0 || index == 1, "Sky layer index must be 0 or 1.");
+ TENAssert(index == 0 || index == 1, "Sky layer index must be 0 or 1.");
if (index == 0)
{
@@ -195,7 +195,7 @@ bool Level::GetSkyLayerEnabled(int index) const
short Level::GetSkyLayerSpeed(int index) const
{
- assertion(index == 0 || index == 1, "Sky layer index must be 0 or 1.");
+ TENAssert(index == 0 || index == 1, "Sky layer index must be 0 or 1.");
if (index == 0)
{
diff --git a/TombEngine/TombEngine.vcxproj b/TombEngine/TombEngine.vcxproj
index c4de82af7..81d212c5a 100644
--- a/TombEngine/TombEngine.vcxproj
+++ b/TombEngine/TombEngine.vcxproj
@@ -340,6 +340,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
+
@@ -385,7 +386,6 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
-
@@ -869,7 +869,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
-
+
diff --git a/TombEngine/framework.h b/TombEngine/framework.h
index 133da0a80..46ce3d07a 100644
--- a/TombEngine/framework.h
+++ b/TombEngine/framework.h
@@ -23,4 +23,6 @@
using namespace DirectX;
using namespace DirectX::SimpleMath;
+using namespace TEN::Debug;
+
constexpr auto NO_VALUE = -1;
From 7248091ca9c02a14d31078ecfe4b9a2ac7b0fe17 Mon Sep 17 00:00:00 2001
From: Adngel <60930991+Adngel@users.noreply.github.com>
Date: Wed, 19 Jun 2024 12:19:39 +0200
Subject: [PATCH 213/410] Adngel several traps fixes (#1379)
* Fix: Impale animation
When I jump in the TR1 spikes, or when I'm over the emerging TR4 spikes, the value it gets is INTERSECT not CONTAINS
I think it is because the TR1 spikes are 2 clicks, it won't contain Lara's collider. And TR4 when they are emerging, also have smaller collider box, so it will neither CONTAINS Lara's collider until it get already very late (for then, Lara is already dead and doing another death animation).
Removing the condition, it will activate where is INTERSECTS or CONTAINS.
* Fix Rome Hammer damage.
It won't hurt Lara anymore while it's deactivated.
* Fix Traps Collision
Updated the code of 4blades (used by floor and ceiling versions).
Added a condition in the colliion check for non-itelligent objects (like traps) so collision will push Lara only for the traps that have ItemFlags[4] equal to 0.
TODO: Consider a different method.
* Update collide_item.cpp
I tried item->Collidable, but deactivating it, has more consecuencies, where spheres collisions are not detected so traps don't harm Lara, therefore I couldn't use it.
I returned it to coll->Setup.EnableObjectPush boolean, this variable is set in GenericSphereBoxCollision reading the ItemFlags[4] like it was before. (Most of the traps are builded around this) changing it could require a refactor of the traps that uses this feature.
* Fixes and Refactor of Joby Spikes
- Created references variables to replace ItemFlags, to make the code more readable.
- Replaced the deprecated GetRandomControl function from this code by Random::GenerateInt function.
- Fix bug with collider. This trap is using an internal collision detection routine to hurt Lara based in her position and the spike height, instead of the sphers. So it wasn't using the GenericSphereBoxCollision, I removed from its obj->collision to avoid it pushing Lara away.
- Fix bug about endless scale. Before it was increasing the spike far beyond the room bounds, now it will only increase 3 blocks and 1 click (3328, based in Troye's code). Leaving for a future enhace it for it to adapt at other room heights.
* Fix Mine bug
Now when Lara steps on a mine with OCB 1, the death animation will trigger correctly without crash the game.
* Increase damage Statue with Blade
from 20 to 200
So it's more likely it removes Lara more than 1/3 per hit.
* Fix and refactor of Sentry Gun
- Created references variables to replace ItemFlags, to make the code more readable.
- Added new ItemFlags [3] to contain the ID of the deactivator inventory item.
- Changed item pointer for item reference.
- Fix bug sentry gun rotation meshes: Looks like the the function "SetBoneRotationFlags" wasn't set properly.
* Changed namespace in 4blades code.
- Changed namespace name
From
namespace TEN::Entities::TR4
to
namespace TEN::Entities::Traps
- Fixed Damage variables names.
* Fix Rolling Spindle Moving through high steps.
Added extra condition to stop the movement of the rolling spindle blade.
In addition to walls, the spinning blade will stop if:
- Ceiling is lower than 4 clicks
- The floor ahead is lower or higher than 2.5 clicks. (To stop it moving up and down into pits, but still allow it to move through 1 and 2 click slopes).
- If there is a stopper flag (so they can be stopped with pushables).
* Update WreckingBall code
Still pending of refactor, but I think it's better manage that in a different branch.
* Update traps namespace
* Update TR4 traps
Disable trap push for Birdblade, Sethblade and Plough.
Deleted duplicated initialization of Plough and Chain in TR4 objects.
* Merge develop branch
There was a conflict with develop, this should fix it.
* Fix Dart Emitter Antitrigger
* Fix Homing Dart Emiter
When triggering, it was continously spawning darts, that was because the trigger code was resetting the item->Timer variable. This variable is aimed to be used to delay the activation or provoke a timed deactivation. Using the variable adittionaly for internal behaviour like the dart spawn frequency, may lead to uncertain results like this actual bug.
Using a separate variable (ItemFlags[1]) the dart spawn frequency timer won't be influenced by the triggers code.
* Formatting
* Update CHANGELOG.md
* Moved the routine from ControlCog to AnimatingControl
So now Animatings will can have the OCB 666 (used in Train level for the helicopter animating) and OCB 2 to make animating dissapear when Antitriggered. (Legacy features of TR4 code, maybe they got lost in the TR5 code).
* Fix SwingingBlade deactivation
It was happening that when the swinging blade got antitriggered, it was going to the stopping animation, but the object state remained activated, doing control calls on every loop. Now it will remove itself from the control loop calls.
---------
Co-authored-by: Sezz
---
CHANGELOG.md | 12 +
TombEngine/Game/collision/collide_item.cpp | 2 +-
TombEngine/Game/control/control.cpp | 4 +-
TombEngine/Objects/Generic/Object/objects.cpp | 28 +-
.../Objects/Generic/Traps/dart_emitter.cpp | 275 ++++----
.../Objects/Generic/Traps/dart_emitter.h | 8 +-
.../Objects/Generic/generic_objects.cpp | 8 +-
TombEngine/Objects/TR1/Trap/DamoclesSword.cpp | 2 +-
TombEngine/Objects/TR1/Trap/DamoclesSword.h | 2 +-
TombEngine/Objects/TR1/Trap/SlammingDoors.cpp | 2 +-
TombEngine/Objects/TR1/Trap/SlammingDoors.h | 2 +-
TombEngine/Objects/TR1/Trap/SwingingBlade.cpp | 13 +-
TombEngine/Objects/TR1/Trap/SwingingBlade.h | 2 +-
TombEngine/Objects/TR1/tr1_objects.cpp | 2 +-
.../Objects/TR2/Trap/tr2_killerstatue.cpp | 59 +-
.../Objects/TR2/Trap/tr2_killerstatue.h | 7 +-
.../Objects/TR2/Trap/tr2_spinningblade.cpp | 103 +--
.../Objects/TR2/Trap/tr2_spinningblade.h | 7 +-
TombEngine/Objects/TR2/tr2_objects.cpp | 5 +-
.../Objects/TR3/Entity/tr3_tribesman.cpp | 3 +-
TombEngine/Objects/TR3/Trap/train.cpp | 215 +++----
TombEngine/Objects/TR3/Trap/train.h | 11 +-
TombEngine/Objects/TR3/tr3_objects.cpp | 4 +-
.../Objects/TR4/Entity/tr4_sentry_gun.cpp | 165 +++--
.../Objects/TR4/Entity/tr4_sentry_gun.h | 2 +-
TombEngine/Objects/TR4/Trap/tr4_birdblade.cpp | 40 +-
TombEngine/Objects/TR4/Trap/tr4_birdblade.h | 5 +-
TombEngine/Objects/TR4/Trap/tr4_blade.cpp | 81 +--
TombEngine/Objects/TR4/Trap/tr4_blade.h | 4 +-
.../Objects/TR4/Trap/tr4_catwalkblade.cpp | 33 +-
.../Objects/TR4/Trap/tr4_catwalkblade.h | 4 +-
TombEngine/Objects/TR4/Trap/tr4_chain.cpp | 35 +-
TombEngine/Objects/TR4/Trap/tr4_chain.h | 7 +-
TombEngine/Objects/TR4/Trap/tr4_cog.cpp | 100 ++-
TombEngine/Objects/TR4/Trap/tr4_cog.h | 6 +-
.../Objects/TR4/Trap/tr4_fourblades.cpp | 53 +-
TombEngine/Objects/TR4/Trap/tr4_fourblades.h | 5 +-
TombEngine/Objects/TR4/Trap/tr4_hammer.cpp | 308 ++++-----
TombEngine/Objects/TR4/Trap/tr4_hammer.h | 4 +-
.../Objects/TR4/Trap/tr4_joby_spikes.cpp | 108 ++--
TombEngine/Objects/TR4/Trap/tr4_joby_spikes.h | 4 +-
TombEngine/Objects/TR4/Trap/tr4_mine.cpp | 157 ++---
TombEngine/Objects/TR4/Trap/tr4_mine.h | 6 +-
.../Objects/TR4/Trap/tr4_moving_blade.cpp | 27 +-
.../Objects/TR4/Trap/tr4_moving_blade.h | 4 +-
.../Objects/TR4/Trap/tr4_plinthblade.cpp | 33 +-
TombEngine/Objects/TR4/Trap/tr4_plinthblade.h | 4 +-
TombEngine/Objects/TR4/Trap/tr4_plough.cpp | 32 +-
TombEngine/Objects/TR4/Trap/tr4_plough.h | 5 +-
TombEngine/Objects/TR4/Trap/tr4_sethblade.cpp | 5 +-
TombEngine/Objects/TR4/Trap/tr4_sethblade.h | 4 +-
.../Objects/TR4/Trap/tr4_slicerdicer.cpp | 52 +-
TombEngine/Objects/TR4/Trap/tr4_slicerdicer.h | 4 +-
TombEngine/Objects/TR4/Trap/tr4_spikeball.cpp | 35 +-
TombEngine/Objects/TR4/Trap/tr4_spikeball.h | 4 +-
.../Objects/TR4/Trap/tr4_teethspike.cpp | 157 ++---
TombEngine/Objects/TR4/Trap/tr4_teethspike.h | 2 +-
TombEngine/Objects/TR4/tr4_objects.cpp | 70 +--
TombEngine/Objects/TR5/Trap/LaserBarrier.cpp | 2 +-
TombEngine/Objects/TR5/Trap/LaserBarrier.h | 2 +-
TombEngine/Objects/TR5/Trap/LaserBeam.cpp | 2 +-
TombEngine/Objects/TR5/Trap/LaserBeam.h | 2 +-
TombEngine/Objects/TR5/Trap/ZipLine.cpp | 2 +-
TombEngine/Objects/TR5/Trap/ZipLine.h | 2 +-
TombEngine/Objects/TR5/Trap/tr5_explosion.cpp | 279 ++++----
TombEngine/Objects/TR5/Trap/tr5_explosion.h | 7 +-
.../Objects/TR5/Trap/tr5_fallingceiling.cpp | 67 +-
.../Objects/TR5/Trap/tr5_fallingceiling.h | 5 +-
.../Objects/TR5/Trap/tr5_romehammer.cpp | 38 +-
TombEngine/Objects/TR5/Trap/tr5_romehammer.h | 6 +-
.../Objects/TR5/Trap/tr5_ventilator.cpp | 538 ++++++++--------
TombEngine/Objects/TR5/Trap/tr5_ventilator.h | 7 +-
.../Objects/TR5/Trap/tr5_wreckingball.cpp | 595 ++++++++++--------
.../Objects/TR5/Trap/tr5_wreckingball.h | 9 +-
TombEngine/Objects/TR5/tr5_objects.cpp | 16 +-
TombEngine/Renderer/RendererDrawEffect.cpp | 2 +-
76 files changed, 2142 insertions(+), 1780 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3bb3f8a02..57f1b3d4f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,8 +18,20 @@ TombEngine releases are located in this repository (alongside with Tomb Editor):
* Fixed Squishy blocks crashing the level.
* Fixed the path finding zones of Larson and Pierre.
* Fixed the torch flame delay in disappearing when Lara threw or dropped the torch object.
+* Fixed Dart emitters which was failing when it was antitriggered.
+* Fixed Homing Dart emitter which was spawning darts continously while Lara was on the trigger.
+* Fixed Floor 4 blades and ceiling 4 blades collision.
+* Fixed Joby spikes collision and abnormal streetching.
+* Fixed Sentry Gun to rotate its parts correctly.
+* Fixed Teeth Spikes bug, now they will activates the Lara impale animation.
+* Fixed TR4 mine with OCB1, to don't crash the game when Lara steps the mine.
### Features/Amendments
+* Changed Rome Hammer for it to don't hurt Lara while it's deactivated.
+* Changed Statue with blade damage, from 20 to 200.
+* Enhaced Rolling Spindle detection to avoid them going down through pits.
+* Enhaced Sentry Guns, with a new ItemFlags[3] to contain the ID of the inventory item that deactivates the sentry guns (by default PUZZLE_ITEM5 ID)
+* Enhaced Dart Emitter, with a new ItemFlags[0] to contain the number of frames between shots (by default 32 in dart emitter, and 24 in homing dar emitter).
### Lua API changes
* Added Inventory.GetUsedItem(), Inventory.SetUsedItem() and Inventory.ClearUsedItem() functions.
diff --git a/TombEngine/Game/collision/collide_item.cpp b/TombEngine/Game/collision/collide_item.cpp
index b979c66eb..a60ac2b82 100644
--- a/TombEngine/Game/collision/collide_item.cpp
+++ b/TombEngine/Game/collision/collide_item.cpp
@@ -706,7 +706,7 @@ bool ItemPushItem(ItemInfo* item0, ItemInfo* item1, CollisionInfo* coll, bool en
item1->Pose.Position.Lerp(item0->Pose.Position + newDeltaPos, SOFT_PUSH_LERP_ALPHA);
}
// Snap to new position.
- else
+ else if (coll->Setup.EnableObjectPush)
{
item1->Pose.Position = item0->Pose.Position + newDeltaPos;
}
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index 4502e5a59..026ff78ff 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -76,8 +76,10 @@ using namespace TEN::Effects::Ripple;
using namespace TEN::Effects::Smoke;
using namespace TEN::Effects::Spark;
using namespace TEN::Effects::Streamer;
+using namespace TEN::Entities::Creatures::TR3;
using namespace TEN::Entities::Generic;
using namespace TEN::Entities::Switches;
+using namespace TEN::Entities::Traps;
using namespace TEN::Entities::TR4;
using namespace TEN::Collision::Floordata;
using namespace TEN::Control::Volumes;
@@ -85,8 +87,6 @@ using namespace TEN::Hud;
using namespace TEN::Input;
using namespace TEN::Math;
using namespace TEN::Renderer;
-using namespace TEN::Traps::TR5;
-using namespace TEN::Entities::Creatures::TR3;
int GameTimer = 0;
int GlobalCounter = 0;
diff --git a/TombEngine/Objects/Generic/Object/objects.cpp b/TombEngine/Objects/Generic/Object/objects.cpp
index 184674ae9..5207da4f0 100644
--- a/TombEngine/Objects/Generic/Object/objects.cpp
+++ b/TombEngine/Objects/Generic/Object/objects.cpp
@@ -236,13 +236,31 @@ void InitializeAnimating(short itemNumber)
void AnimatingControl(short itemNumber)
{
- auto* item = &g_Level.Items[itemNumber];
+ auto& item = g_Level.Items[itemNumber];
- if (!TriggerActive(item))
- return;
+ if (TriggerActive(&item))
+ {
+ item.Status = ITEM_ACTIVE;
+ AnimateItem(&item);
- item->Status = ITEM_ACTIVE;
- AnimateItem(item);
+ if (item.TriggerFlags == 666) //OCB used for the helicopter animating in the Train level.
+ {
+ auto pos = GetJointPosition(item, 0);
+ SoundEffect(SFX_TR4_HELICOPTER_LOOP, (Pose*)&pos);
+
+ if (item.Animation.FrameNumber == GetAnimData(item).frameEnd)
+ {
+ item.Flags &= 0xC1;
+ RemoveActiveItem(itemNumber);
+ item.Status = ITEM_NOT_ACTIVE;
+ }
+ }
+ }
+ else if (item.TriggerFlags == 2) //Make the animating dissapear when anti-triggered.
+ {
+ RemoveActiveItem(itemNumber);
+ item.Status |= ITEM_INVISIBLE;
+ }
// TODO: ID_SHOOT_SWITCH2 is probably the bell in Trajan Markets, use Lua for that.
/*if (item->frameNumber >= g_Level.Anims[item->animNumber].frameEnd)
diff --git a/TombEngine/Objects/Generic/Traps/dart_emitter.cpp b/TombEngine/Objects/Generic/Traps/dart_emitter.cpp
index eb7fa126e..f786b659c 100644
--- a/TombEngine/Objects/Generic/Traps/dart_emitter.cpp
+++ b/TombEngine/Objects/Generic/Traps/dart_emitter.cpp
@@ -9,188 +9,225 @@
#include "Sound/sound.h"
#include "Specific/level.h"
+// NOTES:
+// ItemFlags[0]: Delay between darts in frame time.
+// ItemFlags[1]: Timer in frame time.
+
namespace TEN::Entities::Traps
{
- constexpr auto DART_DEFAULT_DAMAGE = 25;
+ constexpr auto DART_DEFAULT_HARM_DAMAGE = 25;
+ constexpr auto DART_DEFAULT_VELOCITY = BLOCK(0.25f);
+ constexpr auto DART_DEFAULT_DELAY = 32;
+ constexpr auto DART_DEFAULT_HOMING_DELAY = 24;
- void DartControl(short itemNumber)
+ void InitializeDartEmitter(short itemNumber)
{
- auto* item = &g_Level.Items[itemNumber];
+ auto& item = g_Level.Items[itemNumber];
- if (item->TouchBits.TestAny())
+ auto& delay = item.ItemFlags[0];
+
+ if (item.ObjectNumber == ID_HOMING_DART_EMITTER)
{
- if (item->TriggerFlags < 0)
+ if (delay == 0)
+ delay = DART_DEFAULT_HOMING_DELAY;
+ }
+ else
+ {
+ if (delay == 0)
+ delay = DART_DEFAULT_DELAY;
+ }
+ }
+
+ void ControlDart(short itemNumber)
+ {
+ auto& item = g_Level.Items[itemNumber];
+
+ if (item.TouchBits.TestAny())
+ {
+ if (item.TriggerFlags < 0)
Lara.Status.Poison += 1;
- DoDamage(LaraItem, item->TriggerFlags ? abs(item->TriggerFlags) : DART_DEFAULT_DAMAGE);
- DoBloodSplat(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, (GetRandomControl() & 3) + 4, LaraItem->Pose.Orientation.y, LaraItem->RoomNumber);
+ DoDamage(LaraItem, item.TriggerFlags ? abs(item.TriggerFlags) : DART_DEFAULT_HARM_DAMAGE);
+ DoBloodSplat(item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z, (GetRandomControl() & 3) + 4, LaraItem->Pose.Orientation.y, LaraItem->RoomNumber);
KillItem(itemNumber);
}
else
{
- int oldX = item->Pose.Position.x;
- int oldZ = item->Pose.Position.z;
+ auto prevPos = item.Pose.Position;
- int velocity = item->Animation.Velocity.z * phd_cos(item->Pose.Orientation.x);
+ float vel = item.Animation.Velocity.z * phd_cos(item.Pose.Orientation.x);
- item->Pose.Position.x += velocity * phd_sin(item->Pose.Orientation.y);
- item->Pose.Position.y -= item->Animation.Velocity.z * phd_sin(item->Pose.Orientation.x);
- item->Pose.Position.z += velocity * phd_cos(item->Pose.Orientation.y);
+ item.Pose.Position.x += vel * phd_sin(item.Pose.Orientation.y);
+ item.Pose.Position.y -= item.Animation.Velocity.z * phd_sin(item.Pose.Orientation.x);
+ item.Pose.Position.z += vel * phd_cos(item.Pose.Orientation.y);
- short roomNumber = item->RoomNumber;
- FloorInfo* floor = GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &roomNumber);
+ short roomNumber = item.RoomNumber;
+ auto* floor = GetFloor(item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z, &roomNumber);
- if (item->RoomNumber != roomNumber)
+ if (item.RoomNumber != roomNumber)
ItemNewRoom(itemNumber, roomNumber);
- int height = GetFloorHeight(floor, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z);
- item->Floor = height;
+ int height = GetFloorHeight(floor, item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z);
+ item.Floor = height;
- if (item->Pose.Position.y >= height)
+ if (item.Pose.Position.y >= height)
{
for (int i = 0; i < 4; i++)
- TriggerDartSmoke(oldX, item->Pose.Position.y, oldZ, 0, 0, true);
+ SpawnDartSmoke(Vector3(prevPos.x, item.Pose.Position.y, prevPos.z), Vector3::Zero, true);
KillItem(itemNumber);
}
}
}
- void DartEmitterControl(short itemNumber)
+ void ControlDartEmitter(short itemNumber)
{
- ItemInfo* item = &g_Level.Items[itemNumber];
+ auto& item = g_Level.Items[itemNumber];
- if (item->Active)
+ if (TriggerActive(&item))
{
- if (item->Timer > 0)
+ if (item.Active)
{
- item->Timer--;
+ auto& delay = item.ItemFlags[0];
+ auto& timer = item.ItemFlags[1];
+
+ if (timer > 0)
+ {
+ timer--;
+ return;
+ }
+ else
+ {
+ timer = delay;
+ }
+ }
+
+ int dartItemNumber = CreateItem();
+ if (dartItemNumber == NO_VALUE)
return;
- }
- else
- {
- item->Timer = 24;
- }
- }
- int dartItemNumber = CreateItem();
- if (dartItemNumber == NO_VALUE)
- return;
+ auto& dartItem = g_Level.Items[dartItemNumber];
+ dartItem.ObjectNumber = ID_DARTS;
+ dartItem.Pose.Position = item.Pose.Position + Vector3i(0, -CLICK(0.9f), 0);
+ dartItem.Pose.Orientation = item.Pose.Orientation + EulerAngles(0, ANGLE(180.0f), 0);
+ dartItem.RoomNumber = item.RoomNumber;
- ItemInfo* dartItem = &g_Level.Items[dartItemNumber];
+ InitializeItem(dartItemNumber);
- dartItem->ObjectNumber = ID_DARTS;
- dartItem->RoomNumber = item->RoomNumber;
+ dartItem.Animation.Velocity.z = DART_DEFAULT_VELOCITY;
+ dartItem.TriggerFlags = item.TriggerFlags;
+ dartItem.Model.Color = item.Model.Color;
- dartItem->Pose.Position.x = item->Pose.Position.x;
- dartItem->Pose.Position.y = item->Pose.Position.y - CLICK(0.9);
- dartItem->Pose.Position.z = item->Pose.Position.z;
+ for (int i = 0; i < 4; i++)
+ SpawnDartSmoke(dartItem.Pose.Position.ToVector3(), Vector3::Zero, false);
- InitializeItem(dartItemNumber);
+ AddActiveItem(dartItemNumber);
+ dartItem.Status = ITEM_ACTIVE;
- dartItem->Pose.Orientation.x = item->Pose.Orientation.x - ANGLE(180.0f);
- dartItem->Pose.Orientation.y = item->Pose.Orientation.y;
- dartItem->Pose.Orientation.z = item->Pose.Orientation.z;
- dartItem->Animation.Velocity.z = BLOCK(0.25f);
- dartItem->TriggerFlags = item->TriggerFlags;
- dartItem->Model.Color = item->Model.Color;
-
- for (int i = 0; i < 4; i++)
- TriggerDartSmoke(dartItem->Pose.Position.x, dartItem->Pose.Position.y, dartItem->Pose.Position.z, 0, 0, false);
-
- AddActiveItem(dartItemNumber);
- dartItem->Status = ITEM_ACTIVE;
-
- SoundEffect(SFX_TR4_DART_SPIT, &dartItem->Pose);
- }
-
- void TriggerDartSmoke(int x, int y, int z, int xv, int zv, bool hit)
- {
- int dx = LaraItem->Pose.Position.x - x;
- int dz = LaraItem->Pose.Position.z - z;
-
- if (dx < -16384 || dx > 16384 || dz < -16384 || dz > 16384)
- return;
-
- auto* spark = GetFreeParticle();
-
- spark->on = true;
-
- spark->sR = 16;
- spark->sG = 8;
- spark->sB = 4;
-
- spark->dR = 64;
- spark->dG = 48;
- spark->dB = 32;
-
- spark->colFadeSpeed = 8;
- spark->fadeToBlack = 4;
-
- spark->blendMode = BlendMode::Additive;
-
- spark->life = spark->sLife = (GetRandomControl() & 3) + 32;
-
- spark->x = x + ((GetRandomControl() & 31) - 16);
- spark->y = y + ((GetRandomControl() & 31) - 16);
- spark->z = z + ((GetRandomControl() & 31) - 16);
-
- if (hit)
- {
- spark->xVel = -xv + ((GetRandomControl() & 255) - 128);
- spark->yVel = -(GetRandomControl() & 3) - 4;
- spark->zVel = -zv + ((GetRandomControl() & 255) - 128);
- spark->friction = 3;
+ SoundEffect(SFX_TR4_DART_SPIT, &dartItem.Pose);
}
else
{
- if (xv)
- spark->xVel = -xv;
- else
- spark->xVel = ((GetRandomControl() & 255) - 128);
+ item.Status = ITEM_NOT_ACTIVE;
+ RemoveActiveItem(itemNumber, false);
+ item.Active = false;
+ }
+ }
- spark->yVel = -(GetRandomControl() & 3) - 4;
- if (zv)
- spark->zVel = -zv;
- else
- spark->zVel = ((GetRandomControl() & 255) - 128);
+ void SpawnDartSmoke(const Vector3& pos, const Vector3& vel, bool isHit)
+ {
+ auto& part = *GetFreeParticle();
- spark->friction = 3;
+ part.on = true;
+
+ part.sR = 16;
+ part.sG = 8;
+ part.sB = 4;
+
+ part.dR = 64;
+ part.dG = 48;
+ part.dB = 32;
+
+ part.colFadeSpeed = 8;
+ part.fadeToBlack = 4;
+
+ part.blendMode = BlendMode::Additive;
+
+ part.life = part.sLife = (GetRandomControl() & 3) + 32;
+
+ part.x = pos.x + ((GetRandomControl() & 31) - 16);
+ part.y = pos.y + ((GetRandomControl() & 31) - 16);
+ part.z = pos.z + ((GetRandomControl() & 31) - 16);
+
+ if (isHit)
+ {
+ part.xVel = -vel.x + ((GetRandomControl() & 255) - 128);
+ part.yVel = -(GetRandomControl() & 3) - 4;
+ part.zVel = -vel.z + ((GetRandomControl() & 255) - 128);
+ part.friction = 3;
+ }
+ else
+ {
+ if (vel.x != 0.0f)
+ {
+ part.xVel = -vel.x;
+ }
+ else
+ {
+ part.xVel = ((GetRandomControl() & 255) - 128);
+ }
+
+ part.yVel = -(GetRandomControl() & 3) - 4;
+ if (vel.z != 0.0f)
+ {
+ part.zVel = -vel.z;
+ }
+ else
+ {
+ part.zVel = ((GetRandomControl() & 255) - 128);
+ }
+
+ part.friction = 3;
}
- spark->friction = 3;
+ part.friction = 3;
if (GetRandomControl() & 1)
{
- spark->flags = SP_EXPDEF | SP_ROTATE | SP_DEF | SP_SCALE;
+ part.flags = SP_EXPDEF | SP_ROTATE | SP_DEF | SP_SCALE;
- spark->rotAng = GetRandomControl() & 0xFFF;
+ part.rotAng = GetRandomControl() & 0xFFF;
if (GetRandomControl() & 1)
- spark->rotAdd = -16 - (GetRandomControl() & 0xF);
+ {
+ part.rotAdd = -16 - (GetRandomControl() & 0xF);
+ }
else
- spark->rotAdd = (GetRandomControl() & 0xF) + 16;
+ {
+ part.rotAdd = (GetRandomControl() & 0xF) + 16;
+ }
}
else
{
- spark->flags = SP_EXPDEF | SP_DEF | SP_SCALE;
+ part.flags = SP_EXPDEF | SP_DEF | SP_SCALE;
}
- spark->scalar = 1;
+ part.scalar = 1;
int size = (GetRandomControl() & 63) + 72;
- if (hit)
+ if (isHit)
{
- size >>= 1;
- spark->size = spark->sSize = size >> 2;
- spark->gravity = spark->maxYvel = 0;
+ size /= 2;
+ part.size =
+ part.sSize = size *= 4;
+ part.gravity = part.maxYvel = 0;
}
else
{
- spark->size = spark->sSize = size >> 4;
- spark->gravity = -(GetRandomControl() & 3) - 4;
- spark->maxYvel = -(GetRandomControl() & 3) - 4;
+ part.size = part.sSize = size >> 4;
+ part.gravity = -(GetRandomControl() & 3) - 4;
+ part.maxYvel = -(GetRandomControl() & 3) - 4;
}
- spark->dSize = size;
+ part.dSize = size;
}
}
diff --git a/TombEngine/Objects/Generic/Traps/dart_emitter.h b/TombEngine/Objects/Generic/Traps/dart_emitter.h
index f7bc3244c..4a91cc7bb 100644
--- a/TombEngine/Objects/Generic/Traps/dart_emitter.h
+++ b/TombEngine/Objects/Generic/Traps/dart_emitter.h
@@ -2,7 +2,9 @@
namespace TEN::Entities::Traps
{
- void DartControl(short itemNumber);
- void DartEmitterControl(short itemNumber);
- void TriggerDartSmoke(int x, int y, int z, int xv, int zv, bool hit);
+ void InitializeDartEmitter(short itemNumber);
+ void ControlDart(short itemNumber);
+ void ControlDartEmitter(short itemNumber);
+
+ void SpawnDartSmoke(const Vector3& pos, const Vector3& vel, bool isHit);
}
diff --git a/TombEngine/Objects/Generic/generic_objects.cpp b/TombEngine/Objects/Generic/generic_objects.cpp
index 7d57948c5..5e09d44ba 100644
--- a/TombEngine/Objects/Generic/generic_objects.cpp
+++ b/TombEngine/Objects/Generic/generic_objects.cpp
@@ -347,14 +347,15 @@ void StartTraps(ObjectInfo* object)
if (object->loaded)
{
object->collision = ObjectCollision;
- object->control = DartControl;
+ object->control = ControlDart;
object->shadowType = ShadowMode::All;
}
object = &Objects[ID_DART_EMITTER];
if (object->loaded)
{
- object->control = DartEmitterControl;
+ object->Initialize = InitializeDartEmitter;
+ object->control = ControlDartEmitter;
object->drawRoutine = nullptr;
object->usingDrawAnimatingItem = false;
}
@@ -362,7 +363,8 @@ void StartTraps(ObjectInfo* object)
object = &Objects[ID_HOMING_DART_EMITTER];
if (object->loaded)
{
- object->control = DartEmitterControl;
+ object->Initialize = InitializeDartEmitter;
+ object->control = ControlDartEmitter;
object->drawRoutine = nullptr;
object->usingDrawAnimatingItem = false;
}
diff --git a/TombEngine/Objects/TR1/Trap/DamoclesSword.cpp b/TombEngine/Objects/TR1/Trap/DamoclesSword.cpp
index 348827f7e..1a9d9998b 100644
--- a/TombEngine/Objects/TR1/Trap/DamoclesSword.cpp
+++ b/TombEngine/Objects/TR1/Trap/DamoclesSword.cpp
@@ -14,7 +14,7 @@
using namespace TEN::Collision::Point;
using namespace TEN::Math;
-namespace TEN::Entities::Traps::TR1
+namespace TEN::Entities::Traps
{
// NOTES:
// ItemFlags[0] = random turn rate when active.
diff --git a/TombEngine/Objects/TR1/Trap/DamoclesSword.h b/TombEngine/Objects/TR1/Trap/DamoclesSword.h
index 5e76ec675..c5cc457f5 100644
--- a/TombEngine/Objects/TR1/Trap/DamoclesSword.h
+++ b/TombEngine/Objects/TR1/Trap/DamoclesSword.h
@@ -4,7 +4,7 @@ struct CollisionInfo;
struct ItemInfo;
struct ObjectInfo;
-namespace TEN::Entities::Traps::TR1
+namespace TEN::Entities::Traps
{
void InitializeDamoclesSword(short itemNumber);
diff --git a/TombEngine/Objects/TR1/Trap/SlammingDoors.cpp b/TombEngine/Objects/TR1/Trap/SlammingDoors.cpp
index cb1974298..9c41a6a64 100644
--- a/TombEngine/Objects/TR1/Trap/SlammingDoors.cpp
+++ b/TombEngine/Objects/TR1/Trap/SlammingDoors.cpp
@@ -9,7 +9,7 @@
using namespace TEN::Math;
-namespace TEN::Entities::Traps::TR1
+namespace TEN::Entities::Traps
{
constexpr auto SLAMMING_DOORS_HARM_DAMAGE = 400;
diff --git a/TombEngine/Objects/TR1/Trap/SlammingDoors.h b/TombEngine/Objects/TR1/Trap/SlammingDoors.h
index 700de7700..92e111334 100644
--- a/TombEngine/Objects/TR1/Trap/SlammingDoors.h
+++ b/TombEngine/Objects/TR1/Trap/SlammingDoors.h
@@ -3,7 +3,7 @@
struct BiteInfo;
struct ItemInfo;
-namespace TEN::Entities::Traps::TR1
+namespace TEN::Entities::Traps
{
void InitializeSlammingDoors(short itemNumber);
void ControlSlammingDoors(short itemNumber);
diff --git a/TombEngine/Objects/TR1/Trap/SwingingBlade.cpp b/TombEngine/Objects/TR1/Trap/SwingingBlade.cpp
index 05420db62..1475d5662 100644
--- a/TombEngine/Objects/TR1/Trap/SwingingBlade.cpp
+++ b/TombEngine/Objects/TR1/Trap/SwingingBlade.cpp
@@ -3,7 +3,7 @@
#include "Game/Setup.h"
-namespace TEN::Entities::Traps::TR1
+namespace TEN::Entities::Traps
{
constexpr auto SWINGING_BLADE_HARM_DAMAGE = 100;
@@ -57,6 +57,17 @@ namespace TEN::Entities::Traps::TR1
// Unset harm joints.
item.ItemFlags[0] = 0;
}
+ else
+ {
+ if (item.Animation.AnimNumber == GetAnimIndex(item, SWINGING_BLADE_ANIM_DISABLED) &&
+ item.Animation.FrameNumber == GetAnimData(item).frameEnd)
+ {
+ item.Flags &= 0xC1;
+ RemoveActiveItem(itemNumber, false);
+ item.Active = false;
+ item.Status = ITEM_NOT_ACTIVE;
+ }
+ }
}
AnimateItem(&item);
diff --git a/TombEngine/Objects/TR1/Trap/SwingingBlade.h b/TombEngine/Objects/TR1/Trap/SwingingBlade.h
index d85880131..ac88336e6 100644
--- a/TombEngine/Objects/TR1/Trap/SwingingBlade.h
+++ b/TombEngine/Objects/TR1/Trap/SwingingBlade.h
@@ -1,6 +1,6 @@
#pragma once
-namespace TEN::Entities::Traps::TR1
+namespace TEN::Entities::Traps
{
void InitializeSwingingBlade(short itemNumber);
void ControlSwingingBlade(short itemNumber);
diff --git a/TombEngine/Objects/TR1/tr1_objects.cpp b/TombEngine/Objects/TR1/tr1_objects.cpp
index 244deb99f..3a051cd50 100644
--- a/TombEngine/Objects/TR1/tr1_objects.cpp
+++ b/TombEngine/Objects/TR1/tr1_objects.cpp
@@ -30,7 +30,7 @@
#include "Objects/TR1/Trap/SwingingBlade.h"
using namespace TEN::Entities::Creatures::TR1;
-using namespace TEN::Entities::Traps::TR1;
+using namespace TEN::Entities::Traps;
static void StartEntity(ObjectInfo* obj)
{
diff --git a/TombEngine/Objects/TR2/Trap/tr2_killerstatue.cpp b/TombEngine/Objects/TR2/Trap/tr2_killerstatue.cpp
index 9bad3ef5b..f351788ae 100644
--- a/TombEngine/Objects/TR2/Trap/tr2_killerstatue.cpp
+++ b/TombEngine/Objects/TR2/Trap/tr2_killerstatue.cpp
@@ -9,35 +9,44 @@
#include "Game/Setup.h"
#include "Specific/level.h"
-void InitializeKillerStatue(short itemNumber)
+namespace TEN::Entities::Traps
{
- auto* item = &g_Level.Items[itemNumber];
+ constexpr auto KILLER_STATUE_HARM_DAMAGE = 200;
- item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + 3;
- item->Animation.FrameNumber = GetAnimData(item).frameBase;
- item->Animation.ActiveState = 1;
-}
-
-void KillerStatueControl(short itemNumber)
-{
- auto* item = &g_Level.Items[itemNumber];
-
- if (TriggerActive(item) && item->Animation.ActiveState == 1)
- item->Animation.TargetState = 2;
- else
- item->Animation.TargetState = 1;
-
- if (item->TouchBits & 0x80 && item->Animation.ActiveState == 2)
+ void InitializeKillerStatue(short itemNumber)
{
- DoDamage(LaraItem, 20);
+ auto& item = g_Level.Items[itemNumber];
- int x = LaraItem->Pose.Position.x + (GetRandomControl() - BLOCK(16)) / CLICK(1);
- int z = LaraItem->Pose.Position.z + (GetRandomControl() - BLOCK(16)) / CLICK(1);
- int y = LaraItem->Pose.Position.y - GetRandomControl() / 44;
- int d = (GetRandomControl() - BLOCK(16)) / 8 + LaraItem->Pose.Orientation.y;
-
- DoBloodSplat(x, y, z, LaraItem->Animation.Velocity.z, d, LaraItem->RoomNumber);
+ item.Animation.AnimNumber = Objects[item.ObjectNumber].animIndex + 3;
+ item.Animation.FrameNumber = GetAnimData(item).frameBase;
+ item.Animation.ActiveState = 1;
}
- AnimateItem(item);
+ void ControlKillerStatue(short itemNumber)
+ {
+ auto& item = g_Level.Items[itemNumber];
+
+ if (TriggerActive(&item) && item.Animation.ActiveState == 1)
+ {
+ item.Animation.TargetState = 2;
+ }
+ else
+ {
+ item.Animation.TargetState = 1;
+ }
+
+ if (item.TouchBits & 0x80 && item.Animation.ActiveState == 2)
+ {
+ DoDamage(LaraItem, KILLER_STATUE_HARM_DAMAGE);
+
+ int x = LaraItem->Pose.Position.x + (GetRandomControl() - BLOCK(16)) / CLICK(1);
+ int z = LaraItem->Pose.Position.z + (GetRandomControl() - BLOCK(16)) / CLICK(1);
+ int y = LaraItem->Pose.Position.y - GetRandomControl() / 44;
+ int d = (GetRandomControl() - BLOCK(16)) / 8 + LaraItem->Pose.Orientation.y;
+
+ DoBloodSplat(x, y, z, LaraItem->Animation.Velocity.z, d, LaraItem->RoomNumber);
+ }
+
+ AnimateItem(&item);
+ }
}
diff --git a/TombEngine/Objects/TR2/Trap/tr2_killerstatue.h b/TombEngine/Objects/TR2/Trap/tr2_killerstatue.h
index 91878614c..fac277086 100644
--- a/TombEngine/Objects/TR2/Trap/tr2_killerstatue.h
+++ b/TombEngine/Objects/TR2/Trap/tr2_killerstatue.h
@@ -1,4 +1,7 @@
#pragma once
-void InitializeKillerStatue(short itemNumber);
-void KillerStatueControl(short itemNumber);
+namespace TEN::Entities::Traps
+{
+ void InitializeKillerStatue(short itemNumber);
+ void ControlKillerStatue(short itemNumber);
+}
diff --git a/TombEngine/Objects/TR2/Trap/tr2_spinningblade.cpp b/TombEngine/Objects/TR2/Trap/tr2_spinningblade.cpp
index dc027a558..f3107871b 100644
--- a/TombEngine/Objects/TR2/Trap/tr2_spinningblade.cpp
+++ b/TombEngine/Objects/TR2/Trap/tr2_spinningblade.cpp
@@ -14,58 +14,71 @@
using namespace TEN::Collision::Point;
-void InitializeSpinningBlade(short itemNumber)
+namespace TEN::Entities::Traps
{
- auto* item = &g_Level.Items[itemNumber];
- SetAnimation(item, 3);
-}
+ constexpr auto SPINNING_BLADE_DAMAGE = 100;
-void SpinningBladeControl(short itemNumber)
-{
- auto* item = &g_Level.Items[itemNumber];
-
- bool isSpinning = false;
-
- if (item->Animation.ActiveState == 2)
+ void InitializeSpinningBlade(short itemNumber)
{
- if (item->Animation.TargetState != 1)
- {
- int x = item->Pose.Position.x + BLOCK(3) * phd_sin(item->Pose.Orientation.y) / 2;
- int z = item->Pose.Position.z + BLOCK(3) * phd_cos(item->Pose.Orientation.y) / 2;
-
- int floorHeight = GetPointCollision(Vector3i(x, item->Pose.Position.y, z), item->RoomNumber).GetFloorHeight();
- if (floorHeight == NO_HEIGHT)
- item->Animation.TargetState = 1;
- }
-
- isSpinning = true;
-
- if (item->TouchBits.TestAny())
- {
- DoDamage(LaraItem, 100);
- DoLotsOfBlood(LaraItem->Pose.Position.x, LaraItem->Pose.Position.y - CLICK(2), LaraItem->Pose.Position.z, (short)(item->Animation.Velocity.z * 2), LaraItem->Pose.Orientation.y, LaraItem->RoomNumber, 2);
- }
-
- SoundEffect(SFX_TR2_ROLLING_BLADE, &item->Pose);
- }
- else
- {
- if (TriggerActive(item))
- item->Animation.TargetState = 2;
-
- isSpinning = false;
+ auto* item = &g_Level.Items[itemNumber];
+ SetAnimation(item, 3);
}
- AnimateItem(item);
+ void ControlSpinningBlade(short itemNumber)
+ {
+ auto& item = g_Level.Items[itemNumber];
- auto pointColl = GetPointCollision(*item);
+ bool isSpinning = false;
- item->Floor = pointColl.GetFloorHeight();
- item->Pose.Position.y = pointColl.GetFloorHeight();
+ if (item.Animation.ActiveState == 2)
+ {
+ if (item.Animation.TargetState != 1)
+ {
+ int x = item.Pose.Position.x + BLOCK(3) * phd_sin(item.Pose.Orientation.y) / 2;
+ int z = item.Pose.Position.z + BLOCK(3) * phd_cos(item.Pose.Orientation.y) / 2;
- if (pointColl.GetRoomNumber() != item->RoomNumber)
- ItemNewRoom(itemNumber, pointColl.GetRoomNumber());
+ auto aheadPointColl = GetPointCollision(Vector3i(x, item.Pose.Position.y, z), item.RoomNumber);
+ int floorHeight = aheadPointColl.GetFloorHeight();
+ int relFloorHeight = abs(floorHeight - item.Pose.Position.y);
+ int relCeilHeight = abs(aheadPointColl.GetCeilingHeight() - floorHeight);
- if (isSpinning && item->Animation.ActiveState == 1)
- item->Pose.Orientation.y += -ANGLE(180.0f);
+ if (floorHeight == NO_HEIGHT || // Is wall.
+ aheadPointColl.GetSector().Stopper || // Sector has stopper flag.
+ relCeilHeight < BLOCK(1) || // Ceiling is lower than 1 block.
+ relFloorHeight >= CLICK(2.5)) // Is step.
+
+ item.Animation.TargetState = 1;
+ }
+
+ isSpinning = true;
+
+ if (item.TouchBits.TestAny())
+ {
+ DoDamage(LaraItem, SPINNING_BLADE_DAMAGE);
+ DoLotsOfBlood(LaraItem->Pose.Position.x, LaraItem->Pose.Position.y - CLICK(2), LaraItem->Pose.Position.z, (short)(item.Animation.Velocity.z * 2), LaraItem->Pose.Orientation.y, LaraItem->RoomNumber, 2);
+ }
+
+ SoundEffect(SFX_TR2_ROLLING_BLADE, &item.Pose);
+ }
+ else
+ {
+ if (TriggerActive(&item))
+ item.Animation.TargetState = 2;
+
+ isSpinning = false;
+ }
+
+ AnimateItem(&item);
+
+ auto pointColl = GetPointCollision(item);
+
+ item.Floor = pointColl.GetFloorHeight();
+ item.Pose.Position.y = pointColl.GetFloorHeight();
+
+ if (pointColl.GetRoomNumber() != item.RoomNumber)
+ ItemNewRoom(itemNumber, pointColl.GetRoomNumber());
+
+ if (isSpinning && item.Animation.ActiveState == 1)
+ item.Pose.Orientation.y += -ANGLE(180.0f);
+ }
}
diff --git a/TombEngine/Objects/TR2/Trap/tr2_spinningblade.h b/TombEngine/Objects/TR2/Trap/tr2_spinningblade.h
index f1d321b8c..dc612b9cf 100644
--- a/TombEngine/Objects/TR2/Trap/tr2_spinningblade.h
+++ b/TombEngine/Objects/TR2/Trap/tr2_spinningblade.h
@@ -1,4 +1,7 @@
#pragma once
-void InitializeSpinningBlade(short itemNumber);
-void SpinningBladeControl(short itemNumber);
+namespace TEN::Entities::Traps
+{
+ void InitializeSpinningBlade(short itemNumber);
+ void ControlSpinningBlade(short itemNumber);
+}
diff --git a/TombEngine/Objects/TR2/tr2_objects.cpp b/TombEngine/Objects/TR2/tr2_objects.cpp
index 98462ec63..c69e12e3f 100644
--- a/TombEngine/Objects/TR2/tr2_objects.cpp
+++ b/TombEngine/Objects/TR2/tr2_objects.cpp
@@ -41,6 +41,7 @@
#include "Objects/TR2/Vehicles/skidoo.h"
using namespace TEN::Entities::Creatures::TR2;
+using namespace TEN::Entities::Traps;
static void StartEntity(ObjectInfo* obj)
{
@@ -534,7 +535,7 @@ static void StartTrap(ObjectInfo* obj)
if (obj->loaded)
{
obj->Initialize = InitializeSpinningBlade;
- obj->control = SpinningBladeControl;
+ obj->control = ControlSpinningBlade;
obj->collision = ObjectCollision;
}
@@ -548,7 +549,7 @@ static void StartTrap(ObjectInfo* obj)
if (obj->loaded)
{
obj->Initialize = InitializeKillerStatue;
- obj->control = KillerStatueControl;
+ obj->control = ControlKillerStatue;
obj->collision = ObjectCollision;
obj->SetHitEffect(true);
}
diff --git a/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp b/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp
index f97c28937..f32925ff2 100644
--- a/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp
+++ b/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp
@@ -391,8 +391,7 @@ namespace TEN::Entities::Creatures::TR3
pos1.z += 96;
pos1 = GetJointPosition(item, TribesmanDartBite2.BoneID, pos1);
- TriggerDartSmoke(pos1.x, pos1.y, pos1.z, 0, 0, true);
- TriggerDartSmoke(pos1.x, pos1.y, pos1.z, 0, 0, true);
+ SpawnDartSmoke(pos1.ToVector3(), Vector3::Zero, true);
}
void TribemanDartsControl(short itemNumber)
diff --git a/TombEngine/Objects/TR3/Trap/train.cpp b/TombEngine/Objects/TR3/Trap/train.cpp
index 0bd209b1d..aee8a2e81 100644
--- a/TombEngine/Objects/TR3/Trap/train.cpp
+++ b/TombEngine/Objects/TR3/Trap/train.cpp
@@ -19,121 +19,126 @@
using namespace TEN::Collision::Point;
-constexpr auto TRAIN_VEL = 260;
-
-long TrainTestHeight(ItemInfo* item, long x, long z, short* roomNumber)
+namespace TEN::Entities::Traps
{
- float sinX = phd_sin(item->Pose.Orientation.x);
- float sinY = phd_sin(item->Pose.Orientation.y);
- float cosY = phd_cos(item->Pose.Orientation.y);
- float sinZ = phd_sin(item->Pose.Orientation.z);
+ constexpr auto TRAIN_VEL = 260;
- auto pos = Vector3i(
- round(item->Pose.Position.x + ((z * sinY) + (x * cosY))),
- round(item->Pose.Position.y - ((z * sinX) + (x * sinZ))),
- round(item->Pose.Position.z + ((z * cosY) - (x * sinY))));
- auto pointColl = GetPointCollision(pos, item->RoomNumber);
-
- *roomNumber = pointColl.GetRoomNumber();
- return pointColl.GetFloorHeight();
-}
-
-void TrainControl(short itemNumber)
-{
- auto* item = &g_Level.Items[itemNumber];
-
- if (!TriggerActive(item))
- return;
-
- if (item->ItemFlags[0] == 0)
- item->ItemFlags[0] = item->ItemFlags[1] = TRAIN_VEL;
-
- float sinY = phd_sin(item->Pose.Orientation.y);
- float cosY = phd_cos(item->Pose.Orientation.y);
-
- item->Pose.Position.x += item->ItemFlags[1] * sinY;
- item->Pose.Position.z += item->ItemFlags[1] * cosY;
-
- short roomNumber;
- long rh = TrainTestHeight(item, 0, BLOCK(5), &roomNumber);
- long floorHeight = TrainTestHeight(item, 0, 0, &roomNumber);
- item->Pose.Position.y = floorHeight;
-
- if (floorHeight == NO_HEIGHT)
+ long TrainTestHeight(ItemInfo* item, long x, long z, short* roomNumber)
{
- KillItem(itemNumber);
- return;
+ float sinX = phd_sin(item->Pose.Orientation.x);
+ float sinY = phd_sin(item->Pose.Orientation.y);
+ float cosY = phd_cos(item->Pose.Orientation.y);
+ float sinZ = phd_sin(item->Pose.Orientation.z);
+
+ auto pos = Vector3i(
+ round(item->Pose.Position.x + ((z * sinY) + (x * cosY))),
+ round(item->Pose.Position.y - ((z * sinX) + (x * sinZ))),
+ round(item->Pose.Position.z + ((z * cosY) - (x * sinY))));
+ auto pointColl = GetPointCollision(pos, item->RoomNumber);
+
+ *roomNumber = pointColl.GetRoomNumber();
+ return pointColl.GetFloorHeight();
}
- item->Pose.Position.y -= 32;// ?
-
- short probedRoomNumber = GetPointCollision(*item).GetRoomNumber();
- if (probedRoomNumber != item->RoomNumber)
- ItemNewRoom(itemNumber, probedRoomNumber);
-
- item->Pose.Orientation.x = -(rh - floorHeight) * 2;
-
- TriggerDynamicLight(item->Pose.Position.x + BLOCK(3) * sinY, item->Pose.Position.y, item->Pose.Position.z + BLOCK(3) * cosY, 16, 31, 31, 31);
-
- if (item->ItemFlags[1] != TRAIN_VEL)
+ void ControlTrain(short itemNumber)
{
- item->ItemFlags[1] -= 48;
- if (item->ItemFlags[1] < 0)
- item->ItemFlags[1] = 0;
+ auto& item = g_Level.Items[itemNumber];
- if (!UseForcedFixedCamera)
+ if (!TriggerActive(&item))
+ return;
+
+ if (item.ItemFlags[0] == 0)
+ item.ItemFlags[0] = item.ItemFlags[1] = TRAIN_VEL;
+
+ float sinY = phd_sin(item.Pose.Orientation.y);
+ float cosY = phd_cos(item.Pose.Orientation.y);
+
+ item.Pose.Position.x += item.ItemFlags[1] * sinY;
+ item.Pose.Position.z += item.ItemFlags[1] * cosY;
+
+ short roomNumber;
+ long rh = TrainTestHeight(&item, 0, BLOCK(5), &roomNumber);
+ long floorHeight = TrainTestHeight(&item, 0, 0, &roomNumber);
+ item.Pose.Position.y = floorHeight;
+
+ if (floorHeight == NO_HEIGHT)
{
- ForcedFixedCamera.x = item->Pose.Position.x + BLOCK(8) * sinY;
- ForcedFixedCamera.z = item->Pose.Position.z + BLOCK(8) * cosY;
+ KillItem(itemNumber);
+ return;
+ }
- ForcedFixedCamera.y = GetPointCollision(Vector3i(ForcedFixedCamera.x, item->Pose.Position.y - CLICK(2), ForcedFixedCamera.z), item->RoomNumber).GetFloorHeight();
+ item.Pose.Position.y -= 32;// ?
- ForcedFixedCamera.RoomNumber = roomNumber;
- UseForcedFixedCamera = 1;
+ int probedRoomNumber = GetPointCollision(item).GetRoomNumber();
+ if (probedRoomNumber != item.RoomNumber)
+ ItemNewRoom(itemNumber, probedRoomNumber);
+
+ item.Pose.Orientation.x = -(rh - floorHeight) * 2;
+
+ TriggerDynamicLight(item.Pose.Position.x + BLOCK(3) * sinY, item.Pose.Position.y, item.Pose.Position.z + BLOCK(3) * cosY, 16, 31, 31, 31);
+
+ if (item.ItemFlags[1] != TRAIN_VEL)
+ {
+ item.ItemFlags[1] -= 48;
+ if (item.ItemFlags[1] < 0)
+ item.ItemFlags[1] = 0;
+
+ if (!UseForcedFixedCamera)
+ {
+ ForcedFixedCamera.x = item.Pose.Position.x + BLOCK(8) * sinY;
+ ForcedFixedCamera.z = item.Pose.Position.z + BLOCK(8) * cosY;
+
+ ForcedFixedCamera.y = GetPointCollision(Vector3i(ForcedFixedCamera.x, item.Pose.Position.y - CLICK(2), ForcedFixedCamera.z), item.RoomNumber).GetFloorHeight();
+
+ ForcedFixedCamera.RoomNumber = roomNumber;
+ UseForcedFixedCamera = 1;
+ }
+ }
+ else
+ {
+ SoundEffect(SFX_TR3_TUBE_LOOP, &item.Pose, SoundEnvironment::Always);
}
}
- else
- SoundEffect(SFX_TR3_TUBE_LOOP, &item->Pose, SoundEnvironment::Always);
-}
-
-void TrainCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
-{
- auto* item = &g_Level.Items[itemNumber];
- auto* laraInfo = GetLaraInfo(laraItem);
-
- if (!TestBoundsCollide(item, laraItem, coll->Setup.Radius))
- return;
-
- if (!TestCollision(item, laraItem))
- return;
-
- SoundEffect(SFX_TR4_LARA_GENERAL_DEATH, &laraItem->Pose, SoundEnvironment::Always);
- SoundEffect(SFX_TR4_LARA_HIGH_FALL_DEATH, &laraItem->Pose, SoundEnvironment::Always);
- StopSoundEffect(SFX_TR3_TUBE_LOOP);
-
- SetAnimation(*laraItem, ID_LARA_EXTRA_ANIMS, LEA_TRAIN_DEATH_START);
- laraItem->Animation.IsAirborne = false;
- laraItem->Animation.Velocity.y = 0.0f;
- laraItem->Animation.Velocity.z = 0.0f;
- laraItem->Pose.Orientation.y = item->Pose.Orientation.y;
-
- DoDamage(laraItem, INT_MAX);
-
- AnimateItem(laraItem);
-
- laraInfo->ExtraAnim = 1;
- laraInfo->Control.HandStatus = HandStatus::Busy;
- laraInfo->Control.Weapon.GunType = LaraWeaponType::None;
- laraInfo->HitDirection = -1;
- laraInfo->Status.Air = -1;
-
- item->ItemFlags[1] = 160;
-
- float sinY = phd_sin(item->Pose.Orientation.y);
- float cosY = phd_cos(item->Pose.Orientation.y);
-
- long x = laraItem->Pose.Position.x + CLICK(1) * sinY;
- long z = laraItem->Pose.Position.z + CLICK(1) * cosY;
-
- DoLotsOfBlood(x, laraItem->Pose.Position.y - CLICK(2), z, BLOCK(1), item->Pose.Orientation.y, laraItem->RoomNumber, 15);
+
+ void CollideTrain(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll)
+ {
+ auto& item = g_Level.Items[itemNumber];
+ auto& player = GetLaraInfo(*playerItem);
+
+ if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius))
+ return;
+
+ if (!TestCollision(&item, playerItem))
+ return;
+
+ SoundEffect(SFX_TR4_LARA_GENERAL_DEATH, &playerItem->Pose, SoundEnvironment::Always);
+ SoundEffect(SFX_TR4_LARA_HIGH_FALL_DEATH, &playerItem->Pose, SoundEnvironment::Always);
+ StopSoundEffect(SFX_TR3_TUBE_LOOP);
+
+ SetAnimation(*playerItem, ID_LARA_EXTRA_ANIMS, LEA_TRAIN_DEATH_START);
+ playerItem->Animation.IsAirborne = false;
+ playerItem->Animation.Velocity.y = 0.0f;
+ playerItem->Animation.Velocity.z = 0.0f;
+ playerItem->Pose.Orientation.y = item.Pose.Orientation.y;
+
+ DoDamage(playerItem, INT_MAX);
+
+ AnimateItem(playerItem);
+
+ player.ExtraAnim = 1;
+ player.Control.HandStatus = HandStatus::Busy;
+ player.Control.Weapon.GunType = LaraWeaponType::None;
+ player.HitDirection = NO_VALUE;
+ player.Status.Air = NO_VALUE;
+
+ item.ItemFlags[1] = 160;
+
+ float sinY = phd_sin(item.Pose.Orientation.y);
+ float cosY = phd_cos(item.Pose.Orientation.y);
+
+ long x = playerItem->Pose.Position.x + CLICK(1) * sinY;
+ long z = playerItem->Pose.Position.z + CLICK(1) * cosY;
+
+ DoLotsOfBlood(x, playerItem->Pose.Position.y - CLICK(2), z, BLOCK(1), item.Pose.Orientation.y, playerItem->RoomNumber, 15);
+ }
}
diff --git a/TombEngine/Objects/TR3/Trap/train.h b/TombEngine/Objects/TR3/Trap/train.h
index 4d58d54d7..c8780d0ed 100644
--- a/TombEngine/Objects/TR3/Trap/train.h
+++ b/TombEngine/Objects/TR3/Trap/train.h
@@ -1,7 +1,10 @@
#pragma once
-#include "Game/items.h"
-#include "Game/collision/collide_room.h"
+struct CollisionInfo;
+struct ItemInfo;
-void TrainControl(short itemNumber);
-void TrainCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll);
+namespace TEN::Entities::Traps
+{
+ void ControlTrain(short itemNumber);
+ void CollideTrain(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll);
+}
diff --git a/TombEngine/Objects/TR3/tr3_objects.cpp b/TombEngine/Objects/TR3/tr3_objects.cpp
index 2b607a6ca..663f8de36 100644
--- a/TombEngine/Objects/TR3/tr3_objects.cpp
+++ b/TombEngine/Objects/TR3/tr3_objects.cpp
@@ -484,8 +484,8 @@ static void StartTrap(ObjectInfo* obj)
obj = &Objects[ID_TRAIN];
if (obj->loaded)
{
- obj->control = TrainControl;
- obj->collision = TrainCollision;
+ obj->control = ControlTrain;
+ obj->collision = CollideTrain;
obj->SetHitEffect(true);
}
diff --git a/TombEngine/Objects/TR4/Entity/tr4_sentry_gun.cpp b/TombEngine/Objects/TR4/Entity/tr4_sentry_gun.cpp
index 83900153e..6a54d69eb 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_sentry_gun.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_sentry_gun.cpp
@@ -18,124 +18,159 @@
using namespace TEN::Gui;
+// NOTES:
+// item.ItemFlags[0] = Gun flash duration in frame time.
+// item.ItemFlags[1] = Radar angle.
+// item.ItemFlags[2] = Barrel angle.
+// item.ItemFlags[3] = Object ID of inventory item which deactivates sentry gun if present.
+
namespace TEN::Entities::TR4
{
+ constexpr auto SENTRYGUN_SHOT_DAMAGE = 5;
+
+ const auto SentryGunRadarJoints = std::vector{ 3 };
+ const auto SentryGunBarrelJoints = std::vector{ 4 };
+ const auto SentryGunFuelCanJoints = std::vector{ 6 };
+ const auto SentryGunFlashJoints = std::vector{ 8 };
+ const auto SentryGunBodyJoints = std::vector{ 7, 9 };
+
const auto SentryGunFlameOffset = Vector3i(-140, 0, 0);
const auto SentryGunBite = CreatureBiteInfo(Vector3::Zero, 8);
void InitializeSentryGun(short itemNumber)
{
- auto* item = &g_Level.Items[itemNumber];
+ auto& item = g_Level.Items[itemNumber];
InitializeCreature(itemNumber);
- item->ItemFlags[0] = 0;
- item->ItemFlags[1] = 768;
- item->ItemFlags[2] = 0;
+
+ auto& flashDuration = item.ItemFlags[0];
+ auto& radarAngle = item.ItemFlags[1];
+ auto& barrelAngle = item.ItemFlags[2];
+ auto& deactivatorItemObjctID = item.ItemFlags[3];
+
+ flashDuration = 0;
+ radarAngle = 768;
+ barrelAngle = 0;
+
+ if (deactivatorItemObjctID == 0)
+ deactivatorItemObjctID = ID_PUZZLE_ITEM5;
}
- void SentryGunControl(short itemNumber)
+ void ControlSentryGun(short itemNumber)
{
if (!CreatureActive(itemNumber))
return;
- auto* item = &g_Level.Items[itemNumber];
- auto* creature = GetCreatureInfo(item);
+ auto& item = g_Level.Items[itemNumber];
+ auto* creature = GetCreatureInfo(&item);
- int c = 0;
+ auto& flashDuration = item.ItemFlags[0];
+ auto& radarAngle = item.ItemFlags[1];
+ auto& barrelAngle = item.ItemFlags[2];
+ auto& deactivatorItemObjectID = item.ItemFlags[3];
- if (!creature)
+ int headingAngle = 0;
+
+ // TODO: Why this check?
+ if (creature == nullptr)
return;
// Was fuel can exploded?
- if (item->MeshBits.Test(6))
+ if (item.MeshBits.Test(SentryGunFuelCanJoints))
{
- if (item->ItemFlags[0])
+ if (flashDuration)
{
auto pos = GetJointPosition(item, SentryGunBite);
- TriggerDynamicLight(pos.x, pos.y, pos.z, 4 * item->ItemFlags[0] + 12, 24, 16, 4);
- item->ItemFlags[0]--;
+ TriggerDynamicLight(pos.x, pos.y, pos.z, 4 * flashDuration + 12, 24, 16, 4);
+ flashDuration--;
}
- if (item->ItemFlags[0] & 1)
- item->MeshBits.Set(8);
- else
- item->MeshBits.Clear(8);
-
- if (item->TriggerFlags == 0)
+ if (flashDuration & 1)
{
- item->Pose.Position.y -= CLICK(2);
+ item.MeshBits.Set(SentryGunFlashJoints);
+ }
+ else
+ {
+ item.MeshBits.Clear(SentryGunFlashJoints);
+ }
- AI_INFO AI;
- CreatureAIInfo(item, &AI);
+ if (item.TriggerFlags == 0)
+ {
+ item.Pose.Position.y -= CLICK(2);
- item->Pose.Position.y += CLICK(2);
+ AI_INFO ai;
+ CreatureAIInfo(&item, &ai);
- int deltaAngle = AI.angle - creature->JointRotation[0];
+ item.Pose.Position.y += CLICK(2);
- AI.ahead = true;
- if (deltaAngle <= -ANGLE(90.0f) || deltaAngle >= ANGLE(90.0f))
- AI.ahead = false;
+ int deltaAngle = ai.angle - creature->JointRotation[0];
- if (Targetable(item, &AI))
+ ai.ahead = true;
+ if (deltaAngle <= ANGLE(-90.0f) || deltaAngle >= ANGLE(90.0f))
+ ai.ahead = false;
+
+ if (Targetable(&item, &ai))
{
- if (AI.distance < pow(BLOCK(9), 2))
+ if (ai.distance < SQUARE(BLOCK(9)))
{
- if (!g_Gui.IsObjectInInventory(ID_PUZZLE_ITEM5) && !item->ItemFlags[0])
+ if (!g_Gui.IsObjectInInventory(deactivatorItemObjectID) && !flashDuration)
{
- if (AI.distance <= pow(BLOCK(2), 2))
+ if (ai.distance <= SQUARE(BLOCK(2)))
{
- // Throw fire
+ // Throw fire.
ThrowFire(itemNumber, 7, SentryGunFlameOffset, SentryGunFlameOffset);
- c = phd_sin((GlobalCounter & 0x1F) * 2048) * 4096;
+ headingAngle = phd_sin((GlobalCounter & 0x1F) * 2048) * 4096; // TODO: Demagic.
}
else
{
- // Shot to Lara with bullets
- c = 0;
- item->ItemFlags[0] = 2;
+ // Shoot player.
+ headingAngle = 0;
+ flashDuration = 2;
- ShotLara(item, &AI, SentryGunBite, creature->JointRotation[0], 5);
- SoundEffect(SFX_TR4_AUTOGUNS, &item->Pose);
+ ShotLara(&item, &ai, SentryGunBite, creature->JointRotation[0], SENTRYGUN_SHOT_DAMAGE);
+ SoundEffect(SFX_TR4_AUTOGUNS, &item.Pose);
- item->ItemFlags[2] += 256;
- if (item->ItemFlags[2] > 6144)
- item->ItemFlags[2] = 6144;
+ barrelAngle += ANGLE(1.5f);
+ if (barrelAngle > ANGLE(45.0f))
+ barrelAngle = ANGLE(45.0f);
}
}
- deltaAngle = c + AI.angle - creature->JointRotation[0];
+ deltaAngle = (headingAngle + ai.angle) - creature->JointRotation[0];
if (deltaAngle <= ANGLE(10.0f))
{
- if (deltaAngle < -ANGLE(10.0f))
- deltaAngle = -ANGLE(10.0f);
+ if (deltaAngle < ANGLE(-10.0f))
+ deltaAngle = ANGLE(-10.0f);
}
else
+ {
deltaAngle = ANGLE(10.0f);
+ }
creature->JointRotation[0] += deltaAngle;
- CreatureJoint(item, 1, -AI.xAngle);
+ CreatureJoint(&item, 1, -ai.xAngle);
}
}
- // Rotating gunbarrel
- item->ItemFlags[2] -= 32;
- if (item->ItemFlags[2] < 0)
- item->ItemFlags[2] = 0;
+ // Rotate barrel.
+ barrelAngle -= 32;
+ if (barrelAngle < 0)
+ barrelAngle = 0;
- creature->JointRotation[3] += item->ItemFlags[2];
+ creature->JointRotation[3] += barrelAngle;
- // Rotating radar
- creature->JointRotation[2] += item->ItemFlags[1];
- if (creature->JointRotation[2] > ANGLE(90.0f) || creature->JointRotation[2] < -ANGLE(90.0f))
- item->ItemFlags[1] = -item->ItemFlags[1];
+ // Rotate radar.
+ creature->JointRotation[2] += radarAngle;
+ if (creature->JointRotation[2] > ANGLE(90.0f) || creature->JointRotation[2] < ANGLE(-90.0f))
+ radarAngle = -radarAngle;
}
else
{
- // Stuck sentry gun
- CreatureJoint(item, 0, (GetRandomControl() & 0x7FF) - 1024);
- CreatureJoint(item, 1, ANGLE(45.0f));
- CreatureJoint(item, 2, (GetRandomControl() & 0x3FFF) - ANGLE(45.0f));
+ // Stuck sentry gun.
+ CreatureJoint(&item, 0, (GetRandomControl() & 0x7FF) - 1024);
+ CreatureJoint(&item, 1, ANGLE(45.0f));
+ CreatureJoint(&item, 2, (GetRandomControl() & 0x3FFF) - ANGLE(45.0f));
}
}
else
@@ -144,17 +179,17 @@ namespace TEN::Entities::TR4
DisableEntityAI(itemNumber);
KillItem(itemNumber);
- item->Flags |= 1u;
- item->Status = ITEM_DEACTIVATED;
+ item.Flags |= 1;
+ item.Status = ITEM_DEACTIVATED;
- RemoveAllItemsInRoom(item->RoomNumber, ID_SMOKE_EMITTER_BLACK);
+ RemoveAllItemsInRoom(item.RoomNumber, ID_SMOKE_EMITTER_BLACK);
- TriggerExplosionSparks(item->Pose.Position.x, item->Pose.Position.y - CLICK(3), item->Pose.Position.z, 3, -2, 0, item->RoomNumber);
+ TriggerExplosionSparks(item.Pose.Position.x, item.Pose.Position.y - CLICK(3), item.Pose.Position.z, 3, -2, 0, item.RoomNumber);
for (int i = 0; i < 2; i++)
- TriggerExplosionSparks(item->Pose.Position.x, item->Pose.Position.y - CLICK(3), item->Pose.Position.z, 3, -1, 0, item->RoomNumber);
+ TriggerExplosionSparks(item.Pose.Position.x, item.Pose.Position.y - CLICK(3), item.Pose.Position.z, 3, -1, 0, item.RoomNumber);
- SoundEffect(SFX_TR4_EXPLOSION1, &item->Pose, SoundEnvironment::Land, 1.5f);
- SoundEffect(SFX_TR4_EXPLOSION2, &item->Pose);
+ SoundEffect(SFX_TR4_EXPLOSION1, &item.Pose, SoundEnvironment::Land, 1.5f);
+ SoundEffect(SFX_TR4_EXPLOSION2, &item.Pose);
}
}
}
diff --git a/TombEngine/Objects/TR4/Entity/tr4_sentry_gun.h b/TombEngine/Objects/TR4/Entity/tr4_sentry_gun.h
index 195f268eb..937553872 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_sentry_gun.h
+++ b/TombEngine/Objects/TR4/Entity/tr4_sentry_gun.h
@@ -3,5 +3,5 @@
namespace TEN::Entities::TR4
{
void InitializeSentryGun(short itemNumber);
- void SentryGunControl(short itemNumber);
+ void ControlSentryGun(short itemNumber);
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_birdblade.cpp b/TombEngine/Objects/TR4/Trap/tr4_birdblade.cpp
index cf9626f90..e897279ce 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_birdblade.cpp
+++ b/TombEngine/Objects/TR4/Trap/tr4_birdblade.cpp
@@ -1,33 +1,45 @@
#include "framework.h"
-#include "tr4_birdblade.h"
-#include "Specific/level.h"
-#include "Game/control/control.h"
+#include "Objects/TR4/Trap/tr4_birdblade.h"
+
#include "Game/animation.h"
+#include "Game/control/control.h"
#include "Game/items.h"
+#include "Specific/level.h"
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
- void BirdBladeControl(short itemNumber)
+ void InitializeBirdBlade(short itemNumber)
{
- auto* item = &g_Level.Items[itemNumber];
+ auto& item = g_Level.Items[itemNumber];
- item->ItemFlags[3] = 100;
+ item.ItemFlags[4] = 1;
+ }
- if (!TriggerActive(item))
+ void ControlBirdBlade(short itemNumber)
+ {
+ auto& item = g_Level.Items[itemNumber];
+
+ item.ItemFlags[3] = 100;
+
+ if (!TriggerActive(&item))
{
- item->Animation.FrameNumber = GetAnimData(item).frameBase;
- *((int*)&item->ItemFlags[0]) = 0;
+ item.Animation.FrameNumber = GetAnimData(item).frameBase;
+ *((int*)&item.ItemFlags[0]) = 0;
}
else
{
- int frameNumber = item->Animation.FrameNumber - GetAnimData(item).frameBase;
+ int frameNumber = item.Animation.FrameNumber - GetAnimData(item).frameBase;
if (frameNumber <= 14 || frameNumber >= 31)
- *((int*)&item->ItemFlags[0]) = 0;
+ {
+ *((int*)&item.ItemFlags[0]) = 0;
+ }
else
- *((int*)&item->ItemFlags[0]) = 6;
+ {
+ *((int*)&item.ItemFlags[0]) = 6;
+ }
- AnimateItem(item);
+ AnimateItem(&item);
}
}
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_birdblade.h b/TombEngine/Objects/TR4/Trap/tr4_birdblade.h
index 31ec3dce3..397834fdb 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_birdblade.h
+++ b/TombEngine/Objects/TR4/Trap/tr4_birdblade.h
@@ -1,6 +1,7 @@
#pragma once
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
- void BirdBladeControl(short itemNumber);
+ void InitializeBirdBlade(short itemNumber);
+ void ControlBirdBlade(short itemNumber);
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_blade.cpp b/TombEngine/Objects/TR4/Trap/tr4_blade.cpp
index cb6369593..ed011bb4d 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_blade.cpp
+++ b/TombEngine/Objects/TR4/Trap/tr4_blade.cpp
@@ -1,62 +1,49 @@
#include "framework.h"
-#include "tr4_blade.h"
-#include "Specific/level.h"
-#include "Game/collision/collide_room.h"
+#include "Objects/TR4/Trap/tr4_blade.h"
+
#include "Game/collision/collide_item.h"
-#include "Game/Lara/lara.h"
+#include "Game/collision/collide_room.h"
#include "Game/control/control.h"
#include "Game/effects/effects.h"
#include "Game/items.h"
+#include "Game/Lara/lara.h"
+#include "Specific/level.h"
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
- void BladeCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
+ void CollideBlade(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll)
{
- auto* bladeItem = &g_Level.Items[itemNumber];
+ auto& bladeItem = g_Level.Items[itemNumber];
- if (bladeItem->Status == ITEM_INVISIBLE)
+ if (bladeItem.Status == ITEM_INVISIBLE)
return;
- if (bladeItem->ItemFlags[3])
+ if (!bladeItem.ItemFlags[3])
+ return;
+
+ if (!TestBoundsCollide(&bladeItem, playerItem, coll->Setup.Radius))
+ return;
+
+ auto prevPos = playerItem->Pose.Position;
+
+ if (!ItemPushItem(&bladeItem, playerItem, coll, true, 1))
+ return;
+
+ DoDamage(playerItem, bladeItem.ItemFlags[3]);
+
+ auto deltaPos = prevPos - playerItem->Pose.Position;
+ if (deltaPos != Vector3i::Zero && TriggerActive(&bladeItem))
{
- if (TestBoundsCollide(bladeItem, laraItem, coll->Setup.Radius))
- {
- int oldX = laraItem->Pose.Position.x;
- int oldY = laraItem->Pose.Position.y;
- int oldZ = laraItem->Pose.Position.z;
-
- int dx = 0;
- int dy = 0;
- int dz = 0;
-
- if (ItemPushItem(bladeItem, laraItem, coll, true, 1))
- {
- DoDamage(laraItem, bladeItem->ItemFlags[3]);
-
- dx = oldX - laraItem->Pose.Position.x;
- dy = oldY - laraItem->Pose.Position.y;
- dz = oldZ - laraItem->Pose.Position.z;
-
- if ((dx || dy || dz) && TriggerActive(bladeItem))
- {
- DoBloodSplat(
- (GetRandomControl() & 0x3F) + laraItem->Pose.Position.x - 32,
- laraItem->Pose.Position.y - (GetRandomControl() & 0x1FF) - 256,
- (GetRandomControl() & 0x3F) + laraItem->Pose.Position.z - 32,
- (GetRandomControl() & 3) + (bladeItem->ItemFlags[3] / 32) + 2,
- 2 * GetRandomControl(),
- laraItem->RoomNumber
- );
- }
-
- if (!coll->Setup.EnableObjectPush)
- {
- laraItem->Pose.Position.x += dx;
- laraItem->Pose.Position.y += dy;
- laraItem->Pose.Position.z += dz;
- }
- }
- }
+ DoBloodSplat(
+ (GetRandomControl() & 0x3F) + playerItem->Pose.Position.x - 32,
+ playerItem->Pose.Position.y - (GetRandomControl() & 0x1FF) - 256,
+ (GetRandomControl() & 0x3F) + playerItem->Pose.Position.z - 32,
+ (GetRandomControl() & 3) + (bladeItem.ItemFlags[3] / 32) + 2,
+ Random::GenerateAngle(),
+ playerItem->RoomNumber);
}
+
+ if (!coll->Setup.EnableObjectPush)
+ playerItem->Pose.Position += deltaPos;
}
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_blade.h b/TombEngine/Objects/TR4/Trap/tr4_blade.h
index 799b20831..616ea4514 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_blade.h
+++ b/TombEngine/Objects/TR4/Trap/tr4_blade.h
@@ -3,7 +3,7 @@
struct ItemInfo;
struct CollisionInfo;
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
- void BladeCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll);
+ void CollideBlade(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll);
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_catwalkblade.cpp b/TombEngine/Objects/TR4/Trap/tr4_catwalkblade.cpp
index 887ccb796..32772265c 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_catwalkblade.cpp
+++ b/TombEngine/Objects/TR4/Trap/tr4_catwalkblade.cpp
@@ -1,28 +1,35 @@
#include "framework.h"
-#include "tr4_catwalkblade.h"
-#include "Specific/level.h"
-#include "Game/control/control.h"
+#include "Objects/TR4/Trap/tr4_catwalkblade.h"
+
#include "Game/animation.h"
+#include "Game/control/control.h"
#include "Game/items.h"
+#include "Specific/level.h"
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
- void CatwalkBladeControl(short itemNumber)
+ void ControlCatwalkBlade(short itemNumber)
{
- auto* item = &g_Level.Items[itemNumber];
+ auto& item = g_Level.Items[itemNumber];
- if (!TriggerActive(item))
- item->Animation.FrameNumber = GetAnimData(item).frameBase;
+ if (!TriggerActive(&item))
+ {
+ item.Animation.FrameNumber = GetAnimData(item).frameBase;
+ }
else
{
- int frameNumber = item->Animation.FrameNumber - GetAnimData(item).frameBase;
+ int frameNumber = item.Animation.FrameNumber - GetAnimData(item).frameBase;
- if (item->Animation.FrameNumber == GetAnimData(item).frameEnd || frameNumber < 38)
- item->ItemFlags[3] = 0;
+ if (item.Animation.FrameNumber == GetAnimData(item).frameEnd || frameNumber < 38)
+ {
+ item.ItemFlags[3] = 0;
+ }
else
- item->ItemFlags[3] = 100;
+ {
+ item.ItemFlags[3] = 100;
+ }
- AnimateItem(item);
+ AnimateItem(&item);
}
}
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_catwalkblade.h b/TombEngine/Objects/TR4/Trap/tr4_catwalkblade.h
index c95f05ff8..b470b7005 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_catwalkblade.h
+++ b/TombEngine/Objects/TR4/Trap/tr4_catwalkblade.h
@@ -1,6 +1,6 @@
#pragma once
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
- void CatwalkBladeControl(short itemNumber);
+ void ControlCatwalkBlade(short itemNumber);
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_chain.cpp b/TombEngine/Objects/TR4/Trap/tr4_chain.cpp
index c81b77f49..d6f650447 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_chain.cpp
+++ b/TombEngine/Objects/TR4/Trap/tr4_chain.cpp
@@ -1,40 +1,41 @@
#include "framework.h"
-#include "tr4_chain.h"
-#include "Specific/level.h"
-#include "Game/control/control.h"
+#include "Objects/TR4/Trap/tr4_chain.h"
+
#include "Game/animation.h"
+#include "Game/control/control.h"
#include "Game/items.h"
+#include "Specific/level.h"
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
- void ChainControl(short itemNumber)
+ void ControlChain(short itemNumber)
{
- auto* item = &g_Level.Items[itemNumber];
+ auto& item = g_Level.Items[itemNumber];
- if (item->TriggerFlags)
+ if (item.TriggerFlags)
{
- item->ItemFlags[2] = 1;
- item->ItemFlags[3] = 75;
+ item.ItemFlags[2] = 1;
+ item.ItemFlags[3] = 75;
- if (TriggerActive(item))
+ if (TriggerActive(&item))
{
- *((int*)&item->ItemFlags[0]) = 0x787E;
- AnimateItem(item);
+ *((int*)&item.ItemFlags[0]) = 0x787E;
+ AnimateItem(&item);
return;
}
}
else
{
- item->ItemFlags[3] = 25;
+ item.ItemFlags[3] = 25;
- if (TriggerActive(item))
+ if (TriggerActive(&item))
{
- *((int*)&item->ItemFlags[0]) = 0x780;
- AnimateItem(item);
+ *((int*)&item.ItemFlags[0]) = 0x780;
+ AnimateItem(&item);
return;
}
}
- *((int*)&item->ItemFlags[0]) = 0;
+ *((int*)&item.ItemFlags[0]) = 0;
}
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_chain.h b/TombEngine/Objects/TR4/Trap/tr4_chain.h
index de97e60bd..6a09dd1a6 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_chain.h
+++ b/TombEngine/Objects/TR4/Trap/tr4_chain.h
@@ -1,9 +1,6 @@
#pragma once
-struct ItemInfo;
-struct CollisionInfo;
-
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
- void ChainControl(short itemNumber);
+ void ControlChain(short itemNumber);
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_cog.cpp b/TombEngine/Objects/TR4/Trap/tr4_cog.cpp
index e334eb854..514b4bcc9 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_cog.cpp
+++ b/TombEngine/Objects/TR4/Trap/tr4_cog.cpp
@@ -1,64 +1,58 @@
#include "framework.h"
-#include "tr4_cog.h"
-#include "Specific/level.h"
-#include "Game/control/control.h"
-#include "Sound/sound.h"
-#include "Game/collision/collide_room.h"
-#include "Game/collision/collide_item.h"
-#include "Game/effects/effects.h"
-#include "Game/Lara/lara.h"
+#include "Objects/TR4/Trap/tr4_cog.h"
+
#include "Game/animation.h"
+#include "Game/collision/collide_item.h"
+#include "Game/collision/collide_room.h"
+#include "Game/control/control.h"
+#include "Game/effects/effects.h"
#include "Game/items.h"
+#include "Game/Lara/lara.h"
+#include "Sound/sound.h"
+#include "Specific/level.h"
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
- void CogControl(short itemNumber)
- {
- auto* item = &g_Level.Items[itemNumber];
+ void ControlCog(short itemNumber)
+ {
+ auto& item = g_Level.Items[itemNumber];
- if (TriggerActive(item))
- {
- item->Status = ITEM_ACTIVE;
- AnimateItem(item);
+ if (TriggerActive(&item))
+ {
+ item.Status = ITEM_ACTIVE;
+ AnimateItem(&item);
+ }
+ else if (item.TriggerFlags == 2)
+ {
+ item.Status |= ITEM_INVISIBLE;
+ }
+ }
- if (item->TriggerFlags == 666)
- {
- auto pos = GetJointPosition(item, 0);
- SoundEffect(SFX_TR4_LIBRARY_COG_LOOP, (Pose*)&pos);
-
- //Shouldnt this be TR4_LIBRARY_COG_LOOP? Changed. Rollback if incorrect. Stranger1992 06/06/22
+ void CollideCog(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll)
+ {
+ auto& cogItem = g_Level.Items[itemNumber];
+
+ if (cogItem.Status == ITEM_INVISIBLE)
+ return;
- if (item->Animation.FrameNumber == GetAnimData(item).frameEnd)
- item->Flags &= 0xC1;
- }
- }
- else if (item->TriggerFlags == 2)
- item->Status |= ITEM_INVISIBLE;
- }
+ if (!TestBoundsCollide(&cogItem, playerItem, coll->Setup.Radius))
+ return;
- void CogCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
- {
- auto* cogItem = &g_Level.Items[itemNumber];
-
- if (cogItem->Status != ITEM_INVISIBLE)
- {
- if (TestBoundsCollide(cogItem, laraItem, coll->Setup.Radius))
- {
- if (TriggerActive(cogItem))
- {
- DoBloodSplat(
- (GetRandomControl() & 0x3F) + laraItem->Pose.Position.x - 32,
- (GetRandomControl() & 0x1F) + cogItem->Pose.Position.y - 16,
- (GetRandomControl() & 0x3F) + laraItem->Pose.Position.z - 32,
- (GetRandomControl() & 3) + 2,
- 2 * GetRandomControl(),
- laraItem->RoomNumber);
+ if (TriggerActive(&cogItem))
+ {
+ DoBloodSplat(
+ (GetRandomControl() & 0x3F) + playerItem->Pose.Position.x - 32,
+ (GetRandomControl() & 0x1F) + cogItem.Pose.Position.y - 16,
+ (GetRandomControl() & 0x3F) + playerItem->Pose.Position.z - 32,
+ (GetRandomControl() & 3) + 2,
+ Random::GenerateAngle(),
+ playerItem->RoomNumber);
- DoDamage(laraItem, 10);
- }
- else if (coll->Setup.EnableObjectPush)
- ItemPushItem(cogItem, laraItem, coll, false, 0);
- }
- }
- }
+ DoDamage(playerItem, 10);
+ }
+ else if (coll->Setup.EnableObjectPush)
+ {
+ ItemPushItem(&cogItem, playerItem, coll, false, 0);
+ }
+ }
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_cog.h b/TombEngine/Objects/TR4/Trap/tr4_cog.h
index db7829b22..22a4c8bb9 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_cog.h
+++ b/TombEngine/Objects/TR4/Trap/tr4_cog.h
@@ -3,8 +3,8 @@
struct ItemInfo;
struct CollisionInfo;
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
- void CogControl(short itemNumber);
- void CogCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll);
+ void ControlCog(short itemNumber);
+ void CollideCog(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll);
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_fourblades.cpp b/TombEngine/Objects/TR4/Trap/tr4_fourblades.cpp
index bae0f4d45..0c5d0d0d0 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_fourblades.cpp
+++ b/TombEngine/Objects/TR4/Trap/tr4_fourblades.cpp
@@ -1,45 +1,64 @@
#include "framework.h"
-#include "tr4_fourblades.h"
-#include "Specific/level.h"
-#include "Game/control/control.h"
+#include "Objects/TR4/Trap/tr4_fourblades.h"
+
#include "Game/animation.h"
+#include "Game/control/control.h"
#include "Game/items.h"
+#include "Specific/level.h"
-namespace TEN::Entities::TR4
+// NOTES:
+// item.ItemFlags[0] = Damage joints.
+// item.ItemFlags[3] = Damage.
+// item.ItemFlags[4] = Push player (bool).
+
+namespace TEN::Entities::Traps
{
- void FourBladesControl(short itemNumber)
- {
- auto* item = &g_Level.Items[itemNumber];
+ constexpr auto FOUR_BLADES_EMERGE_HARM_DAMAGE = 20;
+ constexpr auto FOUR_BLADES_IDLE_HARM_DAMAGE = 200;
- if (!TriggerActive(item))
+ constexpr auto FOUR_BLADES_HARM_JOINTS = MESH_BITS(1) | MESH_BITS(2) | MESH_BITS(3) | MESH_BITS(4);
+
+ void InitializeFourBlades(short itemNumber)
+ {
+ auto& item = g_Level.Items[itemNumber];
+
+ item.ItemFlags[4] = 1;
+ }
+
+ void ControlFourBlades(short itemNumber)
+ {
+ auto& item = g_Level.Items[itemNumber];
+
+ if (!TriggerActive(&item))
{
- item->Animation.FrameNumber = GetAnimData(item).frameBase;
- *((int*)&item->ItemFlags[0]) = 0;
+ item.Animation.FrameNumber = GetAnimData(item).frameBase;
+ item.ItemFlags[0] = 0;
}
else
{
- int frameNumber = item->Animation.FrameNumber - GetAnimData(item).frameBase;
+ int frameNumber = item.Animation.FrameNumber - GetAnimData(item).frameBase;
if (frameNumber <= 5 ||
frameNumber >= 58 ||
frameNumber >= 8 && frameNumber <= 54)
{
- *((int*)&item->ItemFlags[0]) = 0;
+ item.ItemFlags[0] = 0;
+ item.ItemFlags[3] = 0;
}
else
{
+ item.ItemFlags[0] = FOUR_BLADES_HARM_JOINTS;
+
if (frameNumber >= 6 && frameNumber <= 7)
{
- item->ItemFlags[3] = 20;
- *((int*)&item->ItemFlags[0]) = 30;
+ item.ItemFlags[3] = FOUR_BLADES_EMERGE_HARM_DAMAGE;
}
else if (frameNumber >= 55 && frameNumber <= 57)
{
- item->ItemFlags[3] = 200;
- *((int*)&item->ItemFlags[0]) = 30;
+ item.ItemFlags[3] = FOUR_BLADES_IDLE_HARM_DAMAGE;
}
}
- AnimateItem(item);
+ AnimateItem(&item);
}
}
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_fourblades.h b/TombEngine/Objects/TR4/Trap/tr4_fourblades.h
index dc5dd0f9b..7c89e948a 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_fourblades.h
+++ b/TombEngine/Objects/TR4/Trap/tr4_fourblades.h
@@ -1,6 +1,7 @@
#pragma once
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
- void FourBladesControl(short itemNumber);
+ void InitializeFourBlades(short itemNumber);
+ void ControlFourBlades(short itemNumber);
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_hammer.cpp b/TombEngine/Objects/TR4/Trap/tr4_hammer.cpp
index 8dcd9c655..773134cf9 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_hammer.cpp
+++ b/TombEngine/Objects/TR4/Trap/tr4_hammer.cpp
@@ -14,171 +14,185 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
-constexpr auto RIGHT_HAMMER_BITS = ((1 << 5) | (1 << 6) | (1 << 7));
-constexpr auto LEFT_HAMMER_BITS = ((1 << 8) | (1 << 9) | (1 << 10));
-constexpr auto HAMMER_HIT_DAMAGE = 150;
-constexpr auto HAMMER_OCB4_INTERVAL = 60;
-constexpr auto HAMMER_HIT_FRAME = 8; //frame the hammer explodes pushables
-constexpr auto HAMMER_CLOSED_FRAME = 52; //frame the hammer is fully closed
+// NOTES:
+// ItemFlags[0] | ItemFlags[1] = Harm joints.
+// ItemFlags[2] = Timer in frame time before next activation.
+// ItemFlags[3] = Damage.
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
+ constexpr auto HAMMER_HIT_DAMAGE = 150;
+ constexpr auto HAMMER_OCB4_INTERVAL = 60;
+ constexpr auto HAMMER_HIT_FRAME = 8; // Frame pushables can be destroyed.
+ constexpr auto HAMMER_CLOSED_FRAME = 52; // Frame on whcih hammer is fully closed.
- enum HammerState
- {
- HAMMER_STATE_NONE = 0,
- HAMMER_STATE_IDLE = 1,
- HAMMER_STATE_ACTIVE = 2,
- };
+ constexpr auto RIGHT_HAMMER_BITS = (1 << 5) | (1 << 6) | (1 << 7);
+ constexpr auto LEFT_HAMMER_BITS = (1 << 8) | (1 << 9) | (1 << 10);
- enum HammerAnim
- {
- HAMMER_ANIM_NOT_ACTIVATED = 0,
- HAMMER_ANIM_ACTIVATED = 1
- };
+ enum HammerState
+ {
+ HAMMER_STATE_NONE = 0,
+ HAMMER_STATE_IDLE = 1,
+ HAMMER_STATE_ACTIVE = 2,
+ };
- //ItemFlags[0] | ItemFlags[1] = hurtful bits.
- //ItemFlags[2] = Timer. (X amount of frames before triggering again)
- //ItemFlags[3] = Famage dealt to Lara at touch, per frame.
+ enum HammerAnim
+ {
+ HAMMER_ANIM_INACTIVE = 0,
+ HAMMER_ANIM_ACTIVE = 1
+ };
- void HammerControl(short itemNumber)
- {
- auto* item = &g_Level.Items[itemNumber];
- int frameNumber = item->Animation.FrameNumber - GetAnimData(item).frameBase;
- item->ItemFlags[3] = HAMMER_HIT_DAMAGE;
+ void ControlHammer(short itemNumber)
+ {
+ auto& item = g_Level.Items[itemNumber];
- if (!TriggerActive(item))
- {
- *(long*)&item->ItemFlags[0] = 0;
- return;
- }
+ int frameNumber = item.Animation.FrameNumber - GetAnimData(item).frameBase;
+ item.ItemFlags[3] = HAMMER_HIT_DAMAGE;
- int hammerTouched = 0;
+ if (!TriggerActive(&item))
+ {
+ *(long*)&item.ItemFlags[0] = 0;
+ return;
+ }
- if (!item->TriggerFlags)
- {
- if (frameNumber < HAMMER_CLOSED_FRAME)
- *(long*)&item->ItemFlags[0] = RIGHT_HAMMER_BITS;
- else
- *(long*)&item->ItemFlags[0] = 0;
- }
- else if (item->Animation.ActiveState == HAMMER_STATE_IDLE && item->Animation.TargetState == HAMMER_STATE_IDLE)
- {
- if (item->ItemFlags[2])
- {
- if (item->TriggerFlags == 3)
- {
- item->Flags &= ~CODE_BITS;
- item->ItemFlags[2] = 0;
- }
- else if (item->TriggerFlags == 4)
- item->ItemFlags[2]--;
- else
- item->ItemFlags[2] = 0;
- }
- else
- {
- item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + HAMMER_ANIM_ACTIVATED;
- item->Animation.FrameNumber = GetAnimData(item).frameBase;
- item->Animation.ActiveState = HAMMER_STATE_ACTIVE;
- item->Animation.TargetState = HAMMER_STATE_ACTIVE;
- item->ItemFlags[2] = HAMMER_OCB4_INTERVAL;
- }
- }
- else
- {
- item->Animation.TargetState = HAMMER_STATE_IDLE;
+ bool isHammerTouched = false;
- if (frameNumber < HAMMER_CLOSED_FRAME)
- *(long*)&item->ItemFlags[0] = RIGHT_HAMMER_BITS | LEFT_HAMMER_BITS;
- else
- *(long*)&item->ItemFlags[0] = 0;
+ if (!item.TriggerFlags)
+ {
+ if (frameNumber < HAMMER_CLOSED_FRAME)
+ {
+ *(long*)&item.ItemFlags[0] = RIGHT_HAMMER_BITS;
+ }
+ else
+ {
+ *(long*)&item.ItemFlags[0] = 0;
+ }
+ }
+ else if (item.Animation.ActiveState == HAMMER_STATE_IDLE && item.Animation.TargetState == HAMMER_STATE_IDLE)
+ {
+ if (item.ItemFlags[2])
+ {
+ if (item.TriggerFlags == 3)
+ {
+ item.Flags &= ~CODE_BITS;
+ item.ItemFlags[2] = 0;
+ }
+ else if (item.TriggerFlags == 4)
+ {
+ item.ItemFlags[2]--;
+ }
+ else
+ {
+ item.ItemFlags[2] = 0;
+ }
+ }
+ else
+ {
+ item.Animation.AnimNumber = Objects[item.ObjectNumber].animIndex + HAMMER_ANIM_ACTIVE;
+ item.Animation.FrameNumber = GetAnimData(item).frameBase;
+ item.Animation.ActiveState = HAMMER_STATE_ACTIVE;
+ item.Animation.TargetState = HAMMER_STATE_ACTIVE;
+ item.ItemFlags[2] = HAMMER_OCB4_INTERVAL;
+ }
+ }
+ else
+ {
+ item.Animation.TargetState = HAMMER_STATE_IDLE;
- if (frameNumber == HAMMER_HIT_FRAME)
- {
- if (item->TriggerFlags == 2)
- {
- short targetItem = g_Level.Rooms[item->RoomNumber].itemNumber;
+ if (frameNumber < HAMMER_CLOSED_FRAME)
+ {
+ *(long*)&item.ItemFlags[0] = RIGHT_HAMMER_BITS | LEFT_HAMMER_BITS;
+ }
+ else
+ {
+ *(long*)&item.ItemFlags[0] = 0;
+ }
- if (targetItem != NO_VALUE)
- {
- auto* target = &g_Level.Items[targetItem];
- for (; targetItem != NO_VALUE; targetItem = target->NextItem)
- {
- target = &g_Level.Items[targetItem];
+ if (frameNumber == HAMMER_HIT_FRAME)
+ {
+ if (item.TriggerFlags == 2)
+ {
+ short targetItem = g_Level.Rooms[item.RoomNumber].itemNumber;
- if (target->ObjectNumber == ID_OBELISK && target->Pose.Orientation.y == -ANGLE(270) &&
- g_Level.Items[target->ItemFlags[0]].Pose.Orientation.y == ANGLE(90) &&
- g_Level.Items[target->ItemFlags[1]].Pose.Orientation.y == 0)
- {
- target->Flags |= CODE_BITS;
- g_Level.Items[target->ItemFlags[0]].Flags |= CODE_BITS;
- g_Level.Items[target->ItemFlags[1]].Flags |= CODE_BITS;
- break;
- }
- }
- }
+ if (targetItem != NO_VALUE)
+ {
+ auto* target = &g_Level.Items[targetItem];
+ for (; targetItem != NO_VALUE; targetItem = target->NextItem)
+ {
+ target = &g_Level.Items[targetItem];
- SoundEffect(SFX_TR4_GENERIC_HEAVY_THUD, &item->Pose);
- SoundEffect(SFX_TR4_EXPLOSION2, &item->Pose);
- }
- else
- {
- short targetItem = g_Level.Rooms[item->RoomNumber].itemNumber;
+ if (target->ObjectNumber == ID_OBELISK && target->Pose.Orientation.y == -ANGLE(270) &&
+ g_Level.Items[target->ItemFlags[0]].Pose.Orientation.y == ANGLE(90) &&
+ g_Level.Items[target->ItemFlags[1]].Pose.Orientation.y == 0)
+ {
+ target->Flags |= CODE_BITS;
+ g_Level.Items[target->ItemFlags[0]].Flags |= CODE_BITS;
+ g_Level.Items[target->ItemFlags[1]].Flags |= CODE_BITS;
+ break;
+ }
+ }
+ }
- if (targetItem != NO_VALUE)
- {
- auto* target = &g_Level.Items[targetItem];
- for (; targetItem != NO_VALUE; targetItem = target->NextItem)
- {
- target = &g_Level.Items[targetItem];
+ SoundEffect(SFX_TR4_GENERIC_HEAVY_THUD, &item.Pose);
+ SoundEffect(SFX_TR4_EXPLOSION2, &item.Pose);
+ }
+ else
+ {
+ int targetItemNumber = g_Level.Rooms[item.RoomNumber].itemNumber;
+ if (targetItemNumber != NO_VALUE)
+ {
+ // TODO: What is this syntax?
+ auto* targetItem = &g_Level.Items[targetItemNumber];
+ for (; targetItemNumber != NO_VALUE; targetItemNumber = targetItem->NextItem)
+ {
+ targetItem = &g_Level.Items[targetItemNumber];
- if ( (target->ObjectNumber >= ID_PUSHABLE_OBJECT1 && target->ObjectNumber <= ID_PUSHABLE_OBJECT10) ||
- (target->ObjectNumber >= ID_PUSHABLE_OBJECT_CLIMBABLE1 && target->ObjectNumber <= ID_PUSHABLE_OBJECT_CLIMBABLE10))
- {
- if (item->Pose.Position.x == target->Pose.Position.x &&
- item->Pose.Position.z == target->Pose.Position.z)
- {
- ExplodeItemNode(target, 0, 0, 128);
- KillItem(targetItem);
- hammerTouched = 1;
- }
- }
- }
- }
+ if ((targetItem->ObjectNumber >= ID_PUSHABLE_OBJECT1 && targetItem->ObjectNumber <= ID_PUSHABLE_OBJECT10) ||
+ (targetItem->ObjectNumber >= ID_PUSHABLE_OBJECT_CLIMBABLE1 && targetItem->ObjectNumber <= ID_PUSHABLE_OBJECT_CLIMBABLE10))
+ {
+ if (item.Pose.Position.x == targetItem->Pose.Position.x &&
+ item.Pose.Position.z == targetItem->Pose.Position.z)
+ {
+ ExplodeItemNode(targetItem, 0, 0, 128);
+ KillItem(targetItemNumber);
+ isHammerTouched = true;
+ }
+ }
+ }
+ }
- if (hammerTouched)
- {
- targetItem = g_Level.Rooms[item->RoomNumber].itemNumber;
+ if (isHammerTouched)
+ {
+ targetItemNumber = g_Level.Rooms[item.RoomNumber].itemNumber;
- if (targetItem != NO_VALUE)
- {
- auto* target = &g_Level.Items[targetItem];
- for (; targetItem != NO_VALUE; targetItem = target->NextItem)
- {
- target = &g_Level.Items[targetItem];
+ if (targetItemNumber != NO_VALUE)
+ {
+ auto* target = &g_Level.Items[targetItemNumber];
+ for (; targetItemNumber != NO_VALUE; targetItemNumber = target->NextItem)
+ {
+ target = &g_Level.Items[targetItemNumber];
- //changed to take all puzzle items, keys and their combos. Original is hardcoded to a few slots. -Troye
- if ((target->ObjectNumber >= ID_PUZZLE_ITEM1 && target->ObjectNumber <= ID_PUZZLE_ITEM16) ||
- (target->ObjectNumber >= ID_PUZZLE_ITEM1_COMBO1 && target->ObjectNumber <= ID_PUZZLE_ITEM16_COMBO2) ||
- (target->ObjectNumber >= ID_KEY_ITEM1 && target->ObjectNumber <= ID_KEY_ITEM16) ||
- (target->ObjectNumber >= ID_KEY_ITEM1_COMBO1 && target->ObjectNumber <= ID_KEY_ITEM16_COMBO2))
- {
- if (item->Pose.Position.x == target->Pose.Position.x &&
- item->Pose.Position.z == target->Pose.Position.z)
- {
- target->Status = ITEM_NOT_ACTIVE;
- }
- }
- }
- }
- }
- }
- }
- else if (frameNumber > HAMMER_CLOSED_FRAME && item->TriggerFlags == 2)
- item->Flags &= ~CODE_BITS;
- }
+ // Take all puzzle items, keys, and their combos.
+ if ((target->ObjectNumber >= ID_PUZZLE_ITEM1 && target->ObjectNumber <= ID_PUZZLE_ITEM16) ||
+ (target->ObjectNumber >= ID_PUZZLE_ITEM1_COMBO1 && target->ObjectNumber <= ID_PUZZLE_ITEM16_COMBO2) ||
+ (target->ObjectNumber >= ID_KEY_ITEM1 && target->ObjectNumber <= ID_KEY_ITEM16) ||
+ (target->ObjectNumber >= ID_KEY_ITEM1_COMBO1 && target->ObjectNumber <= ID_KEY_ITEM16_COMBO2))
+ {
+ if (item.Pose.Position.x == target->Pose.Position.x &&
+ item.Pose.Position.z == target->Pose.Position.z)
+ {
+ target->Status = ITEM_NOT_ACTIVE;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (frameNumber > HAMMER_CLOSED_FRAME && item.TriggerFlags == 2)
+ item.Flags &= ~CODE_BITS;
+ }
- AnimateItem(item);
- }
+ AnimateItem(&item);
+ }
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_hammer.h b/TombEngine/Objects/TR4/Trap/tr4_hammer.h
index 649d2f079..5b8998e22 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_hammer.h
+++ b/TombEngine/Objects/TR4/Trap/tr4_hammer.h
@@ -1,6 +1,6 @@
#pragma once
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
- void HammerControl(short itemNumber);
+ void ControlHammer(short itemNumber);
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_joby_spikes.cpp b/TombEngine/Objects/TR4/Trap/tr4_joby_spikes.cpp
index ea72a171b..1caf7e87c 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_joby_spikes.cpp
+++ b/TombEngine/Objects/TR4/Trap/tr4_joby_spikes.cpp
@@ -1,89 +1,109 @@
#include "framework.h"
-#include "tr4_joby_spikes.h"
-#include "Specific/level.h"
+#include "Objects/TR4/Trap/tr4_joby_spikes.h"
+
+#include "Game/animation.h"
#include "Game/collision/collide_room.h"
#include "Game/collision/Point.h"
#include "Game/control/control.h"
-#include "Game/animation.h"
-#include "Sound/sound.h"
-#include "Game/Lara/lara.h"
#include "Game/effects/effects.h"
#include "Game/items.h"
+#include "Game/Lara/lara.h"
+#include "Sound/sound.h"
+#include "Specific/level.h"
using namespace TEN::Collision::Point;
-namespace TEN::Entities::TR4
+// TODO: Need to test and adapt formula for scaling to other heights.
+
+namespace TEN::Entities::Traps
{
+ constexpr auto JOBY_SPIKES_HARM_DAMAGE = 8;
+ constexpr auto JOBY_SPIKES_EXTRA_ROTATION_SPEED = 2;
+ constexpr auto JOBY_SPIKES_SCALE_INCREMENT = 3;
+ constexpr auto JOBY_SPIKES_MAX_SCALE = BLOCK(3.25f);
+
void InitializeJobySpikes(short itemNumber)
{
- auto* item = &g_Level.Items[itemNumber];
+ auto& item = g_Level.Items[itemNumber];
+
+ auto& angleRotationSpeed = item.ItemFlags[0];
+ auto& spikeLength = item.ItemFlags[1];
+ auto& clockworkDirection = item.ItemFlags[2]; // ??
+ auto& maxExtensionLength = item.ItemFlags[3];
// Set bone mutators to EulerAngles identity by default.
- for (auto& mutator : item->Model.Mutators)
+ for (auto& mutator : item.Model.Mutators)
mutator.Scale.y = 0.0f;
- item->Pose.Orientation.y = GetRandomControl() * 1024;
- item->ItemFlags[2] = GetRandomControl() & 1;
+ item.Pose.Orientation.y = Random::GenerateInt(0, INT16_MAX) * ANGLE(5.5f);
+ clockworkDirection = Random::GenerateInt(0, 1);
- auto probe = GetPointCollision(*item);
-
- // TODO: Check this optimized division.
- //v6 = 1321528399i64 * ((probe.GetFloorHeight() - probe.GetCeilingHeight()) << 12);
- //item->itemFlags[3] = (HIDWORD(v6) >> 31) + (SHIDWORD(v6) >> 10);
-
- item->ItemFlags[3] = (short)((probe.GetFloorHeight() - probe.GetCeilingHeight()) * 1024 * 12 / 13);
+ auto pointColl = GetPointCollision(item);
+ maxExtensionLength = (short)(4096 * (pointColl.GetFloorHeight() - pointColl.GetCeilingHeight()) / JOBY_SPIKES_MAX_SCALE);
}
- void JobySpikesControl(short itemNumber)
+ void ControlJobySpikes(short itemNumber)
{
- auto* item = &g_Level.Items[itemNumber];
+ auto& item = g_Level.Items[itemNumber];
- if (!TriggerActive(item))
+ if (!TriggerActive(&item))
return;
- SoundEffect(SFX_TR4_METAL_SCRAPE_LOOP1, &item->Pose);
- auto frameData = GetFrameInterpData(*LaraItem);
+ auto& angleRotationSpeed = item.ItemFlags[0];
+ auto& spikeLength = item.ItemFlags[1];
+ auto& clockworkDirection = item.ItemFlags[2];
+ auto& maxExtensionLength = item.ItemFlags[3];
- int dy = LaraItem->Pose.Position.y + frameData.FramePtr0->BoundingBox.Y1;
- int dl = 3328 * item->ItemFlags[1] / 4096;
+ SoundEffect(SFX_TR4_METAL_SCRAPE_LOOP1, &item.Pose);
+ auto frameData = GetFrameInterpData(*LaraItem);
+
+ // Damage player.
+ int playerHeight = LaraItem->Pose.Position.y + frameData.FramePtr0->BoundingBox.Y1;
+ int spikeHeight = JOBY_SPIKES_MAX_SCALE * spikeLength / 4096;
if (LaraItem->HitPoints > 0)
{
- if (item->Pose.Position.y + dl > dy)
+ if (item.Pose.Position.y + spikeHeight > playerHeight)
{
- if (abs(item->Pose.Position.x - LaraItem->Pose.Position.x) < CLICK(2))
+ if (abs(item.Pose.Position.x - LaraItem->Pose.Position.x) < BLOCK(0.5))
{
- if (abs(item->Pose.Position.z - LaraItem->Pose.Position.z) < CLICK(2))
+ if (abs(item.Pose.Position.z - LaraItem->Pose.Position.z) < BLOCK(0.5))
{
- int x = (GetRandomControl() & 0x7F) + LaraItem->Pose.Position.x - 64;
- int y = dy + GetRandomControl() % (item->Pose.Position.y - dy + dl);
- int z = (GetRandomControl() & 0x7F) + LaraItem->Pose.Position.z - 64;
+ DoDamage(LaraItem, JOBY_SPIKES_HARM_DAMAGE);
- DoBloodSplat(x, y, z, (GetRandomControl() & 3) + 2, 2 * GetRandomControl(), item->RoomNumber);
- DoDamage(LaraItem, 8);
+ int bloodPosX = LaraItem->Pose.Position.x + Random::GenerateInt(-64, 64);
+ int bloodPosY = playerHeight + Random::GenerateInt( 0, item.Pose.Position.y - playerHeight + spikeHeight);
+ int bloodPosZ = LaraItem->Pose.Position.z + Random::GenerateInt(-64, 64);
+
+ DoBloodSplat(bloodPosX, bloodPosY, bloodPosZ, Random::GenerateInt (2,5), 2 * GetRandomControl(), item.RoomNumber);
+
}
}
}
}
- if (item->ItemFlags[2])
+ // Rotate.
+ if (clockworkDirection == 1)
{
- if (item->ItemFlags[0] > -4096)
- item->ItemFlags[0] = item->ItemFlags[1] + (item->ItemFlags[1] / 64) - 2;
+ if (angleRotationSpeed < 4096)
+ angleRotationSpeed = (spikeLength / 64) + spikeLength + JOBY_SPIKES_EXTRA_ROTATION_SPEED;
+ }
+ else
+ {
+ if (angleRotationSpeed > -4096)
+ angleRotationSpeed = spikeLength + (spikeLength / 64) - JOBY_SPIKES_EXTRA_ROTATION_SPEED;
}
- else if (item->ItemFlags[0] < 4096)
- item->ItemFlags[0] = (item->ItemFlags[1] / 64) + item->ItemFlags[1] + 2;
- if (item->ItemFlags[1] < item->ItemFlags[3])
- item->ItemFlags[1] += 3;
+ if (spikeLength < maxExtensionLength)
+ spikeLength += JOBY_SPIKES_SCALE_INCREMENT;
- item->Pose.Orientation.y += item->ItemFlags[0];
+ item.Pose.Orientation.y += angleRotationSpeed;
- // Update bone mutators.
- if (item->ItemFlags[1])
+ // Scale.
+ if (spikeLength)
{
- for (auto& mutator : item->Model.Mutators)
- mutator.Scale = Vector3(1.0f, item->ItemFlags[1] / 4096.0f, 1.0f);
+ for (auto& mutator : item.Model.Mutators)
+ mutator.Scale = Vector3(1.0f, spikeLength / 4096.0f, 1.0f);
}
}
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_joby_spikes.h b/TombEngine/Objects/TR4/Trap/tr4_joby_spikes.h
index 9a27c4fed..ff4e2a37f 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_joby_spikes.h
+++ b/TombEngine/Objects/TR4/Trap/tr4_joby_spikes.h
@@ -1,7 +1,7 @@
#pragma once
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
void InitializeJobySpikes(short itemNumber);
- void JobySpikesControl(short itemNumber);
+ void ControlJobySpikes(short itemNumber);
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_mine.cpp b/TombEngine/Objects/TR4/Trap/tr4_mine.cpp
index 41c38608d..5601c2c8e 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_mine.cpp
+++ b/TombEngine/Objects/TR4/Trap/tr4_mine.cpp
@@ -1,62 +1,65 @@
#include "framework.h"
-#include "tr4_mine.h"
-#include "Specific/level.h"
+#include "Objects/TR4/Trap/tr4_mine.h"
+
+#include "Game/collision/collide_item.h"
#include "Game/collision/sphere.h"
-#include "Sound/sound.h"
#include "Game/effects/debris.h"
#include "Game/effects/effects.h"
#include "Game/effects/tomb4fx.h"
#include "Game/effects/weather.h"
#include "Game/items.h"
-#include "Game/collision/collide_item.h"
#include "Objects/objectslist.h"
+#include "Sound/sound.h"
+#include "Specific/level.h"
using namespace TEN::Effects::Environment;
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
void InitializeMine(short itemNumber)
{
- auto* item = &g_Level.Items[itemNumber];
+ auto& item = g_Level.Items[itemNumber];
- if (item->TriggerFlags)
- item->MeshBits = 0;
+ if (item.TriggerFlags)
+ item.MeshBits = 0;
}
- void MineControl(short itemNumber)
+ void ControlMine(short itemNumber)
{
- auto* item = &g_Level.Items[itemNumber];
+ auto& item = g_Level.Items[itemNumber];
- int num = GetSpheres(item, CreatureSpheres, SPHERES_SPACE_WORLD, Matrix::Identity);
- if (item->ItemFlags[0] >= 150)
+ int sphereCount = GetSpheres(&item, CreatureSpheres, SPHERES_SPACE_WORLD, Matrix::Identity);
+ if (item.ItemFlags[0] >= 150)
{
- SoundEffect(SFX_TR4_EXPLOSION1, &item->Pose);
- SoundEffect(SFX_TR4_EXPLOSION2, &item->Pose);
- SoundEffect(SFX_TR4_EXPLOSION1, &item->Pose, SoundEnvironment::Land, 0.7f, 0.5f);
+ SoundEffect(SFX_TR4_EXPLOSION1, &item.Pose);
+ SoundEffect(SFX_TR4_EXPLOSION2, &item.Pose);
+ SoundEffect(SFX_TR4_EXPLOSION1, &item.Pose, SoundEnvironment::Land, 0.7f, 0.5f);
- if (num > 0)
+ if (sphereCount > 0)
{
- for (int i = 0; i < num; i++)
+ for (int i = 0; i < sphereCount; i++)
{
if (i >= 7 && i != 9)
{
- auto* sphere = &CreatureSpheres[i];
+ auto& sphere = CreatureSpheres[i];
- TriggerExplosionSparks(sphere->x, sphere->y, sphere->z, 3, -2, 0, -item->RoomNumber);
- TriggerExplosionSparks(sphere->x, sphere->y, sphere->z, 3, -1, 0, -item->RoomNumber);
- TriggerShockwave((Pose*)sphere, 48, 304, (GetRandomControl() & 0x1F) + 112, 0, 96, 128, 32, EulerAngles(2048, 0.0f, 0.0f), 0, true, false, false, (int)ShockwaveStyle::Normal);
+ auto pose = Pose(Vector3i(sphere.x, sphere.y, sphere.z));
+
+ TriggerExplosionSparks(sphere.x, sphere.y, sphere.z, 3, -2, 0, -item.RoomNumber);
+ TriggerExplosionSparks(sphere.x, sphere.y, sphere.z, 3, -1, 0, -item.RoomNumber);
+ TriggerShockwave(&pose, 48, 304, (GetRandomControl() & 0x1F) + 112, 0, 96, 128, 32, EulerAngles(ANGLE(11.25f), 0, 0), 0, true, false, false, (int)ShockwaveStyle::Normal);
}
}
- for (int i = 0; i < num; i++)
- ExplodeItemNode(item, i, 0, -128);
+ for (int i = 0; i < sphereCount; i++)
+ ExplodeItemNode(&item, i, 0, -128);
}
Weather.Flash(255, 192, 64, 0.03f);
- short currentItemNumber = g_Level.Rooms[item->RoomNumber].itemNumber;
+ int currentItemNumber = g_Level.Rooms[item.RoomNumber].itemNumber;
- // Make the sentry gun explode?
+ // Make sentry gun explode?
while (currentItemNumber != NO_VALUE)
{
auto* currentItem = &g_Level.Items[currentItemNumber];
@@ -71,93 +74,93 @@ namespace TEN::Entities::TR4
}
else
{
- item->ItemFlags[0]++;
+ item.ItemFlags[0]++;
- int fade = 4 * item->ItemFlags[0];
+ int fade = 4 * item.ItemFlags[0];
if (fade > 255)
fade = 0;
- for (int i = 0; i < num; i++)
+ for (int i = 0; i < sphereCount; i++)
{
if (i == 0 || i > 5)
{
- auto* sphere = &CreatureSpheres[i];
- AddFire(sphere->x, sphere->y, sphere->z, item->RoomNumber, 0.25f, fade);
+ auto& sphere = CreatureSpheres[i];
+ AddFire(sphere.x, sphere.y, sphere.z, item.RoomNumber, 0.25f, fade);
}
}
- SoundEffect(SFX_TR4_LOOP_FOR_SMALL_FIRES, &item->Pose);
+ SoundEffect(SFX_TR4_LOOP_FOR_SMALL_FIRES, &item.Pose);
}
}
- void MineCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
+ void CollideMine(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll)
{
- auto* mineItem = &g_Level.Items[itemNumber];
+ auto& mineItem = g_Level.Items[itemNumber];
- if (mineItem->TriggerFlags && !mineItem->ItemFlags[3])
+ if (!mineItem.TriggerFlags || mineItem.ItemFlags[3])
+ return;
+
+ if (playerItem->Animation.AnimNumber != LA_DETONATOR_USE ||
+ playerItem->Animation.FrameNumber < (GetAnimData(playerItem).frameBase + 57))
{
- if (laraItem->Animation.AnimNumber != LA_DETONATOR_USE ||
- laraItem->Animation.FrameNumber < GetAnimData(laraItem).frameBase + 57)
+ if (TestBoundsCollide(&mineItem, playerItem, BLOCK(0.5f)))
{
- if (TestBoundsCollide(mineItem, laraItem, 512))
- {
- TriggerExplosionSparks(mineItem->Pose.Position.x, mineItem->Pose.Position.y, mineItem->Pose.Position.z, 3, -2, 0, mineItem->RoomNumber);
- for (int i = 0; i < 2; i++)
- TriggerExplosionSparks(mineItem->Pose.Position.x, mineItem->Pose.Position.y, mineItem->Pose.Position.z, 3, -1, 0, mineItem->RoomNumber);
+ TriggerExplosionSparks(mineItem.Pose.Position.x, mineItem.Pose.Position.y, mineItem.Pose.Position.z, 3, -2, 0, mineItem.RoomNumber);
+ for (int i = 0; i < 2; i++)
+ TriggerExplosionSparks(mineItem.Pose.Position.x, mineItem.Pose.Position.y, mineItem.Pose.Position.z, 3, -1, 0, mineItem.RoomNumber);
- mineItem->MeshBits = 1;
+ mineItem.MeshBits = 1;
- ExplodeItemNode(mineItem, 0, 0, 128);
- KillItem(itemNumber);
+ ExplodeItemNode(&mineItem, 0, 0, 128);
+ KillItem(itemNumber);
- laraItem->Animation.AnimNumber = LA_MINE_DEATH;
- laraItem->Animation.FrameNumber = GetAnimData(*mineItem).frameBase;
- laraItem->Animation.ActiveState = LS_DEATH;
- laraItem->Animation.Velocity.z = 0;
+ playerItem->Animation.AnimNumber = LA_MINE_DEATH;
+ playerItem->Animation.FrameNumber = GetAnimData(*playerItem).frameBase;
+ playerItem->Animation.ActiveState = LS_DEATH;
+ playerItem->Animation.Velocity.z = 0;
- SoundEffect(SFX_TR4_MINE_EXPLOSION_OVERLAY, &mineItem->Pose);
- }
+ SoundEffect(SFX_TR4_MINE_EXPLOSION_OVERLAY, &mineItem.Pose);
}
- else
+ }
+ else
+ {
+ for (int i = 0; i < g_Level.NumItems; i++)
{
- for (int i = 0; i < g_Level.NumItems; i++)
- {
- auto* currentItem = &g_Level.Items[i];
+ auto* currentItem = &g_Level.Items[i];
- // Explode other mines
- if (currentItem->ObjectNumber == ID_MINE &&
- currentItem->Status != ITEM_INVISIBLE &&
- currentItem->TriggerFlags == 0)
- {
+ // Explode other mines.
+ if (currentItem->ObjectNumber == ID_MINE &&
+ currentItem->Status != ITEM_INVISIBLE &&
+ currentItem->TriggerFlags == 0)
+ {
+ TriggerExplosionSparks(
+ currentItem->Pose.Position.x,
+ currentItem->Pose.Position.y,
+ currentItem->Pose.Position.z,
+ 3,
+ -2,
+ 0,
+ currentItem->RoomNumber);
+
+ for (int j = 0; j < 2; j++)
TriggerExplosionSparks(
currentItem->Pose.Position.x,
currentItem->Pose.Position.y,
currentItem->Pose.Position.z,
3,
- -2,
+ -1,
0,
currentItem->RoomNumber);
- for (int j = 0; j < 2; j++)
- TriggerExplosionSparks(
- currentItem->Pose.Position.x,
- currentItem->Pose.Position.y,
- currentItem->Pose.Position.z,
- 3,
- -1,
- 0,
- currentItem->RoomNumber);
+ currentItem->MeshBits = 1;
- currentItem->MeshBits = 1;
+ ExplodeItemNode(currentItem, 0, 0, -32);
+ KillItem(i);
- ExplodeItemNode(currentItem, 0, 0, -32);
- KillItem(i);
+ if (!(GetRandomControl() & 3))
+ SoundEffect(SFX_TR4_MINE_EXPLOSION_OVERLAY, ¤tItem->Pose);
- if (!(GetRandomControl() & 3))
- SoundEffect(SFX_TR4_MINE_EXPLOSION_OVERLAY, ¤tItem->Pose);
-
- currentItem->Status = ITEM_INVISIBLE;
- }
+ currentItem->Status = ITEM_INVISIBLE;
}
}
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_mine.h b/TombEngine/Objects/TR4/Trap/tr4_mine.h
index ba19b8010..fb080e401 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_mine.h
+++ b/TombEngine/Objects/TR4/Trap/tr4_mine.h
@@ -3,9 +3,9 @@
struct ItemInfo;
struct CollisionInfo;
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
void InitializeMine(short itemNumber);
- void MineControl(short itemNumber);
- void MineCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll);
+ void ControlMine(short itemNumber);
+ void CollideMine(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll);
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_moving_blade.cpp b/TombEngine/Objects/TR4/Trap/tr4_moving_blade.cpp
index e54965255..48064341d 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_moving_blade.cpp
+++ b/TombEngine/Objects/TR4/Trap/tr4_moving_blade.cpp
@@ -1,26 +1,29 @@
#include "framework.h"
-#include "tr4_moving_blade.h"
-#include "Specific/level.h"
-#include "Game/control/control.h"
-#include "Sound/sound.h"
+#include "Objects/TR4/Trap/tr4_moving_blade.h"\
+
#include "Game/animation.h"
-#include "Game/Lara/lara.h"
+#include "Game/control/control.h"
#include "Game/collision/sphere.h"
#include "Game/effects/effects.h"
#include "Game/items.h"
+#include "Game/Lara/lara.h"
+#include "Sound/sound.h"
+#include "Specific/level.h"
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
- void MovingBladeControl(short itemNumber)
+ void ControlMovingBlade(short itemNumber)
{
- auto* item = &g_Level.Items[itemNumber];
+ auto& item = g_Level.Items[itemNumber];
- if (TriggerActive(item))
+ if (TriggerActive(&item))
{
- item->ItemFlags[3] = 50;
- AnimateItem(item);
+ item.ItemFlags[3] = 50;
+ AnimateItem(&item);
}
else
- item->Animation.FrameNumber = GetAnimData(item).frameBase;
+ {
+ item.Animation.FrameNumber = GetAnimData(item).frameBase;
+ }
}
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_moving_blade.h b/TombEngine/Objects/TR4/Trap/tr4_moving_blade.h
index 84233080e..0deb9ee30 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_moving_blade.h
+++ b/TombEngine/Objects/TR4/Trap/tr4_moving_blade.h
@@ -1,6 +1,6 @@
#pragma once
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
- void MovingBladeControl(short itemNumber);
+ void ControlMovingBlade(short itemNumber);
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_plinthblade.cpp b/TombEngine/Objects/TR4/Trap/tr4_plinthblade.cpp
index e9727ca2b..e5288a731 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_plinthblade.cpp
+++ b/TombEngine/Objects/TR4/Trap/tr4_plinthblade.cpp
@@ -1,28 +1,35 @@
#include "framework.h"
-#include "tr4_plinthblade.h"
-#include "Specific/level.h"
-#include "Game/control/control.h"
+#include "Objects/TR4/Trap/tr4_plinthblade.h"
+
#include "Game/animation.h"
+#include "Game/control/control.h"
#include "Game/items.h"
+#include "Specific/level.h"
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
- void PlinthBladeControl(short itemNumber)
+ void ControlPlinthBlade(short itemNumber)
{
- auto* item = &g_Level.Items[itemNumber];
+ auto& item = g_Level.Items[itemNumber];
- if (!TriggerActive(item))
- item->Animation.FrameNumber = GetAnimData(item).frameBase;
+ if (!TriggerActive(&item))
+ {
+ item.Animation.FrameNumber = GetAnimData(item).frameBase;
+ }
else
{
- int frameNumber = item->Animation.FrameNumber - GetAnimData(item).frameBase;
+ int frameNumber = item.Animation.FrameNumber - GetAnimData(item).frameBase;
- if (item->Animation.FrameNumber == GetAnimData(item).frameEnd)
- item->ItemFlags[3] = 0;
+ if (item.Animation.FrameNumber == GetAnimData(item).frameEnd)
+ {
+ item.ItemFlags[3] = 0;
+ }
else
- item->ItemFlags[3] = 200;
+ {
+ item.ItemFlags[3] = 200;
+ }
- AnimateItem(item);
+ AnimateItem(&item);
}
}
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_plinthblade.h b/TombEngine/Objects/TR4/Trap/tr4_plinthblade.h
index b0393769a..30668c5f2 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_plinthblade.h
+++ b/TombEngine/Objects/TR4/Trap/tr4_plinthblade.h
@@ -1,6 +1,6 @@
#pragma once
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
- void PlinthBladeControl(short itemNumber);
+ void ControlPlinthBlade(short itemNumber);
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_plough.cpp b/TombEngine/Objects/TR4/Trap/tr4_plough.cpp
index 465c303ea..1985d08c3 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_plough.cpp
+++ b/TombEngine/Objects/TR4/Trap/tr4_plough.cpp
@@ -1,24 +1,34 @@
#include "framework.h"
-#include "tr4_plough.h"
-#include "Specific/level.h"
-#include "Game/control/control.h"
+#include "Objects/TR4/Trap/tr4_plough.h"
+
#include "Game/animation.h"
+#include "Game/control/control.h"
#include "Game/items.h"
+#include "Specific/level.h"
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
- void PloughControl(short itemNumber)
+ void InitializePlough(short itemNumber)
{
- auto* item = &g_Level.Items[itemNumber];
+ auto& item = g_Level.Items[itemNumber];
- item->ItemFlags[3] = 50;
+ item.ItemFlags[4] = 1;
+ }
- if (TriggerActive(item))
+ void ControlPlough(short itemNumber)
+ {
+ auto& item = g_Level.Items[itemNumber];
+
+ item.ItemFlags[3] = 50;
+
+ if (TriggerActive(&item))
{
- *((int*)&item->ItemFlags) = 0x3F000;
- AnimateItem(item);
+ *((int*)&item.ItemFlags) = 0x3F000;
+ AnimateItem(&item);
}
else
- *((int*)&item->ItemFlags) = 0;
+ {
+ *((int*)&item.ItemFlags) = 0;
+ }
}
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_plough.h b/TombEngine/Objects/TR4/Trap/tr4_plough.h
index 3485dc324..3b37cfdf3 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_plough.h
+++ b/TombEngine/Objects/TR4/Trap/tr4_plough.h
@@ -1,6 +1,7 @@
#pragma once
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
- void PloughControl(short itemNumber);
+ void InitializePlough(short itemNumber);
+ void ControlPlough(short itemNumber);
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_sethblade.cpp b/TombEngine/Objects/TR4/Trap/tr4_sethblade.cpp
index b690d616d..105abf25f 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_sethblade.cpp
+++ b/TombEngine/Objects/TR4/Trap/tr4_sethblade.cpp
@@ -7,7 +7,7 @@
#include "Game/Setup.h"
#include "Specific/level.h"
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
constexpr auto SETH_BLADE_HARM_DAMAGE = 1000;
@@ -32,9 +32,10 @@ namespace TEN::Entities::TR4
item.ItemFlags[2] = item.TriggerFlags >= 0 ? 1 : abs(item.TriggerFlags); //ItemFlags[2] stores blade timer.
item.ItemFlags[3] = SETH_BLADE_HARM_DAMAGE; //ItemFlags[3] stored blade harm damage.
+ item.ItemFlags[4] = 1;
}
- void SethBladeControl(short itemNumber)
+ void ControlSethBlade(short itemNumber)
{
auto& item = g_Level.Items[itemNumber];
diff --git a/TombEngine/Objects/TR4/Trap/tr4_sethblade.h b/TombEngine/Objects/TR4/Trap/tr4_sethblade.h
index d0ad89ef0..d042b3e3a 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_sethblade.h
+++ b/TombEngine/Objects/TR4/Trap/tr4_sethblade.h
@@ -1,7 +1,7 @@
#pragma once
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
void InitializeSethBlade(short itemNumber);
- void SethBladeControl(short itemNumber);
+ void ControlSethBlade(short itemNumber);
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_slicerdicer.cpp b/TombEngine/Objects/TR4/Trap/tr4_slicerdicer.cpp
index d24178af5..c7b23f32d 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_slicerdicer.cpp
+++ b/TombEngine/Objects/TR4/Trap/tr4_slicerdicer.cpp
@@ -1,50 +1,52 @@
#include "framework.h"
-#include "tr4_slicerdicer.h"
-#include "Specific/level.h"
-#include "Sound/sound.h"
+#include "Objects/TR4/Trap/tr4_slicerdicer.h"
+
+#include "Game/animation.h"
#include "Game/collision/collide_room.h"
#include "Game/collision/Point.h"
#include "Game/items.h"
-#include "Game/animation.h"
#include "Math/Math.h"
+#include "Sound/sound.h"
+#include "Specific/level.h"
using namespace TEN::Collision::Point;
+using namespace TEN::Math;
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
void InitializeSlicerDicer(short itemNumber)
{
- auto* item = &g_Level.Items[itemNumber];
+ auto& item = g_Level.Items[itemNumber];
- int dx = phd_sin(item->Pose.Orientation.y + ANGLE(90.0f)) * 512;
- int dz = phd_cos(item->Pose.Orientation.y + ANGLE(90.0f)) * 512;
+ int dx = phd_sin(item.Pose.Orientation.y + ANGLE(90.0f)) * 512;
+ int dz = phd_cos(item.Pose.Orientation.y + ANGLE(90.0f)) * 512;
- item->Pose.Position.x += dx;
- item->Pose.Position.z += dz;
+ item.Pose.Position.x += dx;
+ item.Pose.Position.z += dz;
- item->ItemFlags[0] = item->Pose.Position.x / 256;
- item->ItemFlags[1] = (item->Pose.Position.y - 4608) / 256;
- item->ItemFlags[2] = item->Pose.Position.z / 256;
- item->ItemFlags[3] = 50;
+ item.ItemFlags[0] = item.Pose.Position.x / 256;
+ item.ItemFlags[1] = (item.Pose.Position.y - 4608) / 256;
+ item.ItemFlags[2] = item.Pose.Position.z / 256;
+ item.ItemFlags[3] = 50;
}
- void SlicerDicerControl(short itemNumber)
+ void ControlSlicerDicer(short itemNumber)
{
- auto* item = &g_Level.Items[itemNumber];
+ auto& item = g_Level.Items[itemNumber];
- SoundEffect(SFX_TR4_METAL_SCRAPE_LOOP1, &item->Pose);
- SoundEffect(SFX_TR4_METAL_SCRAPE_LOOP2, &item->Pose);
+ SoundEffect(SFX_TR4_METAL_SCRAPE_LOOP1, &item.Pose);
+ SoundEffect(SFX_TR4_METAL_SCRAPE_LOOP2, &item.Pose);
- item->Pose.Position.x = (item->ItemFlags[0] * 256) + 4608 * phd_cos(item->TriggerFlags) * phd_sin(item->Pose.Orientation.y);
- item->Pose.Position.y = (item->ItemFlags[1] * 256) - 4608 * phd_sin(item->TriggerFlags);
- item->Pose.Position.z = (item->ItemFlags[2] * 256) + 4608 * phd_cos(item->TriggerFlags) * phd_cos(item->Pose.Orientation.y);
+ item.Pose.Position.x = (item.ItemFlags[0] * 256) + 4608 * phd_cos(item.TriggerFlags) * phd_sin(item.Pose.Orientation.y);
+ item.Pose.Position.y = (item.ItemFlags[1] * 256) - 4608 * phd_sin(item.TriggerFlags);
+ item.Pose.Position.z = (item.ItemFlags[2] * 256) + 4608 * phd_cos(item.TriggerFlags) * phd_cos(item.Pose.Orientation.y);
- item->TriggerFlags += 170;
+ item.TriggerFlags += 170;
- auto probedRoomNumber = GetPointCollision(*item).GetRoomNumber();
- if (item->RoomNumber != probedRoomNumber)
+ int probedRoomNumber = GetPointCollision(item).GetRoomNumber();
+ if (item.RoomNumber != probedRoomNumber)
ItemNewRoom(itemNumber, probedRoomNumber);
- AnimateItem(item);
+ AnimateItem(&item);
}
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_slicerdicer.h b/TombEngine/Objects/TR4/Trap/tr4_slicerdicer.h
index 524476fb6..1b25343f2 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_slicerdicer.h
+++ b/TombEngine/Objects/TR4/Trap/tr4_slicerdicer.h
@@ -1,7 +1,7 @@
#pragma once
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
void InitializeSlicerDicer(short itemNumber);
- void SlicerDicerControl(short itemNumber);
+ void ControlSlicerDicer(short itemNumber);
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_spikeball.cpp b/TombEngine/Objects/TR4/Trap/tr4_spikeball.cpp
index 79d353557..95fd2cc79 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_spikeball.cpp
+++ b/TombEngine/Objects/TR4/Trap/tr4_spikeball.cpp
@@ -1,43 +1,46 @@
#include "framework.h"
-#include "tr4_spikeball.h"
-#include "Specific/level.h"
-#include "Game/control/control.h"
+#include "Objects/TR4/Trap/tr4_spikeball.h"
+
#include "Game/animation.h"
+#include "Game/control/control.h"
#include "Game/items.h"
+#include "Specific/level.h"
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
- void SpikeballControl(short itemNumber)
+ void ControlSpikeball(short itemNumber)
{
- auto* item = &g_Level.Items[itemNumber];
+ auto& item = g_Level.Items[itemNumber];
- if (TriggerActive(item))
+ if (TriggerActive(&item))
{
- int frameNumber = item->Animation.FrameNumber - GetAnimData(item).frameBase;
+ int frameNumber = item.Animation.FrameNumber - GetAnimData(item).frameBase;
if ((frameNumber <= 14 || frameNumber >= 24) &&
(frameNumber < 138 || frameNumber > 140))
{
if (frameNumber < 141)
- *((int*)&item->ItemFlags[0]) = 0;
+ {
+ *((int*)&item.ItemFlags[0]) = 0;
+ }
else
{
- item->ItemFlags[3] = 50;
- *((int*)&item->ItemFlags[0]) = 0x7FF800;
+ item.ItemFlags[3] = 50;
+ *((int*)&item.ItemFlags[0]) = 0x7FF800;
}
}
else
{
- item->ItemFlags[3] = 150;
- *((int*)&item->ItemFlags[0]) = 0x7FF800;
+ item.ItemFlags[3] = 150;
+ *((int*)&item.ItemFlags[0]) = 0x7FF800;
}
- AnimateItem(item);
+ AnimateItem(&item);
}
else
{
- item->Animation.FrameNumber = GetAnimData(item).frameBase;
- *((int*)&item->ItemFlags[0]) = 0;
+ item.Animation.FrameNumber = GetAnimData(item).frameBase;
+ *((int*)&item.ItemFlags[0]) = 0;
}
}
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_spikeball.h b/TombEngine/Objects/TR4/Trap/tr4_spikeball.h
index 3603e843d..38a001cee 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_spikeball.h
+++ b/TombEngine/Objects/TR4/Trap/tr4_spikeball.h
@@ -1,6 +1,6 @@
#pragma once
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
- void SpikeballControl(short itemNumber);
+ void ControlSpikeball(short itemNumber);
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_teethspike.cpp b/TombEngine/Objects/TR4/Trap/tr4_teethspike.cpp
index 2983d3832..0774e0666 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_teethspike.cpp
+++ b/TombEngine/Objects/TR4/Trap/tr4_teethspike.cpp
@@ -8,30 +8,30 @@
#include "Game/items.h"
#include "Game/Lara/lara.h"
#include "Game/Setup.h"
+#include "Math/Math.h"
#include "Sound/sound.h"
#include "Specific/level.h"
-#include "Math/Math.h"
using namespace TEN::Collision::Point;
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
- constexpr auto TEETH_SPIKE_HARM_DAMAGE_CONSTANT = 8;
- constexpr auto TEETH_SPIKE_HARM_DAMAGE_EMERGING = 30;
- constexpr auto TEETH_SPIKES_DEFAULT_INTERVAL = 64;
+ constexpr auto TEETH_SPIKE_HARM_DAMAGE_CONSTANT = 8;
+ constexpr auto TEETH_SPIKE_HARM_DAMAGE_EMERGING = 30;
+ constexpr auto TEETH_SPIKES_DEFAULT_INTERVAL = 64;
constexpr auto TEETH_SPIKE_BOUNDS_TOLERANCE_RATIO = 0.95f;
void InitializeTeethSpikes(short itemNumber)
{
- auto* item = &g_Level.Items[itemNumber];
+ auto& item = g_Level.Items[itemNumber];
// Set mutators to EulerAngles identity by default.
- for (auto& mutator : item->Model.Mutators)
+ for (auto& mutator : item.Model.Mutators)
mutator.Scale.y = 0.0f;
- item->Status = ITEM_INVISIBLE;
- item->ItemFlags[0] = 1024;
- item->ItemFlags[2] = 0;
+ item.Status = ITEM_INVISIBLE;
+ item.ItemFlags[0] = 1024;
+ item.ItemFlags[2] = 0;
}
ContainmentType TestBoundsCollideTeethSpikes(ItemInfo* item, ItemInfo* collidingItem)
@@ -57,94 +57,96 @@ namespace TEN::Entities::TR4
void ControlTeethSpikes(short itemNumber)
{
- auto* item = &g_Level.Items[itemNumber];
+ auto& item = g_Level.Items[itemNumber];
- if (TriggerActive(item) && item->ItemFlags[2] == 0)
+ if (TriggerActive(&item) && item.ItemFlags[2] == 0)
{
// Get current item bounds and radius.
- const auto& bounds = GetBestFrame(*item).BoundingBox;
+ const auto& bounds = GetBestFrame(item).BoundingBox;
int radius = std::max(abs(bounds.X2 - bounds.X1), abs(bounds.Z2 - bounds.Z1)) / 2;
// Play sound only if spikes are just emerging.
- if (item->ItemFlags[0] == 1024 && item->TriggerFlags != 1)
- SoundEffect(SFX_TR4_TEETH_SPIKES, &item->Pose);
+ if (item.ItemFlags[0] == 1024 && item.TriggerFlags != 1)
+ SoundEffect(SFX_TR4_TEETH_SPIKES, &item.Pose);
// Immediately set spike state to fully protruded if flag is set.
- if (item->TriggerFlags == 1)
- item->ItemFlags[1] = 5120;
+ if (item.TriggerFlags == 1)
+ item.ItemFlags[1] = 5120;
// Kill enemies.
- item->Animation.Velocity.z = VEHICLE_COLLISION_TERMINAL_VELOCITY;
- DoTeethSpikeCollision(item, radius * TEETH_SPIKE_BOUNDS_TOLERANCE_RATIO);
+ item.Animation.Velocity.z = VEHICLE_COLLISION_TERMINAL_VELOCITY;
+ DoTeethSpikeCollision(&item, radius * TEETH_SPIKE_BOUNDS_TOLERANCE_RATIO);
- item->Status = ITEM_ACTIVE;
+ item.Status = ITEM_ACTIVE;
- auto intersection = TestBoundsCollideTeethSpikes(item, LaraItem);
+ auto intersection = TestBoundsCollideTeethSpikes(&item, LaraItem);
if (LaraItem->Animation.ActiveState != LS_DEATH && intersection != ContainmentType::DISJOINT)
{
- // Calculate spike angle to the horizon. If angle is upward, impale Lara.
- auto normal = Vector3::Transform(Vector3::UnitY, item->Pose.Orientation.ToRotationMatrix());
+ // Calculate spike angle to horizon. If angle is upward, impale player.
+ auto normal = Vector3::Transform(Vector3::UnitY, item.Pose.Orientation.ToRotationMatrix());
float dot = Vector3::UnitX.Dot(normal);
float angle = acos(dot / sqrt(normal.LengthSquared() * Vector3::UnitX.LengthSquared()));
- const auto& laraBounds = GetBestFrame(*LaraItem).BoundingBox;
+ const auto& playerBounds = GetBestFrame(*LaraItem).BoundingBox;
int bloodCount = 0;
- // Spikes are upward and Lara is jumping, or spikes have just emerged - impale.
- if ((item->ItemFlags[0] >= 1024 || LaraItem->Animation.IsAirborne) &&
+ // Spikes are upward and player is jumping, or spikes have just emerged - impale.
+ if ((item.ItemFlags[0] >= 1024 || LaraItem->Animation.IsAirborne) &&
(angle > PI * 0.25f && angle < PI * 0.75f))
{
- if (LaraItem->Animation.Velocity.y > 6.0f || item->ItemFlags[0] > 1024)
+ if (LaraItem->Animation.Velocity.y > 6.0f || item.ItemFlags[0] > 1024)
{
LaraItem->HitPoints = -1;
bloodCount = 20;
}
}
- // Spikes are emerging or already fully protruded (in latter case, only damage Lara if she runs).
- else if ((item->TriggerFlags != 1) || LaraItem->Animation.Velocity.z >= 30.0f)
+ // Spikes emerging or already fully protruded (in latter case, only damage player if running).
+ else if ((item.TriggerFlags != 1) || LaraItem->Animation.Velocity.z >= 30.0f)
{
- int damage = item->ItemFlags[0] == 1024 ? TEETH_SPIKE_HARM_DAMAGE_EMERGING : TEETH_SPIKE_HARM_DAMAGE_CONSTANT;
+ int damage = item.ItemFlags[0] == 1024 ? TEETH_SPIKE_HARM_DAMAGE_EMERGING : TEETH_SPIKE_HARM_DAMAGE_CONSTANT;
DoDamage(LaraItem, damage);
bloodCount = (GetRandomControl() & 3) + 2;
}
- // Spikes are retracting; do nothing.
+ // Spikes retracting; do nothing.
else
+ {
bloodCount = 0;
+ }
int y1, y2;
- int yTop = laraBounds.Y1 + LaraItem->Pose.Position.y;
- int yBottom = laraBounds.Y2 + LaraItem->Pose.Position.y;
+ int yTop = playerBounds.Y1 + LaraItem->Pose.Position.y;
+ int yBottom = playerBounds.Y2 + LaraItem->Pose.Position.y;
- // Spikes are downward; move blood origin to top.
+ // Spikes pointing downward; move blood origin to top.
if (angle < PI * 0.125f || angle > PI * 0.825f)
{
y1 = -bounds.Y2;
y2 = -bounds.Y1;
}
- // Spikes are upward; leave origin as is.
+ // Spikes pointing upward; leave origin as is.
else
{
y1 = bounds.Y1;
y2 = bounds.Y2;
}
- if (yTop < y1 + item->Pose.Position.y)
- yTop = y1 + item->Pose.Position.y;
- if (yBottom > y2 + item->Pose.Position.y)
- yBottom = y2 + item->Pose.Position.y;
+ if (yTop < y1 + item.Pose.Position.y)
+ yTop = y1 + item.Pose.Position.y;
+ if (yBottom > y2 + item.Pose.Position.y)
+ yBottom = y2 + item.Pose.Position.y;
int dy = (abs(yTop - yBottom)) + 1;
- // Increase blood if spikes are protruding from the side.
+ // Increase blood if spikes are protruding from side.
if ((angle > PI * 0.125f && angle < PI * 0.375f) ||
(angle > PI * 0.625f && angle < PI * 0.750f))
{
bloodCount >>= 1;
}
- for (size_t i = 0; i < bloodCount; i++)
+ for (int i = 0; i < bloodCount; i++)
{
int dx = LaraItem->Pose.Position.x + (GetRandomControl() & 127) - 64;
int dz = LaraItem->Pose.Position.z + (GetRandomControl() & 127) - 64;
@@ -155,8 +157,7 @@ namespace TEN::Entities::TR4
{
int heightFromFloor = GetPointCollision(*LaraItem).GetFloorHeight() - LaraItem->Pose.Position.y;
- if (item->Pose.Position.y >= LaraItem->Pose.Position.y && heightFromFloor < CLICK(1) &&
- intersection == ContainmentType::CONTAINS)
+ if (item.Pose.Position.y >= LaraItem->Pose.Position.y && heightFromFloor < CLICK(1))
{
SetAnimation(LaraItem, LA_SPIKE_DEATH);
LaraItem->Animation.IsAirborne = false;
@@ -164,62 +165,70 @@ namespace TEN::Entities::TR4
}
}
- item->ItemFlags[0] += 128;
- item->ItemFlags[1] += item->ItemFlags[0];
- if (item->ItemFlags[1] >= 5120)
+ item.ItemFlags[0] += 128;
+ item.ItemFlags[1] += item.ItemFlags[0];
+ if (item.ItemFlags[1] >= 5120)
{
- item->ItemFlags[1] = 5120;
- if (item->ItemFlags[0] <= 1024)
+ item.ItemFlags[1] = 5120;
+ if (item.ItemFlags[0] <= 1024)
{
- item->ItemFlags[0] = 0;
- if (item->TriggerFlags != 1 && LaraItem->HitPoints > 0)
+ item.ItemFlags[0] = 0;
+ if (item.TriggerFlags != 1 && LaraItem->HitPoints > 0)
{
- int customInterval = item->TriggerFlags;
- item->ItemFlags[2] = customInterval ? customInterval : TEETH_SPIKES_DEFAULT_INTERVAL;
+ int customInterval = item.TriggerFlags;
+ item.ItemFlags[2] = customInterval ? customInterval : TEETH_SPIKES_DEFAULT_INTERVAL;
}
}
else
- item->ItemFlags[0] = -item->ItemFlags[0] >> 1;
+ {
+ item.ItemFlags[0] = -item.ItemFlags[0] >> 1;
+ }
}
}
- else if (TriggerActive(item))
+ else if (TriggerActive(&item))
{
- item->ItemFlags[0] += (item->ItemFlags[0] >> 3) + 32;
- item->ItemFlags[1] -= item->ItemFlags[0];
- if (item->ItemFlags[1] <= 0)
+ item.ItemFlags[0] += (item.ItemFlags[0] >> 3) + 32;
+ item.ItemFlags[1] -= item.ItemFlags[0];
+ if (item.ItemFlags[1] <= 0)
{
- item->ItemFlags[0] = 1024;
- item->ItemFlags[1] = 0;
- item->Status = ITEM_INVISIBLE;
+ item.ItemFlags[0] = 1024;
+ item.ItemFlags[1] = 0;
+ item.Status = ITEM_INVISIBLE;
}
- if (item->TriggerFlags != 2)
+ if (item.TriggerFlags != 2)
{
- if (item->ItemFlags[2])
- item->ItemFlags[2]--;
+ if (item.ItemFlags[2])
+ item.ItemFlags[2]--;
}
else
- item->ItemFlags[2] = 1;
- }
- else if (!item->Timer)
- {
- if (item->ItemFlags[1] > 0)
{
- item->ItemFlags[0] += (item->ItemFlags[0] >> 3) + 32;
- item->ItemFlags[1] -= item->ItemFlags[0];
- if (item->ItemFlags[1] < 0)
- item->ItemFlags[1] = 0;
+ item.ItemFlags[2] = 1;
+ }
+ }
+ else if (!item.Timer)
+ {
+ if (item.ItemFlags[1] > 0)
+ {
+ item.ItemFlags[0] += (item.ItemFlags[0] >> 3) + 32;
+ item.ItemFlags[1] -= item.ItemFlags[0];
+ if (item.ItemFlags[1] < 0)
+ item.ItemFlags[1] = 0;
}
}
// Update bone mutators.
- for (auto& mutator : item->Model.Mutators)
+ for (auto& mutator : item.Model.Mutators)
{
- float scale = (float)item->ItemFlags[1] / 4096.0f;
+ float scale = (float)item.ItemFlags[1] / 4096.0f;
if (scale > 0.0f)
+ {
mutator.Scale = Vector3(1.0f, scale, 1.0f);
+ }
else
+ {
mutator.Scale = Vector3::Zero;
+ }
}
}
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_teethspike.h b/TombEngine/Objects/TR4/Trap/tr4_teethspike.h
index 8f075cde3..5bcc50302 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_teethspike.h
+++ b/TombEngine/Objects/TR4/Trap/tr4_teethspike.h
@@ -1,6 +1,6 @@
#pragma once
-namespace TEN::Entities::TR4
+namespace TEN::Entities::Traps
{
void InitializeTeethSpikes(short itemNumber);
void ControlTeethSpikes(short itemNumber);
diff --git a/TombEngine/Objects/TR4/tr4_objects.cpp b/TombEngine/Objects/TR4/tr4_objects.cpp
index b54171260..f17c818de 100644
--- a/TombEngine/Objects/TR4/tr4_objects.cpp
+++ b/TombEngine/Objects/TR4/tr4_objects.cpp
@@ -410,7 +410,7 @@ namespace TEN::Entities
if (obj->loaded)
{
obj->Initialize = InitializeSentryGun;
- obj->control = SentryGunControl;
+ obj->control = ControlSentryGun;
obj->collision = CreatureCollision;
obj->shadowType = ShadowMode::All;
obj->damageType = DamageMode::None;
@@ -420,9 +420,8 @@ namespace TEN::Entities
obj->intelligent = true;
obj->explodableMeshbits = 0x40;
obj->SetBoneRotationFlags(0, ROT_X | ROT_Y);
- obj->SetBoneRotationFlags(1, ROT_X | ROT_X);
- obj->SetBoneRotationFlags(2, ROT_X | ROT_Z);
- obj->SetBoneRotationFlags(3, ROT_X | ROT_Z);
+ obj->SetBoneRotationFlags(2, ROT_Z);
+ obj->SetBoneRotationFlags(3, ROT_Z);
obj->SetHitEffect(true);
}
@@ -768,7 +767,7 @@ namespace TEN::Entities
obj = &Objects[ID_CHAIN];
if (obj->loaded)
{
- obj->control = ChainControl;
+ obj->control = ControlChain;
obj->collision = GenericSphereBoxCollision;
obj->SetHitEffect(true);
}
@@ -776,7 +775,8 @@ namespace TEN::Entities
obj = &Objects[ID_PLOUGH];
if (obj->loaded)
{
- obj->control = PloughControl;
+ obj->Initialize = InitializePlough;
+ obj->control = ControlPlough;
obj->collision = GenericSphereBoxCollision;
obj->SetHitEffect(true);
}
@@ -784,8 +784,8 @@ namespace TEN::Entities
obj = &Objects[ID_CATWALK_BLADE];
if (obj->loaded)
{
- obj->control = CatwalkBladeControl;
- obj->collision = BladeCollision;
+ obj->control = ControlCatwalkBlade;
+ obj->collision = CollideBlade;
obj->SetHitEffect(true);
}
@@ -793,7 +793,7 @@ namespace TEN::Entities
if (obj->loaded)
{
obj->Initialize = InitializeSethBlade;
- obj->control = SethBladeControl;
+ obj->control = ControlSethBlade;
obj->collision = GenericSphereBoxCollision;
obj->SetHitEffect(true);
}
@@ -801,15 +801,16 @@ namespace TEN::Entities
obj = &Objects[ID_PLINTH_BLADE];
if (obj->loaded)
{
- obj->control = PlinthBladeControl;
- obj->collision = BladeCollision;
+ obj->control = ControlPlinthBlade;
+ obj->collision = CollideBlade;
obj->SetHitEffect(true);
}
obj = &Objects[ID_BIRD_BLADE];
if (obj->loaded)
{
- obj->control = BirdBladeControl;
+ obj->Initialize = InitializeBirdBlade;
+ obj->control = ControlBirdBlade;
obj->collision = GenericSphereBoxCollision;
obj->SetHitEffect(true);
}
@@ -818,39 +819,22 @@ namespace TEN::Entities
if (obj->loaded)
{
obj->Initialize = InitializeJobySpikes;
- obj->control = JobySpikesControl;
- obj->collision = GenericSphereBoxCollision;
+ obj->control = ControlJobySpikes;
obj->SetHitEffect(true);
}
obj = &Objects[ID_MOVING_BLADE];
if (obj->loaded)
{
- obj->control = MovingBladeControl;
- obj->collision = BladeCollision;
+ obj->control = ControlMovingBlade;
+ obj->collision = CollideBlade;
obj->SetHitEffect(true);
}
obj = &Objects[ID_SPIKEBALL];
if (obj->loaded)
{
- obj->control = SpikeballControl;
- obj->collision = GenericSphereBoxCollision;
- obj->SetHitEffect(true);
- }
-
- obj = &Objects[ID_CHAIN];
- if (obj->loaded)
- {
- obj->control = ChainControl;
- obj->collision = GenericSphereBoxCollision;
- obj->SetHitEffect(true);
- }
-
- obj = &Objects[ID_PLOUGH];
- if (obj->loaded)
- {
- obj->control = PloughControl;
+ obj->control = ControlSpikeball;
obj->collision = GenericSphereBoxCollision;
obj->SetHitEffect(true);
}
@@ -858,7 +842,8 @@ namespace TEN::Entities
obj = &Objects[ID_FLOOR_4BLADES];
if (obj->loaded)
{
- obj->control = FourBladesControl;
+ obj->Initialize = InitializeFourBlades;
+ obj->control = ControlFourBlades;
obj->collision = GenericSphereBoxCollision;
obj->SetHitEffect(true);
}
@@ -866,7 +851,8 @@ namespace TEN::Entities
obj = &Objects[ID_CEILING_4BLADES];
if (obj->loaded)
{
- obj->control = FourBladesControl;
+ obj->Initialize = InitializeFourBlades;
+ obj->control = ControlFourBlades;
obj->collision = GenericSphereBoxCollision;
obj->SetHitEffect(true);
}
@@ -883,8 +869,8 @@ namespace TEN::Entities
if (obj->loaded)
{
obj->Initialize = InitializeSlicerDicer;
- obj->control = SlicerDicerControl;
- obj->collision = BladeCollision;
+ obj->control = ControlSlicerDicer;
+ obj->collision = CollideBlade;
obj->SetHitEffect(true);
}
@@ -892,8 +878,8 @@ namespace TEN::Entities
if (obj->loaded)
{
obj->Initialize = InitializeMine;
- obj->control = MineControl;
- obj->collision = MineCollision;
+ obj->control = ControlMine;
+ obj->collision = CollideMine;
}
obj = &Objects[ID_SPIKY_WALL];
@@ -917,8 +903,8 @@ namespace TEN::Entities
obj = &Objects[ID_COG];
if (obj->loaded)
{
- obj->control = CogControl;
- obj->collision = CogCollision;
+ obj->control = ControlCog;
+ obj->collision = CollideCog;
obj->SetHitEffect(true);
}
@@ -946,7 +932,7 @@ namespace TEN::Entities
obj = &Objects[ID_HAMMER];
if (obj->loaded)
{
- obj->control = HammerControl;
+ obj->control = ControlHammer;
obj->collision = GenericSphereBoxCollision;
obj->SetHitEffect(true);
}
diff --git a/TombEngine/Objects/TR5/Trap/LaserBarrier.cpp b/TombEngine/Objects/TR5/Trap/LaserBarrier.cpp
index cece3c862..45db36846 100644
--- a/TombEngine/Objects/TR5/Trap/LaserBarrier.cpp
+++ b/TombEngine/Objects/TR5/Trap/LaserBarrier.cpp
@@ -13,7 +13,7 @@
using namespace TEN::Collision::Point;
using namespace TEN::Effects::Items;
-namespace TEN::Traps::TR5
+namespace TEN::Entities::Traps
{
// NOTES:
// item.ItemFlags[0] = barrier height.
diff --git a/TombEngine/Objects/TR5/Trap/LaserBarrier.h b/TombEngine/Objects/TR5/Trap/LaserBarrier.h
index 4f0f6bfa2..e2c9e6023 100644
--- a/TombEngine/Objects/TR5/Trap/LaserBarrier.h
+++ b/TombEngine/Objects/TR5/Trap/LaserBarrier.h
@@ -6,7 +6,7 @@ using namespace TEN::Math;
struct CollisionInfo;
struct ItemInfo;
-namespace TEN::Traps::TR5
+namespace TEN::Entities::Traps
{
struct LaserBarrierBeam
{
diff --git a/TombEngine/Objects/TR5/Trap/LaserBeam.cpp b/TombEngine/Objects/TR5/Trap/LaserBeam.cpp
index ae227bcbc..18ee502f5 100644
--- a/TombEngine/Objects/TR5/Trap/LaserBeam.cpp
+++ b/TombEngine/Objects/TR5/Trap/LaserBeam.cpp
@@ -21,7 +21,7 @@ using namespace TEN::Effects::Spark;
using namespace TEN::Math;
using namespace TEN::Renderer;
-namespace TEN::Traps::TR5
+namespace TEN::Entities::Traps
{
constexpr auto LASER_BEAM_LIGHT_INTENSITY = 0.2f;
constexpr auto LASER_BEAM_LIGHT_AMPLITUDE_MAX = 0.1f;
diff --git a/TombEngine/Objects/TR5/Trap/LaserBeam.h b/TombEngine/Objects/TR5/Trap/LaserBeam.h
index 168e1e2fc..ab6569c68 100644
--- a/TombEngine/Objects/TR5/Trap/LaserBeam.h
+++ b/TombEngine/Objects/TR5/Trap/LaserBeam.h
@@ -6,7 +6,7 @@ using namespace TEN::Math;
struct CollisionInfo;
struct ItemInfo;
-namespace TEN::Traps::TR5
+namespace TEN::Entities::Traps
{
struct LaserBeamEffect
{
diff --git a/TombEngine/Objects/TR5/Trap/ZipLine.cpp b/TombEngine/Objects/TR5/Trap/ZipLine.cpp
index e53c5bcae..661ecfc8b 100644
--- a/TombEngine/Objects/TR5/Trap/ZipLine.cpp
+++ b/TombEngine/Objects/TR5/Trap/ZipLine.cpp
@@ -17,7 +17,7 @@ using namespace TEN::Collision::Point;
using namespace TEN::Input;
using namespace TEN::Math;
-namespace TEN::Traps::TR5
+namespace TEN::Entities::Traps
{
const auto ZipLineInteractOffset = Vector3i(0, 0, 371);
const auto ZipLineInteractBasis = ObjectCollisionBounds
diff --git a/TombEngine/Objects/TR5/Trap/ZipLine.h b/TombEngine/Objects/TR5/Trap/ZipLine.h
index 3cdcb5c50..5c5c2fbab 100644
--- a/TombEngine/Objects/TR5/Trap/ZipLine.h
+++ b/TombEngine/Objects/TR5/Trap/ZipLine.h
@@ -3,7 +3,7 @@
struct CollisionInfo;
struct ItemInfo;
-namespace TEN::Traps::TR5
+namespace TEN::Entities::Traps
{
void InitializeZipLine(short itemNumber);
void CollideZipLine(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll);
diff --git a/TombEngine/Objects/TR5/Trap/tr5_explosion.cpp b/TombEngine/Objects/TR5/Trap/tr5_explosion.cpp
index 70bf86659..b80b0de18 100644
--- a/TombEngine/Objects/TR5/Trap/tr5_explosion.cpp
+++ b/TombEngine/Objects/TR5/Trap/tr5_explosion.cpp
@@ -23,168 +23,175 @@
using namespace TEN::Effects::Items;
using namespace TEN::Entities::Switches;
-void InitializeExplosion(short itemNumber)
+namespace TEN::Entities::Traps
{
- auto* item = &g_Level.Items[itemNumber];
-
- if (item->TriggerFlags >= 30000)
+ void InitializeExplosion(short itemNumber)
{
- item->ItemFlags[1] = 3;
- item->TriggerFlags -= 30000;
- }
- else if (item->TriggerFlags >= 20000)
- {
- item->ItemFlags[1] = 2;
- item->TriggerFlags -= 20000;
- }
- else if (item->TriggerFlags >= 10000)
- {
- item->ItemFlags[1] = 1;
- item->TriggerFlags -= 10000;
- }
+ auto& item = g_Level.Items[itemNumber];
- if (item->TriggerFlags >= 1000)
- {
- item->ItemFlags[3] = 1;
- item->TriggerFlags -= 1000;
- }
-
- item->ItemFlags[2] = item->TriggerFlags / 100;
- item->TriggerFlags = 7 * (item->TriggerFlags % 100);
-}
-
-void ExplosionControl(short itemNumber)
-{
- auto* item = &g_Level.Items[itemNumber];
-
- if (TriggerActive(item))
- {
- item->Flags |= IFLAG_INVISIBLE;
-
- if (item->ItemFlags[0] < item->TriggerFlags)
+ if (item.TriggerFlags >= 30000)
{
- ++item->ItemFlags[0];
+ item.ItemFlags[1] = 3;
+ item.TriggerFlags -= 30000;
}
- else if (item->ItemFlags[0] == item->TriggerFlags)
+ else if (item.TriggerFlags >= 20000)
{
- int flag;
- ++item->ItemFlags[0];
+ item.ItemFlags[1] = 2;
+ item.TriggerFlags -= 20000;
+ }
+ else if (item.TriggerFlags >= 10000)
+ {
+ item.ItemFlags[1] = 1;
+ item.TriggerFlags -= 10000;
+ }
- if (TestEnvironment(ENV_FLAG_WATER, item->RoomNumber) ||
- TestEnvironment(ENV_FLAG_SWAMP, item->RoomNumber))
- {
- flag = 1;
- }
- else
- {
- flag = item->ItemFlags[1] == 1 ? 2 : 0;
- }
-
- SoundEffect(SFX_TR4_EXPLOSION1, &item->Pose, SoundEnvironment::Land, 1.5f);
- SoundEffect(SFX_TR4_EXPLOSION2, &item->Pose);
- TriggerExplosionSparks(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, 3, -2, flag, item->RoomNumber);
-
- for (int i = 0; i < item->ItemFlags[2]; ++i)
- {
- TriggerExplosionSparks(
- item->Pose.Position.x + (GetRandomControl() % 128 - 64) * item->ItemFlags[2],
- item->Pose.Position.y + (GetRandomControl() % 128 - 64) * item->ItemFlags[2],
- item->Pose.Position.z + (GetRandomControl() % 128 - 64) * item->ItemFlags[2],
- 2, 0, flag, item->RoomNumber);
- }
-
- Pose pos;
- pos.Position.x = item->Pose.Position.x;
- pos.Position.y = item->Pose.Position.y - 128;
- pos.Position.z = item->Pose.Position.z;
-
- if (item->ItemFlags[3])
- {
- if (flag == 2)
- TriggerShockwave(&pos, 48, 32 * item->ItemFlags[2] + 304, 4 * item->ItemFlags[2] + 96, 0, 96, 128, 24, EulerAngles(2048, 0.0f, 0.0f), 0, true, false, false, (int)ShockwaveStyle::Normal);
- else
- TriggerShockwave(&pos, 48, 32 * item->ItemFlags[2] + 304, 4 * item->ItemFlags[2] + 96, 128, 96, 0, 24, EulerAngles(2048, 0.0f, 0.0f), 0, true, false, false, (int)ShockwaveStyle::Normal);
- }
+ if (item.TriggerFlags >= 1000)
+ {
+ item.ItemFlags[3] = 1;
+ item.TriggerFlags -= 1000;
+ }
- if (flag != 2)
- {
- auto vec = GetJointPosition(LaraItem, LM_HIPS);
+ item.ItemFlags[2] = item.TriggerFlags / 100;
+ item.TriggerFlags = 7 * (item.TriggerFlags % 100);
+ }
- int dx = vec.x - item->Pose.Position.x;
- int dy = vec.y - item->Pose.Position.y;
- int dz = vec.z - item->Pose.Position.z;
-
- if (abs(dx) < BLOCK(1) &&
- abs(dy) < BLOCK(1) &&
- abs(dz) < BLOCK(1))
+ void ControlExplosion(short itemNumber)
+ {
+ auto& item = g_Level.Items[itemNumber];
+
+ if (TriggerActive(&item))
+ {
+ item.Flags |= IFLAG_INVISIBLE;
+
+ if (item.ItemFlags[0] < item.TriggerFlags)
+ {
+ ++item.ItemFlags[0];
+ }
+ else if (item.ItemFlags[0] == item.TriggerFlags)
+ {
+ int flag;
+ ++item.ItemFlags[0];
+
+ if (TestEnvironment(ENV_FLAG_WATER, item.RoomNumber) ||
+ TestEnvironment(ENV_FLAG_SWAMP, item.RoomNumber))
{
- int distance = sqrt(pow(dx, 2) + pow(dy, 2) + pow(dz, 2));
- if (distance < BLOCK(2))
- {
- DoDamage(LaraItem, distance / 16);
-
- if (distance < CLICK(3))
- ItemBurn(LaraItem);
- }
+ flag = 1;
}
- }
-
- auto collObjects = GetCollidedObjects(*item, true, true, BLOCK(2), ObjectCollectionMode::All);
- if (!collObjects.IsEmpty())
- {
- for (auto* itemPtr : collObjects.Items)
+ else
{
- if (itemPtr->ObjectNumber >= ID_SMASH_OBJECT1 && itemPtr->ObjectNumber <= ID_SMASH_OBJECT16)
+ flag = item.ItemFlags[1] == 1 ? 2 : 0;
+ }
+
+ SoundEffect(SFX_TR4_EXPLOSION1, &item.Pose, SoundEnvironment::Land, 1.5f);
+ SoundEffect(SFX_TR4_EXPLOSION2, &item.Pose);
+ TriggerExplosionSparks(item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z, 3, -2, flag, item.RoomNumber);
+
+ for (int i = 0; i < item.ItemFlags[2]; ++i)
+ {
+ TriggerExplosionSparks(
+ item.Pose.Position.x + (GetRandomControl() % 128 - 64) * item.ItemFlags[2],
+ item.Pose.Position.y + (GetRandomControl() % 128 - 64) * item.ItemFlags[2],
+ item.Pose.Position.z + (GetRandomControl() % 128 - 64) * item.ItemFlags[2],
+ 2, 0, flag, item.RoomNumber);
+ }
+
+ auto pose = Pose::Zero;
+ pose.Position.x = item.Pose.Position.x;
+ pose.Position.y = item.Pose.Position.y - 128;
+ pose.Position.z = item.Pose.Position.z;
+
+ if (item.ItemFlags[3])
+ {
+ if (flag == 2)
{
- TriggerExplosionSparks(itemPtr->Pose.Position.x, itemPtr->Pose.Position.y, itemPtr->Pose.Position.z, 3, -2, 0, itemPtr->RoomNumber);
- itemPtr->Pose.Position.y -= 128;
- TriggerShockwave(&itemPtr->Pose, 48, 304, 96, 128, 96, 0, 24, EulerAngles::Identity, 0, true, false, false, (int)ShockwaveStyle::Normal);
- itemPtr->Pose.Position.y += 128;
- ExplodeItemNode(itemPtr, 0, 0, 80);
- SmashObject(itemPtr->Index);
- KillItem(itemPtr->Index);
- }
- else if (itemPtr->ObjectNumber != ID_SWITCH_TYPE7 && itemPtr->ObjectNumber != ID_SWITCH_TYPE8)
- {
- if (Objects[itemPtr->ObjectNumber].intelligent)
- DoExplosiveDamage(*LaraItem, *itemPtr, *item, Weapons[(int)LaraWeaponType::GrenadeLauncher].ExplosiveDamage);
+ TriggerShockwave(&pose, 48, 32 * item.ItemFlags[2] + 304, 4 * item.ItemFlags[2] + 96, 0, 96, 128, 24, EulerAngles(2048, 0.0f, 0.0f), 0, true, false, false, (int)ShockwaveStyle::Normal);
}
else
{
- // @FIXME: This calls CrossbowHitSwitchType78()
+ TriggerShockwave(&pose, 48, 32 * item.ItemFlags[2] + 304, 4 * item.ItemFlags[2] + 96, 128, 96, 0, 24, EulerAngles(2048, 0.0f, 0.0f), 0, true, false, false, (int)ShockwaveStyle::Normal);
}
}
- for (auto* staticPtr : collObjects.Statics)
+ if (flag != 2)
{
- if (StaticObjects[staticPtr->staticNumber].shatterType != ShatterType::None)
+ auto vec = GetJointPosition(LaraItem, LM_HIPS);
+
+ int dx = vec.x - item.Pose.Position.x;
+ int dy = vec.y - item.Pose.Position.y;
+ int dz = vec.z - item.Pose.Position.z;
+
+ if (abs(dx) < BLOCK(1) &&
+ abs(dy) < BLOCK(1) &&
+ abs(dz) < BLOCK(1))
{
- TriggerExplosionSparks(staticPtr->pos.Position.x, staticPtr->pos.Position.y, staticPtr->pos.Position.z, 3, -2, 0, item->RoomNumber);
- staticPtr->pos.Position.y -= 128;
- TriggerShockwave(&staticPtr->pos, 40, 176, 64, 128, 96, 0, 16, EulerAngles::Identity, 0, true, false, false, (int)ShockwaveStyle::Normal);
- staticPtr->pos.Position.y += 128;
- SoundEffect(GetShatterSound(staticPtr->staticNumber), &staticPtr->pos);
- ShatterObject(nullptr, staticPtr, -128, item->RoomNumber, 0);
+ int distance = sqrt(pow(dx, 2) + pow(dy, 2) + pow(dz, 2));
+ if (distance < BLOCK(2))
+ {
+ DoDamage(LaraItem, distance / 16);
+
+ if (distance < CLICK(3))
+ ItemBurn(LaraItem);
+ }
}
}
- AlertNearbyGuards(item);
- }
-
- if (item->ItemFlags[1] >= 2)
- {
- if (item->ItemFlags[1] == 3)
+ auto collObjects = GetCollidedObjects(item, true, true, BLOCK(2), ObjectCollectionMode::All);
+ if (!collObjects.IsEmpty())
{
- short triggerItems[8];
- for (int i = GetSwitchTrigger(item, triggerItems, 1); i > 0; --i)
- g_Level.Items[triggerItems[i - 1]].ItemFlags[0] = 0;
-
- item->ItemFlags[0] = 0;
+ for (auto* itemPtr : collObjects.Items)
+ {
+ if (itemPtr->ObjectNumber >= ID_SMASH_OBJECT1 && itemPtr->ObjectNumber <= ID_SMASH_OBJECT16)
+ {
+ TriggerExplosionSparks(itemPtr->Pose.Position.x, itemPtr->Pose.Position.y, itemPtr->Pose.Position.z, 3, -2, 0, itemPtr->RoomNumber);
+ itemPtr->Pose.Position.y -= 128;
+ TriggerShockwave(&itemPtr->Pose, 48, 304, 96, 128, 96, 0, 24, EulerAngles::Identity, 0, true, false, false, (int)ShockwaveStyle::Normal);
+ itemPtr->Pose.Position.y += 128;
+ ExplodeItemNode(itemPtr, 0, 0, 80);
+ SmashObject(itemPtr->Index);
+ KillItem(itemPtr->Index);
+ }
+ else if (itemPtr->ObjectNumber != ID_SWITCH_TYPE7 && itemPtr->ObjectNumber != ID_SWITCH_TYPE8)
+ {
+ if (Objects[itemPtr->ObjectNumber].intelligent)
+ DoExplosiveDamage(*LaraItem, *itemPtr, item, Weapons[(int)LaraWeaponType::GrenadeLauncher].ExplosiveDamage);
+ }
+ else
+ {
+ // @FIXME: This calls CrossbowHitSwitchType78()
+ }
+ }
+
+ for (auto* staticPtr : collObjects.Statics)
+ {
+ if (StaticObjects[staticPtr->staticNumber].shatterType != ShatterType::None)
+ {
+ TriggerExplosionSparks(staticPtr->pos.Position.x, staticPtr->pos.Position.y, staticPtr->pos.Position.z, 3, -2, 0, item.RoomNumber);
+ staticPtr->pos.Position.y -= 128;
+ TriggerShockwave(&staticPtr->pos, 40, 176, 64, 128, 96, 0, 16, EulerAngles::Identity, 0, true, false, false, (int)ShockwaveStyle::Normal);
+ staticPtr->pos.Position.y += 128;
+ SoundEffect(GetShatterSound(staticPtr->staticNumber), &staticPtr->pos);
+ ShatterObject(nullptr, staticPtr, -128, item.RoomNumber, 0);
+ }
+ }
+
+ AlertNearbyGuards(&item);
+ }
+
+ if (item.ItemFlags[1] >= 2)
+ {
+ if (item.ItemFlags[1] == 3)
+ {
+ short triggerItems[8];
+ for (int i = GetSwitchTrigger(&item, triggerItems, 1); i > 0; --i)
+ g_Level.Items[triggerItems[i - 1]].ItemFlags[0] = 0;
+
+ item.ItemFlags[0] = 0;
+ }
+ }
+ else
+ {
+ KillItem(itemNumber);
}
- }
- else
- {
- KillItem(itemNumber);
}
}
}
diff --git a/TombEngine/Objects/TR5/Trap/tr5_explosion.h b/TombEngine/Objects/TR5/Trap/tr5_explosion.h
index d8e67972e..54f49956b 100644
--- a/TombEngine/Objects/TR5/Trap/tr5_explosion.h
+++ b/TombEngine/Objects/TR5/Trap/tr5_explosion.h
@@ -1,4 +1,7 @@
#pragma once
-void InitializeExplosion(short itemNumber);
-void ExplosionControl(short itemNumber);
+namespace TEN::Entities::Traps
+{
+ void InitializeExplosion(short itemNumber);
+ void ControlExplosion(short itemNumber);
+}
diff --git a/TombEngine/Objects/TR5/Trap/tr5_fallingceiling.cpp b/TombEngine/Objects/TR5/Trap/tr5_fallingceiling.cpp
index a086231d5..624b65c70 100644
--- a/TombEngine/Objects/TR5/Trap/tr5_fallingceiling.cpp
+++ b/TombEngine/Objects/TR5/Trap/tr5_fallingceiling.cpp
@@ -11,42 +11,49 @@
using namespace TEN::Collision::Point;
-void FallingCeilingControl(short itemNumber)
+namespace TEN::Entities::Traps
{
- auto* item = &g_Level.Items[itemNumber];
+ constexpr auto FALLING_CEILING_HARM_DAMAGE = 300;
- if (item->Animation.ActiveState)
+ void ControlFallingCeiling(short itemNumber)
{
- if (item->Animation.ActiveState == 1 && item->TouchBits.TestAny())
- DoDamage(LaraItem, 300);
- }
- else
- {
- item->Animation.TargetState = 1;
- item->Animation.IsAirborne = true;
- }
+ auto& item = g_Level.Items[itemNumber];
- AnimateItem(item);
-
- if (item->Status == ITEM_DEACTIVATED)
- RemoveActiveItem(itemNumber);
- else
- {
- auto probe = GetPointCollision(*item);
-
- item->Floor = probe.GetFloorHeight();
-
- if (probe.GetRoomNumber() != item->RoomNumber)
- ItemNewRoom(itemNumber, probe.GetRoomNumber());
-
- if (item->Animation.ActiveState == 1)
+ if (item.Animation.ActiveState)
{
- if (item->Pose.Position.y >= item->Floor)
+ if (item.Animation.ActiveState == 1 && item.TouchBits.TestAny())
+ DoDamage(LaraItem, FALLING_CEILING_HARM_DAMAGE);
+ }
+ else
+ {
+ item.Animation.TargetState = 1;
+ item.Animation.IsAirborne = true;
+ }
+
+ AnimateItem(&item);
+
+ if (item.Status == ITEM_DEACTIVATED)
+ {
+ RemoveActiveItem(itemNumber);
+ }
+ else
+ {
+ auto pointColl = GetPointCollision(item);
+
+ item.Floor = pointColl.GetFloorHeight();
+
+ if (pointColl.GetRoomNumber() != item.RoomNumber)
+ ItemNewRoom(itemNumber, pointColl.GetRoomNumber());
+
+ if (item.Animation.ActiveState == 1)
{
- item->Pose.Position.y = item->Floor;
- item->Animation.TargetState = 2;
- item->Animation.IsAirborne = false;
- item->Animation.Velocity.y = 0.0f;
+ if (item.Pose.Position.y >= item.Floor)
+ {
+ item.Pose.Position.y = item.Floor;
+ item.Animation.TargetState = 2;
+ item.Animation.IsAirborne = false;
+ item.Animation.Velocity.y = 0.0f;
+ }
}
}
}
diff --git a/TombEngine/Objects/TR5/Trap/tr5_fallingceiling.h b/TombEngine/Objects/TR5/Trap/tr5_fallingceiling.h
index dc01af23d..30f0ab103 100644
--- a/TombEngine/Objects/TR5/Trap/tr5_fallingceiling.h
+++ b/TombEngine/Objects/TR5/Trap/tr5_fallingceiling.h
@@ -1,3 +1,6 @@
#pragma once
-void FallingCeilingControl(short itemNumber);
+namespace TEN::Entities::Traps
+{
+ void ControlFallingCeiling(short itemNumber);
+}
diff --git a/TombEngine/Objects/TR5/Trap/tr5_romehammer.cpp b/TombEngine/Objects/TR5/Trap/tr5_romehammer.cpp
index 9b26ff77c..14d198faf 100644
--- a/TombEngine/Objects/TR5/Trap/tr5_romehammer.cpp
+++ b/TombEngine/Objects/TR5/Trap/tr5_romehammer.cpp
@@ -4,10 +4,38 @@
#include "Game/items.h"
#include "Specific/level.h"
-void InitializeRomeHammer(short itemNumber)
-{
- auto* item = &g_Level.Items[itemNumber];
+// NOTES:
+// item.ItemFlags[0] = Harm joints.
+// item.ItemFlags[3] = Damage.
+// item.ItemFlags[4] = Push player (bool).
- item->ItemFlags[0] = 2;
- item->ItemFlags[3] = 250;
+namespace TEN::Entities::Traps
+{
+ constexpr auto ROME_HAMMER_HARM_DAMAGE = 250;
+ constexpr auto ROME_HAMMER_JOINTS = MESH_BITS(1);
+
+ const auto RomeHammerHarmJoints = std::vector{ 2 };
+
+ void InitializeRomeHammer(short itemNumber)
+ {
+ auto& item = g_Level.Items[itemNumber];
+
+ item.ItemFlags[0] = ROME_HAMMER_JOINTS;
+ item.ItemFlags[3] = 0;
+ }
+
+ void ControlRomeHammer(short itemNumber)
+ {
+ auto& item = g_Level.Items[itemNumber];
+
+ if (TriggerActive(&item))
+ {
+ item.ItemFlags[3] = ROME_HAMMER_HARM_DAMAGE;
+ AnimateItem(&item);
+ }
+ else
+ {
+ item.ItemFlags[3] = 0;
+ }
+ }
}
diff --git a/TombEngine/Objects/TR5/Trap/tr5_romehammer.h b/TombEngine/Objects/TR5/Trap/tr5_romehammer.h
index fe2442331..0b436861f 100644
--- a/TombEngine/Objects/TR5/Trap/tr5_romehammer.h
+++ b/TombEngine/Objects/TR5/Trap/tr5_romehammer.h
@@ -1,3 +1,7 @@
#pragma once
-void InitializeRomeHammer(short itemNumber);
+namespace TEN::Entities::Traps
+{
+ void InitializeRomeHammer(short itemNumber);
+ void ControlRomeHammer(short itemNumber);
+}
diff --git a/TombEngine/Objects/TR5/Trap/tr5_ventilator.cpp b/TombEngine/Objects/TR5/Trap/tr5_ventilator.cpp
index 37515b543..d6ffc7706 100644
--- a/TombEngine/Objects/TR5/Trap/tr5_ventilator.cpp
+++ b/TombEngine/Objects/TR5/Trap/tr5_ventilator.cpp
@@ -9,305 +9,327 @@
#include "Game/Lara/lara.h"
#include "Specific/level.h"
-void VentilatorEffect(GameBoundingBox* bounds, int intensity, short rot, int speed)
+namespace TEN::Entities::Traps
{
- int x, y, z;
+ void VentilatorEffect(GameBoundingBox* bounds, int intensity, short rot, int speed)
+ {
+ int x, y, z;
- if (abs(intensity) == 1)
- {
- x = (bounds->X1 + bounds->X2) / 2;
- if (intensity >= 0)
- y = bounds->Y2;
- else
- y = bounds->Y1;
- z = (bounds->Z1 + bounds->Z2) / 2;
- }
- else
- {
- y = (bounds->Y1 + bounds->Y2) / 2;
- if (rot & 0x7FFF)
+ if (abs(intensity) == 1)
{
- if (intensity >= 0)
- z = bounds->Z2;
- else
- z = bounds->Z1;
x = (bounds->X1 + bounds->X2) / 2;
- }
- else
- {
if (intensity >= 0)
- x = bounds->X2;
+ {
+ y = bounds->Y2;
+ }
else
- x = bounds->X1;
+ {
+ y = bounds->Y1;
+ }
z = (bounds->Z1 + bounds->Z2) / 2;
}
- }
-
- if (abs(Camera.pos.x - x) <= BLOCK(7))
- {
- if (abs(Camera.pos.y - y) <= BLOCK(7))
- {
- if (abs(Camera.pos.z - z) <= BLOCK(7))
- {
- auto* spark = GetFreeParticle();
-
- spark->on = 1;
- spark->sR = 0;
- spark->sG = 0;
- spark->sB = 0;
- spark->dR = spark->dG = (48 * speed) / 128;
- spark->colFadeSpeed = 4;
- spark->fadeToBlack = 8;
- spark->dB = (speed * ((GetRandomControl() & 8) + 48)) / 128;
- spark->blendMode = BlendMode::Additive;
- spark->life = spark->sLife = (GetRandomControl() & 3) + 20;
-
- if (abs(intensity) == 1)
- {
- int factor = 3 * (bounds->X2 - bounds->X1) / 8;
- short angle = 2 * GetRandomControl();
-
- spark->x = ((bounds->X1 + bounds->X2) / 2) + (GetRandomControl() % factor) * phd_sin(angle);
- spark->z = ((bounds->Z1 + bounds->Z2) / 2) + (GetRandomControl() % factor) * phd_cos(angle);
-
- if (intensity >= 0)
- spark->y = bounds->Y2;
- else
- spark->y = bounds->Y1;
-
- spark->zVel = 0;
- spark->xVel = 0;
- spark->yVel = 32 * intensity * ((GetRandomControl() & 0x1F) + 224);
- }
- else
- {
- int factor = 3 * bounds->GetHeight() / 8;
- short angle = 2 * GetRandomControl();
-
- spark->y = (bounds->Y1 + bounds->Y2) / 2;
-
- if (rot & 0x7FFF)
- {
- if (intensity >= 0)
- spark->z = bounds->Z2;
- else
- spark->z = bounds->Z1;
-
- spark->x = ((bounds->X1 + bounds->X2) / 2) + (GetRandomControl() % factor) * phd_cos(angle);
- spark->y += (GetRandomControl() % factor) * phd_sin(angle);
- spark->xVel = 0;
- spark->zVel = 16 * intensity * ((GetRandomControl() & 0x1F) + 224);
- }
- else
- {
- if (intensity >= 0)
- spark->x = bounds->X2;
- else
- spark->x = bounds->X1;
-
- spark->y += (GetRandomControl() % factor) * phd_sin(angle);
- spark->z = ((bounds->Z1 + bounds->Z2) / 2) + (GetRandomControl() % factor) * phd_cos(angle);
- spark->zVel = 0;
- spark->xVel = 16 * intensity * ((GetRandomControl() & 0x1F) + 224);
- }
-
- spark->yVel = 0;
- }
-
- spark->friction = 85;
- spark->xVel = (speed * spark->xVel) / 128;
- spark->yVel = (speed * spark->yVel) / 128;
- spark->zVel = (speed * spark->zVel) / 128;
- spark->maxYvel = 0;
- spark->gravity = 0;
- spark->flags = SP_NONE;
- }
- }
- }
-}
-
-void InitializeVentilator(short itemNumber)
-{
- auto* item = &g_Level.Items[itemNumber];
-
- item->ItemFlags[0] = item->TriggerFlags * BLOCK(1);
- if (item->ItemFlags[0] < 2048)
- item->ItemFlags[0] = 3072;
-}
-
-void VentilatorControl(short itemNumber)
-{
- auto* item = &g_Level.Items[itemNumber];
-
- AnimateItem(item);
-
- int xChange = 0;
- int zChange = 0;
-
- if (TriggerActive(item))
- xChange = 1;
- else
- {
- xChange = 1;
- TestTriggers(item, true);
- if (item->Animation.ActiveState == 1)
- {
- //result = 5 * item->animNumber;
- if (item->Animation.FrameNumber == GetAnimData(item).frameEnd)
- return;
- }
else
- item->Animation.TargetState = 1;
- }
-
- int speed = 0;
- if (item->Animation.ActiveState == 1)
- speed = GetAnimData(item).frameEnd - item->Animation.FrameNumber;
- else
- speed = 128;
-
- auto bounds = GameBoundingBox(item);
- auto effectBounds = GameBoundingBox::Zero;
-
- effectBounds.Y1 = item->Pose.Position.y + bounds.Y1;
- effectBounds.Y2 = item->Pose.Position.y + bounds.Y2;
-
- if (item->ObjectNumber != ID_PROPELLER_V) // TODO: check this ID
- {
- if (item->Pose.Orientation.y != -ANGLE(180.0f))
{
- if (item->Pose.Orientation.y == -ANGLE(90.0f))
+ y = (bounds->Y1 + bounds->Y2) / 2;
+ if (rot & 0x7FFF)
{
- effectBounds.X1 = item->Pose.Position.x - bounds.Z2;
- effectBounds.X2 = item->Pose.Position.x - bounds.Z1;
- effectBounds.Z1 = item->Pose.Position.z + bounds.X1;
- effectBounds.Z2 = item->Pose.Position.z + bounds.X2;
- xChange = 0;
- zChange = 1;
+ if (intensity >= 0)
+ z = bounds->Z2;
+ else
+ z = bounds->Z1;
+ x = (bounds->X1 + bounds->X2) / 2;
}
else
{
- if (item->Pose.Orientation.y != ANGLE(90.0f))
+ if (intensity >= 0)
+ x = bounds->X2;
+ else
+ x = bounds->X1;
+ z = (bounds->Z1 + bounds->Z2) / 2;
+ }
+ }
+
+ auto& part = *GetFreeParticle();
+
+ part.on = 1;
+ part.sR = 0;
+ part.sG = 0;
+ part.sB = 0;
+ part.dR = part.dG = (48 * speed) / 128;
+ part.colFadeSpeed = 4;
+ part.fadeToBlack = 8;
+ part.dB = (speed * ((GetRandomControl() & 8) + 48)) / 128;
+ part.blendMode = BlendMode::Additive;
+ part.life = part.sLife = (GetRandomControl() & 3) + 20;
+
+ if (abs(intensity) == 1)
+ {
+ int factor = 3 * (bounds->X2 - bounds->X1) / 8;
+ short angle = 2 * GetRandomControl();
+
+ part.x = ((bounds->X1 + bounds->X2) / 2) + (GetRandomControl() % factor) * phd_sin(angle);
+ part.z = ((bounds->Z1 + bounds->Z2) / 2) + (GetRandomControl() % factor) * phd_cos(angle);
+
+ if (intensity >= 0)
+ {
+ part.y = bounds->Y2;
+ }
+ else
+ {
+ part.y = bounds->Y1;
+ }
+
+ part.zVel = 0;
+ part.xVel = 0;
+ part.yVel = 32 * intensity * ((GetRandomControl() & 0x1F) + 224);
+ }
+ else
+ {
+ int factor = 3 * bounds->GetHeight() / 8;
+ short angle = Random::GenerateAngle();
+
+ part.y = (bounds->Y1 + bounds->Y2) / 2;
+
+ if (rot & 0x7FFF)
+ {
+ if (intensity >= 0)
{
- effectBounds.X1 = item->Pose.Position.x + bounds.X1;
- effectBounds.X2 = item->Pose.Position.x + bounds.X2;
- effectBounds.Z1 = item->Pose.Position.z + bounds.Z1;
- effectBounds.Z2 = item->Pose.Position.z + bounds.Z2;
- zChange = 0;
+ part.z = bounds->Z2;
}
else
{
- effectBounds.X1 = item->Pose.Position.x + bounds.Z1;
- effectBounds.X2 = item->Pose.Position.x + bounds.Z2;
- effectBounds.Z1 = item->Pose.Position.z - bounds.X2;
- effectBounds.Z2 = item->Pose.Position.z - bounds.X1;
+ part.z = bounds->Z1;
+ }
+
+ part.x = ((bounds->X1 + bounds->X2) / 2) + (GetRandomControl() % factor) * phd_cos(angle);
+ part.y += (GetRandomControl() % factor) * phd_sin(angle);
+ part.xVel = 0;
+ part.zVel = 16 * intensity * ((GetRandomControl() & 0x1F) + 224);
+ }
+ else
+ {
+ if (intensity >= 0)
+ {
+ part.x = bounds->X2;
+ }
+ else
+ {
+ part.x = bounds->X1;
+ }
+
+ part.y += (GetRandomControl() % factor) * phd_sin(angle);
+ part.z = ((bounds->Z1 + bounds->Z2) / 2) + (GetRandomControl() % factor) * phd_cos(angle);
+ part.zVel = 0;
+ part.xVel = 16 * intensity * ((GetRandomControl() & 0x1F) + 224);
+ }
+
+ part.yVel = 0;
+ }
+
+ part.friction = 85;
+ part.xVel = (speed * part.xVel) / 128;
+ part.yVel = (speed * part.yVel) / 128;
+ part.zVel = (speed * part.zVel) / 128;
+ part.maxYvel = 0;
+ part.gravity = 0;
+ part.flags = SP_NONE;
+ }
+
+ void InitializeVentilator(short itemNumber)
+ {
+ auto& item = g_Level.Items[itemNumber];
+
+ item.ItemFlags[0] = item.TriggerFlags * BLOCK(1);
+ if (item.ItemFlags[0] < 2048)
+ item.ItemFlags[0] = 3072;
+ }
+
+ void ControlVentilator(short itemNumber)
+ {
+ auto& item = g_Level.Items[itemNumber];
+
+ AnimateItem(&item);
+
+ int xChange = 0;
+ int zChange = 0;
+
+ if (TriggerActive(&item))
+ {
+ xChange = 1;
+ }
+ else
+ {
+ xChange = 1;
+ TestTriggers(&item, true);
+ if (item.Animation.ActiveState == 1)
+ {
+ // result = 5 * item.animNumber;
+ if (item.Animation.FrameNumber == GetAnimData(item).frameEnd)
+ return;
+ }
+ else
+ {
+ item.Animation.TargetState = 1;
+ }
+ }
+
+ int speed = 0;
+ if (item.Animation.ActiveState == 1)
+ {
+ speed = GetAnimData(item).frameEnd - item.Animation.FrameNumber;
+ }
+ else
+ {
+ speed = 128;
+ }
+
+ auto bounds = GameBoundingBox(&item);
+ auto effectBounds = GameBoundingBox::Zero;
+
+ effectBounds.Y1 = item.Pose.Position.y + bounds.Y1;
+ effectBounds.Y2 = item.Pose.Position.y + bounds.Y2;
+
+ if (item.ObjectNumber != ID_PROPELLER_V) // TODO: check this ID
+ {
+ if (item.Pose.Orientation.y != -ANGLE(180.0f))
+ {
+ if (item.Pose.Orientation.y == -ANGLE(90.0f))
+ {
+ effectBounds.X1 = item.Pose.Position.x - bounds.Z2;
+ effectBounds.X2 = item.Pose.Position.x - bounds.Z1;
+ effectBounds.Z1 = item.Pose.Position.z + bounds.X1;
+ effectBounds.Z2 = item.Pose.Position.z + bounds.X2;
xChange = 0;
zChange = 1;
}
- }
- }
- else
- {
- effectBounds.X1 = item->Pose.Position.x - bounds.X2;
- effectBounds.X2 = item->Pose.Position.x - bounds.X1;
- effectBounds.Z1 = item->Pose.Position.z - bounds.Z2;
- effectBounds.Z2 = item->Pose.Position.z - bounds.Z1;
- zChange = 0;
- }
-
- VentilatorEffect(&effectBounds, 2, item->Pose.Orientation.y, speed);
- VentilatorEffect(&effectBounds, -2, item->Pose.Orientation.y, speed);
-
- if (LaraItem->Pose.Position.y >= effectBounds.Y1 && LaraItem->Pose.Position.y <= effectBounds.Y2)
- {
- if (zChange)
- {
- if (LaraItem->Pose.Position.x >= effectBounds.X1 && LaraItem->Pose.Position.x <= effectBounds.X2)
+ else
{
- int z1 = abs(LaraItem->Pose.Position.z - effectBounds.Z1);
- int z2 = abs(LaraItem->Pose.Position.z - effectBounds.Z2);
-
- if (z2 >= z1)
- zChange = -zChange;
- else
- z1 = z2;
-
- if (z1 < item->ItemFlags[0])
+ if (item.Pose.Orientation.y != ANGLE(90.0f))
{
- int dz = 96 * zChange * (item->ItemFlags[0] - z1) / item->ItemFlags[0];
-
- if (item->Animation.ActiveState == 1)
- dz = speed * dz / 120;
-
- LaraItem->Pose.Position.z += dz;
+ effectBounds.X1 = item.Pose.Position.x + bounds.X1;
+ effectBounds.X2 = item.Pose.Position.x + bounds.X2;
+ effectBounds.Z1 = item.Pose.Position.z + bounds.Z1;
+ effectBounds.Z2 = item.Pose.Position.z + bounds.Z2;
+ zChange = 0;
+ }
+ else
+ {
+ effectBounds.X1 = item.Pose.Position.x + bounds.Z1;
+ effectBounds.X2 = item.Pose.Position.x + bounds.Z2;
+ effectBounds.Z1 = item.Pose.Position.z - bounds.X2;
+ effectBounds.Z2 = item.Pose.Position.z - bounds.X1;
+ xChange = 0;
+ zChange = 1;
}
}
}
else
{
- if (LaraItem->Pose.Position.z >= effectBounds.Z1 && LaraItem->Pose.Position.z <= effectBounds.Z2)
+ effectBounds.X1 = item.Pose.Position.x - bounds.X2;
+ effectBounds.X2 = item.Pose.Position.x - bounds.X1;
+ effectBounds.Z1 = item.Pose.Position.z - bounds.Z2;
+ effectBounds.Z2 = item.Pose.Position.z - bounds.Z1;
+ zChange = 0;
+ }
+
+ VentilatorEffect(&effectBounds, 2, item.Pose.Orientation.y, speed);
+ VentilatorEffect(&effectBounds, -2, item.Pose.Orientation.y, speed);
+
+ if (LaraItem->Pose.Position.y >= effectBounds.Y1 && LaraItem->Pose.Position.y <= effectBounds.Y2)
+ {
+ if (zChange)
{
- int x1 = abs(LaraItem->Pose.Position.x - effectBounds.X1);
- int x2 = abs(LaraItem->Pose.Position.x - effectBounds.X2);
-
- if (x2 >= x1)
- xChange = -xChange;
- else
- x1 = x2;
-
- if (x1 < item->ItemFlags[0])
+ if (LaraItem->Pose.Position.x >= effectBounds.X1 && LaraItem->Pose.Position.x <= effectBounds.X2)
{
- int dx = 96 * xChange * (item->ItemFlags[0] - x1) / item->ItemFlags[0];
+ int z1 = abs(LaraItem->Pose.Position.z - effectBounds.Z1);
+ int z2 = abs(LaraItem->Pose.Position.z - effectBounds.Z2);
- if (item->Animation.ActiveState == 1)
- dx = speed * dx / 120;
+ if (z2 >= z1)
+ zChange = -zChange;
+ else
+ z1 = z2;
- LaraItem->Pose.Position.x += dx;
+ if (z1 < item.ItemFlags[0])
+ {
+ int dz = 96 * zChange * (item.ItemFlags[0] - z1) / item.ItemFlags[0];
+
+ if (item.Animation.ActiveState == 1)
+ dz = speed * dz / 120;
+
+ LaraItem->Pose.Position.z += dz;
+ }
+ }
+ }
+ else
+ {
+ if (LaraItem->Pose.Position.z >= effectBounds.Z1 && LaraItem->Pose.Position.z <= effectBounds.Z2)
+ {
+ int x1 = abs(LaraItem->Pose.Position.x - effectBounds.X1);
+ int x2 = abs(LaraItem->Pose.Position.x - effectBounds.X2);
+
+ if (x2 >= x1)
+ {
+ xChange = -xChange;
+ }
+ else
+ {
+ x1 = x2;
+ }
+
+ if (x1 < item.ItemFlags[0])
+ {
+ int dx = 96 * xChange * (item.ItemFlags[0] - x1) / item.ItemFlags[0];
+
+ if (item.Animation.ActiveState == 1)
+ dx = speed * dx / 120;
+
+ LaraItem->Pose.Position.x += dx;
+ }
}
}
}
}
- }
- else
- {
- auto tBounds = bounds;
- tBounds.Rotate(item->Pose.Orientation);
-
- effectBounds.X1 = item->Pose.Position.x + tBounds.X1;
- effectBounds.X2 = item->Pose.Position.x + tBounds.X2;
- effectBounds.Z1 = item->Pose.Position.z + tBounds.Z1;
- effectBounds.Z2 = item->Pose.Position.z + tBounds.Z2;
-
- VentilatorEffect(&effectBounds, 1, 0, speed);
- VentilatorEffect(&effectBounds, -1, 0, speed);
-
- if (LaraItem->Pose.Position.x >= effectBounds.X1 &&
- LaraItem->Pose.Position.x <= effectBounds.X2)
+ else
{
- if (LaraItem->Pose.Position.z >= effectBounds.Z1 &&
- LaraItem->Pose.Position.z <= effectBounds.Z2)
+ auto tBounds = bounds;
+ tBounds.Rotate(item.Pose.Orientation);
+
+ effectBounds.X1 = item.Pose.Position.x + tBounds.X1;
+ effectBounds.X2 = item.Pose.Position.x + tBounds.X2;
+ effectBounds.Z1 = item.Pose.Position.z + tBounds.Z1;
+ effectBounds.Z2 = item.Pose.Position.z + tBounds.Z2;
+
+ VentilatorEffect(&effectBounds, 1, 0, speed);
+ VentilatorEffect(&effectBounds, -1, 0, speed);
+
+ if (LaraItem->Pose.Position.x >= effectBounds.X1 &&
+ LaraItem->Pose.Position.x <= effectBounds.X2)
{
- int y = effectBounds.Y2;
-
- if (LaraItem->Pose.Position.y <= effectBounds.Y2)
+ if (LaraItem->Pose.Position.z >= effectBounds.Z1 &&
+ LaraItem->Pose.Position.z <= effectBounds.Z2)
{
- if (effectBounds.Y1 - LaraItem->Pose.Position.y >= item->ItemFlags[0])
- return;
+ int y = effectBounds.Y2;
- y = 96 * (effectBounds.Y2 - item->ItemFlags[0]) / item->ItemFlags[0];
+ if (LaraItem->Pose.Position.y <= effectBounds.Y2)
+ {
+ if (effectBounds.Y1 - LaraItem->Pose.Position.y >= item.ItemFlags[0])
+ return;
+
+ y = 96 * (effectBounds.Y2 - item.ItemFlags[0]) / item.ItemFlags[0];
+ }
+ else
+ {
+ if (LaraItem->Pose.Position.y - effectBounds.Y2 >= item.ItemFlags[0])
+ return;
+
+ y = 96 * (item.ItemFlags[0] - (LaraItem->Pose.Position.y - effectBounds.Y2)) / item.ItemFlags[0];
+ }
+
+ if (item.Animation.ActiveState == 1)
+ y = speed * y / 120;
+
+ LaraItem->Pose.Position.y += y;
}
- else
- {
- if (LaraItem->Pose.Position.y - effectBounds.Y2 >= item->ItemFlags[0])
- return;
-
- y = 96 * (item->ItemFlags[0] - (LaraItem->Pose.Position.y - effectBounds.Y2)) / item->ItemFlags[0];
- }
-
- if (item->Animation.ActiveState == 1)
- y = speed * y / 120;
-
- LaraItem->Pose.Position.y += y;
}
}
}
diff --git a/TombEngine/Objects/TR5/Trap/tr5_ventilator.h b/TombEngine/Objects/TR5/Trap/tr5_ventilator.h
index a80f1fe83..d0e920538 100644
--- a/TombEngine/Objects/TR5/Trap/tr5_ventilator.h
+++ b/TombEngine/Objects/TR5/Trap/tr5_ventilator.h
@@ -1,4 +1,7 @@
#pragma once
-void InitializeVentilator(short itemNumber);
-void VentilatorControl(short itemNumber);
+namespace TEN::Entities::Traps
+{
+ void InitializeVentilator(short itemNumber);
+ void ControlVentilator(short itemNumber);
+}
diff --git a/TombEngine/Objects/TR5/Trap/tr5_wreckingball.cpp b/TombEngine/Objects/TR5/Trap/tr5_wreckingball.cpp
index 3df7c9b76..6774daacc 100644
--- a/TombEngine/Objects/TR5/Trap/tr5_wreckingball.cpp
+++ b/TombEngine/Objects/TR5/Trap/tr5_wreckingball.cpp
@@ -19,296 +19,347 @@
using namespace TEN::Effects::Environment;
-static short WreckingBallData[2] = { 0, 0 };
+// TODO: Refactor.
+// - Modularize.
+// - Remove all legacy magic garbage.
+// - Revise logic to remove constrains and allow it to move around different structures.
+// - Change management of base object (item2).
+// - Make light effect optional.
+//
+// NOTES
+// ItemFlags[0] = ??
+// ItemFlags[1] = ??
+// ItemFlags[2] = ??
+// ItemFlags[3] = Base object ID (by default ANIMATING16)
-void InitializeWreckingBall(short itemNumber)
+namespace TEN::Entities::Traps
{
- auto* item = &g_Level.Items[itemNumber];
+ static short WreckingBallData[2] = { 0, 0 };
- item->ItemFlags[3] = FindAllItems(ID_ANIMATING16)[0];
-
- short RoomNumber = item->RoomNumber;
- item->Pose.Position.y = GetCeiling(GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &RoomNumber), item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z) + 1644;
- GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &RoomNumber);
-
- if (RoomNumber != item->RoomNumber)
- ItemNewRoom(itemNumber, RoomNumber);
-}
-
-void WreckingBallCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
-{
- auto* item = &g_Level.Items[itemNumber];
-
- if (TestBoundsCollide(item, laraItem, coll->Setup.Radius))
+ void InitializeWreckingBall(short itemNumber)
{
- int x = laraItem->Pose.Position.x;
- int y = laraItem->Pose.Position.y;
- int z = laraItem->Pose.Position.z;
+ auto& item = g_Level.Items[itemNumber];
- bool test = false;
- if ((x & WALL_MASK) > CLICK(1) &&
- (x & WALL_MASK) < CLICK(3) &&
- (z & WALL_MASK) > CLICK(1) &&
- (z & WALL_MASK) < CLICK(3))
+ auto pointColl = GetPointCollision(item);
+
+ item.ItemFlags[3] = FindAllItems(ID_ANIMATING16)[0];
+ item.Pose.Position.y = pointColl.GetCeilingHeight() + 1644;
+
+ if (pointColl.GetRoomNumber() != item.RoomNumber)
+ ItemNewRoom(itemNumber, pointColl.GetRoomNumber());
+ }
+
+ void CollideWreckingBall(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll)
+ {
+ auto& item = g_Level.Items[itemNumber];
+
+ if (TestBoundsCollide(&item, playerItem, coll->Setup.Radius))
{
- test = true;
+ auto prevPos = playerItem->Pose.Position;
+
+ bool test = false;
+ if ((prevPos.x & WALL_MASK) > CLICK(1) &&
+ (prevPos.x & WALL_MASK) < CLICK(3) &&
+ (prevPos.z & WALL_MASK) > CLICK(1) &&
+ (prevPos.z & WALL_MASK) < CLICK(3))
+ {
+ test = true;
+ }
+
+ int damage = (item.Animation.Velocity.y > 0.0f) ? 96 : 0;
+
+ if (ItemPushItem(&item, playerItem, coll, coll->Setup.EnableSpasm, 1))
+ {
+ if (test)
+ {
+ DoDamage(playerItem, INT_MAX);
+ }
+ else
+ {
+ DoDamage(playerItem, damage);
+ }
+
+ prevPos -= playerItem->Pose.Position;
+
+ if (damage != 0)
+ {
+ for (int i = 14 + (GetRandomControl() & 3); i > 0; --i)
+ {
+ TriggerBlood(playerItem->Pose.Position.x + (GetRandomControl() & 63) - 32, playerItem->Pose.Position.y - (GetRandomControl() & 511) - 256,
+ playerItem->Pose.Position.z + (GetRandomControl() & 63) - 32, -1, 1);
+ }
+ }
+
+ if (!coll->Setup.EnableObjectPush || test)
+ playerItem->Pose.Position += prevPos;
+ }
+ }
+ }
+
+ void ControlWreckingBall(short itemNumber)
+ {
+ int x, z, oldX, oldZ, wx, wz, flagX, flagZ, height, dx, dz, ceilingX, ceilingZ, adx, adz;
+ short room;
+
+ auto& item = g_Level.Items[itemNumber];
+ auto& item2 = g_Level.Items[item.ItemFlags[3]];
+
+ bool test = true;
+
+ if ((LaraItem->Pose.Position.x >= BLOCK(44) &&
+ LaraItem->Pose.Position.x <= BLOCK(56) &&
+ LaraItem->Pose.Position.z >= BLOCK(26) &&
+ LaraItem->Pose.Position.z <= BLOCK(42)) ||
+ item.ItemFlags[2] < 900)
+ {
+ if (item.ItemFlags[2] < 900)
+ {
+ if (!item.ItemFlags[2] || !(GlobalCounter & 0x3F))
+ {
+ WreckingBallData[0] = GetRandomControl() % 7 - 3;
+ WreckingBallData[1] = GetRandomControl() % 7 - 3;
+ }
+
+ x = (WreckingBallData[0] << 10) + 51712;
+ z = (WreckingBallData[1] << 10) + 34304;
+ test = false;
+ }
+ else
+ {
+ x = LaraItem->Pose.Position.x;
+ z = LaraItem->Pose.Position.z;
+ }
+ }
+ else
+ {
+ x = 51200;
+ z = 33792;
+ test = false;
}
- int damage = (item->Animation.Velocity.y > 0.0f) ? 96 : 0;
+ if (item.ItemFlags[2] < 900)
+ ++item.ItemFlags[2];
- if (ItemPushItem(item, laraItem, coll, coll->Setup.EnableSpasm, 1))
+ if (item.ItemFlags[1] <= 0)
{
- if (test)
- DoDamage(laraItem, INT_MAX);
- else
- DoDamage(laraItem, damage);
+ oldX = item.Pose.Position.x;
+ oldZ = item.Pose.Position.z;
+ x = x & 0xFFFFFE00 | 0x200;
+ z = z & 0xFFFFFE00 | 0x200;
+ dx = x - item.Pose.Position.x;
+ dz = z - item.Pose.Position.z;
+ wx = 0;
- x -= laraItem->Pose.Position.x;
- y -= laraItem->Pose.Position.y;
- z -= laraItem->Pose.Position.z;
-
- if (damage)
+ if (dx < 0)
{
- for (int i = 14 + (GetRandomControl() & 3); i > 0; --i)
+ wx = -1024;
+ }
+ else if (dx > 0)
+ {
+ wx = 1024;
+ }
+ wz = 0;
+
+ if (dz < 0)
+ {
+ wz = -1024;
+ }
+ else if (dz > 0)
+ {
+ wz = 1024;
+ }
+
+ room = item.RoomNumber;
+ ceilingX = GetCeiling(GetFloor(item.Pose.Position.x + wx, item2.Pose.Position.y, item.Pose.Position.z, &room), item.Pose.Position.x + wx, item2.Pose.Position.y, item.Pose.Position.z);
+ room = item.RoomNumber;
+
+ ceilingZ = GetCeiling(GetFloor(item.Pose.Position.x, item2.Pose.Position.y, item.Pose.Position.z + wz, &room), item.Pose.Position.x, item2.Pose.Position.y, item.Pose.Position.z + wz);
+ if (ceilingX <= item2.Pose.Position.y && ceilingX != NO_HEIGHT)
+ {
+ flagX = 1;
+ }
+ else
+ {
+ flagX = 0;
+ }
+
+ if (ceilingZ <= item2.Pose.Position.y && ceilingZ != NO_HEIGHT)
+ {
+ flagZ = 1;
+ }
+ else
+ {
+ flagZ = 0;
+ }
+
+ if (!item.ItemFlags[0])
+ {
+ if (flagX && dx && (abs(dx) > abs(dz) || !flagZ || GetRandomControl() & 1))
{
- TriggerBlood(laraItem->Pose.Position.x + (GetRandomControl() & 63) - 32, laraItem->Pose.Position.y - (GetRandomControl() & 511) - 256,
- laraItem->Pose.Position.z + (GetRandomControl() & 63) - 32, -1, 1);
+ item.ItemFlags[0] = 1;
+ }
+ else if (flagZ && dz)
+ {
+ item.ItemFlags[0] = 2;
}
}
- if (!coll->Setup.EnableObjectPush || test)
+ if (item.ItemFlags[0] == 1)
{
- laraItem->Pose.Position.x += x;
- laraItem->Pose.Position.y += y;
- laraItem->Pose.Position.z += z;
+ SoundEffect(SFX_TR5_BASE_CLAW_MOTOR_B_LOOP, &item.Pose);
+
+ adx = abs(dx);
+ if (adx >= 32)
+ adx = 32;
+
+ if (dx > 0)
+ {
+ item.Pose.Position.x += adx;
+ }
+ else if (dx < 0)
+ {
+ item.Pose.Position.x -= adx;
+ }
+ else
+ {
+ item.ItemFlags[0] = 0;
+ }
+ }
+
+ if (item.ItemFlags[0] == 2)
+ {
+ SoundEffect(SFX_TR5_BASE_CLAW_MOTOR_B_LOOP, &item.Pose);
+
+ adz = abs(dz);
+ if (adz >= 32)
+ adz = 32;
+
+ if (dz > 0)
+ {
+ item.Pose.Position.z += adz;
+ }
+ else if (dz < 0)
+ {
+ item.Pose.Position.z -= adz;
+ }
+ else
+ {
+ item.ItemFlags[0] = 0;
+ }
+ }
+
+ if (item.ItemFlags[1] == -1 && (oldX != item.Pose.Position.x || oldZ != item.Pose.Position.z))
+ {
+ item.ItemFlags[1] = 0;
+ SoundEffect(SFX_TR5_BASE_CLAW_MOTOR_A, &item.Pose);
+ }
+
+ if ((item.Pose.Position.x & 0x3FF) == 512 && (item.Pose.Position.z & 0x3FF) == 512)
+ item.ItemFlags[0] = 0;
+
+ if (x == item.Pose.Position.x && z == item.Pose.Position.z && test)
+ {
+ if (item.ItemFlags[1] != -1)
+ {
+ StopSoundEffect(SFX_TR5_BASE_CLAW_MOTOR_B_LOOP);
+ SoundEffect(SFX_TR5_BASE_CLAW_MOTOR_C, &item.Pose);
+ }
+
+ item.ItemFlags[1] = 1;
+ item.TriggerFlags = 30;
}
}
+ else if (item.ItemFlags[1] == 1)
+ {
+ if (!item.TriggerFlags)
+ {
+ --item.TriggerFlags;
+ }
+ else if (!item.Animation.ActiveState)
+ {
+ item.Animation.TargetState = 1;
+ }
+ else if (item.Animation.FrameNumber == GetAnimData(item).frameEnd)
+ {
+ SoundEffect(SFX_TR5_BASE_CLAW_DROP, &item.Pose);
+ ++item.ItemFlags[1];
+ item.Animation.Velocity.y = 6;
+ item.Pose.Position.y += item.Animation.Velocity.y;
+ }
+ }
+ else if (item.ItemFlags[1] == 2)
+ {
+ item.Animation.Velocity.y += 24;
+ item.Pose.Position.y += item.Animation.Velocity.y;
+ room = item.RoomNumber;
+
+ height = GetFloorHeight(GetFloor(item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z, &room), item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z);
+ if (height < item.Pose.Position.y)
+ {
+ item.Pose.Position.y = height;
+ if (item.Animation.Velocity.y > 48)
+ {
+ BounceCamera(&item, 64, 8192);
+ item.Animation.Velocity.y = -item.Animation.Velocity.y / 8.0f;
+ }
+ else
+ {
+ ++item.ItemFlags[1];
+ item.Animation.Velocity.y = 0;
+ }
+ }
+ else if (height - item.Pose.Position.y < 1536 && item.Animation.ActiveState)
+ {
+ item.Animation.TargetState = 0;
+ }
+ }
+ else if (item.ItemFlags[1] == 3)
+ {
+ item.Animation.Velocity.y -= 3;
+ item.Pose.Position.y += item.Animation.Velocity.y;
+
+ if (item.Pose.Position.y < item2.Pose.Position.y + 1644)
+ {
+ StopSoundEffect(SFX_TR5_BASE_CLAW_WINCH_UP_LOOP);
+ item.ItemFlags[0] = 1;
+ item.Pose.Position.y = item2.Pose.Position.y + 1644;
+
+ if (item.Animation.Velocity.y < -32.0f)
+ {
+ SoundEffect(SFX_TR5_BASE_CLAW_TOP_IMPACT, &item.Pose, SoundEnvironment::Land, 1.0f, 0.5f);
+ item.Animation.Velocity.y = -item.Animation.Velocity.y / 8.0f;
+ BounceCamera(&item, 16, 8192);
+ }
+ else
+ {
+ item.ItemFlags[1] = -1;
+ item.Animation.Velocity.y = 0;
+ item.ItemFlags[0] = 0;
+ }
+ }
+ else if (!item.ItemFlags[0])
+ {
+ SoundEffect(SFX_TR5_BASE_CLAW_WINCH_UP_LOOP, &item.Pose);
+ }
+ }
+
+ item2.Pose.Position.x = item.Pose.Position.x;
+ item2.Pose.Position.z = item.Pose.Position.z;
+ room = item.RoomNumber;
+ item2.Pose.Position.y = GetCeiling(GetFloor(item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z, &room), item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z);
+
+ GetFloor(item2.Pose.Position.x, item2.Pose.Position.y, item2.Pose.Position.z, &room);
+ if (room != item2.RoomNumber)
+ ItemNewRoom(item.ItemFlags[3], room);
+
+ TriggerAlertLight(item2.Pose.Position.x, item2.Pose.Position.y + 64, item2.Pose.Position.z, 255, 64, 0, 64 * (GlobalCounter & 0x3F), item2.RoomNumber, 24);
+ TriggerAlertLight(item2.Pose.Position.x, item2.Pose.Position.y + 64, item2.Pose.Position.z, 255, 64, 0, 64 * (GlobalCounter - 32) & 0xFFF, item2.RoomNumber, 24);
+
+ room = item.RoomNumber;
+ GetFloor(item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z, &room);
+ if (room != item.RoomNumber)
+ ItemNewRoom(itemNumber, room);
+
+ AnimateItem(&item);
}
}
-
-void WreckingBallControl(short itemNumber)
-{
- int x, z, oldX, oldZ, wx, wz, flagX, flagZ, height, dx, dz, ceilingX, ceilingZ, adx, adz;
- short room;
-
- auto* item = &g_Level.Items[itemNumber];
- auto* item2 = &g_Level.Items[item->ItemFlags[3]];
-
- bool test = true;
-
- if ((LaraItem->Pose.Position.x >= BLOCK(44) &&
- LaraItem->Pose.Position.x <= BLOCK(56)&&
- LaraItem->Pose.Position.z >= BLOCK(26) &&
- LaraItem->Pose.Position.z <= BLOCK(42)) ||
- item->ItemFlags[2] < 900)
- {
- if (item->ItemFlags[2] < 900)
- {
- if (!item->ItemFlags[2] || !(GlobalCounter & 0x3F))
- {
- WreckingBallData[0] = GetRandomControl() % 7 - 3;
- WreckingBallData[1] = GetRandomControl() % 7 - 3;
- }
-
- x = (WreckingBallData[0] << 10) + 51712;
- z = (WreckingBallData[1] << 10) + 34304;
- test = false;
- }
- else
- {
- x = LaraItem->Pose.Position.x;
- z = LaraItem->Pose.Position.z;
- }
- }
- else
- {
- x = 51200;
- z = 33792;
- test = false;
- }
-
- if (item->ItemFlags[2] < 900)
- ++item->ItemFlags[2];
-
- if (item->ItemFlags[1] <= 0)
- {
- oldX = item->Pose.Position.x;
- oldZ = item->Pose.Position.z;
- x = x & 0xFFFFFE00 | 0x200;
- z = z & 0xFFFFFE00 | 0x200;
- dx = x - item->Pose.Position.x;
- dz = z - item->Pose.Position.z;
- wx = 0;
-
- if (dx < 0)
- wx = -1024;
- else if (dx > 0)
- wx = 1024;
- wz = 0;
-
- if (dz < 0)
- wz = -1024;
- else if (dz > 0)
- wz = 1024;
-
- room = item->RoomNumber;
- ceilingX = GetCeiling(GetFloor(item->Pose.Position.x + wx, item2->Pose.Position.y, item->Pose.Position.z, &room), item->Pose.Position.x + wx, item2->Pose.Position.y, item->Pose.Position.z);
- room = item->RoomNumber;
-
- ceilingZ = GetCeiling(GetFloor(item->Pose.Position.x, item2->Pose.Position.y, item->Pose.Position.z + wz, &room), item->Pose.Position.x, item2->Pose.Position.y, item->Pose.Position.z + wz);
- if (ceilingX <= item2->Pose.Position.y && ceilingX != NO_HEIGHT)
- flagX = 1;
- else
- flagX = 0;
-
- if (ceilingZ <= item2->Pose.Position.y && ceilingZ != NO_HEIGHT)
- flagZ = 1;
- else
- flagZ = 0;
-
- if (!item->ItemFlags[0])
- {
- if (flagX && dx && (abs(dx) > abs(dz) || !flagZ || GetRandomControl() & 1))
- item->ItemFlags[0] = 1;
- else if (flagZ && dz)
- item->ItemFlags[0] = 2;
- }
-
- if (item->ItemFlags[0] == 1)
- {
- SoundEffect(SFX_TR5_BASE_CLAW_MOTOR_B_LOOP, &item->Pose);
-
- adx = abs(dx);
- if (adx >= 32)
- adx = 32;
-
- if (dx > 0)
- item->Pose.Position.x += adx;
- else if (dx < 0)
- item->Pose.Position.x -= adx;
- else
- item->ItemFlags[0] = 0;
- }
-
- if (item->ItemFlags[0] == 2)
- {
- SoundEffect(SFX_TR5_BASE_CLAW_MOTOR_B_LOOP, &item->Pose);
-
- adz = abs(dz);
- if (adz >= 32)
- adz = 32;
-
- if (dz > 0)
- item->Pose.Position.z += adz;
- else if (dz < 0)
- item->Pose.Position.z -= adz;
- else
- item->ItemFlags[0] = 0;
- }
-
- if (item->ItemFlags[1] == -1 && (oldX != item->Pose.Position.x || oldZ != item->Pose.Position.z))
- {
- item->ItemFlags[1] = 0;
- SoundEffect(SFX_TR5_BASE_CLAW_MOTOR_A, &item->Pose);
- }
-
- if ((item->Pose.Position.x & 0x3FF) == 512 && (item->Pose.Position.z & 0x3FF) == 512)
- item->ItemFlags[0] = 0;
-
- if (x == item->Pose.Position.x && z == item->Pose.Position.z && test)
- {
- if (item->ItemFlags[1] != -1)
- {
- StopSoundEffect(SFX_TR5_BASE_CLAW_MOTOR_B_LOOP);
- SoundEffect(SFX_TR5_BASE_CLAW_MOTOR_C, &item->Pose);
- }
-
- item->ItemFlags[1] = 1;
- item->TriggerFlags = 30;
- }
- }
- else if (item->ItemFlags[1] == 1)
- {
- if (!item->TriggerFlags)
- --item->TriggerFlags;
- else if (!item->Animation.ActiveState)
- item->Animation.TargetState = 1;
- else if (item->Animation.FrameNumber == GetAnimData(item).frameEnd)
- {
- SoundEffect(SFX_TR5_BASE_CLAW_DROP, &item->Pose);
- ++item->ItemFlags[1];
- item->Animation.Velocity.y = 6;
- item->Pose.Position.y += item->Animation.Velocity.y;
- }
- }
- else if (item->ItemFlags[1] == 2)
- {
- item->Animation.Velocity.y += 24;
- item->Pose.Position.y += item->Animation.Velocity.y;
- room = item->RoomNumber;
-
- height = GetFloorHeight(GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &room), item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z);
- if (height < item->Pose.Position.y)
- {
- item->Pose.Position.y = height;
- if (item->Animation.Velocity.y > 48)
- {
- BounceCamera(item, 64, 8192);
- item->Animation.Velocity.y = -item->Animation.Velocity.y / 8.0f;
- }
- else
- {
- ++item->ItemFlags[1];
- item->Animation.Velocity.y = 0;
- }
- }
- else if (height - item->Pose.Position.y < 1536 && item->Animation.ActiveState)
- item->Animation.TargetState = 0;
- }
- else if (item->ItemFlags[1] == 3)
- {
- item->Animation.Velocity.y -= 3;
- item->Pose.Position.y += item->Animation.Velocity.y;
-
- if (item->Pose.Position.y < item2->Pose.Position.y + 1644)
- {
- StopSoundEffect(SFX_TR5_BASE_CLAW_WINCH_UP_LOOP);
- item->ItemFlags[0] = 1;
- item->Pose.Position.y = item2->Pose.Position.y + 1644;
-
- if (item->Animation.Velocity.y < -32.0f)
- {
- SoundEffect(SFX_TR5_BASE_CLAW_TOP_IMPACT, &item->Pose, SoundEnvironment::Land, 1.0f, 0.5f);
- item->Animation.Velocity.y = -item->Animation.Velocity.y / 8.0f;
- BounceCamera(item, 16, 8192);
- }
- else
- {
- item->ItemFlags[1] = -1;
- item->Animation.Velocity.y = 0;
- item->ItemFlags[0] = 0;
- }
- }
- else if (!item->ItemFlags[0])
- SoundEffect(SFX_TR5_BASE_CLAW_WINCH_UP_LOOP, &item->Pose);
- }
-
- item2->Pose.Position.x = item->Pose.Position.x;
- item2->Pose.Position.z = item->Pose.Position.z;
- room = item->RoomNumber;
- item2->Pose.Position.y = GetCeiling(GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &room), item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z);
-
- GetFloor(item2->Pose.Position.x, item2->Pose.Position.y, item2->Pose.Position.z, &room);
- if (room != item2->RoomNumber)
- ItemNewRoom(item->ItemFlags[3], room);
-
- TriggerAlertLight(item2->Pose.Position.x, item2->Pose.Position.y + 64, item2->Pose.Position.z, 255, 64, 0, 64 * (GlobalCounter & 0x3F), item2->RoomNumber, 24);
- TriggerAlertLight(item2->Pose.Position.x, item2->Pose.Position.y + 64, item2->Pose.Position.z, 255, 64, 0, 64 * (GlobalCounter - 32) & 0xFFF, item2->RoomNumber, 24);
-
- room = item->RoomNumber;
- GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &room);
- if (room != item->RoomNumber)
- ItemNewRoom(itemNumber, room);
-
- AnimateItem(item);
-}
diff --git a/TombEngine/Objects/TR5/Trap/tr5_wreckingball.h b/TombEngine/Objects/TR5/Trap/tr5_wreckingball.h
index f69f4ebef..625c2749e 100644
--- a/TombEngine/Objects/TR5/Trap/tr5_wreckingball.h
+++ b/TombEngine/Objects/TR5/Trap/tr5_wreckingball.h
@@ -3,6 +3,9 @@
struct CollisionInfo;
struct ItemInfo;
-void InitializeWreckingBall(short itemNumber);
-void WreckingBallCollision(short itemNumber, ItemInfo* l, CollisionInfo* coll);
-void WreckingBallControl(short itemNumber);
\ No newline at end of file
+namespace TEN::Entities::Traps
+{
+ void InitializeWreckingBall(short itemNumber);
+ void CollideWreckingBall(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll);
+ void ControlWreckingBall(short itemNumber);
+}
diff --git a/TombEngine/Objects/TR5/tr5_objects.cpp b/TombEngine/Objects/TR5/tr5_objects.cpp
index 6a72a81b2..e4f112013 100644
--- a/TombEngine/Objects/TR5/tr5_objects.cpp
+++ b/TombEngine/Objects/TR5/tr5_objects.cpp
@@ -76,7 +76,7 @@
using namespace TEN::Effects::EmberEmitter;
using namespace TEN::Entities::Creatures::TR5;
using namespace TEN::Entities::Switches;
-using namespace TEN::Traps::TR5;
+using namespace TEN::Entities::Traps;
static void StartEntity(ObjectInfo *obj)
{
@@ -853,7 +853,7 @@ static void StartTrap(ObjectInfo *obj)
if (obj->loaded)
{
obj->Initialize = InitializeVentilator;
- obj->control = VentilatorControl;
+ obj->control = ControlVentilator;
obj->SetHitEffect(true);
}
@@ -861,7 +861,7 @@ static void StartTrap(ObjectInfo *obj)
if (obj->loaded)
{
obj->Initialize = InitializeVentilator;
- obj->control = VentilatorControl;
+ obj->control = ControlVentilator;
obj->SetHitEffect(true);
}
@@ -876,7 +876,7 @@ static void StartTrap(ObjectInfo *obj)
{
obj->Initialize = InitializeRomeHammer;
obj->collision = GenericSphereBoxCollision;
- obj->control = AnimatingControl;
+ obj->control = ControlRomeHammer;
obj->SetHitEffect(true);
}
@@ -884,7 +884,7 @@ static void StartTrap(ObjectInfo *obj)
if (obj->loaded)
{
obj->collision = TrapCollision;
- obj->control = FallingCeilingControl;
+ obj->control = ControlFallingCeiling;
}
obj = &Objects[ID_ROLLINGBALL];
@@ -934,7 +934,7 @@ static void StartTrap(ObjectInfo *obj)
if (obj->loaded)
{
obj->Initialize = InitializeExplosion;
- obj->control = ExplosionControl;
+ obj->control = ControlExplosion;
obj->drawRoutine = nullptr;
obj->usingDrawAnimatingItem = false;
}
@@ -983,8 +983,8 @@ static void StartSwitch(ObjectInfo *obj)
if (obj->loaded)
{
obj->Initialize = InitializeWreckingBall;
- obj->collision = WreckingBallCollision;
- obj->control = WreckingBallControl;
+ obj->collision = CollideWreckingBall;
+ obj->control = ControlWreckingBall;
obj->SetHitEffect(true);
}
}
diff --git a/TombEngine/Renderer/RendererDrawEffect.cpp b/TombEngine/Renderer/RendererDrawEffect.cpp
index 8055fe78d..b515bebe4 100644
--- a/TombEngine/Renderer/RendererDrawEffect.cpp
+++ b/TombEngine/Renderer/RendererDrawEffect.cpp
@@ -43,8 +43,8 @@ using namespace TEN::Effects::Footprint;
using namespace TEN::Effects::Ripple;
using namespace TEN::Effects::Streamer;
using namespace TEN::Entities::Creatures::TR5;
+using namespace TEN::Entities::Traps;
using namespace TEN::Math;
-using namespace TEN::Traps::TR5;
extern BLOOD_STRUCT Blood[MAX_SPARKS_BLOOD];
extern FIRE_SPARKS FireSparks[MAX_SPARKS_FIRE];
From 2a6a96e03ae4b133af57e8f7d7f550ace09440e4 Mon Sep 17 00:00:00 2001
From: Jakub <80340234+Jakub768@users.noreply.github.com>
Date: Wed, 19 Jun 2024 11:20:57 +0100
Subject: [PATCH 214/410] Implement KeyClearAll() Lua function (#1374)
* Implement KeyClearAll
* add entry to CHANGELOG.md
---
CHANGELOG.md | 1 +
TombEngine/Scripting/Internal/ReservedScriptNames.h | 1 +
.../Scripting/Internal/TEN/Input/InputHandler.cpp | 11 +++++++++++
3 files changed, 13 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 57f1b3d4f..4bff581ce 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -35,6 +35,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor):
### Lua API changes
* Added Inventory.GetUsedItem(), Inventory.SetUsedItem() and Inventory.ClearUsedItem() functions.
+* Added Input.KeyClearAll()
* Removed anims.monkeyAutoJump. It is now a player menu configuration.
## [Version 1.4](https://github.com/TombEngine/TombEditorReleases/releases/tag/v1.7.1) - 2024-04-21
diff --git a/TombEngine/Scripting/Internal/ReservedScriptNames.h b/TombEngine/Scripting/Internal/ReservedScriptNames.h
index 8d0e58181..25c27763e 100644
--- a/TombEngine/Scripting/Internal/ReservedScriptNames.h
+++ b/TombEngine/Scripting/Internal/ReservedScriptNames.h
@@ -318,6 +318,7 @@ static constexpr char ScriptReserved_KeyIsHeld[] = "KeyIsHeld";
static constexpr char ScriptReserved_KeyIsHit[] = "KeyIsHit";
static constexpr char ScriptReserved_KeyPush[] = "KeyPush";
static constexpr char ScriptReserved_KeyClear[] = "KeyClear";
+static constexpr char ScriptReserved_KeyClearAll[] = "KeyClearAll";
static constexpr char ScriptReserved_FlipMap[] = "FlipMap";
static constexpr char ScriptReserved_GetFlipMapStatus[] = "GetFlipMapStatus";
diff --git a/TombEngine/Scripting/Internal/TEN/Input/InputHandler.cpp b/TombEngine/Scripting/Internal/TEN/Input/InputHandler.cpp
index 650854e48..ac1e5c794 100644
--- a/TombEngine/Scripting/Internal/TEN/Input/InputHandler.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Input/InputHandler.cpp
@@ -86,6 +86,16 @@ namespace TEN::Scripting::Input
ActionQueue[actionID] = QueueState::Clear;
}
+#
+ /// Clear all action keys.
+ // @function KeyClear
+ static void KeyClearAll()
+ {
+ for (auto& queue : ActionQueue)
+ {
+ queue = QueueState::Clear;
+ }
+ }
/// Get the display position of the cursor in percent.
// @function GetMouseDisplayPosition()
@@ -110,6 +120,7 @@ namespace TEN::Scripting::Input
table.set_function(ScriptReserved_KeyIsHit, &KeyIsHit);
table.set_function(ScriptReserved_KeyPush, &KeyPush);
table.set_function(ScriptReserved_KeyClear, &KeyClear);
+ table.set_function(ScriptReserved_KeyClearAll, &KeyClearAll);
table.set_function(ScriptReserved_GetMouseDisplayPosition, &GetMouseDisplayPosition);
table.set_function(ScriptReserved_GetCursorDisplayPosition, &GetMouseDisplayPosition);
From cb05e0eae802b6812de9dcd00d23b714af3c77f8 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 19 Jun 2024 21:07:26 +1000
Subject: [PATCH 215/410] Grammar
---
CHANGELOG.md | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4bff581ce..c9e542b5b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,20 +11,20 @@ TombEngine releases are located in this repository (alongside with Tomb Editor):
### Bug fixes
* Fixed original issue with classic switch off trigger wrongly activating some trigger actions.
* Fixed incorrect diving animation when swandiving from a high place.
-* Fixed camera rotating with Lara's hips when climbing out of water.
+* Fixed camera rotating with player's hips when climbing out of water.
* Fixed AI for skidoo driver and worker with shotgun TR2 enemies.
-* Fixed Ember emitter crashing when ocb is between -1 and -10
-* Fixed Electric cleaner and Squishy block not detecting collision with certain block heights.
-* Fixed Squishy blocks crashing the level.
-* Fixed the path finding zones of Larson and Pierre.
-* Fixed the torch flame delay in disappearing when Lara threw or dropped the torch object.
-* Fixed Dart emitters which was failing when it was antitriggered.
-* Fixed Homing Dart emitter which was spawning darts continously while Lara was on the trigger.
-* Fixed Floor 4 blades and ceiling 4 blades collision.
-* Fixed Joby spikes collision and abnormal streetching.
-* Fixed Sentry Gun to rotate its parts correctly.
-* Fixed Teeth Spikes bug, now they will activates the Lara impale animation.
-* Fixed TR4 mine with OCB1, to don't crash the game when Lara steps the mine.
+* Fixed ember emitter crashing when ocb is between -1 and -10.
+* Fixed electric cleaner and squishy block not detecting collision with certain block heights.
+* Fixed squishy blocks crashing the level.
+* Fixed Larson and Pierre pathfinding.
+* Fixed torch flame delay when the player throws or drops a torch.
+* Fixed dart emitters failing with antitrigger.
+* Fixed homing dart emitter spawning darts continously when player is on its trigger.
+* Fixed four blade trap floor and ceiling collision.
+* Fixed Joby spikes collision and deformation.
+* Fixed sentry gun joint rotation.
+* Fixed teeth spikes not triggering the player impale animation.
+* Fixed TR4 mine crash with OCB1 when triggered.
### Features/Amendments
* Changed Rome Hammer for it to don't hurt Lara while it's deactivated.
From 8a8e63b8e6cdd2712ed8d63019b7f1db1f384d35 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 19 Jun 2024 21:15:03 +1000
Subject: [PATCH 216/410] Formatting
---
TombEngine/Scripting/Internal/TEN/Input/InputHandler.cpp | 2 --
1 file changed, 2 deletions(-)
diff --git a/TombEngine/Scripting/Internal/TEN/Input/InputHandler.cpp b/TombEngine/Scripting/Internal/TEN/Input/InputHandler.cpp
index ac1e5c794..4870ae1c2 100644
--- a/TombEngine/Scripting/Internal/TEN/Input/InputHandler.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Input/InputHandler.cpp
@@ -92,9 +92,7 @@ namespace TEN::Scripting::Input
static void KeyClearAll()
{
for (auto& queue : ActionQueue)
- {
queue = QueueState::Clear;
- }
}
/// Get the display position of the cursor in percent.
From c70bba367e1655613bdb49a902e74c212ba88609 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Fri, 21 Jun 2024 13:36:27 +1000
Subject: [PATCH 217/410] Further organise math
---
TombEngine/Math/Interpolation.h | 10 -----
TombEngine/Math/Math.cpp | 35 ---------------
TombEngine/Math/Math.h | 12 +----
TombEngine/Math/Objects/AxisAngle.h | 8 ++++
TombEngine/Math/Objects/EulerAngles.h | 7 +++
TombEngine/Math/Objects/GameBoundingBox.h | 7 +++
TombEngine/Math/Objects/GameVector.h | 5 +++
TombEngine/Math/Objects/Pose.h | 5 +++
TombEngine/Math/Objects/Vector2i.h | 6 +++
TombEngine/Math/Objects/Vector3i.h | 6 +++
.../Math/{Interpolation.cpp => Utils.cpp} | 45 ++++++++++++++++++-
TombEngine/Math/Utils.h | 27 +++++++++++
TombEngine/TombEngine.vcxproj | 5 +--
13 files changed, 118 insertions(+), 60 deletions(-)
delete mode 100644 TombEngine/Math/Interpolation.h
delete mode 100644 TombEngine/Math/Math.cpp
rename TombEngine/Math/{Interpolation.cpp => Utils.cpp} (54%)
create mode 100644 TombEngine/Math/Utils.h
diff --git a/TombEngine/Math/Interpolation.h b/TombEngine/Math/Interpolation.h
deleted file mode 100644
index 83bb060e2..000000000
--- a/TombEngine/Math/Interpolation.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#pragma once
-
-namespace TEN::Math
-{
- float Lerp(float value0, float value1, float alpha);
- float InterpolateCos(float value0, float value1, float alpha);
- float InterpolateCubic(float value0, float value1, float value2, float value3, float alpha);
- float Smoothstep(float alpha);
- float Smoothstep(float value0, float value1, float alpha);
-}
diff --git a/TombEngine/Math/Math.cpp b/TombEngine/Math/Math.cpp
deleted file mode 100644
index 3ede4ffd8..000000000
--- a/TombEngine/Math/Math.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#include "framework.h"
-
-#include
-#include "Math/Math.h"
-
-namespace TEN::Math
-{
- float Luma(const Vector3& color)
- {
- constexpr auto RED_COEFF = 0.2126f;
- constexpr auto GREEN_COEFF = 0.7152f;
- constexpr auto BLUE_COEFF = 0.0722f;
-
- // Use Rec.709 trichromat formula to get perceptive luma value.
- return float((color.x * RED_COEFF) + (color.y * GREEN_COEFF) + (color.z * BLUE_COEFF));
- }
-
- Vector3 Screen(const Vector3& ambient, const Vector3& tint)
- {
- float luma = Luma(tint);
- auto multiplicative = ambient * tint;
- auto additive = ambient + tint;
-
- return Vector3(
- Lerp(multiplicative.x, additive.x, luma),
- Lerp(multiplicative.y, additive.y, luma),
- Lerp(multiplicative.z, additive.z, luma));
- }
-
- Vector4 Screen(const Vector4& ambient, const Vector4& tint)
- {
- auto result = Screen(Vector3(ambient), Vector3(tint));
- return Vector4(result.x, result.y, result.z, ambient.w * tint.w);
- }
-}
diff --git a/TombEngine/Math/Math.h b/TombEngine/Math/Math.h
index e95d96fe2..cb625c648 100644
--- a/TombEngine/Math/Math.h
+++ b/TombEngine/Math/Math.h
@@ -1,7 +1,6 @@
#pragma once
#include "Math/Constants.h"
#include "Math/Geometry.h"
-#include "Math/Interpolation.h"
#include "Math/Legacy.h"
#include "Math/Objects/EulerAngles.h"
#include "Math/Objects/GameBoundingBox.h"
@@ -11,13 +10,4 @@
#include "Math/Objects/Vector3i.h"
#include "Math/Random.h"
#include "Math/Solvers.h"
-
-namespace TEN::Math
-{
- constexpr inline auto OFFSET_RADIUS = [](auto x) { return ((x * SQRT_2) + 4); };
- constexpr inline auto MESH_BITS = [](auto x) { return (1 << x); };
-
- float Luma(const Vector3& color);
- Vector3 Screen(const Vector3& ambient, const Vector3& tint);
- Vector4 Screen(const Vector4& ambient, const Vector4& tint);
-}
+#include "Math/Utils.h"
diff --git a/TombEngine/Math/Objects/AxisAngle.h b/TombEngine/Math/Objects/AxisAngle.h
index 7ccc2cd90..ddcc72e31 100644
--- a/TombEngine/Math/Objects/AxisAngle.h
+++ b/TombEngine/Math/Objects/AxisAngle.h
@@ -8,14 +8,17 @@ class EulerAngles;
{
private:
// Members
+
Vector3 _axis = Vector3::Backward;
short _angle = 0;
public:
// Constants
+
static const AxisAngle Identity;
// Constructors
+
AxisAngle() {};
AxisAngle(const Vector3& axis, short angle);
AxisAngle(const EulerAngles& eulers);
@@ -23,24 +26,29 @@ class EulerAngles;
AxisAngle(const Matrix& rotMatrix);
// Getters
+
Vector3 GetAxis() const;
short GetAngle() const;
// Setters
+
void SetAxis(const Vector3& axis);
void SetAngle(short angle);
// Utilities
+
void Slerp(const AxisAngle& axisAngleTo, float alpha);
static AxisAngle Slerp(const AxisAngle& axisAngleFrom, const AxisAngle& axisAngleTo, float alpha);
// Converters
+
Vector3 ToDirection() const;
EulerAngles ToEulerAngles() const;
Quaternion ToQuaternion() const;
Matrix ToRotationMatrix() const;
// Operators
+
bool operator ==(const AxisAngle& axisAngle) const;
bool operator !=(const AxisAngle& axisAngle) const;
AxisAngle& operator =(const AxisAngle& axisAngle);
diff --git a/TombEngine/Math/Objects/EulerAngles.h b/TombEngine/Math/Objects/EulerAngles.h
index e08973cfa..f25f69d1a 100644
--- a/TombEngine/Math/Objects/EulerAngles.h
+++ b/TombEngine/Math/Objects/EulerAngles.h
@@ -7,14 +7,17 @@
{
public:
// Members (CONVENTION: X = Pitch, Y = Yaw, Z = Roll)
+
short x = 0;
short y = 0;
short z = 0;
// Constants
+
static const EulerAngles Identity;
// Constructors
+
constexpr EulerAngles() {};
constexpr EulerAngles(short x, short y, short z) { this->x = x; this->y = y; this->z = z; };
EulerAngles(const Vector3& dir);
@@ -23,6 +26,7 @@
EulerAngles(const Matrix& rotMatrix);
// Utilities
+
static bool Compare(const EulerAngles& eulers0, const EulerAngles& eulers1, short epsilon = 3);
void Lerp(const EulerAngles& eulersTo, float alpha, short epsilon = 3);
static EulerAngles Lerp(const EulerAngles& eulersFrom, const EulerAngles& eulersTo, float alpha, short epsilon = 3);
@@ -32,12 +36,14 @@
static EulerAngles InterpolateConstant(const EulerAngles& eulersFrom, const EulerAngles& eulerTo, short angularVel);
// Converters
+
Vector3 ToDirection() const;
AxisAngle ToAxisAngle() const;
Quaternion ToQuaternion() const;
Matrix ToRotationMatrix() const;
// Operators
+
bool operator ==(const EulerAngles& eulers) const;
bool operator !=(const EulerAngles& eulers) const;
EulerAngles& operator =(const EulerAngles& eulers);
@@ -54,6 +60,7 @@
private:
// Temporary. Will be integrated into eventual Angle class.
+
static float ClampAlpha(float alpha);
static bool Compare(short angle0, short angle1, short epsilon = 3);
static short Lerp(short angleFrom, short angleTo, float alpha, short epsilon = 3);
diff --git a/TombEngine/Math/Objects/GameBoundingBox.h b/TombEngine/Math/Objects/GameBoundingBox.h
index 705688145..17569391d 100644
--- a/TombEngine/Math/Objects/GameBoundingBox.h
+++ b/TombEngine/Math/Objects/GameBoundingBox.h
@@ -12,6 +12,7 @@ struct ObjectInfo;
{
public:
// Members
+
int X1 = 0;
int X2 = 0;
int Y1 = 0;
@@ -20,15 +21,18 @@ struct ObjectInfo;
int Z2 = 0;
// Constants
+
static const GameBoundingBox Zero;
// Constructors
+
GameBoundingBox() {};
GameBoundingBox(float x1, float x2, float y1, float y2, float z1, float z2);
GameBoundingBox(GAME_OBJECT_ID objectID, int animNumber = 0, int frameNumber = 0);
GameBoundingBox(const ItemInfo* item);
// Getters
+
int GetWidth() const;
int GetHeight() const;
int GetDepth() const;
@@ -36,13 +40,16 @@ struct ObjectInfo;
Vector3 GetExtents() const;
// Utilities
+
void Rotate(const EulerAngles& rot);
// Converters
+
BoundingOrientedBox ToBoundingOrientedBox(const Pose& pose) const;
BoundingOrientedBox ToBoundingOrientedBox(const Vector3& pos, const Quaternion& orient) const;
// Operators
+
GameBoundingBox operator +(const GameBoundingBox& bounds) const;
GameBoundingBox operator +(const Pose& pose) const;
GameBoundingBox operator -(const GameBoundingBox& bounds) const;
diff --git a/TombEngine/Math/Objects/GameVector.h b/TombEngine/Math/Objects/GameVector.h
index f75cc748c..ac43cdd2e 100644
--- a/TombEngine/Math/Objects/GameVector.h
+++ b/TombEngine/Math/Objects/GameVector.h
@@ -8,6 +8,7 @@ class Vector3i;
{
public:
// Members
+
int x = 0;
int y = 0;
int z = 0;
@@ -15,9 +16,11 @@ class Vector3i;
int BoxNumber = 0; // Unused.
// Constants
+
static const GameVector Zero;
// Constructors
+
GameVector();
GameVector(const Vector3i& pos);
GameVector(const Vector3i& pos, short roomNumber);
@@ -25,10 +28,12 @@ class Vector3i;
GameVector(int xPos, int yPos, int zPos, short roomNumber);
// Converters
+
Vector3 ToVector3() const;
Vector3i ToVector3i() const;
// Operators
+
bool operator ==(const GameVector& vector) const;
bool operator !=(const GameVector& vector) const;
GameVector& operator =(const GameVector& vector);
diff --git a/TombEngine/Math/Objects/Pose.h b/TombEngine/Math/Objects/Pose.h
index 1a4342262..e60a7bc73 100644
--- a/TombEngine/Math/Objects/Pose.h
+++ b/TombEngine/Math/Objects/Pose.h
@@ -8,13 +8,16 @@
{
public:
// Members
+
Vector3i Position = Vector3i::Zero;
EulerAngles Orientation = EulerAngles::Identity;
// Constants
+
static const Pose Zero;
// Constructors
+
Pose();
Pose(const Vector3i& pos);
Pose(int xPos, int yPos, int zPos);
@@ -26,11 +29,13 @@
Pose(int xPos, int yPos, int zPos, short xOrient, short yOrient, short zOrient);
// Utilities
+
void Translate(short headingAngle, float forward, float down = 0.0f, float right = 0.0f);
void Translate(const EulerAngles& orient, float dist);
void Translate(const Vector3& dir, float dist);
// Operators
+
bool operator ==(const Pose& pose) const;
bool operator !=(const Pose& pose) const;
};
diff --git a/TombEngine/Math/Objects/Vector2i.h b/TombEngine/Math/Objects/Vector2i.h
index bf0e7d44b..38fef4d0e 100644
--- a/TombEngine/Math/Objects/Vector2i.h
+++ b/TombEngine/Math/Objects/Vector2i.h
@@ -6,25 +6,31 @@ namespace TEN::Math
{
public:
// Members
+
int x = 0;
int y = 0;
// Constants
+
static const Vector2i Zero;
// Constructors
+
constexpr Vector2i() {};
constexpr Vector2i(int x, int y) { this->x = x; this->y = y; };
Vector2i(const Vector2& vector);
// Utilities
+
static float Distance(const Vector2i& origin, const Vector2i& target);
static float DistanceSquared(const Vector2i& origin, const Vector2i& target);
// Converters
+
Vector2 ToVector2() const;
// Operators
+
bool operator ==(const Vector2i& vector) const;
bool operator !=(const Vector2i& vector) const;
Vector2i& operator =(const Vector2i& vector);
diff --git a/TombEngine/Math/Objects/Vector3i.h b/TombEngine/Math/Objects/Vector3i.h
index 9a8c75bdf..efa9ec3bb 100644
--- a/TombEngine/Math/Objects/Vector3i.h
+++ b/TombEngine/Math/Objects/Vector3i.h
@@ -6,28 +6,34 @@
{
public:
// Members
+
int x = 0;
int y = 0;
int z = 0;
// Constants
+
static const Vector3i Zero;
// Constructors
+
constexpr Vector3i() {};
constexpr Vector3i(int x, int y, int z) { this->x = x; this->y = y; this->z = z; };
Vector3i(const Vector3& vector);
// Utilities
+
static float Distance(const Vector3i& origin, const Vector3i& target);
static float DistanceSquared(const Vector3i& origin, const Vector3i& target);
void Lerp(const Vector3i& target, float alpha);
static Vector3i Lerp(const Vector3i& origin, const Vector3i& target, float alpha);
// Converters
+
Vector3 ToVector3() const;
// Operators
+
bool operator ==(const Vector3i& vector) const;
bool operator !=(const Vector3i& vector) const;
Vector3i& operator =(const Vector3i& vector);
diff --git a/TombEngine/Math/Interpolation.cpp b/TombEngine/Math/Utils.cpp
similarity index 54%
rename from TombEngine/Math/Interpolation.cpp
rename to TombEngine/Math/Utils.cpp
index 12e8cfb4f..eb5245f02 100644
--- a/TombEngine/Math/Interpolation.cpp
+++ b/TombEngine/Math/Utils.cpp
@@ -1,5 +1,5 @@
#include "framework.h"
-#include "Math/Interpolation.h"
+#include "Math/Utils.h"
#include "Math/Constants.h"
@@ -55,4 +55,47 @@ namespace TEN::Math
// Evaluate polynomial.
return (CUBE(alpha) * (alpha * (alpha * 6 - 15) + 10));
}
+
+ float Luma(const Vector3& color)
+ {
+ constexpr auto RED_COEFF = 0.2126f;
+ constexpr auto GREEN_COEFF = 0.7152f;
+ constexpr auto BLUE_COEFF = 0.0722f;
+
+ // Use Rec.709 trichromat formula to get perceptive luma value.
+ return float((color.x * RED_COEFF) + (color.y * GREEN_COEFF) + (color.z * BLUE_COEFF));
+ }
+
+ Vector3 Screen(const Vector3& ambient, const Vector3& tint)
+ {
+ float luma = Luma(tint);
+ auto multiplicative = ambient * tint;
+ auto additive = ambient + tint;
+
+ return Vector3(
+ Lerp(multiplicative.x, additive.x, luma),
+ Lerp(multiplicative.y, additive.y, luma),
+ Lerp(multiplicative.z, additive.z, luma));
+ }
+
+ Vector4 Screen(const Vector4& ambient, const Vector4& tint)
+ {
+ auto result = Screen(Vector3(ambient), Vector3(tint));
+ return Vector4(result.x, result.y, result.z, ambient.w * tint.w);
+ }
+
+ float FloorToStep(float value, float step)
+ {
+ return (floor(value / step) * step);
+ }
+
+ float CeilToStep(float value, float step)
+ {
+ return (ceil(value / step) * step);
+ }
+
+ float RoundToStep(float value, float step)
+ {
+ return (round(value / step) * step);
+ }
}
diff --git a/TombEngine/Math/Utils.h b/TombEngine/Math/Utils.h
new file mode 100644
index 000000000..53e4e1c7d
--- /dev/null
+++ b/TombEngine/Math/Utils.h
@@ -0,0 +1,27 @@
+#pragma once
+
+namespace TEN::Math
+{
+ constexpr inline auto OFFSET_RADIUS = [](auto x) { return ((x * SQRT_2) + 4); };
+ constexpr inline auto MESH_BITS = [](auto x) { return (1 << x); };
+
+ // Interpolation
+
+ float Lerp(float value0, float value1, float alpha);
+ float InterpolateCos(float value0, float value1, float alpha);
+ float InterpolateCubic(float value0, float value1, float value2, float value3, float alpha);
+ float Smoothstep(float alpha);
+ float Smoothstep(float value0, float value1, float alpha);
+
+ // Color
+
+ float Luma(const Vector3& color);
+ Vector3 Screen(const Vector3& ambient, const Vector3& tint);
+ Vector4 Screen(const Vector4& ambient, const Vector4& tint);
+
+ // Misc.
+
+ float FloorToStep(float value, float step);
+ float CeilToStep(float value, float step);
+ float RoundToStep(float value, float step);
+}
diff --git a/TombEngine/TombEngine.vcxproj b/TombEngine/TombEngine.vcxproj
index 81d212c5a..b9a6701e9 100644
--- a/TombEngine/TombEngine.vcxproj
+++ b/TombEngine/TombEngine.vcxproj
@@ -427,7 +427,6 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
-
@@ -439,6 +438,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
+
@@ -936,9 +936,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
-
-
@@ -948,6 +946,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
+
From ba6841bb180b3e5ffa71b4c7e5175615321b3fcf Mon Sep 17 00:00:00 2001
From: Sezz
Date: Fri, 21 Jun 2024 13:37:06 +1000
Subject: [PATCH 218/410] Add tab
---
TombEngine/Math/Utils.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/TombEngine/Math/Utils.h b/TombEngine/Math/Utils.h
index 53e4e1c7d..abaf295b4 100644
--- a/TombEngine/Math/Utils.h
+++ b/TombEngine/Math/Utils.h
@@ -15,7 +15,7 @@ namespace TEN::Math
// Color
- float Luma(const Vector3& color);
+ float Luma(const Vector3& color);
Vector3 Screen(const Vector3& ambient, const Vector3& tint);
Vector4 Screen(const Vector4& ambient, const Vector4& tint);
From 399c039f2127d1e6ab5ac4db4470e3151551dc8a Mon Sep 17 00:00:00 2001
From: Sezz
Date: Tue, 25 Jun 2024 01:24:32 +1000
Subject: [PATCH 219/410] Prevent more inappropriate tooltips
---
TombEngine/Game/collision/Point.h | 5 +++++
TombEngine/Specific/BitField.h | 9 +++++++++
TombEngine/Specific/Input/InputAction.h | 11 ++++++++++-
3 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/TombEngine/Game/collision/Point.h b/TombEngine/Game/collision/Point.h
index 9f1651f10..9dbc6fe32 100644
--- a/TombEngine/Game/collision/Point.h
+++ b/TombEngine/Game/collision/Point.h
@@ -14,6 +14,7 @@ namespace TEN::Collision::Point
{
private:
// Members
+
Vector3i _position = Vector3i::Zero;
int _roomNumber = 0;
@@ -34,9 +35,11 @@ namespace TEN::Collision::Point
public:
// Constructors
+
PointCollisionData(const Vector3i& pos, int roomNumber);
// Getters
+
Vector3i GetPosition() const;
int GetRoomNumber() const;
@@ -56,6 +59,7 @@ namespace TEN::Collision::Point
int GetWaterTopHeight();
// Inquirers
+
bool IsWall();
bool IsSteepFloor();
bool IsSteepCeiling();
@@ -70,6 +74,7 @@ namespace TEN::Collision::Point
private:
// Helpers
+
Vector3 GetBridgeNormal(bool isFloor);
};
diff --git a/TombEngine/Specific/BitField.h b/TombEngine/Specific/BitField.h
index 98592fd1e..5bd3104e3 100644
--- a/TombEngine/Specific/BitField.h
+++ b/TombEngine/Specific/BitField.h
@@ -9,23 +9,28 @@ namespace TEN::Utils
{
private:
// Constants
+
static constexpr auto SIZE_DEFAULT = 32;
// Members
+
std::vector _bits = {};
public:
// Presets
+
static const BitField Empty;
static const BitField Default;
// Constructors
+
BitField();
BitField(unsigned int size);
BitField(unsigned int size, unsigned int packedBits);
BitField(const std::string& bitString);
// Getters
+
unsigned int GetSize() const;
unsigned int GetCount() const;
@@ -41,17 +46,20 @@ namespace TEN::Utils
void FlipAll();
// Inquirers
+
bool Test(const std::vector& indices, bool testAny = true) const;
bool Test(unsigned int index) const;
bool TestAny() const;
bool TestAll() const;
// Converters
+
unsigned int ToPackedBits() const;
std::string ToString() const;
// Operators
// NOTE: packedBits will not be assessed in full if the size of the given BitField object is less than SIZE_DEFAULT.
+
bool operator ==(unsigned int packedBits) const;
bool operator !=(unsigned int packedBits) const;
BitField& operator =(unsigned int packedBits);
@@ -62,6 +70,7 @@ namespace TEN::Utils
private:
// Helpers
+
void Fill(bool value);
};
}
diff --git a/TombEngine/Specific/Input/InputAction.h b/TombEngine/Specific/Input/InputAction.h
index 29abd2bf0..adeb7eda6 100644
--- a/TombEngine/Specific/Input/InputAction.h
+++ b/TombEngine/Specific/Input/InputAction.h
@@ -5,6 +5,7 @@ namespace TEN::Input
typedef enum class ActionID
{
// General actions
+
Forward,
Back,
Left,
@@ -21,6 +22,7 @@ namespace TEN::Input
Look,
// Vehicle actions
+
Accelerate,
Reverse,
Faster,
@@ -29,6 +31,7 @@ namespace TEN::Input
Fire,
// Quick actions
+
Flare,
SmallMedipack,
LargeMedipack,
@@ -46,6 +49,7 @@ namespace TEN::Input
Weapon10,
// Menu actions
+
Select,
Deselect,
Pause,
@@ -56,11 +60,11 @@ namespace TEN::Input
Count
} In;
- // TODO: For analog triggers, use Value range [0.0f, 1.0f] with deadzone up to a quarter press.
class InputAction
{
private:
// Members
+
ActionID ID = In::Forward;
float Value = 0.0f;
float PrevValue = 0.0f;
@@ -70,21 +74,25 @@ namespace TEN::Input
public:
// Constructors
+
InputAction(ActionID actionID);
// Getters
+
ActionID GetID() const;
float GetValue() const;
float GetTimeActive() const;
float GetTimeInactive() const;
// Inquirers
+
bool IsClicked() const;
bool IsHeld(float delayInSec = 0.0f) const;
bool IsPulsed(float delayInSec, float initialDelayInSec = 0.0f) const;
bool IsReleased(float maxDelayInSec = INFINITY) const;
// Utilities
+
void Update(bool value);
void Update(float value);
void Clear();
@@ -93,6 +101,7 @@ namespace TEN::Input
private:
// Helpers
+
void UpdateValue(float value);
};
}
From 9f2cf860c5aa1e89e12a15ba6579b9d88afe0213 Mon Sep 17 00:00:00 2001
From: Stranger1992 <84292688+Stranger1992@users.noreply.github.com>
Date: Mon, 24 Jun 2024 22:14:30 +0100
Subject: [PATCH 220/410] Update CHANGELOG.md
Small changes to text to improve clarity
---
CHANGELOG.md | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c9e542b5b..5460278fc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,10 +9,10 @@ TombEngine releases are located in this repository (alongside with Tomb Editor):
## Version 1.5 - xxxx-xx-xx
### Bug fixes
-* Fixed original issue with classic switch off trigger wrongly activating some trigger actions.
+* Fixed original issue with classic switch off trigger incorrectly activating some trigger actions.
* Fixed incorrect diving animation when swandiving from a high place.
-* Fixed camera rotating with player's hips when climbing out of water.
-* Fixed AI for skidoo driver and worker with shotgun TR2 enemies.
+* Fixed camera rotating with the player's hips when climbing out of water.
+* Fixed AI for TR2 skidoo driver and worker with shotgun.
* Fixed ember emitter crashing when ocb is between -1 and -10.
* Fixed electric cleaner and squishy block not detecting collision with certain block heights.
* Fixed squishy blocks crashing the level.
@@ -24,14 +24,14 @@ TombEngine releases are located in this repository (alongside with Tomb Editor):
* Fixed Joby spikes collision and deformation.
* Fixed sentry gun joint rotation.
* Fixed teeth spikes not triggering the player impale animation.
-* Fixed TR4 mine crash with OCB1 when triggered.
+* Fixed TR4 mine crash with OCB 1 when triggered.
### Features/Amendments
-* Changed Rome Hammer for it to don't hurt Lara while it's deactivated.
+* Changed Rome Hammer to not hurt player whilst deactivated.
* Changed Statue with blade damage, from 20 to 200.
* Enhaced Rolling Spindle detection to avoid them going down through pits.
-* Enhaced Sentry Guns, with a new ItemFlags[3] to contain the ID of the inventory item that deactivates the sentry guns (by default PUZZLE_ITEM5 ID)
-* Enhaced Dart Emitter, with a new ItemFlags[0] to contain the number of frames between shots (by default 32 in dart emitter, and 24 in homing dar emitter).
+* Enhaced Sentry Guns, with a new ItemFlags[3], to contain the ID of the inventory item that deactivates the sentry guns ( by default PUZZLE_ITEM5 )
+* Enhaced Dart Emitter, with a new ItemFlags[0], to contain the number of frames between shots ( by default 32 in dart emitter, and 24 in homing dar emitter ).
### Lua API changes
* Added Inventory.GetUsedItem(), Inventory.SetUsedItem() and Inventory.ClearUsedItem() functions.
From e39193497f19b7243a44bd94ae663691537f8942 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Tue, 25 Jun 2024 17:32:02 +1000
Subject: [PATCH 221/410] Update sector class; disambiguate pathfinding boxes
---
TombEngine/Game/Lara/lara.cpp | 2 +-
TombEngine/Game/collision/floordata.h | 20 +++--
TombEngine/Game/control/box.cpp | 76 ++++++++---------
TombEngine/Game/control/box.h | 3 +
TombEngine/Game/control/lot.cpp | 8 +-
TombEngine/Game/items.cpp | 2 +-
TombEngine/Game/misc.cpp | 6 +-
.../Objects/Generic/Doors/generic_doors.cpp | 30 +++----
TombEngine/Objects/TR3/Entity/Lizard.cpp | 2 +-
TombEngine/Objects/TR3/Entity/Shiva.cpp | 4 +-
TombEngine/Objects/TR3/Entity/tr3_civvy.cpp | 2 +-
TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp | 2 +-
.../Objects/TR3/Entity/tr3_mp_stick.cpp | 2 +-
.../TR5/Object/tr5_expandingplatform.cpp | 2 +-
.../Objects/TR5/Object/tr5_raisingblock.cpp | 4 +-
.../Objects/TR5/Shatter/tr5_smashobject.cpp | 6 +-
TombEngine/Specific/level.cpp | 85 ++++++++++---------
TombEngine/Specific/level.h | 4 +-
18 files changed, 135 insertions(+), 125 deletions(-)
diff --git a/TombEngine/Game/Lara/lara.cpp b/TombEngine/Game/Lara/lara.cpp
index 550f1397f..053a5ce44 100644
--- a/TombEngine/Game/Lara/lara.cpp
+++ b/TombEngine/Game/Lara/lara.cpp
@@ -335,7 +335,7 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
if (DebugMode)
{
- DrawNearbyPathfinding(GetPointCollision(*item).GetBottomSector().Box);
+ DrawNearbyPathfinding(GetPointCollision(*item).GetBottomSector().PathfindingBoxID);
DrawNearbySectorFlags(*item);
}
}
diff --git a/TombEngine/Game/collision/floordata.h b/TombEngine/Game/collision/floordata.h
index be6e2c456..56dff4dec 100644
--- a/TombEngine/Game/collision/floordata.h
+++ b/TombEngine/Game/collision/floordata.h
@@ -136,16 +136,18 @@ class FloorInfo
{
public:
// Members
- int RoomNumber = 0;
- int SidePortalRoomNumber = 0;
- SectorSurfaceData FloorSurface = {};
- SectorSurfaceData CeilingSurface = {};
- std::set BridgeItemNumbers = {};
- SectorFlagData Flags = {};
+ Vector2i Position = Vector2i::Zero;
+ int RoomNumber = 0;
+ SectorSurfaceData FloorSurface = {};
+ SectorSurfaceData CeilingSurface = {};
+ SectorFlagData Flags = {};
- int Box = 0;
- int TriggerIndex = 0;
- bool Stopper = true;
+ std::set BridgeItemNumbers = {};
+ int SidePortalRoomNumber = 0;
+
+ int PathfindingBoxID = 0;
+ int TriggerIndex = 0;
+ bool Stopper = true;
// Getters
int GetSurfaceTriangleID(int x, int z, bool isFloor) const;
diff --git a/TombEngine/Game/control/box.cpp b/TombEngine/Game/control/box.cpp
index 7f19d68b9..3166286f2 100644
--- a/TombEngine/Game/control/box.cpp
+++ b/TombEngine/Game/control/box.cpp
@@ -55,7 +55,7 @@ void DrawBox(int boxIndex, Vector3 color)
if (boxIndex == NO_VALUE)
return;
- auto& currBox = g_Level.Boxes[boxIndex];
+ auto& currBox = g_Level.PathfindingBoxes[boxIndex];
float x = ((float)currBox.left + (float)(currBox.right - currBox.left) / 2.0f) * 1024.0f;
auto y = currBox.height - CLICK(1);
@@ -78,7 +78,7 @@ void DrawNearbyPathfinding(int boxIndex)
if (boxIndex == NO_VALUE)
return;
- auto& currBox = g_Level.Boxes[boxIndex];
+ auto& currBox = g_Level.PathfindingBoxes[boxIndex];
auto index = currBox.overlapIndex;
// Grey flag box.
@@ -155,13 +155,13 @@ bool SameZone(CreatureInfo* creature, ItemInfo* target)
auto* zone = g_Level.Zones[(int)creature->LOT.Zone][(int)FlipStatus].data();
auto& roomSource = g_Level.Rooms[item.RoomNumber];
- auto& boxSource = GetSector(&roomSource, item.Pose.Position.x - roomSource.x, item.Pose.Position.z - roomSource.z)->Box;
+ auto& boxSource = GetSector(&roomSource, item.Pose.Position.x - roomSource.x, item.Pose.Position.z - roomSource.z)->PathfindingBoxID;
if (boxSource == NO_VALUE)
return false;
item.BoxNumber = boxSource;
auto& roomTarget = g_Level.Rooms[target->RoomNumber];
- auto& boxTarget = GetSector(&roomTarget, target->Pose.Position.x - roomTarget.x, target->Pose.Position.z - roomTarget.z)->Box;
+ auto& boxTarget = GetSector(&roomTarget, target->Pose.Position.x - roomTarget.x, target->Pose.Position.z - roomTarget.z)->PathfindingBoxID;
if (boxTarget == NO_VALUE)
return false;
target->BoxNumber = boxTarget;
@@ -257,7 +257,7 @@ bool CreaturePathfind(ItemInfo* item, Vector3i prevPos, short angle, short tilt)
int boxHeight;
if (item->BoxNumber != NO_VALUE)
- boxHeight = g_Level.Boxes[item->BoxNumber].height;
+ boxHeight = g_Level.PathfindingBoxes[item->BoxNumber].height;
else
boxHeight = item->Floor;
@@ -267,31 +267,31 @@ bool CreaturePathfind(ItemInfo* item, Vector3i prevPos, short angle, short tilt)
GetFloor(prevPos.x, y, prevPos.z, &roomNumber);
auto* floor = GetFloor(item->Pose.Position.x, y, item->Pose.Position.z, &roomNumber);
- if (floor->Box == NO_VALUE)
+ if (floor->PathfindingBoxID == NO_VALUE)
return false;
- int height = g_Level.Boxes[floor->Box].height;
+ int height = g_Level.PathfindingBoxes[floor->PathfindingBoxID].height;
int nextHeight = 0;
int nextBox;
if (!Objects[item->ObjectNumber].nonLot)
{
- nextBox = LOT->Node[floor->Box].exitBox;
+ nextBox = LOT->Node[floor->PathfindingBoxID].exitBox;
}
else
{
floor = GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &roomNumber);
- height = g_Level.Boxes[floor->Box].height;
- nextBox = floor->Box;
+ height = g_Level.PathfindingBoxes[floor->PathfindingBoxID].height;
+ nextBox = floor->PathfindingBoxID;
}
if (nextBox == NO_VALUE)
nextHeight = height;
else
- nextHeight = g_Level.Boxes[nextBox].height;
+ nextHeight = g_Level.PathfindingBoxes[nextBox].height;
- if (floor->Box == NO_VALUE || !LOT->IsJumping &&
- (LOT->Fly == NO_FLYING && item->BoxNumber != NO_VALUE && zone[item->BoxNumber] != zone[floor->Box] ||
+ if (floor->PathfindingBoxID == NO_VALUE || !LOT->IsJumping &&
+ (LOT->Fly == NO_FLYING && item->BoxNumber != NO_VALUE && zone[item->BoxNumber] != zone[floor->PathfindingBoxID] ||
boxHeight - height > LOT->Step ||
boxHeight - height < LOT->Drop))
{
@@ -311,22 +311,22 @@ bool CreaturePathfind(ItemInfo* item, Vector3i prevPos, short angle, short tilt)
item->Pose.Position.z = prevPos.z | WALL_MASK;
floor = GetFloor(item->Pose.Position.x, y, item->Pose.Position.z, &roomNumber);
- height = g_Level.Boxes[floor->Box].height;
+ height = g_Level.PathfindingBoxes[floor->PathfindingBoxID].height;
if (!Objects[item->ObjectNumber].nonLot)
{
- nextBox = LOT->Node[floor->Box].exitBox;
+ nextBox = LOT->Node[floor->PathfindingBoxID].exitBox;
}
else
{
floor = GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &roomNumber);
- height = g_Level.Boxes[floor->Box].height;
- nextBox = floor->Box;
+ height = g_Level.PathfindingBoxes[floor->PathfindingBoxID].height;
+ nextBox = floor->PathfindingBoxID;
}
if (nextBox == NO_VALUE)
nextHeight = height;
else
- nextHeight = g_Level.Boxes[nextBox].height;
+ nextHeight = g_Level.PathfindingBoxes[nextBox].height;
}
int x = item->Pose.Position.x;
@@ -857,13 +857,13 @@ void CreatureDie(int itemNumber, bool doExplosion, int flags)
bool BadFloor(int x, int y, int z, int boxHeight, int nextHeight, short roomNumber, LOTInfo* LOT)
{
auto* floor = GetFloor(x, y, z, &roomNumber);
- if (floor->Box == NO_VALUE)
+ if (floor->PathfindingBoxID == NO_VALUE)
return true;
if (LOT->IsJumping)
return false;
- auto* box = &g_Level.Boxes[floor->Box];
+ auto* box = &g_Level.PathfindingBoxes[floor->PathfindingBoxID];
if (box->flags & LOT->BlockMask)
return true;
@@ -928,7 +928,7 @@ bool ValidBox(ItemInfo* item, short zoneNumber, short boxNumber)
if (creature.LOT.Fly == NO_FLYING && zone[boxNumber] != zoneNumber)
return false;
- const auto& box = g_Level.Boxes[boxNumber];
+ const auto& box = g_Level.PathfindingBoxes[boxNumber];
if (creature.LOT.BlockMask & box.flags)
return false;
@@ -948,7 +948,7 @@ bool EscapeBox(ItemInfo* item, ItemInfo* enemy, int boxNumber)
if (boxNumber == NO_VALUE)
return false;
- const auto& box = g_Level.Boxes[boxNumber];
+ const auto& box = g_Level.PathfindingBoxes[boxNumber];
int x = ((box.top + box.bottom) * BLOCK(0.5f)) - enemy->Pose.Position.x;
int z = ((box.left + box.right) * BLOCK(0.5f)) - enemy->Pose.Position.z;
@@ -966,7 +966,7 @@ void TargetBox(LOTInfo* LOT, int boxNumber)
{
if (boxNumber == NO_VALUE)
return;
- auto* box = &g_Level.Boxes[boxNumber];
+ auto* box = &g_Level.PathfindingBoxes[boxNumber];
// Maximize target precision. DO NOT change bracket precedence!
LOT->Target.x = (int)((box->top * BLOCK(1)) + (float)GetRandomControl() * (((float)(box->bottom - box->top) - 1.0f) / 32.0f) + CLICK(2.0f));
@@ -1016,7 +1016,7 @@ bool SearchLOT(LOTInfo* LOT, int depth)
return false;
}
- auto* box = &g_Level.Boxes[LOT->Head];
+ auto* box = &g_Level.PathfindingBoxes[LOT->Head];
auto* node = &LOT->Node[LOT->Head];
int index = box->overlapIndex;
@@ -1034,7 +1034,7 @@ bool SearchLOT(LOTInfo* LOT, int depth)
if (LOT->Fly == NO_FLYING && searchZone != zone[boxNumber])
continue;
- int delta = g_Level.Boxes[boxNumber].height - box->height;
+ int delta = g_Level.PathfindingBoxes[boxNumber].height - box->height;
if ((delta > LOT->Step || delta < LOT->Drop) && (!(flags & BOX_MONKEY) || !LOT->CanMonkey))
continue;
@@ -1057,7 +1057,7 @@ bool SearchLOT(LOTInfo* LOT, int depth)
if ((node->searchNumber & SEARCH_NUMBER) == (expand->searchNumber & SEARCH_NUMBER) && !(expand->searchNumber & BLOCKED_SEARCH))
continue;
- if (g_Level.Boxes[boxNumber].flags & LOT->BlockMask)
+ if (g_Level.PathfindingBoxes[boxNumber].flags & LOT->BlockMask)
{
expand->searchNumber = node->searchNumber | BLOCKED_SEARCH;
}
@@ -1145,7 +1145,7 @@ bool StalkBox(ItemInfo* item, ItemInfo* enemy, int boxNumber)
{
if (enemy == nullptr || boxNumber == NO_VALUE)
return false;
- auto* box = &g_Level.Boxes[boxNumber];
+ auto* box = &g_Level.PathfindingBoxes[boxNumber];
int xRange = STALK_DIST + ((box->bottom - box->top) * BLOCK(1));
int zRange = STALK_DIST + ((box->right - box->left) * BLOCK(1));
@@ -1461,9 +1461,9 @@ void FindAITargetObject(CreatureInfo* creature, int objectNumber, int ocb, bool
int* zone = g_Level.Zones[(int)creature->LOT.Zone][(int)FlipStatus].data();
auto* room = &g_Level.Rooms[item.RoomNumber];
- item.BoxNumber = GetSector(room, item.Pose.Position.x - room->x, item.Pose.Position.z - room->z)->Box;
+ item.BoxNumber = GetSector(room, item.Pose.Position.x - room->x, item.Pose.Position.z - room->z)->PathfindingBoxID;
room = &g_Level.Rooms[aiObject.roomNumber];
- aiObject.boxNumber = GetSector(room, aiObject.pos.Position.x - room->x, aiObject.pos.Position.z - room->z)->Box;
+ aiObject.boxNumber = GetSector(room, aiObject.pos.Position.x - room->x, aiObject.pos.Position.z - room->z)->PathfindingBoxID;
if (item.BoxNumber == NO_VALUE || aiObject.boxNumber == NO_VALUE)
return;
@@ -1524,7 +1524,7 @@ int TargetReachable(ItemInfo* item, ItemInfo* enemy)
isReachable = abs(enemy->Pose.Position.y - pointColl.GetFloorHeight()) < bounds.GetHeight();
}
- return (isReachable ? floor->Box : NO_VALUE);
+ return (isReachable ? floor->PathfindingBoxID : NO_VALUE);
}
void CreatureAIInfo(ItemInfo* item, AI_INFO* AI)
@@ -1546,7 +1546,7 @@ void CreatureAIInfo(ItemInfo* item, AI_INFO* AI)
auto* zone = g_Level.Zones[(int)creature->LOT.Zone][(int)FlipStatus].data();
auto* room = &g_Level.Rooms[item->RoomNumber];
- item->BoxNumber = GetSector(room, item->Pose.Position.x - room->x, item->Pose.Position.z - room->z)->Box;
+ item->BoxNumber = GetSector(room, item->Pose.Position.x - room->x, item->Pose.Position.z - room->z)->PathfindingBoxID;
AI->zoneNumber = zone[item->BoxNumber];
enemy->BoxNumber = TargetReachable(item, enemy);
@@ -1554,7 +1554,7 @@ void CreatureAIInfo(ItemInfo* item, AI_INFO* AI)
if (!object->nonLot)
{
- if (enemy->BoxNumber != NO_VALUE && g_Level.Boxes[enemy->BoxNumber].flags & creature->LOT.BlockMask)
+ if (enemy->BoxNumber != NO_VALUE && g_Level.PathfindingBoxes[enemy->BoxNumber].flags & creature->LOT.BlockMask)
{
AI->enemyZone |= BLOCKED;
}
@@ -1754,7 +1754,7 @@ void CreatureMood(ItemInfo* item, AI_INFO* AI, bool isViolent)
int endBox = LOT->Node[item->BoxNumber].exitBox;
if (endBox != NO_VALUE)
{
- int overlapIndex = g_Level.Boxes[item->BoxNumber].overlapIndex;
+ int overlapIndex = g_Level.PathfindingBoxes[item->BoxNumber].overlapIndex;
int nextBox = 0;
int flags = 0;
@@ -1901,7 +1901,7 @@ TARGET_TYPE CalculateTarget(Vector3i* target, ItemInfo* item, LOTInfo* LOT)
if (boxNumber == NO_VALUE)
return TARGET_TYPE::NO_TARGET;
- auto* box = &g_Level.Boxes[boxNumber];
+ auto* box = &g_Level.PathfindingBoxes[boxNumber];
int boxLeft = ((int)box->left * BLOCK(1));
int boxRight = ((int)box->right * BLOCK(1)) - 1;
@@ -1915,7 +1915,7 @@ TARGET_TYPE CalculateTarget(Vector3i* target, ItemInfo* item, LOTInfo* LOT)
do
{
- box = &g_Level.Boxes[boxNumber];
+ box = &g_Level.PathfindingBoxes[boxNumber];
if (LOT->Fly != NO_FLYING)
{
@@ -2096,7 +2096,7 @@ TARGET_TYPE CalculateTarget(Vector3i* target, ItemInfo* item, LOTInfo* LOT)
}
boxNumber = LOT->Node[boxNumber].exitBox;
- if (boxNumber != NO_VALUE && (g_Level.Boxes[boxNumber].flags & LOT->BlockMask))
+ if (boxNumber != NO_VALUE && (g_Level.PathfindingBoxes[boxNumber].flags & LOT->BlockMask))
break;
} while (boxNumber != NO_VALUE);
@@ -2157,10 +2157,10 @@ void InitializeItemBoxData()
continue;
auto* floor = &room.floor[index];
- if (floor->Box == NO_VALUE)
+ if (floor->PathfindingBoxID == NO_VALUE)
continue;
- if (!(g_Level.Boxes[floor->Box].flags & BLOCKED))
+ if (!(g_Level.PathfindingBoxes[floor->PathfindingBoxID].flags & BLOCKED))
{
int floorHeight = floor->GetSurfaceHeight(mesh.pos.Position.x, mesh.pos.Position.z, true);
const auto& bBox = GetBoundsAccurate(mesh, false);
diff --git a/TombEngine/Game/control/box.h b/TombEngine/Game/control/box.h
index 50ceb5142..7bf26d8c2 100644
--- a/TombEngine/Game/control/box.h
+++ b/TombEngine/Game/control/box.h
@@ -1,4 +1,5 @@
#pragma once
+
#include "Specific/level.h"
#include "Math/Math.h"
@@ -33,12 +34,14 @@ struct AI_INFO
short enemyFacing;
};
+// TODO: Use DX BoundingBox class to store AABB.
struct BOX_INFO
{
unsigned int left;
unsigned int right;
unsigned int top;
unsigned int bottom;
+
int height;
int overlapIndex;
int flags;
diff --git a/TombEngine/Game/control/lot.cpp b/TombEngine/Game/control/lot.cpp
index 01dc1f065..74a9b7771 100644
--- a/TombEngine/Game/control/lot.cpp
+++ b/TombEngine/Game/control/lot.cpp
@@ -25,7 +25,7 @@ void InitializeLOTarray(int itemNumber)
if (!creature->LOT.Initialized)
{
- creature->LOT.Node = std::vector(g_Level.Boxes.size(), BoxNode{});
+ creature->LOT.Node = std::vector(g_Level.PathfindingBoxes.size(), BoxNode{});
creature->LOT.Initialized = true;
}
}
@@ -240,14 +240,14 @@ void CreateZone(ItemInfo* item)
auto* creature = GetCreatureInfo(item);
auto* room = &g_Level.Rooms[item->RoomNumber];
- item->BoxNumber = GetSector(room, item->Pose.Position.x - room->x, item->Pose.Position.z - room->z)->Box;
+ item->BoxNumber = GetSector(room, item->Pose.Position.x - room->x, item->Pose.Position.z - room->z)->PathfindingBoxID;
if (creature->LOT.Fly)
{
auto* node = creature->LOT.Node.data();
creature->LOT.ZoneCount = 0;
- for (int i = 0; i < g_Level.Boxes.size(); i++)
+ for (int i = 0; i < g_Level.PathfindingBoxes.size(); i++)
{
node->boxNumber = i;
node++;
@@ -265,7 +265,7 @@ void CreateZone(ItemInfo* item)
auto* node = creature->LOT.Node.data();
creature->LOT.ZoneCount = 0;
- for (int i = 0; i < g_Level.Boxes.size(); i++)
+ for (int i = 0; i < g_Level.PathfindingBoxes.size(); i++)
{
if (*zone == zoneNumber || *flippedZone == flippedZoneNumber)
{
diff --git a/TombEngine/Game/items.cpp b/TombEngine/Game/items.cpp
index 718b83fff..bd3631e8b 100644
--- a/TombEngine/Game/items.cpp
+++ b/TombEngine/Game/items.cpp
@@ -586,7 +586,7 @@ void InitializeItem(short itemNumber)
FloorInfo* floor = GetSector(room, item->Pose.Position.x - room->x, item->Pose.Position.z - room->z);
item->Floor = floor->GetSurfaceHeight(item->Pose.Position.x, item->Pose.Position.z, true);
- item->BoxNumber = floor->Box;
+ item->BoxNumber = floor->PathfindingBoxID;
item->ResetModelToDefault();
diff --git a/TombEngine/Game/misc.cpp b/TombEngine/Game/misc.cpp
index 29fa3e945..6365f6209 100644
--- a/TombEngine/Game/misc.cpp
+++ b/TombEngine/Game/misc.cpp
@@ -132,13 +132,13 @@ bool IsNextSectorValid(const ItemInfo& item, const Vector3& dir, float dist, boo
}
// Check for inaccessible sector.
- if (pointColl.GetSector().Box == NO_VALUE)
+ if (pointColl.GetSector().PathfindingBoxID == NO_VALUE)
return false;
// Check for blocked grey box.
- if (g_Level.Boxes[pointColl.GetSector().Box].flags & BLOCKABLE)
+ if (g_Level.PathfindingBoxes[pointColl.GetSector().PathfindingBoxID].flags & BLOCKABLE)
{
- if (g_Level.Boxes[pointColl.GetSector().Box].flags & BLOCKED)
+ if (g_Level.PathfindingBoxes[pointColl.GetSector().PathfindingBoxID].flags & BLOCKED)
return false;
}
diff --git a/TombEngine/Objects/Generic/Doors/generic_doors.cpp b/TombEngine/Objects/Generic/Doors/generic_doors.cpp
index a12db1847..84bc395df 100644
--- a/TombEngine/Objects/Generic/Doors/generic_doors.cpp
+++ b/TombEngine/Objects/Generic/Doors/generic_doors.cpp
@@ -81,14 +81,14 @@ namespace TEN::Entities::Doors
auto roomNumber = doorData->d1.floor->SidePortalRoomNumber;
if (roomNumber == NO_VALUE)
- boxNumber = doorData->d1.floor->Box;
+ boxNumber = doorData->d1.floor->PathfindingBoxID;
else
{
auto* b = &g_Level.Rooms[roomNumber];
- boxNumber = GetSector(b, doorItem->Pose.Position.x - b->x + xOffset, doorItem->Pose.Position.z - b->z + zOffset)->Box;
+ boxNumber = GetSector(b, doorItem->Pose.Position.x - b->x + xOffset, doorItem->Pose.Position.z - b->z + zOffset)->PathfindingBoxID;
}
- doorData->d1.block = (boxNumber != NO_VALUE && g_Level.Boxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_VALUE;
+ doorData->d1.block = (boxNumber != NO_VALUE && g_Level.PathfindingBoxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_VALUE;
doorData->d1.data = *doorData->d1.floor;
if (r->flippedRoom != -1)
@@ -98,14 +98,14 @@ namespace TEN::Entities::Doors
roomNumber = doorData->d1flip.floor->SidePortalRoomNumber;
if (roomNumber == NO_VALUE)
- boxNumber = doorData->d1flip.floor->Box;
+ boxNumber = doorData->d1flip.floor->PathfindingBoxID;
else
{
auto* b = &g_Level.Rooms[roomNumber];
- boxNumber = GetSector(b, doorItem->Pose.Position.x - b->x + xOffset, doorItem->Pose.Position.z - b->z + zOffset)->Box;
+ boxNumber = GetSector(b, doorItem->Pose.Position.x - b->x + xOffset, doorItem->Pose.Position.z - b->z + zOffset)->PathfindingBoxID;
}
- doorData->d1flip.block = (boxNumber != NO_VALUE && g_Level.Boxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_VALUE;
+ doorData->d1flip.block = (boxNumber != NO_VALUE && g_Level.PathfindingBoxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_VALUE;
doorData->d1flip.data = *doorData->d1flip.floor;
}
else
@@ -128,14 +128,14 @@ namespace TEN::Entities::Doors
roomNumber = doorData->d2.floor->SidePortalRoomNumber;
if (roomNumber == NO_VALUE)
- boxNumber = doorData->d2.floor->Box;
+ boxNumber = doorData->d2.floor->PathfindingBoxID;
else
{
auto* b = &g_Level.Rooms[roomNumber];
- boxNumber = GetSector(b, doorItem->Pose.Position.x - b->x, doorItem->Pose.Position.z - b->z)->Box;
+ boxNumber = GetSector(b, doorItem->Pose.Position.x - b->x, doorItem->Pose.Position.z - b->z)->PathfindingBoxID;
}
- doorData->d2.block = (boxNumber != NO_VALUE && g_Level.Boxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_VALUE;
+ doorData->d2.block = (boxNumber != NO_VALUE && g_Level.PathfindingBoxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_VALUE;
doorData->d2.data = *doorData->d2.floor;
if (r->flippedRoom != -1)
@@ -145,14 +145,14 @@ namespace TEN::Entities::Doors
roomNumber = doorData->d2flip.floor->SidePortalRoomNumber;
if (roomNumber == NO_VALUE)
- boxNumber = doorData->d2flip.floor->Box;
+ boxNumber = doorData->d2flip.floor->PathfindingBoxID;
else
{
auto* b = &g_Level.Rooms[roomNumber];
- boxNumber = GetSector(b, doorItem->Pose.Position.x - b->x, doorItem->Pose.Position.z - b->z)->Box;
+ boxNumber = GetSector(b, doorItem->Pose.Position.x - b->x, doorItem->Pose.Position.z - b->z)->PathfindingBoxID;
}
- doorData->d2flip.block = (boxNumber != NO_VALUE && g_Level.Boxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_VALUE;
+ doorData->d2flip.block = (boxNumber != NO_VALUE && g_Level.PathfindingBoxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_VALUE;
doorData->d2flip.data = *doorData->d2flip.floor;
}
else
@@ -401,7 +401,7 @@ namespace TEN::Entities::Doors
short boxIndex = doorPos->block;
if (boxIndex != NO_VALUE)
{
- g_Level.Boxes[boxIndex].flags &= ~BLOCKED;
+ g_Level.PathfindingBoxes[boxIndex].flags &= ~BLOCKED;
for (auto& currentCreature : ActiveCreatures)
currentCreature->LOT.TargetBox = NO_VALUE;
}
@@ -416,7 +416,7 @@ namespace TEN::Entities::Doors
if (floor)
{
- floor->Box = NO_VALUE;
+ floor->PathfindingBoxID = NO_VALUE;
floor->TriggerIndex = 0;
// FIXME: HACK!!!!!!!
@@ -435,7 +435,7 @@ namespace TEN::Entities::Doors
short boxIndex = doorPos->block;
if (boxIndex != NO_VALUE)
{
- g_Level.Boxes[boxIndex].flags |= BLOCKED;
+ g_Level.PathfindingBoxes[boxIndex].flags |= BLOCKED;
for (auto& currentCreature : ActiveCreatures)
currentCreature->LOT.TargetBox = NO_VALUE;
diff --git a/TombEngine/Objects/TR3/Entity/Lizard.cpp b/TombEngine/Objects/TR3/Entity/Lizard.cpp
index d5a10e72b..a57c724a0 100644
--- a/TombEngine/Objects/TR3/Entity/Lizard.cpp
+++ b/TombEngine/Objects/TR3/Entity/Lizard.cpp
@@ -69,7 +69,7 @@ namespace TEN::Entities::Creatures::TR3
auto& creature = *GetCreatureInfo(&item);
return (creature.Enemy && creature.Enemy->BoxNumber != NO_VALUE &&
- (g_Level.Boxes[creature.Enemy->BoxNumber].flags & BLOCKABLE));
+ (g_Level.PathfindingBoxes[creature.Enemy->BoxNumber].flags & BLOCKABLE));
}
static void SpawnLizardGas(int itemNumber, const CreatureBiteInfo& bite, int speed)
diff --git a/TombEngine/Objects/TR3/Entity/Shiva.cpp b/TombEngine/Objects/TR3/Entity/Shiva.cpp
index 21ccd1586..de1c28033 100644
--- a/TombEngine/Objects/TR3/Entity/Shiva.cpp
+++ b/TombEngine/Objects/TR3/Entity/Shiva.cpp
@@ -341,9 +341,9 @@ namespace TEN::Entities::Creatures::TR3
{
int x = item->Pose.Position.x + BLOCK(1) * phd_sin(item->Pose.Orientation.y + ANGLE(180.0f));
int z = item->Pose.Position.z + BLOCK(1) * phd_cos(item->Pose.Orientation.y + ANGLE(180.0f));
- auto box = GetPointCollision(Vector3i(x, item->Pose.Position.y, z), item->RoomNumber).GetBottomSector().Box;
+ auto box = GetPointCollision(Vector3i(x, item->Pose.Position.y, z), item->RoomNumber).GetBottomSector().PathfindingBoxID;
- if (box != NO_VALUE && !(g_Level.Boxes[box].flags & BLOCKABLE) && !creature.Flags)
+ if (box != NO_VALUE && !(g_Level.PathfindingBoxes[box].flags & BLOCKABLE) && !creature.Flags)
item->Animation.TargetState = SHIVA_STATE_WALK_BACK;
else
item->Animation.TargetState = SHIVA_STATE_GUARD_IDLE;
diff --git a/TombEngine/Objects/TR3/Entity/tr3_civvy.cpp b/TombEngine/Objects/TR3/Entity/tr3_civvy.cpp
index 7a86c5c01..0a98b223c 100644
--- a/TombEngine/Objects/TR3/Entity/tr3_civvy.cpp
+++ b/TombEngine/Objects/TR3/Entity/tr3_civvy.cpp
@@ -182,7 +182,7 @@ namespace TEN::Entities::Creatures::TR3
auto jointHeadRot = EulerAngles::Identity;
auto jointTorsoRot = EulerAngles::Identity;
- if (item.BoxNumber != NO_VALUE && (g_Level.Boxes[item.BoxNumber].flags & BLOCKED) && item.HitPoints > 0)
+ if (item.BoxNumber != NO_VALUE && (g_Level.PathfindingBoxes[item.BoxNumber].flags & BLOCKED) && item.HitPoints > 0)
{
DoDamage(&item, INT_MAX);
DoLotsOfBlood(item.Pose.Position.x, item.Pose.Position.y - (GetRandomControl() & 255) - 32, item.Pose.Position.z, (GetRandomControl() & 127) + 128, GetRandomControl() << 1, item.RoomNumber, 3);
diff --git a/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp b/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp
index 7383b8925..31c011d34 100644
--- a/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp
+++ b/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp
@@ -72,7 +72,7 @@ namespace TEN::Entities::Creatures::TR3
if (creature->MuzzleFlash[0].Delay != 0)
creature->MuzzleFlash[0].Delay--;
- if (item->BoxNumber != NO_VALUE && (g_Level.Boxes[item->BoxNumber].flags & BLOCKED))
+ if (item->BoxNumber != NO_VALUE && (g_Level.PathfindingBoxes[item->BoxNumber].flags & BLOCKED))
{
DoDamage(item, 20);
DoLotsOfBlood(item->Pose.Position.x, item->Pose.Position.y - (GetRandomControl() & 255) - 32, item->Pose.Position.z, (GetRandomControl() & 127) + 128, GetRandomControl() * 2, item->RoomNumber, 3);
diff --git a/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp b/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp
index 643f4d6c6..7b1bf2bab 100644
--- a/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp
+++ b/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp
@@ -77,7 +77,7 @@ namespace TEN::Entities::Creatures::TR3
short head = 0;
auto extraTorsoRot = EulerAngles::Identity;
- if (item->BoxNumber != NO_VALUE && (g_Level.Boxes[item->BoxNumber].flags & BLOCKED))
+ if (item->BoxNumber != NO_VALUE && (g_Level.PathfindingBoxes[item->BoxNumber].flags & BLOCKED))
{
DoDamage(item, 20);
DoLotsOfBlood(item->Pose.Position.x, item->Pose.Position.y - (GetRandomControl() & 255) - 32, item->Pose.Position.z, (GetRandomControl() & 127) + 128, GetRandomControl() * 2, item->RoomNumber, 3);
diff --git a/TombEngine/Objects/TR5/Object/tr5_expandingplatform.cpp b/TombEngine/Objects/TR5/Object/tr5_expandingplatform.cpp
index 9fb14881b..b6de0dbcd 100644
--- a/TombEngine/Objects/TR5/Object/tr5_expandingplatform.cpp
+++ b/TombEngine/Objects/TR5/Object/tr5_expandingplatform.cpp
@@ -131,7 +131,7 @@ namespace TEN::Entities::Generic
short roomNumber = item.RoomNumber;
FloorInfo* floor = GetFloor(item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z, &roomNumber);
- g_Level.Boxes[floor->Box].flags &= ~BLOCKED;
+ g_Level.PathfindingBoxes[floor->PathfindingBoxID].flags &= ~BLOCKED;
// Set mutators to default.
UpdateExpandingPlatformMutators(itemNumber);
diff --git a/TombEngine/Objects/TR5/Object/tr5_raisingblock.cpp b/TombEngine/Objects/TR5/Object/tr5_raisingblock.cpp
index 24835ed4d..ac204e528 100644
--- a/TombEngine/Objects/TR5/Object/tr5_raisingblock.cpp
+++ b/TombEngine/Objects/TR5/Object/tr5_raisingblock.cpp
@@ -74,8 +74,8 @@ namespace TEN::Entities::Generic
short roomNumber = item->RoomNumber;
auto* floor = GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &roomNumber);
- if (floor->Box != NO_VALUE)
- g_Level.Boxes[floor->Box].flags &= ~BLOCKED;
+ if (floor->PathfindingBoxID != NO_VALUE)
+ g_Level.PathfindingBoxes[floor->PathfindingBoxID].flags &= ~BLOCKED;
// Set mutators to EulerAngles identity by default.
for (auto& mutator : item->Model.Mutators)
diff --git a/TombEngine/Objects/TR5/Shatter/tr5_smashobject.cpp b/TombEngine/Objects/TR5/Shatter/tr5_smashobject.cpp
index 4125df0a4..54f008213 100644
--- a/TombEngine/Objects/TR5/Shatter/tr5_smashobject.cpp
+++ b/TombEngine/Objects/TR5/Shatter/tr5_smashobject.cpp
@@ -18,13 +18,13 @@ void InitializeSmashObject(short itemNumber)
// NOTE: Avoids crash when attempting to access Boxes[] array while box is equal to NO_VALUE. -- TokyoSU 2022.12.20
FloorInfo* floor = GetSector(room, item->Pose.Position.x - room->x, item->Pose.Position.z - room->z);
- if (floor->Box == NO_VALUE)
+ if (floor->PathfindingBoxID == NO_VALUE)
{
TENLog("Smash object with ID " + std::to_string(itemNumber) + " may be inside a wall." , LogLevel::Warning);
return;
}
- auto* box = &g_Level.Boxes[floor->Box];
+ auto* box = &g_Level.PathfindingBoxes[floor->PathfindingBoxID];
if (box->flags & 0x8000)
box->flags |= BLOCKED;
}
@@ -36,7 +36,7 @@ void SmashObject(short itemNumber)
int sector = ((item->Pose.Position.z - room->z) / 1024) + room->zSize * ((item->Pose.Position.x - room->x) / 1024);
- auto* box = &g_Level.Boxes[room->floor[sector].Box];
+ auto* box = &g_Level.PathfindingBoxes[room->floor[sector].PathfindingBoxID];
if (box->flags & 0x8000)
box->flags &= ~BOX_BLOCKED;
diff --git a/TombEngine/Specific/level.cpp b/TombEngine/Specific/level.cpp
index 88596ddc4..6a3caf420 100644
--- a/TombEngine/Specific/level.cpp
+++ b/TombEngine/Specific/level.cpp
@@ -771,52 +771,57 @@ void ReadRooms()
room.zSize = ReadInt32();
room.xSize = ReadInt32();
+ auto roomPos = Vector2i(room.x, room.z);
room.floor.reserve(room.zSize * room.xSize);
- for (int j = 0; j < (room.zSize * room.xSize); j++)
+ for (int x = 0; x < room.xSize; x++)
{
- auto sector = FloorInfo{};
+ for (int z = 0; z < room.zSize; z++)
+ {
+ auto sector = FloorInfo{};
- sector.TriggerIndex = ReadInt32();
- sector.Box = ReadInt32();
+ sector.Position = roomPos + Vector2i(BLOCK(x), BLOCK(z));
+ sector.RoomNumber = i;
- sector.FloorSurface.Triangles[0].Material =
- sector.FloorSurface.Triangles[1].Material =
- sector.CeilingSurface.Triangles[0].Material =
- sector.CeilingSurface.Triangles[1].Material = (MaterialType)ReadInt32();
+ sector.TriggerIndex = ReadInt32();
+ sector.PathfindingBoxID = ReadInt32();
- sector.Stopper = (bool)ReadInt32();
+ sector.FloorSurface.Triangles[0].Material =
+ sector.FloorSurface.Triangles[1].Material =
+ sector.CeilingSurface.Triangles[0].Material =
+ sector.CeilingSurface.Triangles[1].Material = (MaterialType)ReadInt32();
- sector.FloorSurface.SplitAngle = FROM_RAD(ReadFloat());
- sector.FloorSurface.Triangles[0].SteepSlopeAngle = ILLEGAL_FLOOR_SLOPE_ANGLE;
- sector.FloorSurface.Triangles[1].SteepSlopeAngle = ILLEGAL_FLOOR_SLOPE_ANGLE;
- sector.FloorSurface.Triangles[0].PortalRoomNumber = ReadInt32();
- sector.FloorSurface.Triangles[1].PortalRoomNumber = ReadInt32();
- sector.FloorSurface.Triangles[0].Plane = ConvertFakePlaneToPlane(ReadVector3(), true);
- sector.FloorSurface.Triangles[1].Plane = ConvertFakePlaneToPlane(ReadVector3(), true);
+ sector.Stopper = (bool)ReadInt32();
- sector.CeilingSurface.SplitAngle = FROM_RAD(ReadFloat());
- sector.CeilingSurface.Triangles[0].SteepSlopeAngle = ILLEGAL_CEILING_SLOPE_ANGLE;
- sector.CeilingSurface.Triangles[1].SteepSlopeAngle = ILLEGAL_CEILING_SLOPE_ANGLE;
- sector.CeilingSurface.Triangles[0].PortalRoomNumber = ReadInt32();
- sector.CeilingSurface.Triangles[1].PortalRoomNumber = ReadInt32();
- sector.CeilingSurface.Triangles[0].Plane = ConvertFakePlaneToPlane(ReadVector3(), false);
- sector.CeilingSurface.Triangles[1].Plane = ConvertFakePlaneToPlane(ReadVector3(), false);
+ sector.FloorSurface.SplitAngle = FROM_RAD(ReadFloat());
+ sector.FloorSurface.Triangles[0].SteepSlopeAngle = ILLEGAL_FLOOR_SLOPE_ANGLE;
+ sector.FloorSurface.Triangles[1].SteepSlopeAngle = ILLEGAL_FLOOR_SLOPE_ANGLE;
+ sector.FloorSurface.Triangles[0].PortalRoomNumber = ReadInt32();
+ sector.FloorSurface.Triangles[1].PortalRoomNumber = ReadInt32();
+ sector.FloorSurface.Triangles[0].Plane = ConvertFakePlaneToPlane(ReadVector3(), true);
+ sector.FloorSurface.Triangles[1].Plane = ConvertFakePlaneToPlane(ReadVector3(), true);
- sector.SidePortalRoomNumber = ReadInt32();
- sector.Flags.Death = ReadBool();
- sector.Flags.Monkeyswing = ReadBool();
- sector.Flags.ClimbNorth = ReadBool();
- sector.Flags.ClimbSouth = ReadBool();
- sector.Flags.ClimbEast = ReadBool();
- sector.Flags.ClimbWest = ReadBool();
- sector.Flags.MarkTriggerer = ReadBool();
- sector.Flags.MarkTriggererActive = 0; // TODO: Needs to be written to and read from savegames.
- sector.Flags.MarkBeetle = ReadBool();
+ sector.CeilingSurface.SplitAngle = FROM_RAD(ReadFloat());
+ sector.CeilingSurface.Triangles[0].SteepSlopeAngle = ILLEGAL_CEILING_SLOPE_ANGLE;
+ sector.CeilingSurface.Triangles[1].SteepSlopeAngle = ILLEGAL_CEILING_SLOPE_ANGLE;
+ sector.CeilingSurface.Triangles[0].PortalRoomNumber = ReadInt32();
+ sector.CeilingSurface.Triangles[1].PortalRoomNumber = ReadInt32();
+ sector.CeilingSurface.Triangles[0].Plane = ConvertFakePlaneToPlane(ReadVector3(), false);
+ sector.CeilingSurface.Triangles[1].Plane = ConvertFakePlaneToPlane(ReadVector3(), false);
- sector.RoomNumber = i;
+ sector.SidePortalRoomNumber = ReadInt32();
+ sector.Flags.Death = ReadBool();
+ sector.Flags.Monkeyswing = ReadBool();
+ sector.Flags.ClimbNorth = ReadBool();
+ sector.Flags.ClimbSouth = ReadBool();
+ sector.Flags.ClimbEast = ReadBool();
+ sector.Flags.ClimbWest = ReadBool();
+ sector.Flags.MarkTriggerer = ReadBool();
+ sector.Flags.MarkTriggererActive = 0; // TODO: Needs to be written to and read from savegames.
+ sector.Flags.MarkBeetle = ReadBool();
- room.floor.push_back(sector);
+ room.floor.push_back(sector);
+ }
}
room.ambient = ReadVector3();
@@ -948,7 +953,7 @@ void FreeLevel()
g_Level.Meshes.resize(0);
MoveablesIds.resize(0);
SpriteSequencesIds.resize(0);
- g_Level.Boxes.resize(0);
+ g_Level.PathfindingBoxes.resize(0);
g_Level.Overlaps.resize(0);
g_Level.Anims.resize(0);
g_Level.Changes.resize(0);
@@ -1363,8 +1368,8 @@ void LoadBoxes()
// Read boxes
int numBoxes = ReadInt32();
TENLog("Num boxes: " + std::to_string(numBoxes), LogLevel::Info);
- g_Level.Boxes.resize(numBoxes);
- ReadBytes(g_Level.Boxes.data(), numBoxes * sizeof(BOX_INFO));
+ g_Level.PathfindingBoxes.resize(numBoxes);
+ ReadBytes(g_Level.PathfindingBoxes.data(), numBoxes * sizeof(BOX_INFO));
// Read overlaps
int numOverlaps = ReadInt32();
@@ -1398,8 +1403,8 @@ void LoadBoxes()
// By default all blockable boxes are blocked
for (int i = 0; i < numBoxes; i++)
{
- if (g_Level.Boxes[i].flags & BLOCKABLE)
- g_Level.Boxes[i].flags |= BLOCKED;
+ if (g_Level.PathfindingBoxes[i].flags & BLOCKABLE)
+ g_Level.PathfindingBoxes[i].flags |= BLOCKED;
}
}
diff --git a/TombEngine/Specific/level.h b/TombEngine/Specific/level.h
index 01c65380a..1c0c84853 100644
--- a/TombEngine/Specific/level.h
+++ b/TombEngine/Specific/level.h
@@ -107,8 +107,8 @@ struct LEVEL
std::vector Sinks = {};
// Pathfinding data
- std::vector Boxes = {};
- std::vector Overlaps = {};
+ std::vector PathfindingBoxes = {};
+ std::vector Overlaps = {};
std::vector Zones[(int)ZoneType::MaxZone][2] = {};
// Sound data
From 2be193a9973362b6f3608ae824ddb34ca68de51c Mon Sep 17 00:00:00 2001
From: Sezz
Date: Wed, 26 Jun 2024 14:50:39 +1000
Subject: [PATCH 222/410] Use NO_VALUE in GetPlayerScrolledWeaponType()
---
TombEngine/Game/Lara/lara_helpers.cpp | 30 +++++++++++++--------------
1 file changed, 14 insertions(+), 16 deletions(-)
diff --git a/TombEngine/Game/Lara/lara_helpers.cpp b/TombEngine/Game/Lara/lara_helpers.cpp
index 35596d7df..3a18ecf09 100644
--- a/TombEngine/Game/Lara/lara_helpers.cpp
+++ b/TombEngine/Game/Lara/lara_helpers.cpp
@@ -278,7 +278,7 @@ void HandlePlayerStatusEffects(ItemInfo& item, WaterStatus waterStatus, PlayerWa
}
}
-static std::optional GetPlayerScrolledWeaponType(const ItemInfo& item, LaraWeaponType currentWeaponType, bool getPrev)
+static LaraWeaponType GetPlayerScrolledWeaponType(const ItemInfo& item, LaraWeaponType currentWeaponType, bool getPrev)
{
static const auto SCROLL_WEAPON_TYPES = std::vector
{
@@ -293,15 +293,15 @@ static std::optional GetPlayerScrolledWeaponType(const ItemInfo&
LaraWeaponType::RocketLauncher
};
- auto getNextIndex = [getPrev](unsigned int index)
+ auto getNextIndex = [getPrev](int index)
{
- return (index + (getPrev ? ((unsigned int)SCROLL_WEAPON_TYPES.size() - 1) : 1)) % (unsigned int)SCROLL_WEAPON_TYPES.size();
+ return (index + (getPrev ? ((int)SCROLL_WEAPON_TYPES.size() - 1) : 1)) % (int)SCROLL_WEAPON_TYPES.size();
};
auto& player = GetLaraInfo(item);
// Get vector index for current weapon type.
- auto currentIndex = std::optional(std::nullopt);
+ auto currentIndex = NO_VALUE;
for (int i = 0; i < SCROLL_WEAPON_TYPES.size(); i++)
{
if (SCROLL_WEAPON_TYPES[i] == currentWeaponType)
@@ -311,13 +311,13 @@ static std::optional GetPlayerScrolledWeaponType(const ItemInfo&
}
}
- // Invalid current weapon type; return nullopt.
- if (!currentIndex.has_value())
- return std::nullopt;
+ // Invalid current weapon type; return None type.
+ if (currentIndex == NO_VALUE)
+ return LaraWeaponType::None;
// Get next valid weapon type in sequence.
- unsigned int nextIndex = getNextIndex(*currentIndex);
- while (nextIndex != *currentIndex)
+ int nextIndex = getNextIndex(currentIndex);
+ while (nextIndex != currentIndex)
{
auto nextWeaponType = SCROLL_WEAPON_TYPES[nextIndex];
if (player.Weapons[(int)nextWeaponType].Present)
@@ -326,8 +326,8 @@ static std::optional GetPlayerScrolledWeaponType(const ItemInfo&
nextIndex = getNextIndex(nextIndex);
}
- // No valid weapon type; return nullopt.
- return std::nullopt;
+ // No valid weapon type; return None type.
+ return LaraWeaponType::None;
}
void HandlePlayerQuickActions(ItemInfo& item)
@@ -347,11 +347,9 @@ void HandlePlayerQuickActions(ItemInfo& item)
// Handle weapon scroll request.
if (IsClicked(In::PreviousWeapon) || IsClicked(In::NextWeapon))
{
- bool getPrev = IsClicked(In::PreviousWeapon);
- auto weaponType = GetPlayerScrolledWeaponType(item, player.Control.Weapon.GunType, getPrev);
-
- if (weaponType.has_value())
- player.Control.Weapon.RequestGunType = *weaponType;
+ auto weaponType = GetPlayerScrolledWeaponType(item, player.Control.Weapon.GunType, IsClicked(In::PreviousWeapon));
+ if (weaponType != LaraWeaponType::None)
+ player.Control.Weapon.RequestGunType = weaponType;
}
// Handle weapon requests.
From 4c4a0b051024fe062bafba34b35ac8a66c056c21 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Thu, 27 Jun 2024 21:10:19 +1000
Subject: [PATCH 223/410] Global access to debug objects (#1382)
* Make debug object drawing globally accessible and therefore convenient
* Fix case in debug includes
* Add math constants
* Add missing space
* Fix debug strings; reduce debug string scale
* Remove unused method
* Remove commented lines
---
TombEngine/Game/Hud/PickupSummary.cpp | 2 +-
TombEngine/Game/Hud/Speedometer.cpp | 12 +-
TombEngine/Game/Hud/TargetHighlighter.cpp | 8 +-
TombEngine/Game/Lara/lara_helpers.cpp | 4 +-
TombEngine/Game/Lara/lara_tests.cpp | 11 +-
TombEngine/Game/camera.cpp | 4 +-
TombEngine/Game/collision/collide_item.cpp | 8 +-
TombEngine/Game/collision/collide_room.cpp | 20 +-
TombEngine/Game/control/box.cpp | 3 +-
TombEngine/Game/control/volume.cpp | 10 +-
TombEngine/Game/debug/debug.cpp | 88 ++++-
TombEngine/Game/debug/debug.h | 31 +-
TombEngine/Math/Constants.h | 6 +
.../Renderer/ConstantBuffers/ConstantBuffer.h | 20 +-
TombEngine/Renderer/Graphics/IndexBuffer.h | 2 +-
TombEngine/Renderer/Renderer.h | 10 +-
TombEngine/Renderer/RendererDebug.cpp | 29 +-
TombEngine/Renderer/RendererDraw.cpp | 17 +-
TombEngine/Renderer/RendererDrawMenu.cpp | 321 +++++++++---------
TombEngine/Renderer/RendererUtils.cpp | 2 +-
.../Scripting/Internal/TEN/Util/LevelLog.h | 2 +-
TombEngine/Specific/Input/InputAction.cpp | 24 +-
TombEngine/framework.h | 4 +-
23 files changed, 356 insertions(+), 282 deletions(-)
diff --git a/TombEngine/Game/Hud/PickupSummary.cpp b/TombEngine/Game/Hud/PickupSummary.cpp
index f38c0f6b6..b10e8bab1 100644
--- a/TombEngine/Game/Hud/PickupSummary.cpp
+++ b/TombEngine/Game/Hud/PickupSummary.cpp
@@ -222,6 +222,6 @@ namespace TEN::Hud
void PickupSummaryController::DrawDebug() const
{
- g_Renderer.PrintDebugMessage("Display pickups in summary: %d", _displayPickups.size());
+ PrintDebugMessage("Display pickups in summary: %d", _displayPickups.size());
}
}
diff --git a/TombEngine/Game/Hud/Speedometer.cpp b/TombEngine/Game/Hud/Speedometer.cpp
index 5768c69cf..0fd5ed245 100644
--- a/TombEngine/Game/Hud/Speedometer.cpp
+++ b/TombEngine/Game/Hud/Speedometer.cpp
@@ -3,12 +3,10 @@
#include "Game/effects/DisplaySprite.h"
#include "Math/Math.h"
-#include "Renderer/Renderer.h"
#include "Specific/clock.h"
using namespace TEN::Effects::DisplaySprite;
using namespace TEN::Math;
-using TEN::Renderer::g_Renderer;
namespace TEN::Hud
{
@@ -80,10 +78,10 @@ namespace TEN::Hud
void SpeedometerController::DrawDebug() const
{
- g_Renderer.PrintDebugMessage("SPEEDOMETER DEBUG");
- g_Renderer.PrintDebugMessage("Value: %.3f", _value);
- g_Renderer.PrintDebugMessage("Pointer angle: %.3f", _pointerAngle);
- g_Renderer.PrintDebugMessage("Opacity: %.3f", _opacity);
- g_Renderer.PrintDebugMessage("Life: %.3f", _life / FPS);
+ PrintDebugMessage("SPEEDOMETER DEBUG");
+ PrintDebugMessage("Value: %.3f", _value);
+ PrintDebugMessage("Pointer angle: %.3f", _pointerAngle);
+ PrintDebugMessage("Opacity: %.3f", _opacity);
+ PrintDebugMessage("Life: %.3f", _life / FPS);
}
}
diff --git a/TombEngine/Game/Hud/TargetHighlighter.cpp b/TombEngine/Game/Hud/TargetHighlighter.cpp
index 34638f991..aed040ff5 100644
--- a/TombEngine/Game/Hud/TargetHighlighter.cpp
+++ b/TombEngine/Game/Hud/TargetHighlighter.cpp
@@ -350,9 +350,9 @@ namespace TEN::Hud
for (const auto& [itemNumber, crosshair] : _crosshairs)
crosshair.IsPrimary ? primaryCount++ : peripheralCount++;
- g_Renderer.PrintDebugMessage("TARGET HIGHLIGHTER DEBUG");
- g_Renderer.PrintDebugMessage(g_Configuration.EnableTargetHighlighter ? "Enabled" : "Disabled");
- g_Renderer.PrintDebugMessage("Primary crosshairs: %d", primaryCount);
- g_Renderer.PrintDebugMessage("Peripheral crosshairs: %d", peripheralCount);
+ PrintDebugMessage("TARGET HIGHLIGHTER DEBUG");
+ PrintDebugMessage(g_Configuration.EnableTargetHighlighter ? "Enabled" : "Disabled");
+ PrintDebugMessage("Primary crosshairs: %d", primaryCount);
+ PrintDebugMessage("Peripheral crosshairs: %d", peripheralCount);
}
}
diff --git a/TombEngine/Game/Lara/lara_helpers.cpp b/TombEngine/Game/Lara/lara_helpers.cpp
index 3a18ecf09..c2b60dd45 100644
--- a/TombEngine/Game/Lara/lara_helpers.cpp
+++ b/TombEngine/Game/Lara/lara_helpers.cpp
@@ -22,7 +22,6 @@
#include "Game/savegame.h"
#include "Game/Setup.h"
#include "Math/Math.h"
-#include "Renderer/Renderer.h"
#include "Scripting/Include/ScriptInterfaceLevel.h"
#include "Sound/sound.h"
#include "Specific/Input/Input.h"
@@ -46,7 +45,6 @@ using namespace TEN::Entities::Player;
using namespace TEN::Gui;
using namespace TEN::Input;
using namespace TEN::Math;
-using namespace TEN::Renderer;
// -----------------------------
// HELPER FUNCTIONS
@@ -1490,7 +1488,7 @@ void ModulateLaraSlideVelocity(ItemInfo* item, CollisionInfo* coll)
//int slideVelocity = std::min(minVelocity + 10 * (steepness * velocityMultiplier), LARA_TERMINAL_VELOCITY);
//short deltaAngle = abs((short)(direction - item->Pose.Orientation.y));
- //g_Renderer.PrintDebugMessage("%d", slideVelocity);
+ //PrintDebugMessage("%d", slideVelocity);
//lara->ExtraVelocity.x += slideVelocity;
//lara->ExtraVelocity.y += slideVelocity * phd_sin(steepness);
diff --git a/TombEngine/Game/Lara/lara_tests.cpp b/TombEngine/Game/Lara/lara_tests.cpp
index ee7b8d809..a208daf54 100644
--- a/TombEngine/Game/Lara/lara_tests.cpp
+++ b/TombEngine/Game/Lara/lara_tests.cpp
@@ -17,7 +17,7 @@
#include "Game/Lara/lara_helpers.h"
#include "Game/Lara/lara_monkey.h"
#include "Math/Math.h"
-#include "Renderer/Renderer.h"
+#include "Specific/configuration.h"
#include "Specific/Input/Input.h"
#include "Specific/level.h"
#include "Specific/trutils.h"
@@ -27,7 +27,6 @@ using namespace TEN::Collision::Point;
using namespace TEN::Entities::Player;
using namespace TEN::Input;
using namespace TEN::Math;
-using namespace TEN::Renderer;
using namespace TEN::Utils;
// -----------------------------
@@ -58,8 +57,8 @@ bool TestValidLedge(ItemInfo* item, CollisionInfo* coll, bool ignoreHeadroom, bo
if (frontLeft.GetCeilingHeight() >(item->Pose.Position.y - coll->Setup.Height) || frontRight.GetCeilingHeight() > (item->Pose.Position.y - coll->Setup.Height))
return false;
- //g_Renderer.AddDebugSphere(Vector3(item->pos.Position.x + xl, left, item->pos.Position.z + zl), 64, Vector4::One, RendererDebugPage::CollisionStats);
- //g_Renderer.AddDebugSphere(Vector3(item->pos.Position.x + xr, right, item->pos.Position.z + zr), 64, Vector4::One, RendererDebugPage::CollisionStats);
+ //DrawDebugSphere(Vector3(item->pos.Position.x + xl, left, item->pos.Position.z + zl), 64, Vector4::One, RendererDebugPage::CollisionStats);
+ //DrawDebugSphere(Vector3(item->pos.Position.x + xr, right, item->pos.Position.z + zr), 64, Vector4::One, RendererDebugPage::CollisionStats);
// Determine ledge probe embed offset.
// We use 0.2f radius extents here for two purposes. First - we can't guarantee that shifts weren't already applied
@@ -1793,7 +1792,7 @@ bool TestLaraPoleCollision(ItemInfo* item, CollisionInfo* coll, bool goingUp, fl
auto sphere = BoundingSphere(spherePos, poleProbeCollRadius);
auto offsetSphere = BoundingSphere(spherePos + sphereOffset2D, poleProbeCollRadius);
- //g_Renderer.AddDebugSphere(sphere.Center, 16.0f, Vector4(1, 0, 0, 1), RendererDebugPage::CollisionStats);
+ //DrawDebugSphere(sphere.Center, 16.0f, Vector4(1, 0, 0, 1), RendererDebugPage::CollisionStats);
for (const auto* itemPtr : collObjects.Items)
{
@@ -1803,7 +1802,7 @@ bool TestLaraPoleCollision(ItemInfo* item, CollisionInfo* coll, bool goingUp, fl
auto poleBox = GameBoundingBox(itemPtr).ToBoundingOrientedBox(itemPtr->Pose);
poleBox.Extents = poleBox.Extents + Vector3(coll->Setup.Radius, 0.0f, coll->Setup.Radius);
- //g_Renderer.AddDebugBox(poleBox, Vector4(0, 0, 1, 1), RendererDebugPage::CollisionStats);
+ //DrawDebugBox(poleBox, Vector4(0, 0, 1, 1), RendererDebugPage::CollisionStats);
if (poleBox.Intersects(sphere) || poleBox.Intersects(offsetSphere))
{
diff --git a/TombEngine/Game/camera.cpp b/TombEngine/Game/camera.cpp
index e0863e650..431de8ce8 100644
--- a/TombEngine/Game/camera.cpp
+++ b/TombEngine/Game/camera.cpp
@@ -1486,7 +1486,7 @@ void ItemsCollideCamera()
if (TestBoundsCollideCamera(bounds, item->Pose, CAMERA_RADIUS))
ItemPushCamera(&bounds, &item->Pose, RADIUS);
- TEN::Renderer::g_Renderer.AddDebugBox(
+ DrawDebugBox(
bounds.ToBoundingOrientedBox(item->Pose),
Vector4(1.0f, 0.0f, 0.0f, 1.0f), RendererDebugPage::CollisionStats);
}
@@ -1509,7 +1509,7 @@ void ItemsCollideCamera()
if (TestBoundsCollideCamera(bounds, mesh->pos, CAMERA_RADIUS))
ItemPushCamera(&bounds, &mesh->pos, RADIUS);
- TEN::Renderer::g_Renderer.AddDebugBox(
+ DrawDebugBox(
bounds.ToBoundingOrientedBox(mesh->pos),
Vector4(1.0f, 0.0f, 0.0f, 1.0f), RendererDebugPage::CollisionStats);
}
diff --git a/TombEngine/Game/collision/collide_item.cpp b/TombEngine/Game/collision/collide_item.cpp
index a60ac2b82..077c77cc8 100644
--- a/TombEngine/Game/collision/collide_item.cpp
+++ b/TombEngine/Game/collision/collide_item.cpp
@@ -18,14 +18,12 @@
#include "Game/room.h"
#include "Game/Setup.h"
#include "Math/Math.h"
-#include "Renderer/Renderer.h"
#include "Scripting/Include/ScriptInterfaceGame.h"
#include "Sound/sound.h"
using namespace TEN::Collision::Floordata;
using namespace TEN::Collision::Point;
using namespace TEN::Math;
-using namespace TEN::Renderer;
constexpr auto ANIMATED_ALIGNMENT_FRAME_COUNT_THRESHOLD = 6;
@@ -307,7 +305,7 @@ void TestForObjectOnLedge(ItemInfo* item, CollisionInfo* coll)
auto mxR = Matrix::CreateFromYawPitchRoll(TO_RAD(coll->Setup.ForwardAngle), 0.0f, 0.0f);
auto direction = (Matrix::CreateTranslation(Vector3::UnitZ) * mxR).Translation();
- // g_Renderer.AddDebugSphere(origin, 16, Vector4::One, RendererDebugPage::CollisionStats);
+ // DrawDebugSphere(origin, 16, Vector4::One, RendererDebugPage::CollisionStats);
for (auto i : g_Level.Rooms[item->RoomNumber].neighbors)
{
@@ -989,7 +987,7 @@ bool CollideSolidBounds(ItemInfo* item, const GameBoundingBox& box, const Pose&
itemBounds.Extents = itemBounds.Extents - Vector3(BLOCK(1));
// Draw static bounds.
- g_Renderer.AddDebugBox(staticBounds, Vector4(1, 0.3f, 0, 1), RendererDebugPage::CollisionStats);
+ DrawDebugBox(staticBounds, Vector4(1, 0.3f, 0, 1), RendererDebugPage::CollisionStats);
// Calculate horizontal item collision bounds according to radius.
GameBoundingBox collBox;
@@ -1016,7 +1014,7 @@ bool CollideSolidBounds(ItemInfo* item, const GameBoundingBox& box, const Pose&
bool intersects = staticBounds.Intersects(collBounds);
// Draw item coll bounds.
- g_Renderer.AddDebugBox(collBounds, intersects ? Vector4(1, 0, 0, 1) : Vector4(0, 1, 0, 1), RendererDebugPage::CollisionStats);
+ DrawDebugBox(collBounds, intersects ? Vector4(1, 0, 0, 1) : Vector4(0, 1, 0, 1), RendererDebugPage::CollisionStats);
// Decompose static bounds into top/bottom plane vertices.
Vector3 corners[8];
diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp
index 137d8d62e..04670f47a 100644
--- a/TombEngine/Game/collision/collide_room.cpp
+++ b/TombEngine/Game/collision/collide_room.cpp
@@ -11,13 +11,11 @@
#include "Game/room.h"
#include "Math/Math.h"
#include "Sound/sound.h"
-#include "Renderer/Renderer.h"
using namespace TEN::Collision::Floordata;
using namespace TEN::Collision::Point;
using namespace TEN::Collision::Room;
using namespace TEN::Math;
-using namespace TEN::Renderer;
void ShiftItem(ItemInfo* item, CollisionInfo* coll)
{
@@ -299,8 +297,8 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
coll->NearestLedgeAngle = GetNearestLedgeAngle(item, coll, coll->NearestLedgeDistance);
// Debug angle and distance
- // g_Renderer.PrintDebugMessage("Nearest angle: %d", coll->NearestLedgeAngle);
- // g_Renderer.PrintDebugMessage("Nearest dist: %f", coll->NearestLedgeDistance);
+ // PrintDebugMessage("Nearest angle: %d", coll->NearestLedgeAngle);
+ // PrintDebugMessage("Nearest dist: %f", coll->NearestLedgeDistance);
// TEST 2: CENTERPOINT PROBE
@@ -339,7 +337,7 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
probePos.x = entityPos.x + xFront;
probePos.z = entityPos.z + zFront;
- g_Renderer.AddDebugSphere(probePos.ToVector3(), 32, Vector4(1, 0, 0, 1), RendererDebugPage::CollisionStats);
+ DrawDebugSphere(probePos.ToVector3(), 32, Vector4(1, 0, 0, 1), RendererDebugPage::CollisionStats);
pointColl = GetPointCollision(probePos, topRoomNumber);
@@ -394,7 +392,7 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
probePos.x = entityPos.x + xLeft;
probePos.z = entityPos.z + zLeft;
- g_Renderer.AddDebugSphere(probePos.ToVector3(), 32, Vector4(0, 0, 1, 1), RendererDebugPage::CollisionStats);
+ DrawDebugSphere(probePos.ToVector3(), 32, Vector4(0, 0, 1, 1), RendererDebugPage::CollisionStats);
pointColl = GetPointCollision(probePos, item->RoomNumber);
@@ -460,7 +458,7 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
probePos.x = entityPos.x + xRight;
probePos.z = entityPos.z + zRight;
- g_Renderer.AddDebugSphere(probePos.ToVector3(), 32, Vector4(0, 1, 0, 1), RendererDebugPage::CollisionStats);
+ DrawDebugSphere(probePos.ToVector3(), 32, Vector4(0, 1, 0, 1), RendererDebugPage::CollisionStats);
pointColl = GetPointCollision(probePos, item->RoomNumber);
@@ -807,7 +805,7 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance)
}
// Debug probe point
- // g_Renderer.AddDebugSphere(Vector3(eX, y, eZ), 16, Vector4(1, 1, 0, 1), RendererDebugPage::CollisionStats);
+ // DrawDebugSphere(Vector3(eX, y, eZ), 16, Vector4(1, 1, 0, 1), RendererDebugPage::CollisionStats);
// Determine front floor probe offset.
// It is needed to identify if there is bridge or ceiling split in front.
@@ -849,7 +847,7 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance)
auto fpZ = eZ + floorProbeOffset * cosForwardAngle;
// Debug probe point.
- // g_Renderer.AddDebugSphere(Vector3(fpX, y, fpZ), 16, Vector4(0, 1, 0, 1), RendererDebugPage::CollisionStats);
+ // DrawDebugSphere(Vector3(fpX, y, fpZ), 16, Vector4(0, 1, 0, 1), RendererDebugPage::CollisionStats);
// Get true room number and block, based on derived height
room = GetRoomVector(item->Location, Vector3i(fpX, height, fpZ)).RoomNumber;
@@ -865,7 +863,7 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance)
auto ray = Ray(Vector3(eX, cY, eZ), direction);
// Debug ray direction.
- // g_Renderer.AddDebugLine(Vector3(eX, y, eZ), Vector3(eX, y, eZ) + direction * 256, Vector4(1, 0, 0, 1));
+ // DrawDebugLine(Vector3(eX, y, eZ), Vector3(eX, y, eZ) + direction * 256, Vector4(1, 0, 0, 1));
// Keep origin ray to calculate true centerpoint distance to ledge later.
if (p == 0)
@@ -920,7 +918,7 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance)
auto cZ = fZ + BLOCK(1) + 1;
// Debug used block
- // g_Renderer.AddDebugSphere(Vector3(round(eX / BLOCK(1)) * BLOCK(1) + BLOCK(0.5f), y, round(eZ / BLOCK(1)) * BLOCK(1) + BLOCK(0.5f)), 16, Vector4::One, RendererDebugPage::CollisionStats);
+ // DrawDebugSphere(Vector3(round(eX / BLOCK(1)) * BLOCK(1) + BLOCK(0.5f), y, round(eZ / BLOCK(1)) * BLOCK(1) + BLOCK(0.5f)), 16, Vector4::One, RendererDebugPage::CollisionStats);
// Get split angle coordinates.
auto sX = fX + 1 + BLOCK(0.5f);
diff --git a/TombEngine/Game/control/box.cpp b/TombEngine/Game/control/box.cpp
index 3166286f2..453435568 100644
--- a/TombEngine/Game/control/box.cpp
+++ b/TombEngine/Game/control/box.cpp
@@ -21,7 +21,6 @@
#include "Math/Math.h"
#include "Objects/objectslist.h"
#include "Objects/Generic/Object/Pushable/PushableObject.h"
-#include "Renderer/Renderer.h"
using namespace TEN::Collision::Point;
using namespace TEN::Collision::Room;
@@ -69,7 +68,7 @@ void DrawBox(int boxIndex, Vector3 color)
for (int i = 0; i <= 10; i++)
{
dBox.Extents = extents + Vector3(i);
- TEN::Renderer::g_Renderer.AddDebugBox(dBox, Vector4(color.x, color.y, color.z, 1), RendererDebugPage::PathfindingStats);
+ DrawDebugBox(dBox, Vector4(color.x, color.y, color.z, 1), RendererDebugPage::PathfindingStats);
}
}
diff --git a/TombEngine/Game/control/volume.cpp b/TombEngine/Game/control/volume.cpp
index 55ace1293..10bcdfe8a 100644
--- a/TombEngine/Game/control/volume.cpp
+++ b/TombEngine/Game/control/volume.cpp
@@ -10,12 +10,8 @@
#include "Game/room.h"
#include "Game/savegame.h"
#include "Game/Setup.h"
-#include "Renderer/Renderer.h"
-#include "Renderer/RendererEnums.h"
#include "Scripting/Include/ScriptInterfaceGame.h"
-using TEN::Renderer::g_Renderer;
-
namespace TEN::Control::Volumes
{
constexpr auto CAM_SIZE = 32;
@@ -30,7 +26,7 @@ namespace TEN::Control::Volumes
case VolumeType::Box:
if (roomNumber == Camera.pos.RoomNumber)
{
- g_Renderer.AddDebugBox(volume.Box,
+ DrawDebugBox(volume.Box,
Vector4(color, 0.0f, color, 1.0f), RendererDebugPage::CollisionStats);
}
return volume.Box.Intersects(box);
@@ -38,7 +34,7 @@ namespace TEN::Control::Volumes
case VolumeType::Sphere:
if (roomNumber == Camera.pos.RoomNumber)
{
- g_Renderer.AddDebugSphere(volume.Sphere.Center, volume.Sphere.Radius,
+ DrawDebugSphere(volume.Sphere.Center, volume.Sphere.Radius,
Vector4(color, 0.0f, color, 1.0f), RendererDebugPage::CollisionStats);
}
return volume.Sphere.Intersects(box);
@@ -252,7 +248,7 @@ namespace TEN::Control::Volumes
auto box = (coll != nullptr) ?
ConstructRoughBox(item, *coll) : GameBoundingBox(&item).ToBoundingOrientedBox(item.Pose);
- g_Renderer.AddDebugBox(box, Vector4(1.0f, 1.0f, 0.0f, 1.0f), RendererDebugPage::CollisionStats);
+ DrawDebugBox(box, Vector4(1.0f, 1.0f, 0.0f, 1.0f), RendererDebugPage::CollisionStats);
if (item.IsLara() || item.Index == Lara.Context.Vehicle)
{
diff --git a/TombEngine/Game/debug/debug.cpp b/TombEngine/Game/debug/debug.cpp
index a5cba1b3f..4e06330f3 100644
--- a/TombEngine/Game/debug/debug.cpp
+++ b/TombEngine/Game/debug/debug.cpp
@@ -1,9 +1,14 @@
#include "framework.h"
-#include "Game/debug/debug.h"
+#include "Game/Debug/Debug.h"
#include
#include
#include
+#include
+
+#include "Renderer/Renderer.h"
+
+using TEN::Renderer::g_Renderer;
namespace TEN::Debug
{
@@ -30,11 +35,10 @@ namespace TEN::Debug
spdlog::shutdown();
}
- void TENLog(const std::string_view& string, LogLevel level, LogConfig config, bool allowSpam)
+ void TENLog(const std::string_view& msg, LogLevel level, LogConfig config, bool allowSpam)
{
static auto prevString = std::string();
-
- if (prevString == string && !allowSpam)
+ if (prevString == msg && !allowSpam)
return;
if constexpr (!DebugBuild)
@@ -47,20 +51,88 @@ namespace TEN::Debug
switch (level)
{
case LogLevel::Error:
- logger->error(string);
+ logger->error(msg);
break;
case LogLevel::Warning:
- logger->warn(string);
+ logger->warn(msg);
break;
case LogLevel::Info:
- logger->info(string);
+ logger->info(msg);
break;
}
logger->flush();
- prevString = std::string(string);
+ prevString = std::string(msg);
+ }
+
+ void PrintDebugMessage(LPCSTR msg, ...)
+ {
+ auto args = va_list{};
+ va_start(args, msg);
+ g_Renderer.PrintDebugMessage(msg, args);
+ va_end(args);
+ }
+
+ void DrawDebug2DLine(const Vector2& origin, const Vector2& target, const Color& color, RendererDebugPage page)
+ {
+ g_Renderer.AddLine2D(origin, target, color, page);
+ }
+
+ void DrawDebugLine(const Vector3& origin, const Vector3& target, const Color& color, RendererDebugPage page)
+ {
+ g_Renderer.AddDebugLine(origin, target, color, page);
+ }
+
+ void DrawDebugTriangle(const Vector3& vertex0, const Vector3& vertex1, const Vector3& vertex2, const Color& color, RendererDebugPage page)
+ {
+ g_Renderer.AddDebugTriangle(vertex0, vertex1, vertex2, color, page);
+ }
+
+ void DrawDebugTarget(const Vector3& center, const Quaternion& orient, float radius, const Color& color, RendererDebugPage page)
+ {
+ g_Renderer.AddDebugTarget(center, orient, radius, color, page);
+ }
+
+ void DrawDebugBox(const std::array& corners, const Color& color, RendererDebugPage page, bool isWireframe)
+ {
+ g_Renderer.AddDebugBox(corners, color, page, isWireframe);
+ }
+
+ void DrawDebugBox(const Vector3& min, const Vector3& max, const Color& color, RendererDebugPage page, bool isWireframe)
+ {
+ g_Renderer.AddDebugBox(min, max, color, page, isWireframe);
+ }
+
+ void DrawDebugBox(const BoundingOrientedBox& box, const Color& color, RendererDebugPage page, bool isWireframe)
+ {
+ g_Renderer.AddDebugBox(box, color, page, isWireframe);
+ }
+
+ void DrawDebugBox(const BoundingBox& box, const Color& color, RendererDebugPage page, bool isWireframe)
+ {
+ g_Renderer.AddDebugBox(box, color, page, isWireframe);
+ }
+
+ void DrawDebugCone(const Vector3& center, const Quaternion& orient, float radius, float length, const Vector4& color, RendererDebugPage page, bool isWireframe)
+ {
+ g_Renderer.AddDebugCone(center, orient, radius, length, color, page, isWireframe);
+ }
+
+ void DrawDebugCylinder(const Vector3& center, const Quaternion& orient, float radius, float length, const Color& color, RendererDebugPage page, bool isWireframe)
+ {
+ g_Renderer.AddDebugCylinder(center, orient, radius, length, color, page, isWireframe);
+ }
+
+ void DrawDebugSphere(const Vector3& center, float radius, const Color& color, RendererDebugPage page, bool isWireframe)
+ {
+ g_Renderer.AddDebugSphere(center, radius, color, page, isWireframe);
+ }
+
+ void DrawDebugSphere(const BoundingSphere& sphere, const Color& color, RendererDebugPage page, bool isWireframe)
+ {
+ g_Renderer.AddDebugSphere(sphere, color, page, isWireframe);
}
}
diff --git a/TombEngine/Game/debug/debug.h b/TombEngine/Game/debug/debug.h
index 561a2d28a..448855af6 100644
--- a/TombEngine/Game/debug/debug.h
+++ b/TombEngine/Game/debug/debug.h
@@ -1,16 +1,19 @@
#pragma once
-#if _DEBUG
-constexpr bool DebugBuild = true;
-#else
-constexpr bool DebugBuild = false;
-#endif
#include
#include
#include
+#include "Renderer/RendererEnums.h"
+
namespace TEN::Debug
{
+#if _DEBUG
+ constexpr bool DebugBuild = true;
+#else
+ constexpr bool DebugBuild = false;
+#endif
+
enum class LogLevel
{
Error,
@@ -32,9 +35,9 @@ namespace TEN::Debug
void InitTENLog(const std::string& logDirContainingDir);
void ShutdownTENLog();
- void TENLog(const std::string_view& string, LogLevel level = LogLevel::Info, LogConfig config = LogConfig::All, bool allowSpam = false);
+ void TENLog(const std::string_view& msg, LogLevel level = LogLevel::Info, LogConfig config = LogConfig::All, bool allowSpam = false);
- inline void TENAssert(const bool& cond, const char* msg)
+ inline void TENAssert(const bool& cond, const std::string& msg)
{
if constexpr (DebugBuild)
{
@@ -45,4 +48,18 @@ namespace TEN::Debug
}
}
};
+
+ void PrintDebugMessage(LPCSTR msg, ...);
+ void DrawDebug2DLine(const Vector2& origin, const Vector2& target, const Color& color, RendererDebugPage page = RendererDebugPage::None);
+ void DrawDebugLine(const Vector3& origin, const Vector3& target, const Color& color, RendererDebugPage page = RendererDebugPage::None);
+ void DrawDebugTriangle(const Vector3& vertex0, const Vector3& vertex1, const Vector3& vertex2, const Color& color, RendererDebugPage page = RendererDebugPage::None);
+ void DrawDebugTarget(const Vector3& center, const Quaternion& orient, float radius, const Color& color, RendererDebugPage page = RendererDebugPage::None);
+ void DrawDebugBox(const std::array& corners, const Color& color, RendererDebugPage page = RendererDebugPage::None, bool isWireframe = true);
+ void DrawDebugBox(const Vector3& min, const Vector3& max, const Color& color, RendererDebugPage page = RendererDebugPage::None, bool isWireframe = true);
+ void DrawDebugBox(const BoundingOrientedBox& box, const Color& color, RendererDebugPage page = RendererDebugPage::None, bool isWireframe = true);
+ void DrawDebugBox(const BoundingBox& box, const Color& color, RendererDebugPage page = RendererDebugPage::None, bool isWireframe = true);
+ void DrawDebugCone(const Vector3& center, const Quaternion& orient, float radius, float length, const Vector4& color, RendererDebugPage page, bool isWireframe = true);
+ void DrawDebugCylinder(const Vector3& center, const Quaternion& orient, float radius, float length, const Color& color, RendererDebugPage page = RendererDebugPage::None, bool isWireframe = true);
+ void DrawDebugSphere(const Vector3& center, float radius, const Color& color, RendererDebugPage page = RendererDebugPage::None, bool isWireframe = true);
+ void DrawDebugSphere(const BoundingSphere& sphere, const Color& color, RendererDebugPage page = RendererDebugPage::None, bool isWireframe = true);
}
diff --git a/TombEngine/Math/Constants.h b/TombEngine/Math/Constants.h
index 7147986d0..a43ba00a8 100644
--- a/TombEngine/Math/Constants.h
+++ b/TombEngine/Math/Constants.h
@@ -16,6 +16,12 @@
constexpr auto SQUARE = [](auto x) { return (x * x); };
constexpr auto CUBE = [](auto x) { return (x * x * x); };
+ // Geometry constants
+
+ constexpr auto BOX_VERTEX_COUNT = 8;
+ constexpr auto BOX_EDGE_COUNT = 12;
+ constexpr auto BOX_FACE_COUNT = 6;
+
// World constants
constexpr auto BLOCK_UNIT = 1024;
diff --git a/TombEngine/Renderer/ConstantBuffers/ConstantBuffer.h b/TombEngine/Renderer/ConstantBuffers/ConstantBuffer.h
index 3ae6c47b3..147bf2f9a 100644
--- a/TombEngine/Renderer/ConstantBuffers/ConstantBuffer.h
+++ b/TombEngine/Renderer/ConstantBuffers/ConstantBuffer.h
@@ -1,8 +1,10 @@
#pragma once
-#include "Renderer/RendererUtils.h"
-#include "Game/debug/debug.h"
-#include
+
#include
+#include
+
+#include "Game/Debug/Debug.h"
+#include "Renderer/RendererUtils.h"
namespace TEN::Renderer::ConstantBuffers
{
@@ -15,12 +17,12 @@ namespace TEN::Renderer::ConstantBuffers
ConstantBuffer() = default;
ConstantBuffer(ID3D11Device* device)
{
- D3D11_BUFFER_DESC desc = {};
+ auto desc = D3D11_BUFFER_DESC{};
desc.ByteWidth = sizeof(CBuff);
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
- Utils::throwIfFailed(device->CreateBuffer(&desc, NULL, buffer.GetAddressOf()));
+ Utils::throwIfFailed(device->CreateBuffer(&desc, nullptr, buffer.GetAddressOf()));
buffer->SetPrivateData(WKPDID_D3DDebugObjectName, 32, typeid(CBuff).name());
}
@@ -31,8 +33,8 @@ namespace TEN::Renderer::ConstantBuffers
void UpdateData(CBuff& data, ID3D11DeviceContext* ctx)
{
- D3D11_MAPPED_SUBRESOURCE mappedResource;
- HRESULT res = ctx->Map(buffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+ auto mappedResource = D3D11_MAPPED_SUBRESOURCE{};
+ auto res = ctx->Map(buffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (SUCCEEDED(res))
{
void* dataPtr = (mappedResource.pData);
@@ -40,7 +42,9 @@ namespace TEN::Renderer::ConstantBuffers
ctx->Unmap(buffer.Get(), 0);
}
else
- TENLog("Could not update constant buffer!", LogLevel::Error);
+ {
+ TENLog("Could not update constant buffer.", LogLevel::Error);
+ }
}
};
}
diff --git a/TombEngine/Renderer/Graphics/IndexBuffer.h b/TombEngine/Renderer/Graphics/IndexBuffer.h
index d2869b00e..690264d5d 100644
--- a/TombEngine/Renderer/Graphics/IndexBuffer.h
+++ b/TombEngine/Renderer/Graphics/IndexBuffer.h
@@ -3,7 +3,7 @@
#include
#include
#include "Renderer/RendererUtils.h"
-#include "Game/debug/debug.h"
+#include "Game/Debug/Debug.h"
#include "Specific/fast_vector.h"
namespace TEN::Renderer::Graphics
diff --git a/TombEngine/Renderer/Renderer.h b/TombEngine/Renderer/Renderer.h
index d738ae413..9cb74a15a 100644
--- a/TombEngine/Renderer/Renderer.h
+++ b/TombEngine/Renderer/Renderer.h
@@ -288,7 +288,7 @@ namespace TEN::Renderer
int _numCheckPortalCalls = 0;
int _numGetVisibleRoomsCalls = 0;
- int _currentY;
+ float _currentLineHeight = 0.0f;;
RendererDebugPage _debugPage = RendererDebugPage::None;
@@ -404,7 +404,6 @@ namespace TEN::Renderer
void ClearShadowMap();
void CalculateSSAO(RenderView& view);
void UpdateItemAnimations(RenderView& view);
- bool PrintDebugMessage(int x, int y, int alpha, byte r, byte g, byte b, LPCSTR Message);
void InitializeScreen(int w, int h, HWND handle, bool reset);
void InitializeCommonTextures();
void InitializeGameBars();
@@ -593,7 +592,8 @@ namespace TEN::Renderer
void RenderScene(RenderTarget2D* renderTarget, bool doAntialiasing, RenderView& view);
void ClearScene();
void SaveScreenshot();
- void PrintDebugMessage(LPCSTR message, ...);
+ void PrintDebugMessage(LPCSTR msg, va_list args);
+ void PrintDebugMessage(LPCSTR msg, ...);
void DrawDebugInfo(RenderView& view);
void SwitchDebugPage(bool goBack);
void DrawDisplayPickup(const DisplayPickup& pickup);
@@ -615,11 +615,11 @@ namespace TEN::Renderer
void AddDebugLine(const Vector3& origin, const Vector3& target, const Color& color, RendererDebugPage page = RendererDebugPage::None);
void AddDebugTriangle(const Vector3& vertex0, const Vector3& vertex1, const Vector3& vertex2, const Color& color, RendererDebugPage page = RendererDebugPage::None);
void AddDebugTarget(const Vector3& center, const Quaternion& orient, float radius, const Color& color, RendererDebugPage page = RendererDebugPage::None);
- void AddDebugBox(const std::array& corners, const Color& color, RendererDebugPage page = RendererDebugPage::None, bool isWireframe = true);
+ void AddDebugBox(const std::array& corners, const Color& color, RendererDebugPage page = RendererDebugPage::None, bool isWireframe = true);
void AddDebugBox(const Vector3& min, const Vector3& max, const Color& color, RendererDebugPage page = RendererDebugPage::None, bool isWireframe = true);
void AddDebugBox(const BoundingOrientedBox& box, const Color& color, RendererDebugPage page = RendererDebugPage::None, bool isWireframe = true);
void AddDebugBox(const BoundingBox& box, const Color& color, RendererDebugPage page = RendererDebugPage::None, bool isWireframe = true);
- void AddDebugCone(const Vector3& center, const Quaternion& orient, float radius, float length, const Vector4& color, RendererDebugPage page, bool isWireframe);
+ void AddDebugCone(const Vector3& center, const Quaternion& orient, float radius, float length, const Vector4& color, RendererDebugPage page, bool isWireframe = true);
void AddDebugCylinder(const Vector3& center, const Quaternion& orient, float radius, float length, const Color& color, RendererDebugPage page = RendererDebugPage::None, bool isWireframe = true);
void AddDebugSphere(const Vector3& center, float radius, const Color& color, RendererDebugPage page = RendererDebugPage::None, bool isWireframe = true);
void AddDebugSphere(const BoundingSphere& sphere, const Color& color, RendererDebugPage page = RendererDebugPage::None, bool isWireframe = true);
diff --git a/TombEngine/Renderer/RendererDebug.cpp b/TombEngine/Renderer/RendererDebug.cpp
index 89ce89d6e..b65d6d02c 100644
--- a/TombEngine/Renderer/RendererDebug.cpp
+++ b/TombEngine/Renderer/RendererDebug.cpp
@@ -35,26 +35,29 @@ namespace TEN::Renderer
_numCheckPortalCalls = 0;
_numGetVisibleRoomsCalls = 0;
- _currentY;
+ _currentLineHeight;
}
- bool Renderer::PrintDebugMessage(int x, int y, int alpha, byte r, byte g, byte b, LPCSTR Message)
+ void Renderer::PrintDebugMessage(LPCSTR msg, va_list args)
{
- return true;
- }
+ constexpr auto LINE_X_POS = DISPLAY_SPACE_RES.x / 100;
+ constexpr auto LINE_SPACING = DISPLAY_SPACE_RES.y / 30;
+ constexpr auto COLOR = Color(1.0f, 1.0f, 1.0f);
+ constexpr auto SCALE = 0.8f;
- void Renderer::PrintDebugMessage(LPCSTR message, ...)
- {
char buffer[255];
ZeroMemory(buffer, 255);
+ _vsprintf_l(buffer, msg, nullptr, args);
+ AddString(buffer, Vector2(LINE_X_POS, _currentLineHeight), COLOR, SCALE, (int)PrintStringFlags::Outline);
- va_list args;
- va_start(args, message);
- _vsprintf_l(buffer, message, NULL, args);
+ _currentLineHeight += LINE_SPACING;
+ }
+
+ void Renderer::PrintDebugMessage(LPCSTR msg, ...)
+ {
+ auto args = va_list{};
+ va_start(args, msg);
+ PrintDebugMessage(msg, args);
va_end(args);
-
- AddString(10, _currentY, buffer, 0xFFFFFFFF, (int)PrintStringFlags::Outline);
-
- _currentY += 20;
}
}
diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp
index 573141b8c..6c9fc6307 100644
--- a/TombEngine/Renderer/RendererDraw.cpp
+++ b/TombEngine/Renderer/RendererDraw.cpp
@@ -1236,11 +1236,8 @@ namespace TEN::Renderer
AddDebugLine(origin2, target2, color);
}
- void Renderer::AddDebugBox(const std::array& corners, const Color& color, RendererDebugPage page, bool isWireframe)
+ void Renderer::AddDebugBox(const std::array& corners, const Color& color, RendererDebugPage page, bool isWireframe)
{
- constexpr auto LINE_COUNT = 12;
- constexpr auto PLANE_COUNT = 6;
-
if (_isLocked)
return;
@@ -1250,7 +1247,7 @@ namespace TEN::Renderer
// Construct box.
if (isWireframe)
{
- for (int i = 0; i < LINE_COUNT; i++)
+ for (int i = 0; i < BOX_EDGE_COUNT; i++)
{
switch (i)
{
@@ -1297,7 +1294,7 @@ namespace TEN::Renderer
}
else
{
- for (int i = 0; i < PLANE_COUNT; i++)
+ for (int i = 0; i < BOX_FACE_COUNT; i++)
{
switch (i)
{
@@ -1349,15 +1346,13 @@ namespace TEN::Renderer
void Renderer::AddDebugBox(const BoundingOrientedBox& box, const Color& color, RendererDebugPage page, bool isWireframe)
{
- constexpr auto CORNER_COUNT = 8;
-
if (_isLocked)
return;
if (!DebugMode || (_debugPage != page && page != RendererDebugPage::None))
return;
- auto corners = std::array{};
+ auto corners = std::array{};
box.GetCorners(corners.data());
AddDebugBox(corners, color, page, isWireframe);
@@ -1365,15 +1360,13 @@ namespace TEN::Renderer
void Renderer::AddDebugBox(const BoundingBox& box, const Color& color, RendererDebugPage page, bool isWireframe)
{
- constexpr auto CORNER_COUNT = 8;
-
if (_isLocked)
return;
if (!DebugMode || (_debugPage != page && page != RendererDebugPage::None))
return;
- auto corners = std::array{};
+ auto corners = std::array{};
box.GetCorners(corners.data());
AddDebugBox(corners, color, page, isWireframe);
diff --git a/TombEngine/Renderer/RendererDrawMenu.cpp b/TombEngine/Renderer/RendererDrawMenu.cpp
index 4553f5630..fc66d93c3 100644
--- a/TombEngine/Renderer/RendererDrawMenu.cpp
+++ b/TombEngine/Renderer/RendererDrawMenu.cpp
@@ -1125,186 +1125,181 @@ namespace TEN::Renderer
void Renderer::DrawDebugInfo(RenderView& view)
{
- if (CurrentLevel != 0)
+ if (CurrentLevel == 0)
+ return;
+
+ _currentLineHeight = DISPLAY_SPACE_RES.y / 30;
+
+ const auto& room = g_Level.Rooms[LaraItem->RoomNumber];
+
+ float aspectRatio = _screenWidth / (float)_screenHeight;
+ int thumbWidth = _screenWidth / 6;
+ auto rect = RECT{};
+ int thumbY = 0;
+
+ switch (_debugPage)
{
- _currentY = 20;
+ case RendererDebugPage::None:
+ break;
- ROOM_INFO* r = &g_Level.Rooms[LaraItem->RoomNumber];
-
- float aspectRatio = _screenWidth / (float)_screenHeight;
- int thumbWidth = _screenWidth / 6;
- RECT rect;
- int thumbY = 0;
-
- switch (_debugPage)
- {
- case RendererDebugPage::None:
- break;
-
- case RendererDebugPage::RendererStats:
- PrintDebugMessage("RENDERER STATS");
- PrintDebugMessage("FPS: %3.2f", _fps);
- PrintDebugMessage("Resolution: %d x %d", _screenWidth, _screenHeight);
- PrintDebugMessage("GPU: %s", g_Configuration.AdapterName.c_str());
- PrintDebugMessage("Update time: %d", _timeUpdate);
- PrintDebugMessage("Frame time: %d", _timeFrame);
- PrintDebugMessage("ControlPhase() time: %d", ControlPhaseTime);
- PrintDebugMessage("Room collector time: %d", _timeRoomsCollector);
- PrintDebugMessage("TOTAL Draw calls: %d", _numDrawCalls);
- PrintDebugMessage(" Rooms: %d", _numRoomsDrawCalls);
- PrintDebugMessage(" Movables: %d", _numMoveablesDrawCalls);
- PrintDebugMessage(" Statics: %d", _numStaticsDrawCalls);
- PrintDebugMessage(" Instanced Statics: %d", _numInstancedStaticsDrawCalls);
- PrintDebugMessage(" Sprites: %d", _numSpritesDrawCalls);
- PrintDebugMessage(" Instanced Sprites: %d", _numInstancedSpritesDrawCalls);
- PrintDebugMessage("TOTAL Triangles: %d", _numTriangles);
- PrintDebugMessage("Sprites: %d", view.SpritesToDraw.size());
- PrintDebugMessage("SORTED Draw calls: %d", (_numSortedRoomsDrawCalls + _numSortedMoveablesDrawCalls + _numSortedStaticsDrawCalls
- + _numSortedSpritesDrawCalls));
- PrintDebugMessage(" Rooms: %d", _numSortedRoomsDrawCalls);
- PrintDebugMessage(" Movables: %d", _numSortedMoveablesDrawCalls);
- PrintDebugMessage(" Statics: %d", _numSortedStaticsDrawCalls);
- PrintDebugMessage(" Sprites: %d", _numSortedSpritesDrawCalls);
- PrintDebugMessage("SHADOW MAPS Draw calls: %d", _numShadowMapDrawCalls);
- PrintDebugMessage("DEBRIS Draw calls: %d", _numDebrisDrawCalls);
- PrintDebugMessage("Rooms: %d", view.RoomsToDraw.size());
- PrintDebugMessage(" CheckPortal() calls: %d", _numCheckPortalCalls);
- PrintDebugMessage(" GetVisibleRooms() calls: %d", _numGetVisibleRoomsCalls);
- PrintDebugMessage(" Dot products: %d", _numDotProducts);
+ case RendererDebugPage::RendererStats:
+ PrintDebugMessage("RENDERER STATS");
+ PrintDebugMessage("FPS: %3.2f", _fps);
+ PrintDebugMessage("Resolution: %d x %d", _screenWidth, _screenHeight);
+ PrintDebugMessage("GPU: %s", g_Configuration.AdapterName.c_str());
+ PrintDebugMessage("Update time: %d", _timeUpdate);
+ PrintDebugMessage("Frame time: %d", _timeFrame);
+ PrintDebugMessage("ControlPhase() time: %d", ControlPhaseTime);
+ PrintDebugMessage("Room collector time: %d", _timeRoomsCollector);
+ PrintDebugMessage("TOTAL draw calls: %d", _numDrawCalls);
+ PrintDebugMessage(" Rooms: %d", _numRoomsDrawCalls);
+ PrintDebugMessage(" Movables: %d", _numMoveablesDrawCalls);
+ PrintDebugMessage(" Statics: %d", _numStaticsDrawCalls);
+ PrintDebugMessage(" Instanced Statics: %d", _numInstancedStaticsDrawCalls);
+ PrintDebugMessage(" Sprites: %d", _numSpritesDrawCalls);
+ PrintDebugMessage(" Instanced Sprites: %d", _numInstancedSpritesDrawCalls);
+ PrintDebugMessage("TOTAL triangles: %d", _numTriangles);
+ PrintDebugMessage("Sprites: %d", view.SpritesToDraw.size());
+ PrintDebugMessage("SORTED draw calls: %d", (_numSortedRoomsDrawCalls + _numSortedMoveablesDrawCalls + _numSortedStaticsDrawCalls + _numSortedSpritesDrawCalls));
+ PrintDebugMessage(" Rooms: %d", _numSortedRoomsDrawCalls);
+ PrintDebugMessage(" Movables: %d", _numSortedMoveablesDrawCalls);
+ PrintDebugMessage(" Statics: %d", _numSortedStaticsDrawCalls);
+ PrintDebugMessage(" Sprites: %d", _numSortedSpritesDrawCalls);
+ PrintDebugMessage("SHADOW MAP draw calls: %d", _numShadowMapDrawCalls);
+ PrintDebugMessage("DEBRIS draw calls: %d", _numDebrisDrawCalls);
+ PrintDebugMessage("Rooms: %d", view.RoomsToDraw.size());
+ PrintDebugMessage(" CheckPortal() calls: %d", _numCheckPortalCalls);
+ PrintDebugMessage(" GetVisibleRooms() calls: %d", _numGetVisibleRoomsCalls);
+ PrintDebugMessage(" Dot products: %d", _numDotProducts);
- _spriteBatch->Begin(SpriteSortMode_Deferred, _renderStates->Opaque());
+ _spriteBatch->Begin(SpriteSortMode_Deferred, _renderStates->Opaque());
- rect.left = _screenWidth - thumbWidth;
- rect.top = thumbY;
- rect.right = rect.left+ thumbWidth;
- rect.bottom = rect.top+thumbWidth / aspectRatio;
+ rect.left = _screenWidth - thumbWidth;
+ rect.top = thumbY;
+ rect.right = rect.left+ thumbWidth;
+ rect.bottom = rect.top+thumbWidth / aspectRatio;
- _spriteBatch->Draw(_normalsRenderTarget.ShaderResourceView.Get(), rect);
- thumbY += thumbWidth / aspectRatio;
+ _spriteBatch->Draw(_normalsRenderTarget.ShaderResourceView.Get(), rect);
+ thumbY += thumbWidth / aspectRatio;
- rect.left = _screenWidth - thumbWidth;
- rect.top = thumbY;
- rect.right = rect.left + thumbWidth;
- rect.bottom = rect.top + thumbWidth / aspectRatio;
-
- //_spriteBatch->Draw(_depthRenderTarget.ShaderResourceView.Get(), rect);
- //thumbY += thumbWidth / aspectRatio;
+ rect.left = _screenWidth - thumbWidth;
+ rect.top = thumbY;
+ rect.right = rect.left + thumbWidth;
+ rect.bottom = rect.top + thumbWidth / aspectRatio;
- rect.left = _screenWidth - thumbWidth;
- rect.top = thumbY;
- rect.right = rect.left + thumbWidth;
- rect.bottom = rect.top + thumbWidth / aspectRatio;
+ rect.left = _screenWidth - thumbWidth;
+ rect.top = thumbY;
+ rect.right = rect.left + thumbWidth;
+ rect.bottom = rect.top + thumbWidth / aspectRatio;
- _spriteBatch->Draw(_SSAOBlurredRenderTarget.ShaderResourceView.Get(), rect);
- thumbY += thumbWidth / aspectRatio;
+ _spriteBatch->Draw(_SSAOBlurredRenderTarget.ShaderResourceView.Get(), rect);
+ thumbY += thumbWidth / aspectRatio;
- if (g_Configuration.AntialiasingMode > AntialiasingMode::Low)
- {
- rect.left = _screenWidth - thumbWidth;
- rect.top = thumbY;
- rect.right = rect.left + thumbWidth;
- rect.bottom = rect.top + thumbWidth / aspectRatio;
-
- _spriteBatch->Draw(_SMAAEdgesRenderTarget.ShaderResourceView.Get(), rect);
- thumbY += thumbWidth / aspectRatio;
-
- rect.left = _screenWidth - thumbWidth;
- rect.top = thumbY;
- rect.right = rect.left + thumbWidth;
- rect.bottom = rect.top + thumbWidth / aspectRatio;
-
- _spriteBatch->Draw(_SMAABlendRenderTarget.ShaderResourceView.Get(), rect);
- thumbY += thumbWidth / aspectRatio;
- }
-
- _spriteBatch->End();
-
- break;
-
- case RendererDebugPage::DimensionStats:
- PrintDebugMessage("DIMENSION STATS");
- PrintDebugMessage("Pos: %d %d %d", LaraItem->Pose.Position.x, LaraItem->Pose.Position.y, LaraItem->Pose.Position.z);
- PrintDebugMessage("Orient: %d %d %d", LaraItem->Pose.Orientation.x, LaraItem->Pose.Orientation.y, LaraItem->Pose.Orientation.z);
- PrintDebugMessage("RoomNumber: %d", LaraItem->RoomNumber);
- PrintDebugMessage("Room location: %d %d", LaraItem->Location.RoomNumber, LaraItem->Location.Height);
- PrintDebugMessage("BoxNumber: %d", LaraItem->BoxNumber);
- PrintDebugMessage("WaterSurfaceDist: %d", Lara.Context.WaterSurfaceDist);
- PrintDebugMessage("Room: %d %d %d %d", r->x, r->z, r->x + r->xSize * BLOCK(1), r->z + r->zSize * BLOCK(1));
- PrintDebugMessage("Room.y, minFloor, maxCeiling: %d %d %d ", r->y, r->minfloor, r->maxceiling);
- PrintDebugMessage("Camera.pos: %d %d %d", Camera.pos.x, Camera.pos.y, Camera.pos.z);
- PrintDebugMessage("Camera.target: %d %d %d", Camera.target.x, Camera.target.y, Camera.target.z);
- PrintDebugMessage("Camera.RoomNumber: %d", Camera.pos.RoomNumber);
- break;
-
- case RendererDebugPage::PlayerStats:
- PrintDebugMessage("PLAYER STATS");
- PrintDebugMessage("AnimObjectID: %d", LaraItem->Animation.AnimObjectID);
- PrintDebugMessage("AnimNumber: %d", LaraItem->Animation.AnimNumber);
- PrintDebugMessage("FrameNumber: %d", LaraItem->Animation.FrameNumber);
- PrintDebugMessage("ActiveState: %d", LaraItem->Animation.ActiveState);
- PrintDebugMessage("TargetState: %d", LaraItem->Animation.TargetState);
- PrintDebugMessage("Velocity: %.3f %.3f %.3f", LaraItem->Animation.Velocity.z, LaraItem->Animation.Velocity.y, LaraItem->Animation.Velocity.x);
- PrintDebugMessage("IsAirborne: %d", LaraItem->Animation.IsAirborne);
- PrintDebugMessage("HandStatus: %d", Lara.Control.HandStatus);
- PrintDebugMessage("WaterStatus: %d", Lara.Control.WaterStatus);
- PrintDebugMessage("CanClimbLadder: %d", Lara.Control.CanClimbLadder);
- PrintDebugMessage("CanMonkeySwing: %d", Lara.Control.CanMonkeySwing);
- PrintDebugMessage("Target HitPoints: %d", Lara.TargetEntity ? Lara.TargetEntity->HitPoints : 0);
- break;
-
- case RendererDebugPage::InputStats:
+ if (g_Configuration.AntialiasingMode > AntialiasingMode::Low)
{
- auto clickedActions = BitField((int)In::Count);
- auto heldActions = BitField((int)In::Count);
- auto releasedActions = BitField((int)In::Count);
+ rect.left = _screenWidth - thumbWidth;
+ rect.top = thumbY;
+ rect.right = rect.left + thumbWidth;
+ rect.bottom = rect.top + thumbWidth / aspectRatio;
- for (const auto& action : ActionMap)
- {
- if (action.IsClicked())
- clickedActions.Set((int)action.GetID());
+ _spriteBatch->Draw(_SMAAEdgesRenderTarget.ShaderResourceView.Get(), rect);
+ thumbY += thumbWidth / aspectRatio;
- if (action.IsHeld())
- heldActions.Set((int)action.GetID());
+ rect.left = _screenWidth - thumbWidth;
+ rect.top = thumbY;
+ rect.right = rect.left + thumbWidth;
+ rect.bottom = rect.top + thumbWidth / aspectRatio;
- if (action.IsReleased())
- releasedActions.Set((int)action.GetID());
- }
-
- PrintDebugMessage("INPUT STATS");
- PrintDebugMessage(("Clicked actions: " + clickedActions.ToString()).c_str());
- PrintDebugMessage(("Held actions: " + heldActions.ToString()).c_str());
- PrintDebugMessage(("Released actions: " + releasedActions.ToString()).c_str());
- PrintDebugMessage("Move axes: %.3f, %.3f", AxisMap[(int)InputAxis::Move].x, AxisMap[(int)InputAxis::Move].y);
- PrintDebugMessage("Camera axes: %.3f, %.3f", AxisMap[(int)InputAxis::Camera].x, AxisMap[(int)InputAxis::Camera].y);
- PrintDebugMessage("Mouse axes: %.3f, %.3f", AxisMap[(int)InputAxis::Mouse].x, AxisMap[(int)InputAxis::Mouse].y);
- PrintDebugMessage("Cursor pos: %.3f, %.3f", GetMouse2DPosition().x, GetMouse2DPosition().y);
+ _spriteBatch->Draw(_SMAABlendRenderTarget.ShaderResourceView.Get(), rect);
+ thumbY += thumbWidth / aspectRatio;
}
- break;
- case RendererDebugPage::CollisionStats:
- PrintDebugMessage("COLLISION STATS");
- PrintDebugMessage("Collision type: %d", LaraCollision.CollisionType);
- PrintDebugMessage("Bridge item ID: %d", LaraCollision.Middle.Bridge);
- PrintDebugMessage("Front floor: %d", LaraCollision.Front.Floor);
- PrintDebugMessage("Front left floor: %d", LaraCollision.FrontLeft.Floor);
- PrintDebugMessage("Front right floor: %d", LaraCollision.FrontRight.Floor);
- PrintDebugMessage("Front ceil: %d", LaraCollision.Front.Ceiling);
- PrintDebugMessage("Front left ceil: %d", LaraCollision.FrontLeft.Ceiling);
- PrintDebugMessage("Front right ceil: %d", LaraCollision.FrontRight.Ceiling);
- break;
-
- case RendererDebugPage::PathfindingStats:
- PrintDebugMessage("PATHFINDING STATS");
- PrintDebugMessage("BoxNumber: %d", LaraItem->BoxNumber);
- break;
-
- case RendererDebugPage::WireframeMode:
- PrintDebugMessage("WIREFRAME MODE");
- break;
+ _spriteBatch->End();
- default:
- break;
+ break;
+
+ case RendererDebugPage::DimensionStats:
+ PrintDebugMessage("DIMENSION STATS");
+ PrintDebugMessage("Position: %d, %d, %d", LaraItem->Pose.Position.x, LaraItem->Pose.Position.y, LaraItem->Pose.Position.z);
+ PrintDebugMessage("Orientation: %d, %d, %d", LaraItem->Pose.Orientation.x, LaraItem->Pose.Orientation.y, LaraItem->Pose.Orientation.z);
+ PrintDebugMessage("RoomNumber: %d", LaraItem->RoomNumber);
+ PrintDebugMessage("PathfindingBoxID: %d", LaraItem->BoxNumber);
+ PrintDebugMessage("WaterSurfaceDist: %d", Lara.Context.WaterSurfaceDist);
+ PrintDebugMessage("Room Position: %d, %d, %d, %d", room.x, room.z, room.x + BLOCK(room.xSize), room.z + BLOCK(room.zSize));
+ PrintDebugMessage("Room.y, minFloor, maxCeiling: %d, %d, %d ", room.y, room.minfloor, room.maxceiling);
+ PrintDebugMessage("Camera Position: %d, %d, %d", Camera.pos.x, Camera.pos.y, Camera.pos.z);
+ PrintDebugMessage("Camera LookAt: %d, %d, %d", Camera.target.x, Camera.target.y, Camera.target.z);
+ PrintDebugMessage("Camera RoomNumber: %d", Camera.pos.RoomNumber);
+ break;
+
+ case RendererDebugPage::PlayerStats:
+ PrintDebugMessage("PLAYER STATS");
+ PrintDebugMessage("AnimObjectID: %d", LaraItem->Animation.AnimObjectID);
+ PrintDebugMessage("AnimNumber: %d", LaraItem->Animation.AnimNumber);
+ PrintDebugMessage("FrameNumber: %d", LaraItem->Animation.FrameNumber);
+ PrintDebugMessage("ActiveState: %d", LaraItem->Animation.ActiveState);
+ PrintDebugMessage("TargetState: %d", LaraItem->Animation.TargetState);
+ PrintDebugMessage("Velocity: %.3f, %.3f, %.3f", LaraItem->Animation.Velocity.z, LaraItem->Animation.Velocity.y, LaraItem->Animation.Velocity.x);
+ PrintDebugMessage("IsAirborne: %d", LaraItem->Animation.IsAirborne);
+ PrintDebugMessage("HandStatus: %d", Lara.Control.HandStatus);
+ PrintDebugMessage("WaterStatus: %d", Lara.Control.WaterStatus);
+ PrintDebugMessage("CanClimbLadder: %d", Lara.Control.CanClimbLadder);
+ PrintDebugMessage("CanMonkeySwing: %d", Lara.Control.CanMonkeySwing);
+ PrintDebugMessage("Target HitPoints: %d", Lara.TargetEntity ? Lara.TargetEntity->HitPoints : 0);
+ break;
+
+ case RendererDebugPage::InputStats:
+ {
+ auto clickedActions = BitField((int)In::Count);
+ auto heldActions = BitField((int)In::Count);
+ auto releasedActions = BitField((int)In::Count);
+
+ for (const auto& action : ActionMap)
+ {
+ if (action.IsClicked())
+ clickedActions.Set((int)action.GetID());
+
+ if (action.IsHeld())
+ heldActions.Set((int)action.GetID());
+
+ if (action.IsReleased())
+ releasedActions.Set((int)action.GetID());
}
+
+ PrintDebugMessage("INPUT STATS");
+ PrintDebugMessage(("Clicked actions: " + clickedActions.ToString()).c_str());
+ PrintDebugMessage(("Held actions: " + heldActions.ToString()).c_str());
+ PrintDebugMessage(("Released actions: " + releasedActions.ToString()).c_str());
+ PrintDebugMessage("Move axes: %.3f, %.3f", AxisMap[(int)InputAxis::Move].x, AxisMap[(int)InputAxis::Move].y);
+ PrintDebugMessage("Camera axes: %.3f, %.3f", AxisMap[(int)InputAxis::Camera].x, AxisMap[(int)InputAxis::Camera].y);
+ PrintDebugMessage("Mouse axes: %.3f, %.3f", AxisMap[(int)InputAxis::Mouse].x, AxisMap[(int)InputAxis::Mouse].y);
+ PrintDebugMessage("Cursor pos: %.3f, %.3f", GetMouse2DPosition().x, GetMouse2DPosition().y);
+ }
+ break;
+
+ case RendererDebugPage::CollisionStats:
+ PrintDebugMessage("COLLISION STATS");
+ PrintDebugMessage("Collision type: %d", LaraCollision.CollisionType);
+ PrintDebugMessage("Bridge item ID: %d", LaraCollision.Middle.Bridge);
+ PrintDebugMessage("Front floor: %d", LaraCollision.Front.Floor);
+ PrintDebugMessage("Front left floor: %d", LaraCollision.FrontLeft.Floor);
+ PrintDebugMessage("Front right floor: %d", LaraCollision.FrontRight.Floor);
+ PrintDebugMessage("Front ceil: %d", LaraCollision.Front.Ceiling);
+ PrintDebugMessage("Front left ceil: %d", LaraCollision.FrontLeft.Ceiling);
+ PrintDebugMessage("Front right ceil: %d", LaraCollision.FrontRight.Ceiling);
+ break;
+
+ case RendererDebugPage::PathfindingStats:
+ PrintDebugMessage("PATHFINDING STATS");
+ PrintDebugMessage("BoxNumber: %d", LaraItem->BoxNumber);
+ break;
+
+ case RendererDebugPage::WireframeMode:
+ PrintDebugMessage("WIREFRAME MODE");
+ break;
+
+ default:
+ break;
}
}
diff --git a/TombEngine/Renderer/RendererUtils.cpp b/TombEngine/Renderer/RendererUtils.cpp
index de53f6f07..b6601bbe2 100644
--- a/TombEngine/Renderer/RendererUtils.cpp
+++ b/TombEngine/Renderer/RendererUtils.cpp
@@ -68,7 +68,7 @@ namespace TEN::Renderer::Utils
ComPtr shader;
throwIfFailed(device->CreateVertexShader(bytecode->GetBufferPointer(), bytecode->GetBufferSize(), nullptr, shader.GetAddressOf()));
- if constexpr(DebugBuild)
+ if constexpr (DebugBuild)
{
char buffer[100];
unsigned int size = (unsigned int)std::wcstombs(buffer, fileName.c_str(), 100);
diff --git a/TombEngine/Scripting/Internal/TEN/Util/LevelLog.h b/TombEngine/Scripting/Internal/TEN/Util/LevelLog.h
index a87fd9351..554dde516 100644
--- a/TombEngine/Scripting/Internal/TEN/Util/LevelLog.h
+++ b/TombEngine/Scripting/Internal/TEN/Util/LevelLog.h
@@ -2,7 +2,7 @@
#include
#include
-#include "Game/debug/debug.h"
+#include "Game/Debug/Debug.h"
#include "Scripting/Internal/ReservedScriptNames.h"
/***
diff --git a/TombEngine/Specific/Input/InputAction.cpp b/TombEngine/Specific/Input/InputAction.cpp
index 6c62db8b7..b832bcac0 100644
--- a/TombEngine/Specific/Input/InputAction.cpp
+++ b/TombEngine/Specific/Input/InputAction.cpp
@@ -1,10 +1,8 @@
#include "framework.h"
#include "Specific/Input/InputAction.h"
-#include "Renderer/Renderer.h"
#include "Specific/clock.h"
-using TEN::Renderer::g_Renderer;
namespace TEN::Input
{
@@ -126,17 +124,17 @@ namespace TEN::Input
void InputAction::DrawDebug() const
{
- g_Renderer.PrintDebugMessage("ID: %d", (int)ID);
- g_Renderer.PrintDebugMessage("IsClicked: %d", IsClicked());
- g_Renderer.PrintDebugMessage("IsHeld: %d", IsHeld());
- g_Renderer.PrintDebugMessage("IsPulsed (.2s, .6s): %d", IsPulsed(0.2f, 0.6f));
- g_Renderer.PrintDebugMessage("IsReleased: %d", IsReleased());
- g_Renderer.PrintDebugMessage("");
- g_Renderer.PrintDebugMessage("Value: %.3f", Value);
- g_Renderer.PrintDebugMessage("PrevValue: %.3f", PrevValue);
- g_Renderer.PrintDebugMessage("TimeActive: %.3f", TimeActive);
- g_Renderer.PrintDebugMessage("PrevTimeActive: %.3f", PrevTimeActive);
- g_Renderer.PrintDebugMessage("TimeInactive: %.3f", TimeInactive);
+ PrintDebugMessage("ID: %d", (int)ID);
+ PrintDebugMessage("IsClicked: %d", IsClicked());
+ PrintDebugMessage("IsHeld: %d", IsHeld());
+ PrintDebugMessage("IsPulsed (.2s, .6s): %d", IsPulsed(0.2f, 0.6f));
+ PrintDebugMessage("IsReleased: %d", IsReleased());
+ PrintDebugMessage("");
+ PrintDebugMessage("Value: %.3f", Value);
+ PrintDebugMessage("PrevValue: %.3f", PrevValue);
+ PrintDebugMessage("TimeActive: %.3f", TimeActive);
+ PrintDebugMessage("PrevTimeActive: %.3f", PrevTimeActive);
+ PrintDebugMessage("TimeInactive: %.3f", TimeInactive);
}
void InputAction::UpdateValue(float value)
diff --git a/TombEngine/framework.h b/TombEngine/framework.h
index 46ce3d07a..6740dadd0 100644
--- a/TombEngine/framework.h
+++ b/TombEngine/framework.h
@@ -18,11 +18,11 @@
#include
#include
-#include "Game/debug/debug.h"
-
using namespace DirectX;
using namespace DirectX::SimpleMath;
+#include "Game/Debug/Debug.h"
+
using namespace TEN::Debug;
constexpr auto NO_VALUE = -1;
From 8aae53c2c2d2c69462c169225d3993540db6f305 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sun, 30 Jun 2024 23:25:00 +1000
Subject: [PATCH 224/410] New animation sound conditions (#1284)
* Base for new sound conditions
* Read flags
* Refine anim sound effect handling
* Add swamp check for DryLand anim sound effect
* Update local variable names
* Use proper math functions
* Update animation.cpp
* Address PR notes
* Syntax
---------
Co-authored-by: Stranger1992 <84292688+Stranger1992@users.noreply.github.com>
---
TombEngine/Game/Lara/lara_flare.cpp | 2 +-
TombEngine/Game/Lara/lara_helpers.cpp | 4 +-
TombEngine/Game/Lara/lara_one_gun.cpp | 2 +-
TombEngine/Game/animation.cpp | 112 +++++++++++------
TombEngine/Game/missile.cpp | 2 +-
TombEngine/Sound/sound.cpp | 167 ++++++++++++++------------
TombEngine/Sound/sound.h | 26 ++--
7 files changed, 186 insertions(+), 129 deletions(-)
diff --git a/TombEngine/Game/Lara/lara_flare.cpp b/TombEngine/Game/Lara/lara_flare.cpp
index 2cab1151e..0cae11806 100644
--- a/TombEngine/Game/Lara/lara_flare.cpp
+++ b/TombEngine/Game/Lara/lara_flare.cpp
@@ -260,7 +260,7 @@ void DrawFlare(ItemInfo& laraItem)
SoundEffect(
SFX_TR4_FLARE_IGNITE_DRY,
&laraItem.Pose,
- TestEnvironment(ENV_FLAG_WATER, &laraItem) ? SoundEnvironment::Water : SoundEnvironment::Land);
+ TestEnvironment(ENV_FLAG_WATER, &laraItem) ? SoundEnvironment::ShallowWater : SoundEnvironment::Land);
}
DoFlareInHand(laraItem, player.Flare.Life);
diff --git a/TombEngine/Game/Lara/lara_helpers.cpp b/TombEngine/Game/Lara/lara_helpers.cpp
index c2b60dd45..b706b2b20 100644
--- a/TombEngine/Game/Lara/lara_helpers.cpp
+++ b/TombEngine/Game/Lara/lara_helpers.cpp
@@ -990,7 +990,7 @@ void HandlePlayerAirBubbles(ItemInfo* item)
{
constexpr auto BUBBLE_COUNT_MAX = 3;
- SoundEffect(SFX_TR4_LARA_BUBBLES, &item->Pose, SoundEnvironment::Water);
+ SoundEffect(SFX_TR4_LARA_BUBBLES, &item->Pose, SoundEnvironment::ShallowWater);
const auto& level = *g_GameFlow->GetLevel(CurrentLevel);
@@ -1465,7 +1465,7 @@ void UpdateLaraSubsuitAngles(ItemInfo* item)
auto mul1 = (float)abs(lara->Control.Subsuit.Velocity[0]) / BLOCK(8);
auto mul2 = (float)abs(lara->Control.Subsuit.Velocity[1]) / BLOCK(8);
auto vol = ((mul1 + mul2) * 5.0f) + 0.5f;
- SoundEffect(SFX_TR5_VEHICLE_DIVESUIT_ENGINE, &item->Pose, SoundEnvironment::Water, 1.0f + (mul1 + mul2), vol);
+ SoundEffect(SFX_TR5_VEHICLE_DIVESUIT_ENGINE, &item->Pose, SoundEnvironment::ShallowWater, 1.0f + (mul1 + mul2), vol);
}
}
diff --git a/TombEngine/Game/Lara/lara_one_gun.cpp b/TombEngine/Game/Lara/lara_one_gun.cpp
index 41f841d9b..4270b6c9b 100644
--- a/TombEngine/Game/Lara/lara_one_gun.cpp
+++ b/TombEngine/Game/Lara/lara_one_gun.cpp
@@ -428,7 +428,7 @@ void FireShotgun(ItemInfo& laraItem)
player.RightArm.GunFlash = Weapons[(int)LaraWeaponType::Shotgun].FlashTime;
- SoundEffect(SFX_TR4_EXPLOSION1, &laraItem.Pose, TestEnvironment(ENV_FLAG_WATER, &laraItem) ? SoundEnvironment::Water : SoundEnvironment::Land);
+ SoundEffect(SFX_TR4_EXPLOSION1, &laraItem.Pose, TestEnvironment(ENV_FLAG_WATER, &laraItem) ? SoundEnvironment::ShallowWater : SoundEnvironment::Land);
SoundEffect(Weapons[(int)LaraWeaponType::Shotgun].SampleNum, &laraItem.Pose);
Rumble(0.5f, 0.2f);
diff --git a/TombEngine/Game/animation.cpp b/TombEngine/Game/animation.cpp
index d4f5cd6d1..c245ad097 100644
--- a/TombEngine/Game/animation.cpp
+++ b/TombEngine/Game/animation.cpp
@@ -3,6 +3,7 @@
#include "Game/camera.h"
#include "Game/collision/collide_room.h"
+#include "Game/collision/Point.h"
#include "Game/control/box.h"
#include "Game/control/flipeffect.h"
#include "Game/items.h"
@@ -15,6 +16,7 @@
#include "Sound/sound.h"
#include "Specific/level.h"
+using namespace TEN::Collision::Point;
using namespace TEN::Entities::Generic;
using namespace TEN::Math;
using TEN::Renderer::g_Renderer;
@@ -110,49 +112,87 @@ static void PerformAnimCommands(ItemInfo& item, bool isFrameBased)
break;
case AnimCommandType::SoundEffect:
- if (isFrameBased && item.Animation.FrameNumber == commandDataPtr[0])
+ {
+ int frameNumber = commandDataPtr[0];
+ if (isFrameBased && item.Animation.FrameNumber == frameNumber)
{
- if (!Objects[item.ObjectNumber].waterCreature)
- {
- bool playInWater = (commandDataPtr[1] & 0x8000) != 0;
- bool playOnLand = (commandDataPtr[1] & 0x4000) != 0;
- bool playAlways = (playInWater && playOnLand) || (!playInWater && !playOnLand);
+ // Get sound ID and sound environment flag from packed data.
+ int soundID = commandDataPtr[1] & 0xFFF; // Exclude last 4 bits for sound ID.
+ int soundEnvFlag = commandDataPtr[1] & 0xF000; // Keep only last 4 bits for sound environment flag.
- if (item.IsLara())
- {
- auto& player = GetLaraInfo(item);
-
- if (playAlways ||
- (playOnLand && (player.Context.WaterSurfaceDist >= -SHALLOW_WATER_DEPTH || player.Context.WaterSurfaceDist == NO_HEIGHT)) ||
- (playInWater && player.Context.WaterSurfaceDist < -SHALLOW_WATER_DEPTH && player.Context.WaterSurfaceDist != NO_HEIGHT && !TestEnvironment(ENV_FLAG_SWAMP, &item)))
- {
- SoundEffect(commandDataPtr[1] & 0x3FFF, &item.Pose, SoundEnvironment::Always);
- }
- }
- else
- {
- if (item.RoomNumber == NO_VALUE)
- {
- SoundEffect(commandDataPtr[1] & 0x3FFF, &item.Pose, SoundEnvironment::Always);
- }
- else if (TestEnvironment(ENV_FLAG_WATER, &item))
- {
- if (playAlways || (playInWater && TestEnvironment(ENV_FLAG_WATER, Camera.pos.RoomNumber)))
- SoundEffect(commandDataPtr[1] & 0x3FFF, &item.Pose, SoundEnvironment::Always);
- }
- else if (playAlways || (playOnLand && !TestEnvironment(ENV_FLAG_WATER, Camera.pos.RoomNumber) && !TestEnvironment(ENV_FLAG_SWAMP, Camera.pos.RoomNumber)))
- {
- SoundEffect(commandDataPtr[1] & 0x3FFF, &item.Pose, SoundEnvironment::Always);
- }
- }
- }
- else
+ // Get required sound environment from flag.
+ auto requiredSoundEnv = SoundEnvironment::Always;
+ switch (soundEnvFlag)
{
- SoundEffect(commandDataPtr[1] & 0x3FFF, &item.Pose, TestEnvironment(ENV_FLAG_WATER, &item) ? SoundEnvironment::Water : SoundEnvironment::Land);
+ default:
+ case 0:
+ requiredSoundEnv = SoundEnvironment::Always;
+ break;
+
+ case (1 << 14):
+ requiredSoundEnv = SoundEnvironment::Land;
+ break;
+
+ case (1 << 15):
+ requiredSoundEnv = SoundEnvironment::ShallowWater;
+ break;
+
+ case (1 << 12):
+ requiredSoundEnv = SoundEnvironment::Swamp;
+ break;
+
+ case (1 << 13):
+ requiredSoundEnv = SoundEnvironment::Underwater;
+ break;
}
+
+ int roomNumberAtPos = GetPointCollision(item).GetRoomNumber();
+ bool isWater = TestEnvironment(ENV_FLAG_WATER, roomNumberAtPos);
+ bool isSwamp = TestEnvironment(ENV_FLAG_SWAMP, roomNumberAtPos);
+
+ // Get sound environment for sound effect.
+ auto soundEnv = std::optional();
+ switch (requiredSoundEnv)
+ {
+ case SoundEnvironment::Always:
+ soundEnv = SoundEnvironment::Always;
+ break;
+
+ case SoundEnvironment::Land:
+ if (!isWater && !isSwamp)
+ soundEnv = SoundEnvironment::Land;
+
+ break;
+
+ case SoundEnvironment::ShallowWater:
+ if (isWater)
+ {
+ // HACK: Must update assets before removing this exception for water creatures.
+ const auto& object = Objects[item.ObjectNumber];
+ soundEnv = object.waterCreature ? SoundEnvironment::Underwater : SoundEnvironment::ShallowWater;
+ }
+
+ break;
+
+ case SoundEnvironment::Swamp:
+ if (isSwamp)
+ soundEnv = SoundEnvironment::Swamp;
+
+ break;
+
+ case SoundEnvironment::Underwater:
+ if (isWater)
+ soundEnv = SoundEnvironment::Underwater;
+
+ break;
+ }
+
+ if (soundEnv.has_value())
+ SoundEffect(soundID, &item.Pose, *soundEnv);
}
commandDataPtr += 2;
+ }
break;
case AnimCommandType::Flipeffect:
diff --git a/TombEngine/Game/missile.cpp b/TombEngine/Game/missile.cpp
index 29739935a..2dba2b650 100644
--- a/TombEngine/Game/missile.cpp
+++ b/TombEngine/Game/missile.cpp
@@ -50,7 +50,7 @@ void ControlMissile(short fxNumber)
auto& fx = EffectList[fxNumber];
auto isUnderwater = TestEnvironment(ENV_FLAG_WATER, fx.roomNumber);
- auto soundFXType = isUnderwater ? SoundEnvironment::Water : SoundEnvironment::Land;
+ auto soundFXType = isUnderwater ? SoundEnvironment::ShallowWater : SoundEnvironment::Land;
if (fx.objectNumber == ID_SCUBA_HARPOON && isUnderwater &&
fx.pos.Orientation.x > ANGLE(-67.5f))
diff --git a/TombEngine/Sound/sound.cpp b/TombEngine/Sound/sound.cpp
index 7580fe325..fdd831cbc 100644
--- a/TombEngine/Sound/sound.cpp
+++ b/TombEngine/Sound/sound.cpp
@@ -11,12 +11,21 @@
#include "Game/Lara/lara.h"
#include "Game/room.h"
#include "Game/Setup.h"
+#include "Math/Math.h"
#include "Specific/configuration.h"
#include "Specific/level.h"
#include "Specific/trutils.h"
#include "Specific/winmain.h"
using namespace TEN::Gui;
+using namespace TEN::Math;
+
+enum SoundSourceFlags
+{
+ SS_FLAG_PLAY_FLIP_ROOM = 1 << 13,
+ SS_FLAG_PLAY_BASE_ROOM = 1 << 14,
+ SS_FLAG_PLAY_ALWAYS = 1 << 15
+};
HSAMPLE BASS_SamplePointer[SOUND_MAX_SAMPLES];
HSTREAM BASS_3D_Mixdown;
@@ -150,44 +159,46 @@ bool LoadSample(char* pointer, int compSize, int uncompSize, int index)
return true;
}
-bool SoundEffect(int effectID, Pose* position, SoundEnvironment condition, float pitchMultiplier, float gainMultiplier)
+// TODO: Use std::optional for pose argument.
+bool SoundEffect(int soundID, Pose* pose, SoundEnvironment soundEnv, float pitchMult, float gainMult)
{
if (!g_Configuration.EnableSound)
return false;
- if (effectID >= g_Level.SoundMap.size())
+ if (soundID >= g_Level.SoundMap.size())
return false;
if (BASS_GetDevice() == -1)
return false;
- if (condition != SoundEnvironment::Always)
+ // Test if sound effect environment matches camera environment.
+ if (soundEnv != SoundEnvironment::Always)
{
- // Get current camera room's environment
- auto cameraCondition = TestEnvironment(ENV_FLAG_WATER, Camera.pos.RoomNumber) ? SoundEnvironment::Water : SoundEnvironment::Land;
-
- // Don't play effect if effect's environment isn't the same as camera position's environment
- if (condition != cameraCondition)
+ bool isCameraUnderwater = TestEnvironment(ENV_FLAG_WATER, Camera.pos.RoomNumber);
+ if ((soundEnv == SoundEnvironment::Underwater && !isCameraUnderwater) ||
+ (soundEnv != SoundEnvironment::Underwater && isCameraUnderwater))
+ {
return false;
+ }
}
- // Get actual sample index from SoundMap
- int sampleIndex = g_Level.SoundMap[effectID];
+ // Get actual sample index from sound map.
+ int sampleIndex = g_Level.SoundMap[soundID];
- // -1 means no such effect exists in level file.
- // We set it to -2 afterwards to prevent further debug message firings.
+ // -1 means no such effect exists in level file.Set to -2 afterwards to prevent further debug message firings.
if (sampleIndex == -1)
{
- TENLog("Missing sound effect: " + std::to_string(effectID), LogLevel::Warning);
- g_Level.SoundMap[effectID] = -2;
+ TENLog("Missing sound effect " + std::to_string(soundID), LogLevel::Warning);
+ g_Level.SoundMap[soundID] = -2;
return false;
}
else if (sampleIndex == -2)
+ {
return false;
+ }
- SampleInfo* sampleInfo = &g_Level.SoundDetails[sampleIndex];
-
- if (sampleInfo->Number < 0)
+ const auto& sample = g_Level.SoundDetails[sampleIndex];
+ if (sample.Number < 0)
{
TENLog("No valid samples count for effect " + std::to_string(sampleIndex), LogLevel::Warning);
return false;
@@ -196,77 +207,85 @@ bool SoundEffect(int effectID, Pose* position, SoundEnvironment condition, float
// Assign common sample flags.
DWORD sampleFlags = SOUND_SAMPLE_FLAGS;
- // Effect's chance to play.
- if ((sampleInfo->Randomness) && ((GetRandomControl() & UCHAR_MAX) > sampleInfo->Randomness))
+ // Test play chance.
+ if (sample.Randomness && ((GetRandomControl() & UCHAR_MAX) > sample.Randomness))
return false;
- // Apply 3D attrib only to sound with position property
- if (position)
+ // Apply 3D attribute only to sound with position property.
+ if (pose != nullptr)
sampleFlags |= BASS_SAMPLE_3D;
- // Set & randomize volume (if needed)
- float gain = (static_cast(sampleInfo->Volume) / UCHAR_MAX) * std::clamp(gainMultiplier, SOUND_MIN_PARAM_MULTIPLIER, SOUND_MAX_PARAM_MULTIPLIER);
- if ((sampleInfo->Flags & SOUND_FLAG_RND_GAIN))
- gain -= (static_cast(GetRandomControl()) / static_cast(RAND_MAX))* SOUND_MAX_GAIN_CHANGE;
+ // Set and randomize volume (if needed).
+ float gain = ((float)sample.Volume / UCHAR_MAX) * std::clamp(gainMult, SOUND_MIN_PARAM_MULTIPLIER, SOUND_MAX_PARAM_MULTIPLIER);
+ if ((sample.Flags & SOUND_FLAG_RND_GAIN))
+ gain -= Random::GenerateFloat(0.0f, 1.0f) * SOUND_MAX_GAIN_CHANGE;
- // Set and randomize pitch and additionally multiply by provided value (for vehicles etc)
- float pitch = (1.0f + static_cast(sampleInfo->Pitch) / 127.0f) * std::clamp(pitchMultiplier, SOUND_MIN_PARAM_MULTIPLIER, SOUND_MAX_PARAM_MULTIPLIER);
+ // Set and randomize pitch and additionally multiply by provided value (e.g. for vehicles).
+ float pitch = (1.0f + ((float)sample.Pitch / 127.0f)) * std::clamp(pitchMult, SOUND_MIN_PARAM_MULTIPLIER, SOUND_MAX_PARAM_MULTIPLIER);
// Randomize pitch (if needed)
- if ((sampleInfo->Flags & SOUND_FLAG_RND_PITCH))
- pitch += ((static_cast(GetRandomControl()) / static_cast(RAND_MAX)) - 0.5f) * SOUND_MAX_PITCH_CHANGE * 2.0f;
+ if ((sample.Flags & SOUND_FLAG_RND_PITCH))
+ pitch += Random::GenerateFloat(-0.5f, 0.5f) * (SOUND_MAX_PITCH_CHANGE * 2);
- // Calculate sound radius and distance to sound
- float radius = (float)(sampleInfo->Radius) * BLOCK(1);
- float distance = Sound_DistanceToListener(position);
+ // Calculate sound radius and distance to sound.
+ float radius = BLOCK(sample.Radius);
+ float dist = Sound_DistanceToListener(pose);
- // Don't play sound if it's too far from listener's position.
- if (distance > radius)
+ // Skip playing if too far from listener position.
+ if (dist > radius)
return false;
- // Get final volume of a sound.
- float volume = Sound_Attenuate(gain, distance, radius);
+ // Get final sound volume.
+ float volume = Sound_Attenuate(gain, dist, radius);
- // Get existing index, if any, of sound which is playing.
- int existingChannel = Sound_EffectIsPlaying(effectID, position);
+ // Get existing index, if any, of playing sound.
+ int existingChannel = Sound_EffectIsPlaying(soundID, pose);
- // Select behaviour based on effect playback type (bytes 0-1 of flags field)
- auto playType = (SoundPlayMode)(sampleInfo->Flags & 3);
- switch (playType)
+ // Select behaviour based on effect playback type (bytes 0-1 of flags field).
+ auto playMode = (SoundPlayMode)(sample.Flags & 3);
+ switch (playMode)
{
case SoundPlayMode::Normal:
break;
case SoundPlayMode::Wait:
- if (existingChannel != SOUND_NO_CHANNEL) // Don't play until stopped
+ // Don't play until stopped.
+ if (existingChannel != SOUND_NO_CHANNEL)
return false;
break;
case SoundPlayMode::Restart:
- if (existingChannel != SOUND_NO_CHANNEL) // Stop existing and continue
+ // Stop existing and continue.
+ if (existingChannel != SOUND_NO_CHANNEL)
Sound_FreeSlot(existingChannel, SOUND_XFADETIME_CUTSOUND);
break;
case SoundPlayMode::Looped:
- if (existingChannel != SOUND_NO_CHANNEL) // Just update parameters and return, if already playing
+ // Update parameters and return if already playing.
+ if (existingChannel != SOUND_NO_CHANNEL)
{
- Sound_UpdateEffectPosition(existingChannel, position);
+ Sound_UpdateEffectPosition(existingChannel, pose);
Sound_UpdateEffectAttributes(existingChannel, pitch, volume);
return false;
}
+
sampleFlags |= BASS_SAMPLE_LOOP;
break;
}
- // Randomly select arbitrary sample from the list, if more than one is present
+ // Randomly select arbitrary sample from list if more than one is present.
int sampleToPlay = 0;
- int numSamples = (sampleInfo->Flags >> 2) & 15;
- if (numSamples == 1)
- sampleToPlay = sampleInfo->Number;
+ int sampleCount = (sample.Flags >> 2) & 15;
+ if (sampleCount == 1)
+ {
+ sampleToPlay = sample.Number;
+ }
else
- sampleToPlay = sampleInfo->Number + (int)((GetRandomControl() * numSamples) >> 15);
+ {
+ sampleToPlay = sample.Number + (int)((GetRandomControl() * sampleCount) >> 15);
+ }
- // Get free channel to play sample
+ // Get free channel to play sample.
int freeSlot = Sound_GetFreeSlot();
if (freeSlot == SOUND_NO_CHANNEL)
{
@@ -280,32 +299,33 @@ bool SoundEffect(int effectID, Pose* position, SoundEnvironment condition, float
if (Sound_CheckBASSError("Trying to create channel for sample %d", false, sampleToPlay))
return false;
- // Finally ready to play sound, assign it to sound slot.
- SoundSlot[freeSlot].State = SoundState::Idle;
- SoundSlot[freeSlot].EffectID = effectID;
- SoundSlot[freeSlot].Channel = channel;
- SoundSlot[freeSlot].Gain = gain;
- SoundSlot[freeSlot].Origin = position ? Vector3(position->Position.x, position->Position.y, position->Position.z) : SOUND_OMNIPRESENT_ORIGIN;
+ // Ready to play sound; assign to sound slot.
+ auto& soundSlot = SoundSlot[freeSlot];
+ soundSlot.State = SoundState::Idle;
+ soundSlot.EffectID = soundID;
+ soundSlot.Channel = channel;
+ soundSlot.Gain = gain;
+ soundSlot.Origin = (pose != nullptr) ? pose->Position.ToVector3() : SOUND_OMNIPRESENT_ORIGIN;
if (Sound_CheckBASSError("Applying pitch/gain attribs on channel %x, sample %d", false, channel, sampleToPlay))
return false;
- // Set looped flag, if necessary
- if (playType == SoundPlayMode::Looped)
+ // Set looped flag if necessary.
+ if (playMode == SoundPlayMode::Looped)
BASS_ChannelFlags(channel, BASS_SAMPLE_LOOP, BASS_SAMPLE_LOOP);
- // Play channel
+ // Play channel.
BASS_ChannelPlay(channel, false);
if (Sound_CheckBASSError("Queuing channel %x on sample mixer", false, freeSlot))
return false;
- // Set attributes
- BASS_ChannelSet3DAttributes(channel, position ? BASS_3DMODE_NORMAL : BASS_3DMODE_OFF, SOUND_MAXVOL_RADIUS, radius, 360, 360, 0.0f);
- Sound_UpdateEffectPosition(freeSlot, position, true);
+ // Set attributes.
+ BASS_ChannelSet3DAttributes(channel, pose ? BASS_3DMODE_NORMAL : BASS_3DMODE_OFF, SOUND_MAXVOL_RADIUS, radius, 360, 360, 0.0f);
+ Sound_UpdateEffectPosition(freeSlot, pose, true);
Sound_UpdateEffectAttributes(freeSlot, pitch, volume);
- if (Sound_CheckBASSError("Applying 3D attribs on channel %x, sound %d", false, channel, effectID))
+ if (Sound_CheckBASSError("Applying 3D attribs on channel %x, sound %d", false, channel, soundID))
return false;
return true;
@@ -1070,24 +1090,19 @@ int GetShatterSound(int shatterID)
void PlaySoundSources()
{
- static constexpr int PLAY_ALWAYS = 0x8000;
- static constexpr int PLAY_BASE_ROOM = 0x4000;
- static constexpr int PLAY_FLIP_ROOM = 0x2000;
-
- for (size_t i = 0; i < g_Level.SoundSources.size(); i++)
+ for (const auto& soundSource : g_Level.SoundSources)
{
- const auto& sound = g_Level.SoundSources[i];
-
- int group = sound.Flags & 0x1FFF;
+ int group = soundSource.Flags & 0x1FFF;
if (group >= MAX_FLIPMAP)
continue;
- if (!FlipStats[group] && (sound.Flags & PLAY_FLIP_ROOM))
- continue;
- else if (FlipStats[group] && (sound.Flags & PLAY_BASE_ROOM))
+ if ((!FlipStats[group] && (soundSource.Flags & SS_FLAG_PLAY_FLIP_ROOM)) ||
+ (FlipStats[group] && (soundSource.Flags & SS_FLAG_PLAY_BASE_ROOM)))
+ {
continue;
+ }
- SoundEffect(sound.SoundID, (Pose*)&sound.Position);
+ SoundEffect(soundSource.SoundID, (Pose*)&soundSource.Position);
}
}
diff --git a/TombEngine/Sound/sound.h b/TombEngine/Sound/sound.h
index 8b70f7ea2..eb18997e9 100644
--- a/TombEngine/Sound/sound.h
+++ b/TombEngine/Sound/sound.h
@@ -48,9 +48,11 @@ enum class SoundTrackType
enum class SoundEnvironment
{
+ Always,
Land,
- Water,
- Always
+ ShallowWater,
+ Swamp,
+ Underwater
};
enum class SoundPlayMode
@@ -121,9 +123,9 @@ struct SoundTrackInfo
struct SoundSourceInfo
{
Vector3i Position = Vector3i::Zero;
- int SoundID = 0;
- int Flags = 0;
- std::string Name {};
+ int SoundID = 0;
+ int Flags = 0;
+ std::string Name = {};
SoundSourceInfo()
{
@@ -131,27 +133,27 @@ struct SoundSourceInfo
SoundSourceInfo(int xPos, int yPos, int zPos)
{
- this->Position = Vector3i(xPos, yPos, zPos);
+ Position = Vector3i(xPos, yPos, zPos);
}
SoundSourceInfo(int xPos, int yPos, int zPos, short soundID)
{
- this->Position = Vector3i(xPos, yPos, zPos);
- this->SoundID = soundID;
+ Position = Vector3i(xPos, yPos, zPos);
+ SoundID = soundID;
}
SoundSourceInfo(int xPos, int yPos, int zPos, short soundID, short newflags)
{
- this->Position = Vector3i(xPos, yPos, zPos);
- this->SoundID = soundID;
- this->Flags = newflags;
+ Position = Vector3i(xPos, yPos, zPos);
+ SoundID = soundID;
+ Flags = newflags;
}
};
extern std::map