remove singleton for dpWorld (#1427)

Removes the singleton inheritance from dpWorld.
Tested that crux prime, nimbus station, avant gardens and nexus tower still use navmeshes and physics and that physics volumes are still collided with.
This commit is contained in:
David Markowitz 2024-01-19 13:12:05 -08:00 committed by GitHub
parent ea5360cb99
commit 36f7b8a928
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 85 additions and 82 deletions

View File

@ -6,7 +6,6 @@
#include <string_view>
#include <vector>
#include "Singleton.h"
#include "dCommonVars.h"
#include "LDFFormat.h"

View File

@ -25,6 +25,7 @@
#include "Metrics.hpp"
#include "CDComponentsRegistryTable.h"
#include "CDPhysicsComponentTable.h"
#include "dNavMesh.h"
BaseCombatAIComponent::BaseCombatAIComponent(Entity* parent, const uint32_t id): Component(parent) {
m_Target = LWOOBJID_EMPTY;
@ -128,17 +129,17 @@ BaseCombatAIComponent::BaseCombatAIComponent(Entity* parent, const uint32_t id):
m_dpEntity->SetPosition(m_Parent->GetPosition());
m_dpEntityEnemy->SetPosition(m_Parent->GetPosition());
dpWorld::Instance().AddEntity(m_dpEntity);
dpWorld::Instance().AddEntity(m_dpEntityEnemy);
dpWorld::AddEntity(m_dpEntity);
dpWorld::AddEntity(m_dpEntityEnemy);
}
BaseCombatAIComponent::~BaseCombatAIComponent() {
if (m_dpEntity)
dpWorld::Instance().RemoveEntity(m_dpEntity);
dpWorld::RemoveEntity(m_dpEntity);
if (m_dpEntityEnemy)
dpWorld::Instance().RemoveEntity(m_dpEntityEnemy);
dpWorld::RemoveEntity(m_dpEntityEnemy);
}
void BaseCombatAIComponent::Update(const float deltaTime) {
@ -653,8 +654,8 @@ void BaseCombatAIComponent::Wander() {
auto destination = m_StartPosition + delta;
if (dpWorld::Instance().IsLoaded()) {
destination.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(destination);
if (dpWorld::IsLoaded()) {
destination.y = dpWorld::GetNavMesh()->GetHeightAtPoint(destination);
}
if (Vector3::DistanceSquared(destination, m_MovementAI->GetParent()->GetPosition()) < 2 * 2) {

View File

@ -57,13 +57,13 @@ ControllablePhysicsComponent::ControllablePhysicsComponent(Entity* entity) : Phy
float radius = 1.5f;
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), radius, false);
m_dpEntity->SetCollisionGroup(COLLISION_GROUP_DYNAMIC | COLLISION_GROUP_FRIENDLY);
dpWorld::Instance().AddEntity(m_dpEntity);
dpWorld::AddEntity(m_dpEntity);
}
}
ControllablePhysicsComponent::~ControllablePhysicsComponent() {
if (m_dpEntity) {
dpWorld::Instance().RemoveEntity(m_dpEntity);
dpWorld::RemoveEntity(m_dpEntity);
}
}

View File

@ -16,6 +16,8 @@
#include "CDComponentsRegistryTable.h"
#include "CDPhysicsComponentTable.h"
#include "dNavMesh.h"
namespace {
/**
* Cache of all lots and their respective speeds
@ -169,8 +171,8 @@ NiPoint3 MovementAIComponent::ApproximateLocation() const {
auto approximation = source + ((destination - source) * percentageToWaypoint);
if (dpWorld::Instance().IsLoaded()) {
approximation.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(approximation);
if (dpWorld::IsLoaded()) {
approximation.y = dpWorld::GetNavMesh()->GetHeightAtPoint(approximation);
}
return approximation;
@ -181,8 +183,8 @@ bool MovementAIComponent::Warp(const NiPoint3& point) {
NiPoint3 destination = point;
if (dpWorld::Instance().IsLoaded()) {
destination.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(point);
if (dpWorld::IsLoaded()) {
destination.y = dpWorld::GetNavMesh()->GetHeightAtPoint(point);
if (std::abs(destination.y - point.y) > 3) {
return false;
@ -302,8 +304,8 @@ void MovementAIComponent::SetDestination(const NiPoint3& destination) {
}
std::vector<NiPoint3> computedPath;
if (dpWorld::Instance().IsLoaded()) {
computedPath = dpWorld::Instance().GetNavMesh()->GetPath(m_Parent->GetPosition(), destination, m_Info.wanderSpeed);
if (dpWorld::IsLoaded()) {
computedPath = dpWorld::GetNavMesh()->GetPath(m_Parent->GetPosition(), destination, m_Info.wanderSpeed);
}
// Somehow failed
@ -328,8 +330,8 @@ void MovementAIComponent::SetDestination(const NiPoint3& destination) {
// Simply path
for (auto& point : computedPath) {
if (dpWorld::Instance().IsLoaded()) {
point.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(point);
if (dpWorld::IsLoaded()) {
point.y = dpWorld::GetNavMesh()->GetHeightAtPoint(point);
}
m_InterpolatedWaypoints.push_back(point);

View File

@ -30,6 +30,7 @@
#include "eObjectBits.h"
#include "eGameMasterLevel.h"
#include "eMissionState.h"
#include "dNavMesh.h"
std::unordered_map<LOT, PetComponent::PetPuzzleData> PetComponent::buildCache{};
std::unordered_map<LWOOBJID, LWOOBJID> PetComponent::currentActivities{};
@ -250,17 +251,17 @@ void PetComponent::OnUse(Entity* originator) {
NiPoint3 forward = NiQuaternion::LookAt(m_Parent->GetPosition(), originator->GetPosition()).GetForwardVector();
forward.y = 0;
if (dpWorld::Instance().IsLoaded()) {
if (dpWorld::IsLoaded()) {
NiPoint3 attempt = petPosition + forward * interactionDistance;
float y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(attempt);
float y = dpWorld::GetNavMesh()->GetHeightAtPoint(attempt);
while (std::abs(y - petPosition.y) > 4 && interactionDistance > 10) {
const NiPoint3 forward = m_Parent->GetRotation().GetForwardVector();
attempt = originatorPosition + forward * interactionDistance;
y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(attempt);
y = dpWorld::GetNavMesh()->GetHeightAtPoint(attempt);
interactionDistance -= 0.5f;
}
@ -812,8 +813,8 @@ void PetComponent::Wander() {
auto destination = m_StartPosition + delta;
if (dpWorld::Instance().IsLoaded()) {
destination.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(destination);
if (dpWorld::IsLoaded()) {
destination.y = dpWorld::GetNavMesh()->GetHeightAtPoint(destination);
}
if (Vector3::DistanceSquared(destination, m_MovementAI->GetParent()->GetPosition()) < 2 * 2) {

View File

@ -161,7 +161,7 @@ PhantomPhysicsComponent::PhantomPhysicsComponent(Entity* parent) : PhysicsCompon
m_dpEntity->SetRotation(m_Rotation);
m_dpEntity->SetPosition(m_Position);
dpWorld::Instance().AddEntity(m_dpEntity);
dpWorld::AddEntity(m_dpEntity);
} else if (info->physicsAsset == "miscellaneous\\misc_phys_640x640.hkx") {
// Move this down by 13.521004 units so it is still effectively at the same height as before
m_Position = m_Position - NiPoint3::UNIT_Y * 13.521004f;
@ -172,56 +172,56 @@ PhantomPhysicsComponent::PhantomPhysicsComponent(Entity* parent) : PhysicsCompon
m_dpEntity->SetRotation(m_Rotation);
m_dpEntity->SetPosition(m_Position);
dpWorld::Instance().AddEntity(m_dpEntity);
dpWorld::AddEntity(m_dpEntity);
} else if (info->physicsAsset == "env\\trigger_wall_tall.hkx") {
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 10.0f, 25.0f, 1.0f);
m_dpEntity->SetScale(m_Scale);
m_dpEntity->SetRotation(m_Rotation);
m_dpEntity->SetPosition(m_Position);
dpWorld::Instance().AddEntity(m_dpEntity);
dpWorld::AddEntity(m_dpEntity);
} else if (info->physicsAsset == "env\\env_gen_placeholderphysics.hkx") {
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 20.0f, 20.0f, 20.0f);
m_dpEntity->SetScale(m_Scale);
m_dpEntity->SetRotation(m_Rotation);
m_dpEntity->SetPosition(m_Position);
dpWorld::Instance().AddEntity(m_dpEntity);
dpWorld::AddEntity(m_dpEntity);
} else if (info->physicsAsset == "env\\POI_trigger_wall.hkx") {
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 1.0f, 12.5f, 20.0f); // Not sure what the real size is
m_dpEntity->SetScale(m_Scale);
m_dpEntity->SetRotation(m_Rotation);
m_dpEntity->SetPosition(m_Position);
dpWorld::Instance().AddEntity(m_dpEntity);
dpWorld::AddEntity(m_dpEntity);
} else if (info->physicsAsset == "env\\NG_NinjaGo\\env_ng_gen_gate_chamber_puzzle_ceiling_tile_falling_phantom.hkx") {
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 18.0f, 5.0f, 15.0f);
m_dpEntity->SetScale(m_Scale);
m_dpEntity->SetRotation(m_Rotation);
m_dpEntity->SetPosition(m_Position + m_Rotation.GetForwardVector() * 7.5f);
dpWorld::Instance().AddEntity(m_dpEntity);
dpWorld::AddEntity(m_dpEntity);
} else if (info->physicsAsset == "env\\NG_NinjaGo\\ng_flamejet_brick_phantom.HKX") {
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 1.0f, 1.0f, 12.0f);
m_dpEntity->SetScale(m_Scale);
m_dpEntity->SetRotation(m_Rotation);
m_dpEntity->SetPosition(m_Position + m_Rotation.GetForwardVector() * 6.0f);
dpWorld::Instance().AddEntity(m_dpEntity);
dpWorld::AddEntity(m_dpEntity);
} else if (info->physicsAsset == "env\\Ring_Trigger.hkx") {
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 6.0f, 6.0f, 6.0f);
m_dpEntity->SetScale(m_Scale);
m_dpEntity->SetRotation(m_Rotation);
m_dpEntity->SetPosition(m_Position);
dpWorld::Instance().AddEntity(m_dpEntity);
dpWorld::AddEntity(m_dpEntity);
} else if (info->physicsAsset == "env\\vfx_propertyImaginationBall.hkx") {
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 4.5f);
m_dpEntity->SetScale(m_Scale);
m_dpEntity->SetRotation(m_Rotation);
m_dpEntity->SetPosition(m_Position);
dpWorld::Instance().AddEntity(m_dpEntity);
dpWorld::AddEntity(m_dpEntity);
} else if (info->physicsAsset == "env\\env_won_fv_gas-blocking-volume.hkx") {
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 390.496826f, 111.467964f, 600.821534f, true);
m_dpEntity->SetScale(m_Scale);
m_dpEntity->SetRotation(m_Rotation);
m_Position.y -= (111.467964f * m_Scale) / 2;
m_dpEntity->SetPosition(m_Position);
dpWorld::Instance().AddEntity(m_dpEntity);
dpWorld::AddEntity(m_dpEntity);
} else {
//LOG("This one is supposed to have %s", info->physicsAsset.c_str());
@ -230,7 +230,7 @@ PhantomPhysicsComponent::PhantomPhysicsComponent(Entity* parent) : PhysicsCompon
m_dpEntity->SetScale(m_Scale);
m_dpEntity->SetRotation(m_Rotation);
m_dpEntity->SetPosition(m_Position);
dpWorld::Instance().AddEntity(m_dpEntity);
dpWorld::AddEntity(m_dpEntity);
}
}
@ -238,7 +238,7 @@ PhantomPhysicsComponent::PhantomPhysicsComponent(Entity* parent) : PhysicsCompon
PhantomPhysicsComponent::~PhantomPhysicsComponent() {
if (m_dpEntity) {
dpWorld::Instance().RemoveEntity(m_dpEntity);
dpWorld::RemoveEntity(m_dpEntity);
}
}
@ -300,7 +300,7 @@ void PhantomPhysicsComponent::CreatePhysics() {
m_dpEntity->SetPosition({ m_Position.x, m_Position.y - (height / 2), m_Position.z });
dpWorld::Instance().AddEntity(m_dpEntity);
dpWorld::AddEntity(m_dpEntity);
m_HasCreatedPhysics = true;
}

View File

@ -18,7 +18,7 @@ ProximityMonitorComponent::~ProximityMonitorComponent() {
for (const auto& en : m_ProximitiesData) {
if (!en.second) continue;
dpWorld::Instance().RemoveEntity(en.second);
dpWorld::RemoveEntity(en.second);
}
m_ProximitiesData.clear();
@ -28,12 +28,12 @@ void ProximityMonitorComponent::SetProximityRadius(float proxRadius, const std::
dpEntity* en = new dpEntity(m_Parent->GetObjectID(), proxRadius);
en->SetPosition(m_Parent->GetPosition());
dpWorld::Instance().AddEntity(en);
dpWorld::AddEntity(en);
m_ProximitiesData.insert(std::make_pair(name, en));
}
void ProximityMonitorComponent::SetProximityRadius(dpEntity* entity, const std::string& name) {
dpWorld::Instance().AddEntity(entity);
dpWorld::AddEntity(entity);
entity->SetPosition(m_Parent->GetPosition());
m_ProximitiesData.insert(std::make_pair(name, entity));
}

View File

@ -88,6 +88,7 @@
#include "CDObjectsTable.h"
#include "CDZoneTableTable.h"
#include "ePlayerFlag.h"
#include "dNavMesh.h"
void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entity* entity, const SystemAddress& sysAddr) {
auto commandCopy = command;
@ -768,7 +769,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
auto control = static_cast<ControllablePhysicsComponent*>(entity->GetComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS));
if (!control) return;
float y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(control->GetPosition());
float y = dpWorld::GetNavMesh()->GetHeightAtPoint(control->GetPosition());
std::u16string msg = u"Navmesh height: " + (GeneralUtils::to_u16string(y));
ChatPackets::SendSystemMessage(sysAddr, msg);
}
@ -1737,7 +1738,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
if (chatCommand == "reloadconfig" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
Game::config->ReloadConfig();
VanityUtilities::SpawnVanity();
dpWorld::Instance().Reload();
dpWorld::Reload();
auto entities = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY);
for (auto entity : entities) {
auto* scriptedActivityComponent = entity->GetComponent<ScriptedActivityComponent>();

View File

@ -9,6 +9,21 @@
#include "Logger.h"
#include "dConfig.h"
#include "dNavMesh.h"
namespace {
dpGrid* m_Grid = nullptr;
dNavMesh* m_NavMesh = nullptr;
int32_t phys_sp_tilesize = 205;
int32_t phys_sp_tilecount = 12;
uint32_t m_ZoneID = 0;
std::vector<dpEntity*> m_StaticEntities;
std::vector<dpEntity*> m_DynamicEntites;
bool phys_spatial_partitioning = true;
};
void dpWorld::Initialize(unsigned int zoneID, bool generateNewNavMesh) {
const auto physSpTilecount = Game::config->GetValue("phys_sp_tilecount");
if (!physSpTilecount.empty()) GeneralUtils::TryParse(physSpTilecount, phys_sp_tilecount);
@ -51,7 +66,7 @@ void dpWorld::Reload() {
}
}
dpWorld::~dpWorld() {
void dpWorld::Shutdown() {
if (m_Grid) {
// Triple check this is true
m_Grid->SetDeleteGrid(true);
@ -65,6 +80,10 @@ dpWorld::~dpWorld() {
}
}
bool dpWorld::IsLoaded() {
return m_NavMesh->GetdtNavMesh() != nullptr;
}
void dpWorld::StepWorld(float deltaTime) {
if (m_Grid) {
m_Grid->Update(deltaTime);
@ -91,6 +110,10 @@ void dpWorld::StepWorld(float deltaTime) {
}
}
dNavMesh* dpWorld::GetNavMesh() {
return m_NavMesh;
}
void dpWorld::AddEntity(dpEntity* entity) {
if (m_Grid) entity->SetGrid(m_Grid); //This sorts this entity into the right cell
else { //old method, slow
@ -125,7 +148,7 @@ void dpWorld::RemoveEntity(dpEntity* entity) {
}
}
bool dpWorld::ShouldUseSP(unsigned int zoneID) {
bool dpWorld::ShouldUseSP(uint32_t zoneID) {
if (!phys_spatial_partitioning) return false;
// TODO: Add to this list as needed.

View File

@ -1,48 +1,22 @@
#pragma once
#include "Singleton.h"
#include <cstdint>
//Navmesh includes:
#include "Recast.h"
#include "DetourNavMesh.h"
#include "DetourNavMeshBuilder.h"
#include "DetourNavMeshQuery.h"
#include <vector>
#include <map>
#include "dNavMesh.h"
class NiPoint3;
class dNavMesh;
class dpEntity;
class dpGrid;
class dpWorld : public Singleton<dpWorld> {
public:
void Initialize(unsigned int zoneID, bool generateNewNavMesh = true);
namespace dpWorld {
void Initialize(uint32_t zoneID, bool generateNewNavMesh = true);
void Shutdown();
void Reload();
~dpWorld();
bool ShouldUseSP(unsigned int zoneID);
bool IsLoaded() const { return m_NavMesh->GetdtNavMesh() != nullptr; }
bool ShouldUseSP(uint32_t zoneID);
bool IsLoaded();
void StepWorld(float deltaTime);
void AddEntity(dpEntity* entity);
void RemoveEntity(dpEntity* entity);
dNavMesh* GetNavMesh() { return m_NavMesh; }
private:
dpGrid* m_Grid;
bool phys_spatial_partitioning = true;
int phys_sp_tilesize = 205;
int phys_sp_tilecount = 12;
std::vector<dpEntity*> m_StaticEntities;
std::vector<dpEntity*> m_DynamicEntites;
dNavMesh* m_NavMesh = nullptr;
uint32_t m_ZoneID = 0;
dNavMesh* GetNavMesh();
};

View File

@ -7,6 +7,7 @@
#include "GeneralUtils.h"
#include "DestroyableComponent.h"
#include "eReplicaComponentType.h"
#include "dNavMesh.h"
void BaseEnemyMech::OnStartup(Entity* self) {
auto* destroyableComponent = self->GetComponent<DestroyableComponent>();
@ -19,7 +20,7 @@ void BaseEnemyMech::OnDie(Entity* self, Entity* killer) {
ControllablePhysicsComponent* controlPhys = static_cast<ControllablePhysicsComponent*>(self->GetComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS));
if (!controlPhys) return;
NiPoint3 newLoc = { controlPhys->GetPosition().x, dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(controlPhys->GetPosition()), controlPhys->GetPosition().z };
NiPoint3 newLoc = { controlPhys->GetPosition().x, dpWorld::GetNavMesh()->GetHeightAtPoint(controlPhys->GetPosition()), controlPhys->GetPosition().z };
EntityInfo info = EntityInfo();
std::vector<LDFBaseData*> cfg;

View File

@ -84,7 +84,6 @@
namespace Game {
Logger* logger = nullptr;
dServer* server = nullptr;
dpWorld* physicsWorld = nullptr;
dChatFilter* chatFilter = nullptr;
dConfig* config = nullptr;
AssetManager* assetManager = nullptr;
@ -257,7 +256,7 @@ int main(int argc, char** argv) {
Game::zoneManager = new dZoneManager();
//Load our level:
if (zoneID != 0) {
dpWorld::Instance().Initialize(zoneID);
dpWorld::Initialize(zoneID);
Game::zoneManager->Initialize(LWOZONEID(zoneID, instanceID, cloneID));
g_CloneID = cloneID;
@ -388,7 +387,7 @@ int main(int argc, char** argv) {
if (zoneID != 0 && deltaTime > 0.0f) {
Metrics::StartMeasurement(MetricVariable::Physics);
dpWorld::Instance().StepWorld(deltaTime);
dpWorld::StepWorld(deltaTime);
Metrics::EndMeasurement(MetricVariable::Physics);
Metrics::StartMeasurement(MetricVariable::UpdateEntities);
@ -1439,6 +1438,7 @@ void FinalizeShutdown() {
//Delete our objects here:
Metrics::Clear();
dpWorld::Shutdown();
Database::Destroy("WorldServer");
if (Game::chatFilter) delete Game::chatFilter;
Game::chatFilter = nullptr;

View File

@ -17,6 +17,7 @@
#include "eTriggerCommandType.h"
#include "eTriggerEventType.h"
#include "dNavMesh.h"
Zone::Zone(const LWOMAPID& mapID, const LWOINSTANCEID& instanceID, const LWOCLONEID& cloneID) :
m_ZoneID(mapID, instanceID, cloneID) {
@ -463,9 +464,9 @@ void Zone::LoadPath(std::istream& file) {
// We verify the waypoint heights against the navmesh because in many movement paths,
// the waypoint is located near 0 height,
if (path.pathType == PathType::Movement) {
if (dpWorld::Instance().IsLoaded()) {
if (dpWorld::IsLoaded()) {
// 2000 should be large enough for every world.
waypoint.position.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(waypoint.position, 2000.0f);
waypoint.position.y = dpWorld::GetNavMesh()->GetHeightAtPoint(waypoint.position, 2000.0f);
}
}
path.pathWaypoints.push_back(waypoint);