From 384083ea1809587f8352522c9c1bf678f669d9c3 Mon Sep 17 00:00:00 2001 From: jadebenn Date: Fri, 5 Jan 2024 14:50:49 -0600 Subject: [PATCH] use reference instead of pointer for cdclient data --- .../CDClientTables/CDPetComponentTable.cpp | 5 +- .../CDClientTables/CDPetComponentTable.h | 2 +- dGame/dComponents/PetComponent.cpp | 56 +++---------------- dGame/dComponents/PetComponent.h | 51 ++++++++++++++--- 4 files changed, 55 insertions(+), 59 deletions(-) diff --git a/dDatabase/CDClientDatabase/CDClientTables/CDPetComponentTable.cpp b/dDatabase/CDClientDatabase/CDClientTables/CDPetComponentTable.cpp index 03bf479d..754e7b7c 100644 --- a/dDatabase/CDClientDatabase/CDClientTables/CDPetComponentTable.cpp +++ b/dDatabase/CDClientDatabase/CDClientTables/CDPetComponentTable.cpp @@ -28,7 +28,8 @@ void CDPetComponentTable::LoadValuesFromDatabase() { } -CDPetComponent* CDPetComponentTable::GetByID(unsigned int componentID) { +CDPetComponent& CDPetComponentTable::GetByID(unsigned int componentID) { auto itr = m_entries.find(componentID); - return itr != m_entries.end() ? &itr->second : nullptr; + if (itr == m_entries.end()) throw std::exception(); // TODO: Use a default set of values instead? + return itr->second; } diff --git a/dDatabase/CDClientDatabase/CDClientTables/CDPetComponentTable.h b/dDatabase/CDClientDatabase/CDClientTables/CDPetComponentTable.h index 5e0d6477..bb37edab 100644 --- a/dDatabase/CDClientDatabase/CDClientTables/CDPetComponentTable.h +++ b/dDatabase/CDClientDatabase/CDClientTables/CDPetComponentTable.h @@ -25,7 +25,7 @@ public: void LoadValuesFromDatabase(); static const std::string GetTableName() { return "PetComponent"; }; - CDPetComponent* GetByID(unsigned int componentID); + CDPetComponent& GetByID(unsigned int componentID); private: std::map m_entries; diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index d235b7b5..2f0478ad 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -35,9 +35,6 @@ #include "eGameMasterLevel.h" #include "eMissionState.h" -#define START_BITMASK_SWITCH(x) \ - for (uint32_t bit = 1; x >= bit; bit *= 2) if (x & bit) switch (bit) - std::unordered_map PetComponent::buildCache{}; std::unordered_map PetComponent::currentActivities{}; std::unordered_map PetComponent::activePets{}; @@ -76,39 +73,6 @@ std::map PetComponent::petFlags = { { 13067, 838 }, // Skeleton dragon }; -PetComponent::PetComponent(Entity* parent, uint32_t componentId) : Component(parent) { - m_ComponentId = componentId; - - m_Interaction = LWOOBJID_EMPTY; - m_InteractType = PetInteractType::none; - m_Owner = LWOOBJID_EMPTY; - m_ModerationStatus = 0; - m_Tamer = LWOOBJID_EMPTY; - m_ModelId = LWOOBJID_EMPTY; - m_Timer = 0; - m_TimerAway = 0; - m_TimerBounce = 0; - m_DatabaseId = LWOOBJID_EMPTY; - m_Flags = PetFlag::SPAWNING; // Tameable - m_Ability = ePetAbilityType::Invalid; - m_StartPosition = m_Parent->GetPosition(); //NiPoint3::ZERO; - m_MovementAI = nullptr; - m_Preconditions = nullptr; - - m_ReadyToInteract = false; - SetPetAiState(PetAiState::spawn); - SetIsHandlingInteraction(false); - - std::string checkPreconditions = GeneralUtils::UTF16ToWTF8(parent->GetVar(u"CheckPrecondition")); - - if (!checkPreconditions.empty()) { - SetPreconditions(checkPreconditions); - } - - // Load database values - m_FollowRadius = Game::zoneManager->GetPetFollowRadius(); -} - void PetComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { const bool tamed = m_Owner != LWOOBJID_EMPTY; @@ -760,17 +724,14 @@ void PetComponent::Wander() { return; } - m_MovementAI->SetMaxSpeed(m_PetInfo->sprintSpeed); //info.wanderSpeed); + m_MovementAI->SetMaxSpeed(m_PetInfo.sprintSpeed); //info.wanderSpeed); m_MovementAI->SetDestination(destination); - m_Timer += (m_MovementAI->GetParent()->GetPosition().x - destination.x) / m_PetInfo->sprintSpeed; + m_Timer += (m_MovementAI->GetParent()->GetPosition().x - destination.x) / m_PetInfo.sprintSpeed; } void PetComponent::OnSpawn() { - m_PetInfo = CDClientManager::Instance().GetTable()->GetByID(m_ComponentId); - if (!m_PetInfo) LOG("Failed to load PetComponent (id: %d) information from CDClient!", m_ComponentId); - m_MovementAI = m_Parent->GetComponent(); if (m_StartPosition == NiPoint3::ZERO) { @@ -779,7 +740,7 @@ void PetComponent::OnSpawn() { if (m_Owner != LWOOBJID_EMPTY) { m_Parent->SetOwnerOverride(m_Owner); - m_MovementAI->SetMaxSpeed(m_PetInfo->sprintSpeed); + m_MovementAI->SetMaxSpeed(m_PetInfo.sprintSpeed); m_MovementAI->SetHaltDistance(m_FollowRadius); //SetOnlyFlag(IDLE); //SetStatus(PetFlag::NONE); SetPetAiState(PetAiState::follow); @@ -891,7 +852,7 @@ void PetComponent::StartInteract(const NiPoint3& position, const PetInteractType SetInteractType(interactType); SetAbility(ePetAbilityType::GoToObject); SetPetAiState(PetAiState::goToObj); - m_MovementAI->SetMaxSpeed(m_PetInfo->runSpeed); + m_MovementAI->SetMaxSpeed(m_PetInfo.runSpeed); m_MovementAI->SetHaltDistance(0.0f); m_MovementAI->SetDestination(position); LOG_DEBUG("Starting interaction!"); @@ -911,7 +872,7 @@ void PetComponent::StopInteract(bool bDontSerialize) { SetOnlyFlag(IDLE); //SetStatus(PetFlag::NONE); SetIsReadyToInteract(false); SetIsHandlingInteraction(false); // Needed? - m_MovementAI->SetMaxSpeed(m_PetInfo->sprintSpeed); + m_MovementAI->SetMaxSpeed(m_PetInfo.sprintSpeed); m_MovementAI->SetHaltDistance(m_FollowRadius); LOG_DEBUG("Stopping interaction!"); @@ -991,7 +952,7 @@ void PetComponent::HandleInteractBouncer() { GameMessages::SendRequestClientBounce(bouncerId, this->GetOwnerId(), NiPoint3::ZERO, NiPoint3::ZERO, bouncerId, true, false, UNASSIGNED_SYSTEM_ADDRESS); //TODO: Check packet captures!! bouncerComp->SetPetBouncerEnabled(false); RenderComponent::PlayAnimation(petSwitchEntity, u"up"); - }); + }); RenderComponent::PlayAnimation(petSwitchEntity, u"launch"); //u"engaged"); //TODO: Check if the timing on this is right // TODO: Need to freeze player movement until the bounce begins! @@ -1078,9 +1039,6 @@ void PetComponent::HandleInteractTreasureDig() { } void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) { // TODO: Offset spawn position so it's not on top of player char - m_PetInfo = CDClientManager::Instance().GetTable()->GetByID(m_ComponentId); - if (!m_PetInfo) LOG("Failed to load PetComponent (id: %d) information from CDClient!", m_ComponentId); - AddDrainImaginationTimer(item, fromTaming); m_ItemId = item->GetId(); @@ -1162,7 +1120,7 @@ void PetComponent::AddDrainImaginationTimer(Item* item, bool fromTaming) { if (!fromTaming) playerDestroyableComponent->Imagine(-1); // Set this to a variable so when this is called back from the player the timer doesn't fire off. - m_Parent->AddCallbackTimer(m_PetInfo->imaginationDrainRate, [playerDestroyableComponent, this, item]() { + m_Parent->AddCallbackTimer(m_PetInfo.imaginationDrainRate, [playerDestroyableComponent, this, item]() { if (!playerDestroyableComponent) { LOG("No petComponent and/or no playerDestroyableComponent"); return; diff --git a/dGame/dComponents/PetComponent.h b/dGame/dComponents/PetComponent.h index f82cb132..fb9d7f11 100644 --- a/dGame/dComponents/PetComponent.h +++ b/dGame/dComponents/PetComponent.h @@ -8,6 +8,7 @@ #include "eReplicaComponentType.h" #include "ePetAbilityType.h" #include "CDPetComponentTable.h" +#include "CDClientManager.h" /* * The current state of the pet AI @@ -67,9 +68,50 @@ class PetComponent : public Component { public: inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PET; - PetComponent(Entity* parentEntity, uint32_t componentId); + /** + * Pet information loaded from the CDClientDatabase + */ + CDPetComponent& m_PetInfo; + + /** + * PetComponent constructor + * @param parentEntity The parent entity + * @param componentId The component id + */ + explicit PetComponent(Entity* parentEntity, uint32_t componentId) : Component{ parentEntity }, + m_PetInfo{ CDClientManager::Instance().GetTable()->GetByID(componentId) } { + m_ComponentId = componentId; + m_Interaction = LWOOBJID_EMPTY; + m_InteractType = PetInteractType::none; + m_Owner = LWOOBJID_EMPTY; + m_ModerationStatus = 0; + m_Tamer = LWOOBJID_EMPTY; + m_ModelId = LWOOBJID_EMPTY; + m_Timer = 0; + m_TimerAway = 0; + m_TimerBounce = 0; + m_DatabaseId = LWOOBJID_EMPTY; + m_Flags = PetFlag::SPAWNING; // Tameable + m_Ability = ePetAbilityType::Invalid; + m_StartPosition = m_Parent->GetPosition(); + m_MovementAI = nullptr; + m_Preconditions = nullptr; + + m_ReadyToInteract = false; + SetPetAiState(PetAiState::spawn); + SetIsHandlingInteraction(false); + + std::string checkPreconditions = GeneralUtils::UTF16ToWTF8(parentEntity->GetVar(u"CheckPrecondition")); + + if (!checkPreconditions.empty()) { + SetPreconditions(checkPreconditions); + } + + m_FollowRadius = 8.0f; //Game::zoneManager->GetPetFollowRadius(); // TODO: FIX THIS TO LOAD DYNAMICALLY + } + ~PetComponent() override; - + /** * Serializes the pet * @param outBitStream The output bitstream @@ -439,11 +481,6 @@ private: int32_t numValidPieces; }; - /** - * Pet information loaded from the CDClientDatabase - */ - CDPetComponent* m_PetInfo; - /** * Cache of all the pets that are currently spawned, indexed by tamer */