mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-05-03 10:17:59 +03:00
125 lines
3.3 KiB
C++
125 lines
3.3 KiB
C++
#include "framework.h"
|
|
#include "Game/control/volume.h"
|
|
|
|
#include "Game/animation.h"
|
|
#include "Game/items.h"
|
|
#include "Game/Lara/lara.h"
|
|
#include "Game/room.h"
|
|
#include "Game/savegame.h"
|
|
#include "Specific/setup.h"
|
|
#include "Renderer/Renderer11Enums.h"
|
|
#include "Renderer/Renderer11.h"
|
|
|
|
|
|
using TEN::Renderer::g_Renderer;
|
|
|
|
namespace TEN::Control::Volumes
|
|
{
|
|
constexpr auto CAM_SIZE = 32;
|
|
|
|
int CurrentCollidedVolume;
|
|
|
|
void TestVolumes(short roomNumber, BoundingOrientedBox bbox, TriggerVolumeActivators activatorType)
|
|
{
|
|
CurrentCollidedVolume = 0;
|
|
|
|
auto* room = &g_Level.Rooms[roomNumber];
|
|
|
|
for (size_t i = 0; i < room->triggerVolumes.size(); i++)
|
|
{
|
|
auto* volume = &room->triggerVolumes[i];
|
|
|
|
if ((volume->Activators & activatorType) != activatorType)
|
|
continue;
|
|
|
|
bool contains = false;
|
|
|
|
switch (volume->Type)
|
|
{
|
|
case TriggerVolumeType::Box:
|
|
if (roomNumber == Camera.pos.roomNumber)
|
|
g_Renderer.addDebugBox(volume->Box, Vector4(1.0f, 0.0f, 1.0f, 1.0f), RENDERER_DEBUG_PAGE::LOGIC_STATS);
|
|
|
|
contains = volume->Box.Intersects(bbox);
|
|
break;
|
|
|
|
case TriggerVolumeType::Sphere:
|
|
if (roomNumber == Camera.pos.roomNumber)
|
|
g_Renderer.addDebugSphere(volume->Sphere.Center, volume->Sphere.Radius, Vector4(1.0f, 0.0f, 1.0f, 1.0f), RENDERER_DEBUG_PAGE::LOGIC_STATS);
|
|
|
|
contains = volume->Sphere.Intersects(bbox);
|
|
break;
|
|
}
|
|
|
|
// TODO: Implement checks on which item is entering/inside/leaving volume
|
|
// and pass item name or ID as argument for Lua function, so it knows its caller.
|
|
|
|
if (contains)
|
|
{
|
|
CurrentCollidedVolume = i + 1;
|
|
|
|
if (volume->Status == TriggerStatus::Outside)
|
|
{
|
|
volume->Status = TriggerStatus::Entering;
|
|
|
|
if (!volume->OnEnter.empty())
|
|
g_GameScript->ExecuteFunction(volume->OnEnter);
|
|
}
|
|
else
|
|
{
|
|
volume->Status = TriggerStatus::Inside;
|
|
|
|
if (!volume->OnInside.empty())
|
|
g_GameScript->ExecuteFunction(volume->OnInside);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (volume->Status == TriggerStatus::Inside)
|
|
{
|
|
volume->Status = TriggerStatus::Leaving;
|
|
|
|
if (!volume->OnLeave.empty())
|
|
g_GameScript->ExecuteFunction(volume->OnLeave);
|
|
}
|
|
else
|
|
volume->Status = TriggerStatus::Outside;
|
|
}
|
|
}
|
|
}
|
|
|
|
void TestVolumes(CAMERA_INFO* camera)
|
|
{
|
|
auto pos = PHD_3DPOS(camera->pos.x, camera->pos.y, camera->pos.z, 0, 0, 0);
|
|
auto box = BOUNDING_BOX();
|
|
box.X1 = box.Y1 = box.Z1 = CAM_SIZE;
|
|
box.X2 = box.Y2 = box.Z2 = -CAM_SIZE;
|
|
|
|
auto bbox = TO_DX_BBOX(pos, &box);
|
|
TestVolumes(camera->pos.roomNumber, bbox, TriggerVolumeActivators::Flyby);
|
|
}
|
|
|
|
void TestVolumes(short roomNumber, MESH_INFO* mesh)
|
|
{
|
|
auto* staticInfo = &StaticObjects[mesh->staticNumber];
|
|
auto bbox = TO_DX_BBOX(mesh->pos, &staticInfo->collisionBox);
|
|
|
|
TestVolumes(roomNumber, bbox, TriggerVolumeActivators::Static);
|
|
}
|
|
|
|
void TestVolumes(ITEM_INFO* item)
|
|
{
|
|
auto bbox = TO_DX_BBOX(item->Position, GetBoundsAccurate(item));
|
|
|
|
#ifdef _DEBUG
|
|
g_Renderer.addDebugBox(bbox, Vector4(1.0f, 1.0f, 0.0f, 1.0f), RENDERER_DEBUG_PAGE::LOGIC_STATS);
|
|
#endif
|
|
|
|
if (item->ObjectNumber == ID_LARA)
|
|
TestVolumes(item->RoomNumber, bbox, TriggerVolumeActivators::Player);
|
|
else if (Objects[item->ObjectNumber].intelligent)
|
|
TestVolumes(item->RoomNumber, bbox, TriggerVolumeActivators::NPC);
|
|
else
|
|
TestVolumes(item->RoomNumber, bbox, TriggerVolumeActivators::Movable);
|
|
}
|
|
}
|