mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-19 11:12: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:
@@ -87,9 +87,31 @@ PhantomPhysicsComponent::PhantomPhysicsComponent(Entity* parent, const int32_t c
|
||||
}
|
||||
}
|
||||
|
||||
void ApplyCollisionEffect(const LWOOBJID& target, const ePhysicsEffectType effectType, const float effectScale);
|
||||
|
||||
PhantomPhysicsComponent::~PhantomPhysicsComponent() {
|
||||
if (m_dpEntity) {
|
||||
dpWorld::RemoveEntity(m_dpEntity);
|
||||
if (!m_dpEntity) return;
|
||||
|
||||
if (m_PhysicsActive) dpWorld::RemoveEntity(m_dpEntity);
|
||||
else delete m_dpEntity;
|
||||
}
|
||||
|
||||
void PhantomPhysicsComponent::SetPhysicsActive(const bool active) {
|
||||
if (!m_dpEntity || m_PhysicsActive == active) return;
|
||||
m_PhysicsActive = active;
|
||||
|
||||
if (active) {
|
||||
// Anything already inside enters on the next physics step
|
||||
dpWorld::AddEntity(m_dpEntity);
|
||||
return;
|
||||
}
|
||||
|
||||
dpWorld::DetachEntity(m_dpEntity);
|
||||
const std::vector<LWOOBJID> inside(m_dpEntity->GetCurrentlyCollidingObjects().begin(), m_dpEntity->GetCurrentlyCollidingObjects().end());
|
||||
m_dpEntity->ClearCollisions();
|
||||
for (const auto id : inside) {
|
||||
ApplyCollisionEffect(id, m_EffectType, 1.0f);
|
||||
m_Parent->OnCollisionLeavePhantom(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +173,7 @@ void ApplyCollisionEffect(const LWOOBJID& target, const ePhysicsEffectType effec
|
||||
}
|
||||
|
||||
void PhantomPhysicsComponent::Update(float deltaTime) {
|
||||
if (!m_dpEntity) return;
|
||||
if (!m_dpEntity || !m_PhysicsActive) return;
|
||||
|
||||
//Process enter events
|
||||
for (const auto id : m_dpEntity->GetNewObjects()) {
|
||||
|
||||
@@ -99,6 +99,14 @@ public:
|
||||
|
||||
dpEntity* GetdpEntity() const { return m_dpEntity; }
|
||||
|
||||
/**
|
||||
* Switches the volume on or off (the ActivatePhysics trigger command; the client activates or deactivates
|
||||
* the physics component the same way). Whatever was inside leaves when it is switched off.
|
||||
*/
|
||||
void SetPhysicsActive(bool active);
|
||||
|
||||
bool GetPhysicsActive() const { return m_PhysicsActive; }
|
||||
|
||||
/**
|
||||
* Spawns an object at each of the vertices for debugging purposes
|
||||
*/
|
||||
@@ -161,6 +169,9 @@ private:
|
||||
*/
|
||||
dpEntity* m_dpEntity;
|
||||
|
||||
// Whether m_dpEntity is in the physics world
|
||||
bool m_PhysicsActive = true;
|
||||
|
||||
/**
|
||||
* Whether or not this physics object represents an object that updates the respawn pos of an entity that crosses it
|
||||
*/
|
||||
|
||||
@@ -467,13 +467,18 @@ void TriggerComponent::HandleDestroySpawnerNetworkObjects(std::string args) {
|
||||
}
|
||||
|
||||
void TriggerComponent::HandleActivatePhysics(Entity* targetEntity, std::string args) {
|
||||
if (args == "true") {
|
||||
// TODO add physics entity if there isn't one
|
||||
} else if (args == "false") {
|
||||
// TODO remove Phsyics entity if there is one
|
||||
} else {
|
||||
if (args != "true" && args != "false") {
|
||||
LOG_DEBUG("Invalid argument for ActivatePhysics Trigger: %s", args.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
auto* const phantomPhysicsComponent = targetEntity->GetComponent<PhantomPhysicsComponent>();
|
||||
if (!phantomPhysicsComponent) {
|
||||
LOG_DEBUG("ActivatePhysics on %llu:%i which has no phantom physics", targetEntity->GetObjectID(), targetEntity->GetLOT());
|
||||
return;
|
||||
}
|
||||
|
||||
phantomPhysicsComponent->SetPhysicsActive(args == "true");
|
||||
}
|
||||
|
||||
void TriggerComponent::HandleSetPath(Entity* targetEntity, std::vector<std::string> argArray) {
|
||||
|
||||
Reference in New Issue
Block a user