mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-06-26 16:44:21 +00:00
Add type field for links in flash Add warning level for dangerous buttons fix uninitialzied memory with jetpack variable remove a bunch of duplicated position push code tested that the ui is still functional and components with multiple physics components have all their details visible. tested that jetpack is initialized now
258 lines
7.5 KiB
C++
258 lines
7.5 KiB
C++
/*
|
|
* Darkflame Universe
|
|
* Copyright 2018
|
|
*/
|
|
|
|
#include <sstream>
|
|
#include <iostream>
|
|
|
|
#include "PhantomPhysicsComponent.h"
|
|
#include "Game.h"
|
|
#include "LDFFormat.h"
|
|
#include "Logger.h"
|
|
#include "Entity.h"
|
|
#include "EntityManager.h"
|
|
#include "ControllablePhysicsComponent.h"
|
|
#include "GameMessages.h"
|
|
#include "ePhysicsEffectType.h"
|
|
|
|
#include "CDClientManager.h"
|
|
#include "CDComponentsRegistryTable.h"
|
|
#include "CDPhysicsComponentTable.h"
|
|
#include "dServer.h"
|
|
#include "EntityInfo.h"
|
|
#include "Amf3.h"
|
|
|
|
#include "dpWorld.h"
|
|
#include "dpEntity.h"
|
|
#include "dpShapeBox.h"
|
|
#include "dpShapeSphere.h"
|
|
|
|
PhantomPhysicsComponent::PhantomPhysicsComponent(Entity* parent, const int32_t componentID) : PhysicsComponent(parent, componentID) {
|
|
RegisterMsg(&PhantomPhysicsComponent::OnGetObjectReportInfo);
|
|
|
|
m_Position = m_Parent->GetDefaultPosition();
|
|
m_Rotation = m_Parent->GetDefaultRotation();
|
|
m_Scale = m_Parent->GetDefaultScale();
|
|
m_dpEntity = nullptr;
|
|
|
|
m_EffectInfoDirty = false;
|
|
|
|
m_IsPhysicsEffectActive = false;
|
|
m_EffectType = ePhysicsEffectType::PUSH;
|
|
m_DirectionalMultiplier = 0.0f;
|
|
|
|
m_MinMax = false;
|
|
m_Min = 0;
|
|
m_Max = 1;
|
|
|
|
m_IsDirectional = false;
|
|
m_Direction = NiPoint3(); // * m_DirectionalMultiplier
|
|
|
|
if (m_Parent->GetVar<bool>(u"create_physics")) {
|
|
m_dpEntity = CreatePhysicsLnv(m_Scale, ComponentType);
|
|
}
|
|
|
|
if (m_Parent->GetVar<bool>(u"respawnVol")) {
|
|
m_IsRespawnVolume = true;
|
|
}
|
|
|
|
if (m_IsRespawnVolume) {
|
|
const auto respawnPos = GeneralUtils::SplitString(m_Parent->GetVarAsString(u"rspPos"), '\x1f');
|
|
m_RespawnPos = GeneralUtils::TryParse(respawnPos, NiPoint3Constant::ZERO);
|
|
|
|
const auto respawnRot = GeneralUtils::SplitString(m_Parent->GetVarAsString(u"rspRot"), '\x1f');
|
|
m_RespawnRot = respawnRot.size() >= 4 ? NiQuaternion(
|
|
GeneralUtils::TryParse(respawnRot[0], 1.0f),
|
|
GeneralUtils::TryParse(respawnRot[1], 0.0f),
|
|
GeneralUtils::TryParse(respawnRot[2], 0.0f),
|
|
GeneralUtils::TryParse(respawnRot[3], 0.0f))
|
|
: QuatUtils::IDENTITY;
|
|
}
|
|
|
|
// HF - RespawnPoints. Legacy respawn entity.
|
|
if (m_Parent->GetLOT() == 4945) {
|
|
m_IsRespawnVolume = true;
|
|
m_RespawnPos = m_Position;
|
|
m_RespawnRot = m_Rotation;
|
|
}
|
|
|
|
if (!m_dpEntity) {
|
|
m_dpEntity = CreatePhysicsEntity(ComponentType);
|
|
if (!m_dpEntity) return;
|
|
m_dpEntity->SetScale(m_Scale);
|
|
m_dpEntity->SetRotation(m_Rotation);
|
|
m_dpEntity->SetPosition(m_Position);
|
|
dpWorld::AddEntity(m_dpEntity);
|
|
}
|
|
}
|
|
|
|
PhantomPhysicsComponent::~PhantomPhysicsComponent() {
|
|
if (m_dpEntity) {
|
|
dpWorld::RemoveEntity(m_dpEntity);
|
|
}
|
|
}
|
|
|
|
void PhantomPhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
|
PhysicsComponent::Serialize(outBitStream, bIsInitialUpdate);
|
|
|
|
outBitStream.Write(m_EffectInfoDirty || bIsInitialUpdate);
|
|
if (m_EffectInfoDirty || bIsInitialUpdate) {
|
|
outBitStream.Write(m_IsPhysicsEffectActive);
|
|
|
|
if (m_IsPhysicsEffectActive) {
|
|
outBitStream.Write(m_EffectType);
|
|
outBitStream.Write(m_DirectionalMultiplier);
|
|
|
|
// forgive me father for i have sinned
|
|
outBitStream.Write0();
|
|
//outBitStream.Write(m_MinMax);
|
|
//if (m_MinMax) {
|
|
//outBitStream.Write(m_Min);
|
|
//outBitStream.Write(m_Max);
|
|
//}
|
|
|
|
outBitStream.Write(m_IsDirectional);
|
|
if (m_IsDirectional) {
|
|
outBitStream.Write(m_Direction.x);
|
|
outBitStream.Write(m_Direction.y);
|
|
outBitStream.Write(m_Direction.z);
|
|
}
|
|
}
|
|
|
|
m_EffectInfoDirty = false;
|
|
}
|
|
}
|
|
|
|
// Even if we were to implement Friction server side,
|
|
// it also defaults to 1.0f in the last argument, so we dont need two functions to do the same thing.
|
|
void ApplyCollisionEffect(const LWOOBJID& target, const ePhysicsEffectType effectType, const float effectScale) {
|
|
switch (effectType) {
|
|
case ePhysicsEffectType::GRAVITY_SCALE: {
|
|
auto* targetEntity = Game::entityManager->GetEntity(target);
|
|
if (targetEntity) {
|
|
auto* controllablePhysicsComponent = targetEntity->GetComponent<ControllablePhysicsComponent>();
|
|
// dont want to apply an effect to nothing.
|
|
if (!controllablePhysicsComponent) return;
|
|
controllablePhysicsComponent->SetGravityScale(effectScale);
|
|
GameMessages::SendSetGravityScale(target, effectScale, targetEntity->GetSystemAddress());
|
|
}
|
|
break;
|
|
}
|
|
|
|
case ePhysicsEffectType::ATTRACT:
|
|
case ePhysicsEffectType::FRICTION:
|
|
case ePhysicsEffectType::PUSH:
|
|
case ePhysicsEffectType::REPULSE:
|
|
default:
|
|
break;
|
|
}
|
|
// The other types are not handled by the server and are here to handle all cases of the enum.
|
|
}
|
|
|
|
void PhantomPhysicsComponent::Update(float deltaTime) {
|
|
if (!m_dpEntity) return;
|
|
|
|
//Process enter events
|
|
for (const auto id : m_dpEntity->GetNewObjects()) {
|
|
ApplyCollisionEffect(id, m_EffectType, m_DirectionalMultiplier);
|
|
m_Parent->OnCollisionPhantom(id);
|
|
|
|
//If we are a respawn volume, inform the client:
|
|
if (m_IsRespawnVolume) {
|
|
auto* const entity = Game::entityManager->GetEntity(id);
|
|
|
|
if (entity) {
|
|
GameMessages::SendPlayerReachedRespawnCheckpoint(entity, m_RespawnPos, m_RespawnRot);
|
|
entity->SetRespawnPos(m_RespawnPos);
|
|
entity->SetRespawnRot(m_RespawnRot);
|
|
}
|
|
}
|
|
}
|
|
|
|
//Process exit events
|
|
for (const auto id : m_dpEntity->GetRemovedObjects()) {
|
|
ApplyCollisionEffect(id, m_EffectType, 1.0f);
|
|
m_Parent->OnCollisionLeavePhantom(id);
|
|
}
|
|
}
|
|
|
|
void PhantomPhysicsComponent::SetDirection(const NiPoint3& pos) {
|
|
m_Direction = pos;
|
|
m_Direction.x *= m_DirectionalMultiplier;
|
|
m_Direction.y *= m_DirectionalMultiplier;
|
|
m_Direction.z *= m_DirectionalMultiplier;
|
|
|
|
m_EffectInfoDirty = true;
|
|
m_IsDirectional = true;
|
|
}
|
|
|
|
void PhantomPhysicsComponent::SpawnVertices() const {
|
|
if (!m_dpEntity) {
|
|
LOG("No dpEntity to spawn vertices for %llu:%i", m_Parent->GetObjectID(), m_Parent->GetLOT());
|
|
return;
|
|
}
|
|
PhysicsComponent::SpawnVertices(m_dpEntity);
|
|
}
|
|
|
|
void PhantomPhysicsComponent::SetDirectionalMultiplier(float mul) {
|
|
m_DirectionalMultiplier = mul;
|
|
m_EffectInfoDirty = true;
|
|
}
|
|
|
|
void PhantomPhysicsComponent::SetEffectType(ePhysicsEffectType type) {
|
|
m_EffectType = type;
|
|
m_EffectInfoDirty = true;
|
|
}
|
|
|
|
void PhantomPhysicsComponent::SetMin(uint32_t min) {
|
|
m_Min = min;
|
|
m_MinMax = true;
|
|
m_EffectInfoDirty = true;
|
|
}
|
|
|
|
void PhantomPhysicsComponent::SetMax(uint32_t max) {
|
|
m_Max = max;
|
|
m_MinMax = true;
|
|
m_EffectInfoDirty = true;
|
|
}
|
|
|
|
void PhantomPhysicsComponent::SetPosition(const NiPoint3& pos) {
|
|
PhysicsComponent::SetPosition(pos);
|
|
if (m_dpEntity) m_dpEntity->SetPosition(pos);
|
|
}
|
|
|
|
void PhantomPhysicsComponent::SetRotation(const NiQuaternion& rot) {
|
|
PhysicsComponent::SetRotation(rot);
|
|
if (m_dpEntity) m_dpEntity->SetRotation(rot);
|
|
}
|
|
|
|
bool PhantomPhysicsComponent::OnGetObjectReportInfo(GameMessages::GetObjectReportInfo& reportInfo) {
|
|
PhysicsComponent::OnGetObjectReportInfo(reportInfo);
|
|
if (!reportInfo.subCategory) {
|
|
return false;
|
|
}
|
|
auto& info = reportInfo.subCategory->PushDebug("Phantom Physics Info");
|
|
info.PushDebug<AMFDoubleValue>("Scale") = m_Scale;
|
|
info.PushDebug<AMFBoolValue>("Is Physics Effect Active") = m_IsPhysicsEffectActive;
|
|
info.PushDebug<AMFIntValue>("Effect Type") = static_cast<int>(m_EffectType);
|
|
info.PushDebug<AMFDoubleValue>("Directional Multiplier") = m_DirectionalMultiplier;
|
|
info.PushDebug<AMFBoolValue>("Is Directional") = m_IsDirectional;
|
|
auto& direction = info.PushDebug("Direction").PushDebug(m_Direction);
|
|
|
|
if (m_MinMax) {
|
|
auto& minMaxInfo = info.PushDebug("Min Max Info");
|
|
minMaxInfo.PushDebug<AMFIntValue>("Min") = m_Min;
|
|
minMaxInfo.PushDebug<AMFIntValue>("Max") = m_Max;
|
|
}
|
|
|
|
if (m_IsRespawnVolume) {
|
|
auto& respawnInfo = info.PushDebug("Respawn Info");
|
|
respawnInfo.PushDebug<AMFBoolValue>("Is Respawn Volume") = m_IsRespawnVolume;
|
|
respawnInfo.PushDebug("Respawn Position").PushDebug(m_RespawnPos);
|
|
respawnInfo.PushDebug("Respawn Rotation").PushDebug(m_RespawnRot);
|
|
}
|
|
|
|
return true;
|
|
}
|