mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-11-14 15:57:13 +00:00
refactor(component): the client's component lifecycle
Components get the client's per-component functions: LoadDataFromTemplate, PrepareConfigData, LoadConfigData, LoadFromSaveData, Startup, Run, OnEnterScope, OnLeaveScope, Preshutdown and Shutdown, called by the entity in the client's order. Update is renamed Run, LoadFromXml LoadFromSaveData and UpdateXml WriteSaveData. Nothing sent changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -217,6 +217,10 @@ Entity::~Entity() {
|
||||
CancelAllTimers();
|
||||
CancelCallbackTimers();
|
||||
|
||||
// The client's Preshutdown, then Shutdown, for every component before any is deleted
|
||||
for (auto* const component : m_Components | std::views::values) if (component) component->Preshutdown();
|
||||
for (auto* const component : m_Components | std::views::values) if (component) component->Shutdown();
|
||||
|
||||
for (auto& component : m_Components | std::views::values) {
|
||||
if (component) {
|
||||
delete component;
|
||||
@@ -309,7 +313,7 @@ void Entity::Initialize() {
|
||||
* Player components (the client makes them with the character, not from the registry)
|
||||
*/
|
||||
if (m_Character && m_Character->GetParentUser()) {
|
||||
AddComponent<MissionComponent>(-1)->LoadFromXml(m_Character->GetXMLDoc());
|
||||
AddComponent<MissionComponent>(-1)->LoadFromSaveData(m_Character->GetXMLDoc());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -347,7 +351,7 @@ void Entity::Initialize() {
|
||||
auto* controllablePhysics = AddComponent<ControllablePhysicsComponent>(controllablePhysicsComponentID);
|
||||
|
||||
if (m_Character) {
|
||||
controllablePhysics->LoadFromXml(m_Character->GetXMLDoc());
|
||||
controllablePhysics->LoadFromSaveData(m_Character->GetXMLDoc());
|
||||
|
||||
const auto mapID = Game::server->GetZoneID();
|
||||
const auto& targetSceneName = m_Character->GetTargetScene();
|
||||
@@ -430,7 +434,7 @@ void Entity::Initialize() {
|
||||
std::vector<CDDestructibleComponent> destCompData = destCompTable->Query([componentID](const CDDestructibleComponent& entry) { return (entry.id == componentID); });
|
||||
|
||||
if (m_Character) {
|
||||
comp->LoadFromXml(m_Character->GetXMLDoc());
|
||||
comp->LoadFromSaveData(m_Character->GetXMLDoc());
|
||||
} else {
|
||||
// extraInfo overrides. Client ORs the database smashable and the luz smashable.
|
||||
comp->SetIsSmashable(comp->GetIsSmashable() || isSmashable);
|
||||
@@ -519,14 +523,14 @@ void Entity::Initialize() {
|
||||
AddComponent<PossessorComponent>(characterID);
|
||||
|
||||
// load in the xml for the level
|
||||
AddComponent<LevelProgressionComponent>(characterID)->LoadFromXml(m_Character->GetXMLDoc());
|
||||
AddComponent<LevelProgressionComponent>(characterID)->LoadFromSaveData(m_Character->GetXMLDoc());
|
||||
|
||||
AddComponent<PlayerForcedMovementComponent>(characterID);
|
||||
|
||||
auto& systemAddress = m_Character->GetParentUser() ? m_Character->GetParentUser()->GetSystemAddress() : UNASSIGNED_SYSTEM_ADDRESS;
|
||||
AddComponent<CharacterComponent>(characterID, m_Character, systemAddress)->LoadFromXml(m_Character->GetXMLDoc());
|
||||
AddComponent<CharacterComponent>(characterID, m_Character, systemAddress)->LoadFromSaveData(m_Character->GetXMLDoc());
|
||||
|
||||
AddComponent<GhostComponent>(characterID)->LoadFromXml(m_Character->GetXMLDoc());
|
||||
AddComponent<GhostComponent>(characterID)->LoadFromSaveData(m_Character->GetXMLDoc());
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -670,7 +674,7 @@ void Entity::Initialize() {
|
||||
const auto skillID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SKILL, -1);
|
||||
if (skillID > -1 || m_Character) {
|
||||
auto* const skillComponent = AddComponent<SkillComponent>(skillID);
|
||||
if (m_Character) skillComponent->LoadFromXml(m_Character->GetXMLDoc());
|
||||
if (m_Character) skillComponent->LoadFromSaveData(m_Character->GetXMLDoc());
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1125,6 +1129,10 @@ void Entity::Initialize() {
|
||||
const auto triggerInfo = GetVarAsString(u"trigger_id");
|
||||
if (!triggerInfo.empty()) AddComponent<TriggerComponent>(-1, triggerInfo);
|
||||
|
||||
// Every component exists: the client's Startup step
|
||||
for (auto* const component : m_Components | std::views::values) if (component) component->Startup();
|
||||
m_ComponentsStarted = true;
|
||||
|
||||
// Hacky way to trigger these when the object has had a chance to get constructed
|
||||
AddCallbackTimer(0, [this]() {
|
||||
this->GetScript()->OnStartup(this);
|
||||
@@ -1186,6 +1194,14 @@ no_ghosting:
|
||||
}
|
||||
}
|
||||
|
||||
void Entity::OnEnterScope(Entity& player) {
|
||||
for (auto* const component : m_Components | std::views::values) if (component) component->OnEnterScope(player);
|
||||
}
|
||||
|
||||
void Entity::OnLeaveScope(Entity& player) {
|
||||
for (auto* const component : m_Components | std::views::values) if (component) component->OnLeaveScope(player);
|
||||
}
|
||||
|
||||
bool Entity::operator==(const Entity& other) const {
|
||||
return other.m_ObjectID == m_ObjectID;
|
||||
}
|
||||
@@ -1436,7 +1452,7 @@ void Entity::UpdateXMLDoc(tinyxml2::XMLDocument& doc) {
|
||||
for (const auto& component : m_Components | std::views::values) {
|
||||
if (!component) continue;
|
||||
|
||||
component->UpdateXml(doc);
|
||||
component->WriteSaveData(doc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1516,7 +1532,7 @@ void Entity::Update(const float deltaTime) {
|
||||
for (const auto& component : m_Components | std::views::values) {
|
||||
if (!component) continue;
|
||||
|
||||
component->Update(deltaTime);
|
||||
component->Run(deltaTime);
|
||||
}
|
||||
|
||||
if (m_ShouldDestroyAfterUpdate) {
|
||||
|
||||
@@ -229,6 +229,10 @@ public:
|
||||
void UpdateXMLDoc(tinyxml2::XMLDocument& doc);
|
||||
void Update(float deltaTime);
|
||||
|
||||
// A player starts or stops seeing this object: its components' OnEnterScope / OnLeaveScope
|
||||
void OnEnterScope(Entity& player);
|
||||
void OnLeaveScope(Entity& player);
|
||||
|
||||
// Events
|
||||
void OnCollisionProximity(LWOOBJID otherEntity, const std::string& proxName, const std::string& status);
|
||||
void OnCollisionPhantom(LWOOBJID otherEntity);
|
||||
@@ -421,6 +425,9 @@ private:
|
||||
std::vector<std::function<void(Entity* target)>> m_PhantomCollisionCallbacks;
|
||||
|
||||
std::unordered_map<eReplicaComponentType, Component*> m_Components;
|
||||
|
||||
// Every component has had its Startup (the end of Initialize)
|
||||
bool m_ComponentsStarted = false;
|
||||
std::vector<EntityTimer> m_Timers;
|
||||
std::vector<EntityTimer> m_PendingTimers;
|
||||
std::vector<EntityCallbackTimer> m_CallbackTimers;
|
||||
@@ -608,6 +615,13 @@ inline ComponentType* Entity::AddComponent(VaArgs... args) {
|
||||
new(componentToReturn) ComponentType(this, std::forward<VaArgs>(args)...);
|
||||
}
|
||||
|
||||
// The client's load steps for a new component (DoObjectComponentLoad: the allocator reads the CDClient row, then
|
||||
// PrepareConfigData); one added after the object started up starts up at once
|
||||
componentToReturn->LoadDataFromTemplate();
|
||||
componentToReturn->PrepareConfigData();
|
||||
componentToReturn->LoadConfigData();
|
||||
if (m_ComponentsStarted) componentToReturn->Startup();
|
||||
|
||||
// Finally return the created or already existing component.
|
||||
// Because of the assert above, this should always be a ComponentType* but I need a way to guarantee the map cannot be modifed outside this function
|
||||
// To allow a static cast here instead of a dynamic one.
|
||||
|
||||
@@ -450,6 +450,8 @@ void EntityManager::ConstructAllEntities(const SystemAddress& sysAddr) {
|
||||
for (auto* entity : m_Entities | std::views::values) {
|
||||
if (entity && (entity->GetSpawnerID() != 0 || entity->GetLOT() == 1) && !entity->GetIsGhostingCandidate()) {
|
||||
ConstructEntity(entity, sysAddr);
|
||||
// Objects that are never ghosted enter a joining player's scope here
|
||||
if (auto* const player = PlayerManager::GetPlayer(sysAddr)) entity->OnEnterScope(*player);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -583,6 +585,7 @@ void EntityManager::UpdateGhosting(Entity* player) {
|
||||
DestructEntity(entity, player->GetSystemAddress());
|
||||
|
||||
entity->SetObservers(entity->GetObservers() - 1);
|
||||
entity->OnLeaveScope(*player);
|
||||
} else if (!observed && nearEnough) {
|
||||
// Check collectables, don't construct if it has been collected
|
||||
uint32_t collectionId = entity->GetCollectibleID();
|
||||
@@ -600,6 +603,7 @@ void EntityManager::UpdateGhosting(Entity* player) {
|
||||
entity->SetObservers(entity->GetObservers() + 1);
|
||||
|
||||
ConstructEntity(entity, player->GetSystemAddress());
|
||||
entity->OnEnterScope(*player);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -632,10 +636,12 @@ void EntityManager::CheckGhosting(Entity* entity) {
|
||||
ghostComponent->GhostEntity(id);
|
||||
DestructEntity(entity, player->GetSystemAddress());
|
||||
entity->SetObservers(entity->GetObservers() - 1);
|
||||
entity->OnLeaveScope(*player);
|
||||
} else if (!observed && nearEnough) {
|
||||
ghostComponent->ObserveEntity(id);
|
||||
ConstructEntity(entity, player->GetSystemAddress());
|
||||
entity->SetObservers(entity->GetObservers() + 1);
|
||||
entity->OnEnterScope(*player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ BaseCombatAIComponent::~BaseCombatAIComponent() {
|
||||
dpWorld::RemoveEntity(m_dpEntityEnemy);
|
||||
}
|
||||
|
||||
void BaseCombatAIComponent::Update(const float deltaTime) {
|
||||
void BaseCombatAIComponent::Run(const float deltaTime) {
|
||||
//First, we need to process physics:
|
||||
if (!m_dpEntity) return;
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ public:
|
||||
static float TetherSpeedOf(int32_t componentID);
|
||||
~BaseCombatAIComponent() override;
|
||||
|
||||
void Update(float deltaTime) override;
|
||||
void Run(float deltaTime) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
/**
|
||||
|
||||
@@ -70,7 +70,7 @@ void BuffComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUp
|
||||
outBitStream.Write0(); // something to do with immunity buffs?
|
||||
}
|
||||
|
||||
void BuffComponent::Update(float deltaTime) {
|
||||
void BuffComponent::Run(float deltaTime) {
|
||||
/**
|
||||
* Loop through all buffs and apply deltaTime to ther time.
|
||||
* If they have expired, remove the buff and break.
|
||||
@@ -353,7 +353,7 @@ Entity* BuffComponent::GetParent() const {
|
||||
return m_Parent;
|
||||
}
|
||||
|
||||
void BuffComponent::LoadFromXml(const tinyxml2::XMLDocument& doc) {
|
||||
void BuffComponent::LoadFromSaveData(const tinyxml2::XMLDocument& doc) {
|
||||
// Load buffs
|
||||
auto* dest = doc.FirstChildElement("obj")->FirstChildElement("dest");
|
||||
|
||||
@@ -413,7 +413,7 @@ void BuffComponent::LoadFromXml(const tinyxml2::XMLDocument& doc) {
|
||||
}
|
||||
}
|
||||
|
||||
void BuffComponent::UpdateXml(tinyxml2::XMLDocument& doc) {
|
||||
void BuffComponent::WriteSaveData(tinyxml2::XMLDocument& doc) {
|
||||
// Save buffs
|
||||
auto* dest = doc.FirstChildElement("obj")->FirstChildElement("dest");
|
||||
|
||||
|
||||
@@ -57,13 +57,13 @@ public:
|
||||
|
||||
Entity* GetParent() const;
|
||||
|
||||
void LoadFromXml(const tinyxml2::XMLDocument& doc) override;
|
||||
void LoadFromSaveData(const tinyxml2::XMLDocument& doc) override;
|
||||
|
||||
void UpdateXml(tinyxml2::XMLDocument& doc) override;
|
||||
void WriteSaveData(tinyxml2::XMLDocument& doc) override;
|
||||
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
void Update(float deltaTime) override;
|
||||
void Run(float deltaTime) override;
|
||||
|
||||
/**
|
||||
* Applies a buff to the parent entity
|
||||
|
||||
@@ -292,7 +292,7 @@ void CharacterComponent::SetGMLevel(eGameMasterLevel gmlevel) {
|
||||
m_GMLevel = gmlevel;
|
||||
}
|
||||
|
||||
void CharacterComponent::LoadFromXml(const tinyxml2::XMLDocument& doc) {
|
||||
void CharacterComponent::LoadFromSaveData(const tinyxml2::XMLDocument& doc) {
|
||||
|
||||
auto* character = doc.FirstChildElement("obj")->FirstChildElement("char");
|
||||
if (!character) {
|
||||
@@ -398,7 +398,7 @@ void CharacterComponent::LoadFromXml(const tinyxml2::XMLDocument& doc) {
|
||||
}
|
||||
}
|
||||
|
||||
void CharacterComponent::UpdateXml(tinyxml2::XMLDocument& doc) {
|
||||
void CharacterComponent::WriteSaveData(tinyxml2::XMLDocument& doc) {
|
||||
tinyxml2::XMLElement* minifig = doc.FirstChildElement("obj")->FirstChildElement("mf");
|
||||
if (!minifig) {
|
||||
LOG("Failed to find mf tag while updating XML!");
|
||||
|
||||
@@ -48,8 +48,8 @@ public:
|
||||
CharacterComponent(Entity* parent, const int32_t componentID, Character* character, const SystemAddress& systemAddress);
|
||||
~CharacterComponent() override;
|
||||
|
||||
void LoadFromXml(const tinyxml2::XMLDocument& doc) override;
|
||||
void UpdateXml(tinyxml2::XMLDocument& doc) override;
|
||||
void LoadFromSaveData(const tinyxml2::XMLDocument& doc) override;
|
||||
void WriteSaveData(tinyxml2::XMLDocument& doc) override;
|
||||
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
|
||||
@@ -15,7 +15,13 @@ namespace GameMessages {
|
||||
class Entity;
|
||||
|
||||
/**
|
||||
* Component base class, provides methods for game loop updates, usage events and loading and saving to XML.
|
||||
* Component base class, with the client's component lifecycle (LWOGameObjComponent's vtable,
|
||||
* LWOGameObjComponentFunctions), which the entity calls in the client's order (ObjectLoader2::DoObjectComponentLoad):
|
||||
* constructed, LoadDataFromTemplate (its CDClient row), PrepareConfigData and LoadConfigData (the object's level
|
||||
* config), LoadFromSaveData (a character's save), then Startup once every component of the object exists; Run every
|
||||
* frame; OnEnterScope / OnLeaveScope when a player starts or stops seeing the object; Preshutdown and Shutdown before it
|
||||
* is deleted. Serialize is the server side of the client's Deserialize. Client-only slots (GetSizeInMemory,
|
||||
* GraphicsDeviceReset, GetPickTypePriority) are left out.
|
||||
*/
|
||||
class Component {
|
||||
public:
|
||||
@@ -30,11 +36,26 @@ public:
|
||||
|
||||
[[nodiscard]] int32_t GetComponentID() const noexcept { return m_ComponentID; }
|
||||
|
||||
/**
|
||||
* Updates the component in the game loop
|
||||
* @param deltaTime time passed since last update
|
||||
*/
|
||||
virtual void Update(float deltaTime) {}
|
||||
// The CDClient row (componentID) of the component's table
|
||||
virtual void LoadDataFromTemplate() {}
|
||||
|
||||
// The object's level config (LDF): PrepareConfigData first, then LoadConfigData
|
||||
virtual void PrepareConfigData() {}
|
||||
virtual void LoadConfigData() {}
|
||||
|
||||
// After every component of the object exists
|
||||
virtual void Startup() {}
|
||||
|
||||
// Every frame
|
||||
virtual void Run(float deltaTime) {}
|
||||
|
||||
// A player starts or stops seeing the object (ghosting)
|
||||
virtual void OnEnterScope(Entity& player) {}
|
||||
virtual void OnLeaveScope(Entity& player) {}
|
||||
|
||||
// Before the object is deleted
|
||||
virtual void Preshutdown() {}
|
||||
virtual void Shutdown() {}
|
||||
|
||||
/**
|
||||
* Event called when this component is being used, e.g. when some entity interacted with it
|
||||
@@ -42,17 +63,9 @@ public:
|
||||
*/
|
||||
virtual void OnUse(Entity* originator) {}
|
||||
|
||||
/**
|
||||
* Save data from this componennt to character XML
|
||||
* @param doc the document to write data to
|
||||
*/
|
||||
virtual void UpdateXml(tinyxml2::XMLDocument& doc) {}
|
||||
|
||||
/**
|
||||
* Load base data for this component from character XML
|
||||
* @param doc the document to read data from
|
||||
*/
|
||||
virtual void LoadFromXml(const tinyxml2::XMLDocument& doc) {}
|
||||
// A character's save (its XML): read on load, written on save
|
||||
virtual void LoadFromSaveData(const tinyxml2::XMLDocument& doc) {}
|
||||
virtual void WriteSaveData(tinyxml2::XMLDocument& doc) {}
|
||||
|
||||
virtual void Serialize(RakNet::BitStream& outBitStream, bool isConstruction) {}
|
||||
protected:
|
||||
|
||||
@@ -70,7 +70,7 @@ ControllablePhysicsComponent::~ControllablePhysicsComponent() {
|
||||
}
|
||||
}
|
||||
|
||||
void ControllablePhysicsComponent::Update(float deltaTime) {
|
||||
void ControllablePhysicsComponent::Run(float deltaTime) {
|
||||
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ void ControllablePhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bo
|
||||
}
|
||||
}
|
||||
|
||||
void ControllablePhysicsComponent::LoadFromXml(const tinyxml2::XMLDocument& doc) {
|
||||
void ControllablePhysicsComponent::LoadFromSaveData(const tinyxml2::XMLDocument& doc) {
|
||||
auto* character = doc.FirstChildElement("obj")->FirstChildElement("char");
|
||||
if (!character) {
|
||||
LOG("Failed to find char tag!");
|
||||
@@ -186,7 +186,7 @@ void ControllablePhysicsComponent::LoadFromXml(const tinyxml2::XMLDocument& doc)
|
||||
m_DirtyPosition = true;
|
||||
}
|
||||
|
||||
void ControllablePhysicsComponent::UpdateXml(tinyxml2::XMLDocument& doc) {
|
||||
void ControllablePhysicsComponent::WriteSaveData(tinyxml2::XMLDocument& doc) {
|
||||
tinyxml2::XMLElement* character = doc.FirstChildElement("obj")->FirstChildElement("char");
|
||||
if (!character) {
|
||||
LOG("Failed to find char tag while updating XML!");
|
||||
|
||||
@@ -28,10 +28,10 @@ public:
|
||||
ControllablePhysicsComponent(Entity* entity, const int32_t componentID);
|
||||
~ControllablePhysicsComponent() override;
|
||||
|
||||
void Update(float deltaTime) override;
|
||||
void Run(float deltaTime) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
void LoadFromXml(const tinyxml2::XMLDocument& doc) override;
|
||||
void UpdateXml(tinyxml2::XMLDocument& doc) override;
|
||||
void LoadFromSaveData(const tinyxml2::XMLDocument& doc) override;
|
||||
void WriteSaveData(tinyxml2::XMLDocument& doc) override;
|
||||
|
||||
/**
|
||||
* Sets the position of this entity, also ensures this update is serialized next tick.
|
||||
|
||||
@@ -158,11 +158,11 @@ void DestroyableComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsIn
|
||||
}
|
||||
}
|
||||
|
||||
void DestroyableComponent::Update(float deltaTime) {
|
||||
void DestroyableComponent::Run(float deltaTime) {
|
||||
m_DamageCooldownTimer -= deltaTime;
|
||||
}
|
||||
|
||||
void DestroyableComponent::LoadFromXml(const tinyxml2::XMLDocument& doc) {
|
||||
void DestroyableComponent::LoadFromSaveData(const tinyxml2::XMLDocument& doc) {
|
||||
auto* dest = doc.FirstChildElement("obj")->FirstChildElement("dest");
|
||||
if (!dest) {
|
||||
LOG("Failed to find dest tag!");
|
||||
@@ -172,7 +172,7 @@ void DestroyableComponent::LoadFromXml(const tinyxml2::XMLDocument& doc) {
|
||||
auto* buffComponent = m_Parent->GetComponent<BuffComponent>();
|
||||
|
||||
if (buffComponent != nullptr) {
|
||||
buffComponent->LoadFromXml(doc);
|
||||
buffComponent->LoadFromSaveData(doc);
|
||||
}
|
||||
|
||||
dest->QueryAttribute("hc", &m_iHealth);
|
||||
@@ -184,7 +184,7 @@ void DestroyableComponent::LoadFromXml(const tinyxml2::XMLDocument& doc) {
|
||||
m_DirtyHealth = true;
|
||||
}
|
||||
|
||||
void DestroyableComponent::UpdateXml(tinyxml2::XMLDocument& doc) {
|
||||
void DestroyableComponent::WriteSaveData(tinyxml2::XMLDocument& doc) {
|
||||
tinyxml2::XMLElement* dest = doc.FirstChildElement("obj")->FirstChildElement("dest");
|
||||
if (!dest) {
|
||||
LOG("Failed to find dest tag!");
|
||||
@@ -194,7 +194,7 @@ void DestroyableComponent::UpdateXml(tinyxml2::XMLDocument& doc) {
|
||||
auto* buffComponent = m_Parent->GetComponent<BuffComponent>();
|
||||
|
||||
if (buffComponent != nullptr) {
|
||||
buffComponent->UpdateXml(doc);
|
||||
buffComponent->WriteSaveData(doc);
|
||||
}
|
||||
|
||||
dest->SetAttribute("hc", m_iHealth);
|
||||
|
||||
@@ -47,10 +47,10 @@ public:
|
||||
DestroyableComponent(Entity* parentEntity, const int32_t componentID);
|
||||
~DestroyableComponent() override;
|
||||
|
||||
void Update(float deltaTime) override;
|
||||
void Run(float deltaTime) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
void LoadFromXml(const tinyxml2::XMLDocument& doc) override;
|
||||
void UpdateXml(tinyxml2::XMLDocument& doc) override;
|
||||
void LoadFromSaveData(const tinyxml2::XMLDocument& doc) override;
|
||||
void WriteSaveData(tinyxml2::XMLDocument& doc) override;
|
||||
|
||||
/**
|
||||
* Sets the health of this entity. Makes sure this is serialized on the next tick and if this is a character its
|
||||
|
||||
@@ -798,7 +798,7 @@ void InventoryComponent::LoadXml(const tinyxml2::XMLDocument& document) {
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryComponent::UpdateXml(tinyxml2::XMLDocument& document) {
|
||||
void InventoryComponent::WriteSaveData(tinyxml2::XMLDocument& document) {
|
||||
UpdatePetXml(document);
|
||||
|
||||
auto* inventoryElement = document.FirstChildElement("obj")->FirstChildElement("inv");
|
||||
@@ -964,7 +964,7 @@ void InventoryComponent::Serialize(RakNet::BitStream& outBitStream, const bool b
|
||||
if (bIsInitialUpdate) outBitStream.Write<uint32_t>(0);
|
||||
}
|
||||
|
||||
void InventoryComponent::Update(float deltaTime) {
|
||||
void InventoryComponent::Run(float deltaTime) {
|
||||
for (auto* set : m_Itemsets) {
|
||||
set->Update(deltaTime);
|
||||
}
|
||||
|
||||
@@ -101,10 +101,10 @@ public:
|
||||
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::INVENTORY;
|
||||
InventoryComponent(Entity* parent, const int32_t componentID);
|
||||
|
||||
void Update(float deltaTime) override;
|
||||
void Run(float deltaTime) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
void LoadXml(const tinyxml2::XMLDocument& document);
|
||||
void UpdateXml(tinyxml2::XMLDocument& document) override;
|
||||
void WriteSaveData(tinyxml2::XMLDocument& document) override;
|
||||
|
||||
/**
|
||||
* Returns an inventory of the specified type, if it exists
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "LUPExhibitComponent.h"
|
||||
#include "EntityManager.h"
|
||||
|
||||
void LUPExhibitComponent::Update(float deltaTime) {
|
||||
void LUPExhibitComponent::Run(float deltaTime) {
|
||||
m_UpdateTimer += deltaTime;
|
||||
if (m_UpdateTimer > 20.0f) {
|
||||
NextLUPExhibit();
|
||||
|
||||
@@ -17,7 +17,7 @@ public:
|
||||
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::LUP_EXHIBIT;
|
||||
|
||||
LUPExhibitComponent(Entity* parent, const int32_t componentID) : Component(parent, componentID) {};
|
||||
void Update(float deltaTime) override;
|
||||
void Run(float deltaTime) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
void NextLUPExhibit();
|
||||
private:
|
||||
|
||||
@@ -14,7 +14,7 @@ LevelProgressionComponent::LevelProgressionComponent(Entity* parent, const int32
|
||||
m_CharacterVersion = eCharacterVersion::LIVE;
|
||||
}
|
||||
|
||||
void LevelProgressionComponent::UpdateXml(tinyxml2::XMLDocument& doc) {
|
||||
void LevelProgressionComponent::WriteSaveData(tinyxml2::XMLDocument& doc) {
|
||||
tinyxml2::XMLElement* level = doc.FirstChildElement("obj")->FirstChildElement("lvl");
|
||||
if (!level) {
|
||||
LOG("Failed to find lvl tag while updating XML!");
|
||||
@@ -25,7 +25,7 @@ void LevelProgressionComponent::UpdateXml(tinyxml2::XMLDocument& doc) {
|
||||
level->SetAttribute("cv", static_cast<uint32_t>(m_CharacterVersion));
|
||||
}
|
||||
|
||||
void LevelProgressionComponent::LoadFromXml(const tinyxml2::XMLDocument& doc) {
|
||||
void LevelProgressionComponent::LoadFromSaveData(const tinyxml2::XMLDocument& doc) {
|
||||
auto* level = doc.FirstChildElement("obj")->FirstChildElement("lvl");
|
||||
if (!level) {
|
||||
LOG("Failed to find lvl tag while loading XML!");
|
||||
|
||||
@@ -27,13 +27,13 @@ public:
|
||||
* Save data from this componennt to character XML
|
||||
* @param doc the document to write data to
|
||||
*/
|
||||
void UpdateXml(tinyxml2::XMLDocument& doc) override;
|
||||
void WriteSaveData(tinyxml2::XMLDocument& doc) override;
|
||||
|
||||
/**
|
||||
* Load base data for this component from character XML
|
||||
* @param doc the document to read data from
|
||||
*/
|
||||
void LoadFromXml(const tinyxml2::XMLDocument& doc) override;
|
||||
void LoadFromSaveData(const tinyxml2::XMLDocument& doc) override;
|
||||
|
||||
/**
|
||||
* Gets the current level of the entity
|
||||
|
||||
@@ -446,7 +446,7 @@ bool MissionComponent::RequiresItem(const LOT lot) {
|
||||
}
|
||||
|
||||
|
||||
void MissionComponent::LoadFromXml(const tinyxml2::XMLDocument& doc) {
|
||||
void MissionComponent::LoadFromSaveData(const tinyxml2::XMLDocument& doc) {
|
||||
auto* mis = doc.FirstChildElement("obj")->FirstChildElement("mis");
|
||||
|
||||
if (mis == nullptr) return;
|
||||
@@ -512,7 +512,7 @@ void MissionComponent::LoadFromXml(const tinyxml2::XMLDocument& doc) {
|
||||
}
|
||||
|
||||
|
||||
void MissionComponent::UpdateXml(tinyxml2::XMLDocument& doc) {
|
||||
void MissionComponent::WriteSaveData(tinyxml2::XMLDocument& doc) {
|
||||
auto shouldInsertMis = false;
|
||||
|
||||
auto* obj = doc.FirstChildElement("obj");
|
||||
|
||||
@@ -33,8 +33,8 @@ public:
|
||||
explicit MissionComponent(Entity* parent, const int32_t componentID);
|
||||
~MissionComponent() override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate, unsigned int& flags);
|
||||
void LoadFromXml(const tinyxml2::XMLDocument& doc) override;
|
||||
void UpdateXml(tinyxml2::XMLDocument& doc) override;
|
||||
void LoadFromSaveData(const tinyxml2::XMLDocument& doc) override;
|
||||
void WriteSaveData(tinyxml2::XMLDocument& doc) override;
|
||||
|
||||
/**
|
||||
* Returns all the missions for this entity, mapped by mission ID
|
||||
|
||||
@@ -73,7 +73,7 @@ bool ModelComponent::OnRequestUse(GameMessages::RequestUseEvent& event) {
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
void ModelComponent::Update(float deltaTime) {
|
||||
void ModelComponent::Run(float deltaTime) {
|
||||
if (m_IsPaused) return;
|
||||
|
||||
for (auto& behavior : m_Behaviors) {
|
||||
|
||||
@@ -32,7 +32,7 @@ public:
|
||||
ModelComponent(Entity* parent, const int32_t componentID);
|
||||
|
||||
void LoadBehaviors();
|
||||
void Update(float deltaTime) override;
|
||||
void Run(float deltaTime) override;
|
||||
|
||||
bool OnRequestUse(GameMessages::RequestUseEvent& event);
|
||||
bool OnResetModelToDefaults(GameMessages::ResetModelToDefaults& resetModelToDefaults);
|
||||
|
||||
@@ -64,7 +64,7 @@ void ModuleAssemblyComponent::Serialize(RakNet::BitStream& outBitStream, bool bI
|
||||
}
|
||||
}
|
||||
|
||||
void ModuleAssemblyComponent::Update(float deltaTime) {
|
||||
void ModuleAssemblyComponent::Run(float deltaTime) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ public:
|
||||
~ModuleAssemblyComponent() override;
|
||||
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
void Update(float deltaTime) override;
|
||||
void Run(float deltaTime) override;
|
||||
|
||||
/**
|
||||
* Sets the subkey of this entity
|
||||
|
||||
@@ -107,7 +107,7 @@ void MovementAIComponent::Resume() {
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
}
|
||||
|
||||
void MovementAIComponent::Update(const float deltaTime) {
|
||||
void MovementAIComponent::Run(const float deltaTime) {
|
||||
if (IsKnockedBack()) {
|
||||
UpdateKnockback(deltaTime);
|
||||
return;
|
||||
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
|
||||
void SetPath(const std::string pathName);
|
||||
|
||||
void Update(float deltaTime) override;
|
||||
void Run(float deltaTime) override;
|
||||
|
||||
/**
|
||||
* Returns the basic settings that this entity uses to move around
|
||||
|
||||
@@ -449,7 +449,7 @@ void MovingPlatformComponent::MoverArrive() {
|
||||
FireArrivalHooks(arrived, atDesired, atEnd);
|
||||
}
|
||||
|
||||
void MovingPlatformComponent::Update(const float deltaTime) {
|
||||
void MovingPlatformComponent::Run(const float deltaTime) {
|
||||
if (!IsMover()) return;
|
||||
auto* const mover = GetMoverSubComponent();
|
||||
if ((mover->mState & ePlatformStateFlag::Travelling) != 0) {
|
||||
|
||||
@@ -282,7 +282,7 @@ private:
|
||||
void MoverArrive();
|
||||
|
||||
public:
|
||||
void Update(float deltaTime) override;
|
||||
void Run(float deltaTime) override;
|
||||
|
||||
// The mover's state as a PlatformResync gives it (RequestPlatformResync)
|
||||
void FillResync(GameMessages::PlatformResync& resync) const;
|
||||
|
||||
@@ -256,7 +256,7 @@ void PetComponent::OnUse(Entity* originator) {
|
||||
}
|
||||
}
|
||||
|
||||
void PetComponent::Update(float deltaTime) {
|
||||
void PetComponent::Run(float deltaTime) {
|
||||
if (m_StartPosition == NiPoint3Constant::ZERO) {
|
||||
m_StartPosition = m_Parent->GetPosition();
|
||||
m_StartRotation = m_Parent->GetRotation();
|
||||
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
~PetComponent() override;
|
||||
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
void Update(float deltaTime) override;
|
||||
void Run(float deltaTime) override;
|
||||
|
||||
/**
|
||||
* Handles an OnUse event from another entity, initializing the pet taming minigame if this pet is untamed.
|
||||
|
||||
@@ -179,7 +179,7 @@ void ApplyCollisionEffect(const LWOOBJID& target, const ePhysicsEffectType effec
|
||||
// The other types are not handled by the server and are here to handle all cases of the enum.
|
||||
}
|
||||
|
||||
void PhantomPhysicsComponent::Update(float deltaTime) {
|
||||
void PhantomPhysicsComponent::Run(float deltaTime) {
|
||||
if (!m_dpEntity || !m_PhysicsActive) return;
|
||||
|
||||
//Process enter events
|
||||
|
||||
@@ -29,7 +29,7 @@ public:
|
||||
|
||||
PhantomPhysicsComponent(Entity* parent, const int32_t componentID);
|
||||
~PhantomPhysicsComponent() override;
|
||||
void Update(float deltaTime) override;
|
||||
void Run(float deltaTime) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
/**
|
||||
|
||||
@@ -100,7 +100,7 @@ bool ProximityMonitorComponent::OnGetObjectReportInfo(GameMessages::GetObjectRep
|
||||
return true;
|
||||
}
|
||||
|
||||
void ProximityMonitorComponent::Update(float deltaTime) {
|
||||
void ProximityMonitorComponent::Run(float deltaTime) {
|
||||
for (const auto& prox : m_ProximitiesData) {
|
||||
if (!prox.second) continue;
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ public:
|
||||
|
||||
ProximityMonitorComponent(Entity* parentEntity, const int32_t componentID, int smallRadius = -1, int largeRadius = -1);
|
||||
~ProximityMonitorComponent() override;
|
||||
void Update(float deltaTime) override;
|
||||
void Run(float deltaTime) override;
|
||||
|
||||
/**
|
||||
* Creates an entry to check proximity for, given a name
|
||||
|
||||
@@ -111,7 +111,7 @@ void QuickBuildComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsIni
|
||||
}
|
||||
}
|
||||
|
||||
void QuickBuildComponent::Update(float deltaTime) {
|
||||
void QuickBuildComponent::Run(float deltaTime) {
|
||||
SetActivator(GetActivator());
|
||||
|
||||
switch (m_State) {
|
||||
|
||||
@@ -28,7 +28,7 @@ public:
|
||||
~QuickBuildComponent() override;
|
||||
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
void Update(float deltaTime) override;
|
||||
void Run(float deltaTime) override;
|
||||
|
||||
/**
|
||||
* Handles a OnUse event from some entity, initiating the quick build
|
||||
|
||||
@@ -572,7 +572,7 @@ RacingPlayerInfo* RacingControlComponent::GetPlayerData(LWOOBJID playerID) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void RacingControlComponent::Update(float deltaTime) {
|
||||
void RacingControlComponent::Run(float deltaTime) {
|
||||
// This method is a mess.
|
||||
|
||||
// Pre-load routine
|
||||
|
||||
@@ -129,7 +129,7 @@ public:
|
||||
~RacingControlComponent();
|
||||
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
void Update(float deltaTime) override;
|
||||
void Run(float deltaTime) override;
|
||||
|
||||
/**
|
||||
* Invoked when a player loads into the zone.
|
||||
|
||||
@@ -83,7 +83,7 @@ void RenderComponent::RemoveEffect(const std::string& name) {
|
||||
m_Effects.pop_back();
|
||||
}
|
||||
|
||||
void RenderComponent::Update(const float deltaTime) {
|
||||
void RenderComponent::Run(const float deltaTime) {
|
||||
for (auto& effect : m_Effects) {
|
||||
if (effect.time == 0) continue; // Skip persistent effects
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ public:
|
||||
RenderComponent(Entity* const parentEntity, const int32_t componentID);
|
||||
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
void Update(float deltaTime) override;
|
||||
void Run(float deltaTime) override;
|
||||
|
||||
/**
|
||||
* Adds an effect to this entity, if successful the effect is returned
|
||||
|
||||
@@ -37,7 +37,7 @@ void RigidbodyPhantomPhysicsComponent::Serialize(RakNet::BitStream& outBitStream
|
||||
PhysicsComponent::Serialize(outBitStream, bIsInitialUpdate);
|
||||
}
|
||||
|
||||
void RigidbodyPhantomPhysicsComponent::Update(const float deltaTime) {
|
||||
void RigidbodyPhantomPhysicsComponent::Run(const float deltaTime) {
|
||||
if (!m_dpEntity) return;
|
||||
|
||||
//Process enter events
|
||||
|
||||
@@ -23,7 +23,7 @@ public:
|
||||
|
||||
RigidbodyPhantomPhysicsComponent(Entity* parent, const int32_t componentID);
|
||||
|
||||
void Update(const float deltaTime) override;
|
||||
void Run(const float deltaTime) override;
|
||||
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ SimplePhysicsComponent::SimplePhysicsComponent(Entity* parent, const int32_t com
|
||||
SimplePhysicsComponent::~SimplePhysicsComponent() {
|
||||
}
|
||||
|
||||
void SimplePhysicsComponent::Update(const float deltaTime) {
|
||||
void SimplePhysicsComponent::Run(const float deltaTime) {
|
||||
if (m_Velocity == NiPoint3Constant::ZERO) return;
|
||||
m_Position += m_Velocity * deltaTime;
|
||||
m_DirtyPosition = true;
|
||||
|
||||
@@ -38,7 +38,7 @@ public:
|
||||
SimplePhysicsComponent(Entity* parent, const int32_t componentID);
|
||||
~SimplePhysicsComponent() override;
|
||||
|
||||
void Update(const float deltaTime) override;
|
||||
void Run(const float deltaTime) override;
|
||||
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ void SkillComponent::StartCooldown(const uint32_t skillID) {
|
||||
left = std::max(left, skill.cooldown);
|
||||
}
|
||||
|
||||
void SkillComponent::LoadFromXml(const tinyxml2::XMLDocument& doc) {
|
||||
void SkillComponent::LoadFromSaveData(const tinyxml2::XMLDocument& doc) {
|
||||
m_CooldownGroups.clear();
|
||||
const auto* const obj = doc.FirstChildElement("obj");
|
||||
const auto* const skil = obj ? obj->FirstChildElement("skil") : nullptr;
|
||||
@@ -81,7 +81,7 @@ void SkillComponent::LoadFromXml(const tinyxml2::XMLDocument& doc) {
|
||||
}
|
||||
}
|
||||
|
||||
void SkillComponent::UpdateXml(tinyxml2::XMLDocument& doc) {
|
||||
void SkillComponent::WriteSaveData(tinyxml2::XMLDocument& doc) {
|
||||
auto* const obj = doc.FirstChildElement("obj");
|
||||
if (!obj) return;
|
||||
auto* skil = obj->FirstChildElement("skil");
|
||||
@@ -184,7 +184,7 @@ void SkillComponent::RegisterPlayerProjectile(const LWOOBJID projectileId, Behav
|
||||
this->m_managedProjectiles.push_back(entry);
|
||||
}
|
||||
|
||||
void SkillComponent::Update(const float deltaTime) {
|
||||
void SkillComponent::Run(const float deltaTime) {
|
||||
for (auto it = m_CooldownGroups.begin(); it != m_CooldownGroups.end();) {
|
||||
it->second -= deltaTime;
|
||||
it = it->second <= 0.0f ? m_CooldownGroups.erase(it) : std::next(it);
|
||||
|
||||
@@ -71,18 +71,18 @@ public:
|
||||
/**
|
||||
* Computes skill updates. Invokes CalculateUpdate.
|
||||
*/
|
||||
void Update(float deltaTime) override;
|
||||
void Run(float deltaTime) override;
|
||||
|
||||
/**
|
||||
* Loads the cooldown groups still running at the last save: <skil sc="group:seconds;group:seconds;"/>
|
||||
*/
|
||||
void LoadFromXml(const tinyxml2::XMLDocument& doc) override;
|
||||
void LoadFromSaveData(const tinyxml2::XMLDocument& doc) override;
|
||||
|
||||
/**
|
||||
* Saves the running cooldown groups the way live did and the client reads them (LWOSkillComponent::LoadFromSaveData
|
||||
* 0x00c2a9c0 splits sc on ';' and ':' into a cooldown group and the seconds left)
|
||||
*/
|
||||
void UpdateXml(tinyxml2::XMLDocument& doc) override;
|
||||
void WriteSaveData(tinyxml2::XMLDocument& doc) override;
|
||||
|
||||
/**
|
||||
* Starts the cooldown of a skill's cooldown group (SkillBehavior.cooldowngroup, cooldown) when the player casts it
|
||||
|
||||
@@ -94,7 +94,7 @@ void SwitchComponent::EntityLeave(Entity* entity) {
|
||||
|
||||
}
|
||||
|
||||
void SwitchComponent::Update(float deltaTime) {
|
||||
void SwitchComponent::Run(float deltaTime) {
|
||||
if (m_Active) {
|
||||
m_Timer -= deltaTime;
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ public:
|
||||
SwitchComponent(Entity* parent, const int32_t componentID);
|
||||
~SwitchComponent() override;
|
||||
|
||||
void Update(float deltaTime) override;
|
||||
void Run(float deltaTime) override;
|
||||
void OnUse(Entity* originator) override;
|
||||
|
||||
Entity* GetParentEntity() const;
|
||||
|
||||
@@ -50,7 +50,7 @@ TEST_F(CharacterSaveFieldsTests, MissionTypeStatesRoundTrip) {
|
||||
|
||||
Entity player(20, info);
|
||||
auto* const missions = player.AddComponent<MissionComponent>(-1);
|
||||
missions->LoadFromXml(doc);
|
||||
missions->LoadFromSaveData(doc);
|
||||
const auto& states = missions->GetMissionTypeStates();
|
||||
ASSERT_EQ(states.size(), 2);
|
||||
EXPECT_EQ(states.at("Build").at(""), eMissionLockState::NEW);
|
||||
@@ -58,12 +58,12 @@ TEST_F(CharacterSaveFieldsTests, MissionTypeStatesRoundTrip) {
|
||||
EXPECT_EQ(states.at("Location").at("Nimbus Station"), eMissionLockState::UNLOCKED);
|
||||
|
||||
missions->SetMissionTypeState("Battle", "General", eMissionLockState::NEW);
|
||||
missions->UpdateXml(doc);
|
||||
missions->WriteSaveData(doc);
|
||||
EXPECT_EQ(Print(doc), R"(<obj v="1"><mis><done/><cur/><ts><type v="Battle"><st sub="General" val="1"/></type><type v="Build"><st sub="" val="1"/></type><type v="Location"><st sub="Avant Gardens" val="1"/><st sub="Nimbus Station" val="2"/></type></ts></mis></obj>)");
|
||||
|
||||
Entity reloaded(21, info);
|
||||
auto* const reloadedMissions = reloaded.AddComponent<MissionComponent>(-1);
|
||||
reloadedMissions->LoadFromXml(doc);
|
||||
reloadedMissions->LoadFromSaveData(doc);
|
||||
EXPECT_EQ(reloadedMissions->GetMissionTypeStates(), states);
|
||||
}
|
||||
|
||||
@@ -74,9 +74,9 @@ TEST_F(CharacterSaveFieldsTests, MissionTypeStatesMissingInOldSave) {
|
||||
|
||||
Entity player(22, info);
|
||||
auto* const missions = player.AddComponent<MissionComponent>(-1);
|
||||
missions->LoadFromXml(doc);
|
||||
missions->LoadFromSaveData(doc);
|
||||
EXPECT_TRUE(missions->GetMissionTypeStates().empty());
|
||||
missions->UpdateXml(doc);
|
||||
missions->WriteSaveData(doc);
|
||||
EXPECT_EQ(Print(doc), R"(<obj v="1"><mis><done/><cur/><ts/></mis></obj>)");
|
||||
}
|
||||
|
||||
@@ -88,16 +88,16 @@ TEST_F(CharacterSaveFieldsTests, TooltipFlagsRoundTrip) {
|
||||
Character character(1, nullptr);
|
||||
Entity player(23, info);
|
||||
auto* const characterComponent = player.AddComponent<CharacterComponent>(-1, &character, UNASSIGNED_SYSTEM_ADDRESS);
|
||||
characterComponent->LoadFromXml(doc);
|
||||
characterComponent->LoadFromSaveData(doc);
|
||||
EXPECT_EQ(characterComponent->GetTooltipFlags(), 16777216u);
|
||||
|
||||
characterComponent->SetTooltipFlag(2, true);
|
||||
characterComponent->UpdateXml(doc);
|
||||
characterComponent->WriteSaveData(doc);
|
||||
EXPECT_STREQ(doc.FirstChildElement("obj")->FirstChildElement("char")->Attribute("ttip"), "16777220");
|
||||
|
||||
Entity reloaded(24, info);
|
||||
auto* const reloadedComponent = reloaded.AddComponent<CharacterComponent>(-1, &character, UNASSIGNED_SYSTEM_ADDRESS);
|
||||
reloadedComponent->LoadFromXml(doc);
|
||||
reloadedComponent->LoadFromSaveData(doc);
|
||||
EXPECT_EQ(reloadedComponent->GetTooltipFlags(), 16777220u);
|
||||
}
|
||||
|
||||
@@ -109,9 +109,9 @@ TEST_F(CharacterSaveFieldsTests, TooltipFlagsMissingInOldSave) {
|
||||
Character character(1, nullptr);
|
||||
Entity player(25, info);
|
||||
auto* const characterComponent = player.AddComponent<CharacterComponent>(-1, &character, UNASSIGNED_SYSTEM_ADDRESS);
|
||||
characterComponent->LoadFromXml(doc);
|
||||
characterComponent->LoadFromSaveData(doc);
|
||||
EXPECT_EQ(characterComponent->GetTooltipFlags(), 0u);
|
||||
characterComponent->UpdateXml(doc);
|
||||
characterComponent->WriteSaveData(doc);
|
||||
EXPECT_STREQ(doc.FirstChildElement("obj")->FirstChildElement("char")->Attribute("ttip"), "0");
|
||||
}
|
||||
|
||||
@@ -134,19 +134,19 @@ TEST_F(CharacterSaveFieldsTests, SkillCooldownsRoundTrip) {
|
||||
|
||||
Entity player(26, info);
|
||||
auto* const skills = player.AddComponent<SkillComponent>(-1);
|
||||
skills->LoadFromXml(doc);
|
||||
skills->LoadFromSaveData(doc);
|
||||
ASSERT_EQ(skills->GetCooldownGroups().size(), 2u);
|
||||
EXPECT_FLOAT_EQ(skills->GetCooldownGroups().at(8), 26.6559f);
|
||||
|
||||
skills->Update(26.7f); // group 8 runs out
|
||||
skills->Run(26.7f); // group 8 runs out
|
||||
skills->StartCooldown(394);
|
||||
skills->StartCooldown(395); // no group: not saved
|
||||
skills->UpdateXml(doc);
|
||||
skills->WriteSaveData(doc);
|
||||
EXPECT_EQ(Print(doc), R"(<obj v="1"><skil sc="17:30;78:4.0363;"/></obj>)");
|
||||
|
||||
Entity reloaded(27, info);
|
||||
auto* const reloadedSkills = reloaded.AddComponent<SkillComponent>(-1);
|
||||
reloadedSkills->LoadFromXml(doc);
|
||||
reloadedSkills->LoadFromSaveData(doc);
|
||||
EXPECT_EQ(reloadedSkills->GetCooldownGroups().size(), 2u);
|
||||
EXPECT_FLOAT_EQ(reloadedSkills->GetCooldownGroups().at(17), 30.0f);
|
||||
|
||||
@@ -160,9 +160,9 @@ TEST_F(CharacterSaveFieldsTests, SkillCooldownsMissingInOldSave) {
|
||||
|
||||
Entity player(28, info);
|
||||
auto* const skills = player.AddComponent<SkillComponent>(-1);
|
||||
skills->LoadFromXml(doc);
|
||||
skills->LoadFromSaveData(doc);
|
||||
EXPECT_TRUE(skills->GetCooldownGroups().empty());
|
||||
skills->UpdateXml(doc);
|
||||
skills->WriteSaveData(doc);
|
||||
EXPECT_EQ(Print(doc), R"(<obj v="1"><skil/></obj>)");
|
||||
}
|
||||
|
||||
@@ -177,6 +177,6 @@ TEST_F(CharacterSaveFieldsTests, PetsAsLiveWroteThem) {
|
||||
auto* const inventory = player.AddComponent<InventoryComponent>(-1);
|
||||
inventory->LoadXml(doc); // the pets load first; there is no <inv> here
|
||||
EXPECT_EQ(inventory->GetDatabasePet(1152921510000000001LL).lot, 3254);
|
||||
inventory->UpdateXml(doc);
|
||||
inventory->WriteSaveData(doc);
|
||||
EXPECT_EQ(Print(doc), R"(<obj v="1"><pet a="0"><p id="1152921510000000001" l="3254" m="2" n="Fluffy" t="0"/></pet></obj>)");
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ protected:
|
||||
tinyxml2::XMLDocument doc;
|
||||
const std::string xml = std::string(R"(<obj v="1"><mis><done/><cur><m id="2040" state=")") + state + R"("/></cur></mis></obj>)";
|
||||
ASSERT_EQ(doc.Parse(xml.c_str()), tinyxml2::XML_SUCCESS);
|
||||
missions.LoadFromXml(doc);
|
||||
missions.LoadFromSaveData(doc);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -577,7 +577,7 @@ TEST_F(DestroyableTest, DestroyableComponentDamageCooldownTest) {
|
||||
ASSERT_TRUE(destroyableComponent->IsCooldownImmune());
|
||||
|
||||
// Test that the Update() function correctly decrements the damage cooldown timer
|
||||
destroyableComponent->Update(0.5f);
|
||||
destroyableComponent->Run(0.5f);
|
||||
EXPECT_FLOAT_EQ(destroyableComponent->GetDamageCooldownTimer(), 0.5f);
|
||||
ASSERT_TRUE(destroyableComponent->IsCooldownImmune());
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ protected:
|
||||
|
||||
// The "eq" attribute the save wrote for an item
|
||||
bool SavedEquipped(const LWOOBJID id) {
|
||||
inventory->UpdateXml(doc);
|
||||
inventory->WriteSaveData(doc);
|
||||
for (auto* bag = doc.FirstChildElement("obj")->FirstChildElement("inv")->FirstChildElement("items")->FirstChildElement("in"); bag; bag = bag->NextSiblingElement("in")) {
|
||||
for (auto* element = bag->FirstChildElement("i"); element; element = element->NextSiblingElement("i")) {
|
||||
if (element->Int64Attribute("id") == id) return element->BoolAttribute("eq");
|
||||
|
||||
@@ -60,7 +60,7 @@ TEST_F(ItemRemovalTests, ARemovedItemIsUsableUntilTheNextUpdate) {
|
||||
EXPECT_EQ(item->GetId(), id);
|
||||
EXPECT_EQ(item->GetCount(), 0u);
|
||||
|
||||
inventoryComponent->Update(0.0f);
|
||||
inventoryComponent->Run(0.0f);
|
||||
EXPECT_FALSE(items->HasRetiredItems());
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ TEST_F(ItemRemovalTests, RemovingSeveralItemsInALoop) {
|
||||
for (auto* const item : held | std::views::values) EXPECT_EQ(item->GetCount(), 0u);
|
||||
|
||||
EXPECT_TRUE(items->GetItems().empty());
|
||||
inventoryComponent->Update(0.0f);
|
||||
inventoryComponent->Run(0.0f);
|
||||
EXPECT_FALSE(items->HasRetiredItems());
|
||||
}
|
||||
|
||||
|
||||
@@ -182,14 +182,14 @@ TEST_F(MovingPlatformComponentTest, MoverRunsLikeLive) {
|
||||
EXPECT_EQ(mover->mCurrentWaypointIndex, 0u);
|
||||
EXPECT_EQ(mover->mNextWaypointIndex, 1u);
|
||||
|
||||
platform->Update(1.9f);
|
||||
platform->Run(1.9f);
|
||||
EXPECT_EQ(mover->mState, 25u);
|
||||
EXPECT_FLOAT_EQ(mover->mIdleTimeElapsed, 1.9f);
|
||||
platform->Update(0.2f);
|
||||
platform->Run(0.2f);
|
||||
EXPECT_EQ(mover->mState, 2u);
|
||||
|
||||
// 5 units a second over 10
|
||||
platform->Update(1.0f);
|
||||
platform->Run(1.0f);
|
||||
EXPECT_NEAR(mover->mPercentBetweenPoints, 0.5f, 0.001f);
|
||||
EXPECT_NEAR(mover->mPosition.x, 5.0f, 0.01f);
|
||||
GameMessages::PlatformResync resync;
|
||||
@@ -199,7 +199,7 @@ TEST_F(MovingPlatformComponentTest, MoverRunsLikeLive) {
|
||||
EXPECT_EQ(resync.iNextIndex, 1);
|
||||
EXPECT_NEAR(resync.fPercentBetweenPoints, 0.5f, 0.001f);
|
||||
|
||||
platform->Update(1.1f);
|
||||
platform->Run(1.1f);
|
||||
EXPECT_EQ(mover->mState, 25u);
|
||||
EXPECT_EQ(mover->mCurrentWaypointIndex, 1u);
|
||||
EXPECT_EQ(mover->mNextWaypointIndex, 0u);
|
||||
@@ -210,23 +210,23 @@ TEST_F(MovingPlatformComponentTest, MoverRunsLikeLive) {
|
||||
platform->GotoWaypoint(0, true);
|
||||
EXPECT_EQ(mover->mState, 2u);
|
||||
EXPECT_EQ(mover->mDesiredWaypointIndex, 0);
|
||||
platform->Update(2.5f);
|
||||
platform->Run(2.5f);
|
||||
EXPECT_EQ(mover->mState, 25u);
|
||||
EXPECT_EQ(mover->mCurrentWaypointIndex, 0u);
|
||||
EXPECT_EQ(mover->mDesiredWaypointIndex, -1);
|
||||
platform->Update(10.0f);
|
||||
platform->Run(10.0f);
|
||||
EXPECT_EQ(mover->mState, 25u);
|
||||
|
||||
// Started at a waypoint it first waits there (issue 964), then stopped mid way and started again
|
||||
platform->StartPathing();
|
||||
EXPECT_EQ(mover->mState, 25u);
|
||||
platform->Update(2.1f);
|
||||
platform->Run(2.1f);
|
||||
EXPECT_EQ(mover->mState, 2u);
|
||||
platform->Update(1.0f);
|
||||
platform->Run(1.0f);
|
||||
platform->StopPathing();
|
||||
EXPECT_EQ(mover->mState & 1u, 1u);
|
||||
const auto percent = mover->mPercentBetweenPoints;
|
||||
platform->Update(1.0f);
|
||||
platform->Run(1.0f);
|
||||
EXPECT_EQ(mover->mPercentBetweenPoints, percent);
|
||||
platform->StartPathing();
|
||||
EXPECT_EQ(mover->mState, 2u);
|
||||
|
||||
@@ -62,7 +62,7 @@ protected:
|
||||
std::vector<CapturedPacket> Build() {
|
||||
quickBuild->OnUse(player.get());
|
||||
return Capture([&] {
|
||||
for (int i = 0; i < 3 && quickBuild->GetState() != eQuickBuildState::COMPLETED; i++) quickBuild->Update(0.1f);
|
||||
for (int i = 0; i < 3 && quickBuild->GetState() != eQuickBuildState::COMPLETED; i++) quickBuild->Run(0.1f);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ protected:
|
||||
character->_doQuickXMLDataParse();
|
||||
character->LoadXmlRespawnCheckpoints();
|
||||
|
||||
entity->AddComponent<CharacterComponent>(-1, character.get(), UNASSIGNED_SYSTEM_ADDRESS)->LoadFromXml(entity->GetCharacter()->GetXMLDoc());
|
||||
entity->AddComponent<CharacterComponent>(-1, character.get(), UNASSIGNED_SYSTEM_ADDRESS)->LoadFromSaveData(entity->GetCharacter()->GetXMLDoc());
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
@@ -63,7 +63,7 @@ TEST_F(SavingTest, CharacterComponentTest) {
|
||||
const auto prevTotalTime = characterComponent->GetTotalTimePlayed();
|
||||
character->_doQuickXMLDataParse();
|
||||
entity->AddComponent<CharacterComponent>(-1, character.get(), UNASSIGNED_SYSTEM_ADDRESS);
|
||||
characterComponent->LoadFromXml(entity->GetCharacter()->GetXMLDoc());
|
||||
characterComponent->LoadFromSaveData(entity->GetCharacter()->GetXMLDoc());
|
||||
|
||||
// Check that the buff component is the same as before which means resaving data and loading it back in didn't change anything
|
||||
ASSERT_EQ("32114;69;343;13;163;2;181;2;388;252;146;24451;25;9022;41898;42186;42524;4404;0;0;0;0;0;0;0;0;0;", characterComponent->StatisticsToString());
|
||||
|
||||
Reference in New Issue
Block a user