mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-22 04:32:49 +00:00
feat: switch trigger physics volumes on and off at runtime
The ActivatePhysics trigger command was a TODO. The client activates or deactivates the object's physics component (LWOPhysicsSystemComponent::msgActivatePhysics, 1.10.64 0x00ccf970); the server now does the same to phantom physics: switching it off takes the volume out of the physics world (dpWorld::DetachEntity, without deleting it) and makes whatever was inside leave, switching it on adds it back and whatever is inside enters on the next step. This lets trigger driven volumes like the monument lasers turn on and off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -57,6 +57,9 @@ public:
|
||||
|
||||
void PreUpdate() { m_NewObjects.clear(); m_RemovedObjects.clear(); }
|
||||
|
||||
// Forgets everything it touches (it was taken out of the world)
|
||||
void ClearCollisions() { m_NewObjects.clear(); m_RemovedObjects.clear(); m_CurrentlyCollidingObjects.clear(); }
|
||||
|
||||
const LWOOBJID& GetObjectID() const { return m_ObjectID; }
|
||||
|
||||
void SetGrid(dpGrid* grid);
|
||||
|
||||
@@ -73,6 +73,12 @@ void dpGrid::Move(dpEntity* entity, float x, float z) {
|
||||
}
|
||||
|
||||
void dpGrid::Delete(dpEntity* entity) {
|
||||
if (!entity) return;
|
||||
Remove(entity);
|
||||
delete entity;
|
||||
}
|
||||
|
||||
void dpGrid::Remove(dpEntity* entity) {
|
||||
if (!entity) return;
|
||||
int oldCellX = static_cast<int>(std::round(entity->m_Position.x)) / dpGrid::CELL_SIZE + NUM_CELLS / 2;
|
||||
int oldCellZ = static_cast<int>(std::round(entity->m_Position.z)) / dpGrid::CELL_SIZE + NUM_CELLS / 2;
|
||||
@@ -88,10 +94,11 @@ void dpGrid::Delete(dpEntity* entity) {
|
||||
cell.pop_back();
|
||||
}
|
||||
|
||||
m_GargantuanObjects.erase(entity->m_ObjectID);
|
||||
const auto gargantuan = m_GargantuanObjects.find(entity->m_ObjectID);
|
||||
if (gargantuan != m_GargantuanObjects.end() && gargantuan->second == entity) m_GargantuanObjects.erase(gargantuan);
|
||||
|
||||
if (entity) delete entity;
|
||||
entity = nullptr;
|
||||
// Out of the grid: moving it mustn't put it back into a cell
|
||||
entity->m_Grid = nullptr;
|
||||
}
|
||||
|
||||
void dpGrid::Update(float deltaTime) {
|
||||
|
||||
@@ -20,6 +20,11 @@ public:
|
||||
void Move(dpEntity* entity, float x, float z);
|
||||
void Delete(dpEntity* entity);
|
||||
|
||||
/**
|
||||
* Takes an entity out of the grid without deleting it
|
||||
*/
|
||||
void Remove(dpEntity* entity);
|
||||
|
||||
void Update(float deltaTime);
|
||||
|
||||
/**
|
||||
|
||||
@@ -128,6 +128,20 @@ void dpWorld::AddEntity(dpEntity* entity) {
|
||||
}
|
||||
}
|
||||
|
||||
void dpWorld::DetachEntity(dpEntity* entity) {
|
||||
if (!entity) return;
|
||||
|
||||
if (m_Grid) {
|
||||
m_Grid->Remove(entity);
|
||||
return;
|
||||
}
|
||||
|
||||
auto& entities = entity->GetIsStatic() ? m_StaticEntities : m_DynamicEntites;
|
||||
for (auto& other : entities) {
|
||||
if (other == entity) other = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void dpWorld::RemoveEntity(dpEntity* entity) {
|
||||
if (!entity) return;
|
||||
|
||||
|
||||
@@ -18,5 +18,10 @@ namespace dpWorld {
|
||||
void AddEntity(dpEntity* entity);
|
||||
void RemoveEntity(dpEntity* entity);
|
||||
|
||||
/**
|
||||
* Takes an entity out of the world without deleting it, so it can be added back later (a volume switched off)
|
||||
*/
|
||||
void DetachEntity(dpEntity* entity);
|
||||
|
||||
dNavMesh* GetNavMesh();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user