#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); } }