mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-11-14 07:47:13 +00:00
Main's model behaviors (every rotation, DoDamage, OnTimer, OnStartup, MoveBackToStart, moves along the model's local axes), raw terrain reading with scene lookups and scene tools, property model and brick by brick fixes and the chat server's player count fix, merged onto this branch's structures: - game messages stay structs; the angular velocity messages join them and the handler sets a message's target - strips own their speed again and the block names, moves and rotations stay in the shared action table (PropertyBehaviorActions, which the dashboard's behavior player reads; it now lists rotations too) - the zone keeps reading its file through ZoneFile and takes the boundaries from it, then loads the raw terrain as main does; the old dNavigation terrain reader is gone - the show all response stays a struct and logs a player count mismatch as main does - the property management component tells models who sent a chat message Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
116 lines
4.6 KiB
C++
116 lines
4.6 KiB
C++
/*
|
|
* Darkflame Universe
|
|
* Copyright 2018
|
|
*/
|
|
|
|
#include "SimplePhysicsComponent.h"
|
|
#include "BitStream.h"
|
|
#include "Game.h"
|
|
#include "Logger.h"
|
|
#include "dpWorld.h"
|
|
#include "CDClientManager.h"
|
|
#include "CDPhysicsComponentTable.h"
|
|
|
|
#include "Entity.h"
|
|
#include "StringifiedEnum.h"
|
|
#include "Amf3.h"
|
|
#include "ObjectLoadState.h"
|
|
#include "PhantomPhysicsComponent.h"
|
|
|
|
SimplePhysicsComponent::SimplePhysicsComponent(Entity* parent, const int32_t componentID) : PhysicsComponent(parent, componentID) {
|
|
RegisterMsg(&SimplePhysicsComponent::OnGetAngularVelocity);
|
|
RegisterMsg(&SimplePhysicsComponent::OnSetAngularVelocity);
|
|
RegisterMsg(&SimplePhysicsComponent::OnGetObjectReportInfo);
|
|
|
|
m_Position = m_Parent->GetDefaultPosition();
|
|
m_Rotation = m_Parent->GetDefaultRotation();
|
|
}
|
|
|
|
// After the physics config: climbable type, motion type and the blocker
|
|
void SimplePhysicsComponent::LoadConfigData() {
|
|
PhysicsComponent::LoadConfigData();
|
|
|
|
const auto& climbable_type = m_Parent->GetVar<std::u16string>(u"climbable");
|
|
if (climbable_type == u"wall") {
|
|
SetClimbableType(eClimbableType::CLIMBABLE_TYPE_WALL);
|
|
} else if (climbable_type == u"ladder") {
|
|
SetClimbableType(eClimbableType::CLIMBABLE_TYPE_LADDER);
|
|
} else if (climbable_type == u"wallstick") {
|
|
SetClimbableType(eClimbableType::CLIMBABLE_TYPE_WALL_STICK);
|
|
} else {
|
|
SetClimbableType(eClimbableType::CLIMBABLE_TYPE_NOT);
|
|
}
|
|
// Without a motionType the object is fixed (live: Fixed on 38,970 of 40,786 constructions, never the invalid 0)
|
|
if (m_Parent->HasVar(u"motionType")) m_PhysicsMotionState = m_Parent->GetVarAs<uint32_t>(u"motionType");
|
|
|
|
// A fixed solid object can be a wall enemies walk into (an enemy only blocker, or a navmesh carver)
|
|
if (m_PhysicsMotionState == MOTION_TYPE_FIXED) RegisterMovementBlocker(eReplicaComponentType::SIMPLE_PHYSICS, true, m_Parent->GetDefaultScale());
|
|
}
|
|
|
|
SimplePhysicsComponent::~SimplePhysicsComponent() {
|
|
}
|
|
|
|
void SimplePhysicsComponent::Run(const float deltaTime) {
|
|
if (m_Velocity == NiPoint3Constant::ZERO) return;
|
|
m_Position += m_Velocity * deltaTime;
|
|
m_DirtyPosition = true;
|
|
Game::entityManager->SerializeEntity(m_Parent);
|
|
}
|
|
|
|
void SimplePhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
|
if (bIsInitialUpdate) {
|
|
outBitStream.Write(m_ClimbableType != eClimbableType::CLIMBABLE_TYPE_NOT);
|
|
outBitStream.Write(m_ClimbableType);
|
|
}
|
|
|
|
// Live left the velocity out of a fixed object's construction and wrote it for keyframed and dynamic ones.
|
|
const bool writeVelocity = bIsInitialUpdate
|
|
? m_PhysicsMotionState != MOTION_TYPE_FIXED || m_Velocity != NiPoint3Constant::ZERO || m_AngularVelocity != NiPoint3Constant::ZERO
|
|
: m_DirtyVelocity;
|
|
outBitStream.Write(writeVelocity);
|
|
if (writeVelocity) {
|
|
outBitStream.Write(m_Velocity);
|
|
outBitStream.Write(m_AngularVelocity);
|
|
}
|
|
if (writeVelocity || bIsInitialUpdate) m_DirtyVelocity = false;
|
|
|
|
// Physics motion state
|
|
outBitStream.Write(m_DirtyPhysicsMotionState || bIsInitialUpdate);
|
|
if (m_DirtyPhysicsMotionState || bIsInitialUpdate) {
|
|
outBitStream.Write<uint32_t>(m_PhysicsMotionState);
|
|
m_DirtyPhysicsMotionState = false;
|
|
}
|
|
PhysicsComponent::Serialize(outBitStream, bIsInitialUpdate);
|
|
}
|
|
|
|
uint32_t SimplePhysicsComponent::GetPhysicsMotionState() const {
|
|
return m_PhysicsMotionState;
|
|
}
|
|
|
|
void SimplePhysicsComponent::SetPhysicsMotionState(uint32_t value) {
|
|
m_DirtyPhysicsMotionState = m_PhysicsMotionState != value;
|
|
m_PhysicsMotionState = value;
|
|
}
|
|
|
|
bool SimplePhysicsComponent::OnGetObjectReportInfo(GameMessages::GetObjectReportInfo& reportInfo) {
|
|
PhysicsComponent::OnGetObjectReportInfo(reportInfo);
|
|
auto& info = reportInfo.subCategory->PushDebug("Simple Physics Info");
|
|
info.PushDebug("Velocity").PushDebug(m_Velocity);
|
|
info.PushDebug("Angular Velocity").PushDebug(m_AngularVelocity);
|
|
info.PushDebug<AMFIntValue>("Physics Motion State") = m_PhysicsMotionState;
|
|
info.PushDebug<AMFStringValue>("Climbable Type") = StringifiedEnum::ToString(m_ClimbableType).data();
|
|
return true;
|
|
}
|
|
|
|
void SimplePhysicsComponent::Allocator(Entity& entity, ObjectLoadState& state) {
|
|
const auto simplePhysicsComponentID = state.GetComponentID(eReplicaComponentType::SIMPLE_PHYSICS);
|
|
if (state.hasModelBehaviors) {
|
|
// LWOSimplePhysicsComponent::Allocator (0x0104ded0): left to the model case
|
|
if (simplePhysicsComponentID > 0) state.modelPhysicsComponentID = simplePhysicsComponentID;
|
|
} else if (simplePhysicsComponentID > 0) {
|
|
// state.markedAsPhantom makes its simple physics phantom physics (with the simple physics row)
|
|
if (state.markedAsPhantom) entity.AddComponent<PhantomPhysicsComponent>(simplePhysicsComponentID)->SetPhysicsEffectActive(false);
|
|
else entity.AddComponent<SimplePhysicsComponent>(simplePhysicsComponentID);
|
|
}
|
|
}
|