mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-11-14 07:47:13 +00:00
refactor(component): controllable physics places its object itself
Where an object starts (where the level put it) moves into ControllablePhysicsComponent::LoadConfigData, and where a character comes into the world (its save, then its respawn point, the target scene or the zone's spawn when it came from elsewhere) into LoadFromSaveData, out of Entity::Initialize. Same placement. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -341,40 +341,9 @@ void Entity::Initialize() {
|
||||
case eReplicaComponentType::CONTROLLABLE_PHYSICS: {
|
||||
const auto controllablePhysicsComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::CONTROLLABLE_PHYSICS);
|
||||
if (controllablePhysicsComponentID > 0) {
|
||||
// The component places it: where the level put an object, where a character's save and the zone put it
|
||||
auto* controllablePhysics = AddComponent<ControllablePhysicsComponent>(controllablePhysicsComponentID);
|
||||
|
||||
if (m_Character) {
|
||||
controllablePhysics->LoadFromSaveData(m_Character->GetXMLDoc());
|
||||
|
||||
const auto mapID = Game::server->GetZoneID();
|
||||
const auto& targetSceneName = m_Character->GetTargetScene();
|
||||
|
||||
//If we came from another zone, put us in the starting loc
|
||||
// Exception for Moon Base as you tend to spawn on the roof.
|
||||
// second exception if we have a specified targetScene since that would only be possible in a test map
|
||||
if (m_Character->GetZoneID() != Game::server->GetZoneID() || mapID == 1603 || !targetSceneName.empty()) {
|
||||
NiPoint3 pos;
|
||||
NiQuaternion rot = QuatUtils::IDENTITY;
|
||||
|
||||
auto* targetScene = Game::entityManager->GetSpawnPointEntity(targetSceneName);
|
||||
if (m_Character->HasBeenToWorld(mapID) && targetSceneName.empty()) {
|
||||
pos = m_Character->GetRespawnPoint(mapID);
|
||||
rot = Game::zoneManager->GetZone()->GetSpawnRot();
|
||||
} else if (targetScene != nullptr) {
|
||||
pos = targetScene->GetPosition();
|
||||
rot = targetScene->GetRotation();
|
||||
} else {
|
||||
pos = Game::zoneManager->GetZone()->GetSpawnPos();
|
||||
rot = Game::zoneManager->GetZone()->GetSpawnRot();
|
||||
}
|
||||
|
||||
controllablePhysics->SetPosition(pos);
|
||||
controllablePhysics->SetRotation(rot);
|
||||
}
|
||||
} else {
|
||||
controllablePhysics->SetPosition(m_DefaultPosition);
|
||||
controllablePhysics->SetRotation(m_DefaultRotation);
|
||||
}
|
||||
if (m_Character) controllablePhysics->LoadFromSaveData(m_Character->GetXMLDoc());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include "EntityManager.h"
|
||||
#include "Character.h"
|
||||
#include "dZoneManager.h"
|
||||
#include "dServer.h"
|
||||
#include "Zone.h"
|
||||
#include "LevelProgressionComponent.h"
|
||||
#include "eStateChangeType.h"
|
||||
#include "StringifiedEnum.h"
|
||||
@@ -55,6 +57,12 @@ ControllablePhysicsComponent::ControllablePhysicsComponent(Entity* entity, const
|
||||
void ControllablePhysicsComponent::LoadConfigData() {
|
||||
PhysicsComponent::LoadConfigData();
|
||||
|
||||
// An object that isn't a character starts where the level put it (a character's place comes with its save)
|
||||
if (!m_Parent->GetCharacter()) {
|
||||
SetPosition(m_Parent->GetDefaultPosition());
|
||||
SetRotation(m_Parent->GetDefaultRotation());
|
||||
}
|
||||
|
||||
if (m_Parent->GetLOT() != 1) // Other physics entities we care about will be added by BaseCombatAI
|
||||
return;
|
||||
|
||||
@@ -171,7 +179,42 @@ void ControllablePhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bo
|
||||
}
|
||||
}
|
||||
|
||||
// A character's save, then where it comes into this world
|
||||
void ControllablePhysicsComponent::LoadFromSaveData(const tinyxml2::XMLDocument& doc) {
|
||||
ReadSaveData(doc);
|
||||
PlaceCharacter();
|
||||
}
|
||||
|
||||
// If it came from another zone it starts at its respawn point, the target scene or the zone's spawn (Moon Base always:
|
||||
// the saved place tends to be on the roof; a target scene too: only possible in a test map)
|
||||
void ControllablePhysicsComponent::PlaceCharacter() {
|
||||
auto* const character = m_Parent->GetCharacter();
|
||||
if (!character) return;
|
||||
|
||||
const auto mapID = Game::server->GetZoneID();
|
||||
const auto& targetSceneName = character->GetTargetScene();
|
||||
if (character->GetZoneID() == Game::server->GetZoneID() && mapID != 1603 && targetSceneName.empty()) return;
|
||||
|
||||
NiPoint3 pos;
|
||||
NiQuaternion rot = QuatUtils::IDENTITY;
|
||||
|
||||
auto* targetScene = Game::entityManager->GetSpawnPointEntity(targetSceneName);
|
||||
if (character->HasBeenToWorld(mapID) && targetSceneName.empty()) {
|
||||
pos = character->GetRespawnPoint(mapID);
|
||||
rot = Game::zoneManager->GetZone()->GetSpawnRot();
|
||||
} else if (targetScene != nullptr) {
|
||||
pos = targetScene->GetPosition();
|
||||
rot = targetScene->GetRotation();
|
||||
} else {
|
||||
pos = Game::zoneManager->GetZone()->GetSpawnPos();
|
||||
rot = Game::zoneManager->GetZone()->GetSpawnRot();
|
||||
}
|
||||
|
||||
SetPosition(pos);
|
||||
SetRotation(rot);
|
||||
}
|
||||
|
||||
void ControllablePhysicsComponent::ReadSaveData(const tinyxml2::XMLDocument& doc) {
|
||||
auto* character = doc.FirstChildElement("obj")->FirstChildElement("char");
|
||||
if (!character) {
|
||||
LOG("Failed to find char tag!");
|
||||
|
||||
@@ -285,6 +285,10 @@ public:
|
||||
const bool GetImmuneToStunUseItem() { return m_ImmuneToStunUseItemCount > 0;};
|
||||
|
||||
private:
|
||||
// The save's physics state (LoadFromSaveData), then where the character comes into the world
|
||||
void ReadSaveData(const tinyxml2::XMLDocument& doc);
|
||||
void PlaceCharacter();
|
||||
|
||||
|
||||
bool OnGetObjectReportInfo(GameMessages::GetObjectReportInfo& reportInfo);
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user