From 8270e0edfe1e8feafe963245dc5d8224ab0de477 Mon Sep 17 00:00:00 2001 From: jadebenn Date: Fri, 17 Nov 2023 19:29:42 -0600 Subject: [PATCH 01/10] Working on pet bouncers --- dGame/dComponents/BouncerComponent.cpp | 3 ++- dGame/dComponents/SwitchComponent.cpp | 13 +++++++++++-- dGame/dComponents/SwitchComponent.h | 2 ++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/dGame/dComponents/BouncerComponent.cpp b/dGame/dComponents/BouncerComponent.cpp index 56002ac4..49f6757f 100644 --- a/dGame/dComponents/BouncerComponent.cpp +++ b/dGame/dComponents/BouncerComponent.cpp @@ -25,7 +25,8 @@ BouncerComponent::~BouncerComponent() { void BouncerComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { outBitStream->Write(m_PetEnabled); if (m_PetEnabled) { - outBitStream->Write(m_PetBouncerEnabled); + LOG("NOPE."); + //outBitStream->Write(m_PetBouncerEnabled); } } diff --git a/dGame/dComponents/SwitchComponent.cpp b/dGame/dComponents/SwitchComponent.cpp index 41dff9f5..9d8cd7bc 100644 --- a/dGame/dComponents/SwitchComponent.cpp +++ b/dGame/dComponents/SwitchComponent.cpp @@ -101,6 +101,15 @@ void SwitchComponent::Update(float deltaTime) { } } +void SwitchComponent::OnUse(Entity* originator) { + LOG("YOU USED ME!"); + m_Parent->TriggerEvent(eTriggerEventType::INTERACT, originator); + + for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) { + script->OnUse(m_Parent, originator); + } +} + Entity* SwitchComponent::GetParentEntity() const { return m_Parent; } @@ -126,8 +135,8 @@ void SwitchComponent::SetPetBouncer(BouncerComponent* value) { m_PetBouncer = value; if (value != nullptr) { - m_PetBouncer->SetPetEnabled(true); - petSwitches.push_back(this); + //m_PetBouncer->SetPetEnabled(true); + //petSwitches.push_back(this); //This seems to govern if pets can "see" this } } diff --git a/dGame/dComponents/SwitchComponent.h b/dGame/dComponents/SwitchComponent.h index 25f694ba..f27dc7b0 100644 --- a/dGame/dComponents/SwitchComponent.h +++ b/dGame/dComponents/SwitchComponent.h @@ -23,6 +23,8 @@ public: void Update(float deltaTime) override; + void OnUse(Entity* originator) override; + Entity* GetParentEntity() const; void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; From 5734ef85e80664899dc83099190ab604f9f310e8 Mon Sep 17 00:00:00 2001 From: jadebenn Date: Sat, 18 Nov 2023 18:43:47 -0600 Subject: [PATCH 02/10] initial dig functionality; need to clean up kruft --- dCommon/dEnums/ePetStatus.h | 18 ++++ dGame/dComponents/PetComponent.cpp | 95 +++++++++++++------ dGame/dComponents/PetComponent.h | 33 +++++++ dGame/dUtilities/SlashCommandHandler.cpp | 27 ++++++ .../02_server/Map/General/PetDigServer.cpp | 11 +++ dScripts/02_server/Map/General/PetDigServer.h | 7 ++ 6 files changed, 162 insertions(+), 29 deletions(-) create mode 100644 dCommon/dEnums/ePetStatus.h diff --git a/dCommon/dEnums/ePetStatus.h b/dCommon/dEnums/ePetStatus.h new file mode 100644 index 00000000..04c9c9b9 --- /dev/null +++ b/dCommon/dEnums/ePetStatus.h @@ -0,0 +1,18 @@ +#ifndef __EPETSTATUS__H__ +#define __EPETSTATUS__H__ + +#include + +enum ePetStatus : uint32_t { + NONE, + UNKNOWN1 = 0x1, + UNKNOWN2 = 0x2, + UNKNOWN3 = 0x4, + UNKNOWN4 = 0x8, + BEING_TAMED = 0x10, + IS_NOT_WAITING = 0x20, // Right name? - used to be decimal 20 + PLAY_SPAWN_ANIM = 0x80, + TAMEABLE = 0x4000000 +}; + +#endif //!__EPETSTATUS__H__ diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index 1780437e..2d364378 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -19,6 +19,7 @@ #include "ePetTamingNotifyType.h" #include "eUseItemResponse.h" #include "ePlayerFlag.h" +#include "ePetStatus.h" #include "Game.h" #include "dConfig.h" @@ -80,13 +81,16 @@ PetComponent::PetComponent(Entity* parent, uint32_t componentId): Component(pare m_Timer = 0; m_TimerAway = 0; m_DatabaseId = LWOOBJID_EMPTY; - m_Status = 67108866; // Tamable + m_Status = ePetStatus::TAMEABLE; // Tameable m_Ability = PetAbilityType::Invalid; m_StartPosition = NiPoint3::ZERO; m_MovementAI = nullptr; m_TresureTime = 0; m_Preconditions = nullptr; + m_ReadyToDig = false; + m_InInteract = false; + std::string checkPreconditions = GeneralUtils::UTF16ToWTF8(parent->GetVar(u"CheckPrecondition")); if (!checkPreconditions.empty()) { @@ -150,6 +154,15 @@ void PetComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpd } void PetComponent::OnUse(Entity* originator) { + LOG("PET USE!"); + + if(m_ReadyToDig) { + LOG("Dig initiated!"); + m_TresureTime = 2.0f; + //m_ReadyToDig = false; + SetAbility(PetAbilityType::DigAtPosition); + } + if (m_Owner != LWOOBJID_EMPTY) { return; } @@ -369,29 +382,8 @@ void PetComponent::Update(float deltaTime) { return; } - if (m_TresureTime > 0) { - auto* tresure = Game::entityManager->GetEntity(m_Interaction); - - if (tresure == nullptr) { - m_TresureTime = 0; - - return; - } - - m_TresureTime -= deltaTime; - - m_MovementAI->Stop(); - - if (m_TresureTime <= 0) { - m_Parent->SetOwnerOverride(m_Owner); - - tresure->Smash(m_Parent->GetObjectID()); - - m_Interaction = LWOOBJID_EMPTY; - - m_TresureTime = 0; - } - + if (m_TresureTime > 0.0f) { + InteractDig(deltaTime); return; } @@ -440,10 +432,9 @@ void PetComponent::Update(float deltaTime) { } } + // Determine if the "Lost Tags" mission has been completed and digging has been unlocked auto* missionComponent = owner->GetComponent(); if (!missionComponent) return; - - // Determine if the "Lost Tags" mission has been completed and digging has been unlocked const bool digUnlocked = missionComponent->GetMissionState(842) == eMissionState::COMPLETE; Entity* closestTresure = PetDigServer::GetClosestTresure(position); @@ -461,11 +452,14 @@ void PetComponent::Update(float deltaTime) { Command(NiPoint3::ZERO, LWOOBJID_EMPTY, 1, 202, true); - m_TresureTime = 2; + SetIsReadyToDig(true); + } else if (distance < 10 * 10) { haltDistance = 1; destination = tresurePosition; + + SetIsReadyToDig(false); } } @@ -480,6 +474,49 @@ skipTresure: m_Timer = 1; } +void PetComponent::SetIsReadyToDig(bool isReady) { + if (isReady) { + LOG("Dig state reached!"); + //m_Interaction = closestTresure->GetObjectID(); + SetAbility(PetAbilityType::JumpOnObject); + SetStatus(ePetStatus::IS_NOT_WAITING); // Treasure dig status + m_ReadyToDig = true; + } + else { + LOG("Dig state ended!"); + //m_Interaction = LWOOBJID_EMPTY; + SetAbility(PetAbilityType::Invalid); + SetStatus(0); // TODO: Check status + m_ReadyToDig = false; + } +} + +void PetComponent::InteractDig(float deltaTime) { //Should I rename to InteractDig? + LOG("Pet digging!"); + + auto* tresure = Game::entityManager->GetEntity(m_Interaction); + + if (tresure == nullptr) { + m_TresureTime = 0.0f; + return; + } + + m_TresureTime -= deltaTime; + + m_MovementAI->Stop(); + + if (m_TresureTime <= 0.0f) { + m_Parent->SetOwnerOverride(m_Owner); + + tresure->Smash(m_Parent->GetObjectID()); + + LOG("Pet dig completed!"); + m_Interaction = LWOOBJID_EMPTY; + m_TresureTime = 0.0f; + SetIsReadyToDig(false); + } +} + void PetComponent::TryBuild(uint32_t numBricks, bool clientFailed) { if (m_Tamer == LWOOBJID_EMPTY) return; @@ -736,7 +773,7 @@ void PetComponent::ClientExitTamingMinigame(bool voluntaryExit) { currentActivities.erase(m_Tamer); - SetStatus(67108866); + SetStatus(ePetStatus::TAMEABLE); m_Tamer = LWOOBJID_EMPTY; m_Timer = 0; @@ -787,7 +824,7 @@ void PetComponent::ClientFailTamingMinigame() { currentActivities.erase(m_Tamer); - SetStatus(67108866); + SetStatus(ePetStatus::TAMEABLE); m_Tamer = LWOOBJID_EMPTY; m_Timer = 0; diff --git a/dGame/dComponents/PetComponent.h b/dGame/dComponents/PetComponent.h index 980bb146..341e592b 100644 --- a/dGame/dComponents/PetComponent.h +++ b/dGame/dComponents/PetComponent.h @@ -29,6 +29,12 @@ public: void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; void Update(float deltaTime) override; + /** + * Handles the pet dig interaction + * @param deltaTime time elapsed + */ + void InteractDig(float deltaTime); + /** * Handles an OnUse event from another entity, initializing the pet taming minigame if this pet is untamed. * @param originator the entity that triggered the event @@ -172,6 +178,23 @@ public: */ void SetPreconditions(std::string& conditions); + /** + * Sets if the pet is ready to dig + * @param isReady whether the pet is ready to dig (true) or not (false) + */ + void SetIsReadyToDig(bool isReady); + + /** + * @return is pet ready to dig + */ + bool GetIsReadyToDig() { return m_ReadyToDig; }; + + /** + * Sets pet's treasure timer + * @param digTime float representing the treasure dig time in seconds + */ + void SetTreasureTime(float digTime) { m_TresureTime = digTime; }; + /** * Returns the entity that this component belongs to * @return the entity that this component belongs to @@ -341,6 +364,16 @@ private: */ float m_TresureTime; + /** + * Boolean that sets if a pet is ready to dig and display the interact prompt + */ + bool m_ReadyToDig; + + /** + * Boolean that sets if a pet is in an interaction + */ + float m_InInteract; + /** * The position that this pet was spawned at */ diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 71f0e38b..96085ecd 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -46,6 +46,7 @@ #include "dServer.h" #include "MissionComponent.h" #include "Mail.h" +#include "PetComponent.h" #include "dpWorld.h" #include "Item.h" #include "PropertyManagementComponent.h" @@ -679,6 +680,32 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit entity->GetCharacter()->SetPlayerFlag(flagId, false); } + if (chatCommand == "setpetstatus" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { + if (args.size() == 0) { + ChatPackets::SendSystemMessage(sysAddr, u"Too few arguments!"); + return; + } + + uint32_t petStatus; + if (!GeneralUtils::TryParse(args[0], petStatus)) { + ChatPackets::SendSystemMessage(sysAddr, u"Invalid pet status!"); + return; + } + + // Determine if player has a pet summoned + auto* petComponent = PetComponent::GetActivePet(entity->GetObjectID()); + if (!petComponent) { + ChatPackets::SendSystemMessage(sysAddr, u"No active pet found!"); + return; + } + + petComponent->SetStatus(petStatus); + //Game::entityManager->SerializeEntity(petComponent->GetParentEntity()); + + std::u16string msg = u"Set pet status to " + (GeneralUtils::to_u16string(petStatus)); + ChatPackets::SendSystemMessage(sysAddr, msg); + } + if (chatCommand == "resetmission" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { if (args.size() == 0) return; diff --git a/dScripts/02_server/Map/General/PetDigServer.cpp b/dScripts/02_server/Map/General/PetDigServer.cpp index 0ea78e4f..5e67368e 100644 --- a/dScripts/02_server/Map/General/PetDigServer.cpp +++ b/dScripts/02_server/Map/General/PetDigServer.cpp @@ -101,6 +101,17 @@ void PetDigServer::OnDie(Entity* self, Entity* killer) { } } +void PetDigServer::OnUse(Entity* self, Entity* user) { + LOG("Treasure used!"); + + auto* petComponent = PetComponent::GetActivePet(user->GetObjectID()); + if (!petComponent) return; + + if(petComponent->GetIsReadyToDig()) { + petComponent->SetTreasureTime(2.0f); + } +} + void PetDigServer::HandleXBuildDig(const Entity* self, Entity* owner, Entity* pet) { auto playerID = self->GetVar(u"builder"); if (playerID == LWOOBJID_EMPTY || playerID != owner->GetObjectID()) diff --git a/dScripts/02_server/Map/General/PetDigServer.h b/dScripts/02_server/Map/General/PetDigServer.h index 1122517b..232214d8 100644 --- a/dScripts/02_server/Map/General/PetDigServer.h +++ b/dScripts/02_server/Map/General/PetDigServer.h @@ -17,6 +17,13 @@ public: void OnStartup(Entity* self) override; void OnDie(Entity* self, Entity* killer) override; + /** + * Invoked when a player interacts with treasure. + * @param self the entity the script belongs to + * @param user the entity that used the treasure + */ + void OnUse(Entity* self, Entity* user) override; + static Entity* GetClosestTresure(NiPoint3 position); private: From a76ddd9ae1b3ac9eee7184f70273f4fe7fcbb06c Mon Sep 17 00:00:00 2001 From: jadebenn Date: Sat, 18 Nov 2023 18:50:09 -0600 Subject: [PATCH 03/10] cleaned up kruft --- dGame/dComponents/BouncerComponent.cpp | 3 +-- dGame/dComponents/SwitchComponent.cpp | 13 ++----------- dGame/dComponents/SwitchComponent.h | 2 -- 3 files changed, 3 insertions(+), 15 deletions(-) diff --git a/dGame/dComponents/BouncerComponent.cpp b/dGame/dComponents/BouncerComponent.cpp index 49f6757f..56002ac4 100644 --- a/dGame/dComponents/BouncerComponent.cpp +++ b/dGame/dComponents/BouncerComponent.cpp @@ -25,8 +25,7 @@ BouncerComponent::~BouncerComponent() { void BouncerComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { outBitStream->Write(m_PetEnabled); if (m_PetEnabled) { - LOG("NOPE."); - //outBitStream->Write(m_PetBouncerEnabled); + outBitStream->Write(m_PetBouncerEnabled); } } diff --git a/dGame/dComponents/SwitchComponent.cpp b/dGame/dComponents/SwitchComponent.cpp index 9d8cd7bc..41dff9f5 100644 --- a/dGame/dComponents/SwitchComponent.cpp +++ b/dGame/dComponents/SwitchComponent.cpp @@ -101,15 +101,6 @@ void SwitchComponent::Update(float deltaTime) { } } -void SwitchComponent::OnUse(Entity* originator) { - LOG("YOU USED ME!"); - m_Parent->TriggerEvent(eTriggerEventType::INTERACT, originator); - - for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) { - script->OnUse(m_Parent, originator); - } -} - Entity* SwitchComponent::GetParentEntity() const { return m_Parent; } @@ -135,8 +126,8 @@ void SwitchComponent::SetPetBouncer(BouncerComponent* value) { m_PetBouncer = value; if (value != nullptr) { - //m_PetBouncer->SetPetEnabled(true); - //petSwitches.push_back(this); //This seems to govern if pets can "see" this + m_PetBouncer->SetPetEnabled(true); + petSwitches.push_back(this); } } diff --git a/dGame/dComponents/SwitchComponent.h b/dGame/dComponents/SwitchComponent.h index f27dc7b0..25f694ba 100644 --- a/dGame/dComponents/SwitchComponent.h +++ b/dGame/dComponents/SwitchComponent.h @@ -23,8 +23,6 @@ public: void Update(float deltaTime) override; - void OnUse(Entity* originator) override; - Entity* GetParentEntity() const; void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; From bd6f9a7a3b6cf2848efcf992ecd61d5f0c3317e5 Mon Sep 17 00:00:00 2001 From: jadebenn Date: Sat, 18 Nov 2023 20:11:28 -0600 Subject: [PATCH 04/10] added imagination cost to digs --- dGame/dComponents/PetComponent.h | 2 +- dScripts/02_server/Map/General/PetDigServer.cpp | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/dGame/dComponents/PetComponent.h b/dGame/dComponents/PetComponent.h index 341e592b..60038cb7 100644 --- a/dGame/dComponents/PetComponent.h +++ b/dGame/dComponents/PetComponent.h @@ -372,7 +372,7 @@ private: /** * Boolean that sets if a pet is in an interaction */ - float m_InInteract; + bool m_InInteract; /** * The position that this pet was spawned at diff --git a/dScripts/02_server/Map/General/PetDigServer.cpp b/dScripts/02_server/Map/General/PetDigServer.cpp index 5e67368e..3aa62fce 100644 --- a/dScripts/02_server/Map/General/PetDigServer.cpp +++ b/dScripts/02_server/Map/General/PetDigServer.cpp @@ -1,5 +1,6 @@ #include "dZoneManager.h" #include "PetDigServer.h" +#include "DestroyableComponent.h" #include "MissionComponent.h" #include "EntityManager.h" #include "Character.h" @@ -107,8 +108,16 @@ void PetDigServer::OnUse(Entity* self, Entity* user) { auto* petComponent = PetComponent::GetActivePet(user->GetObjectID()); if (!petComponent) return; - if(petComponent->GetIsReadyToDig()) { + if(petComponent->GetIsReadyToDig()) { // TODO: Add handling of the "first time" dig message petComponent->SetTreasureTime(2.0f); + + auto* destroyableComponent = user->GetComponent(); + if (!destroyableComponent) return; + + auto imagination = destroyableComponent->GetImagination(); + imagination -= 1; // TODO: Get rid of this magic number + destroyableComponent->SetImagination(imagination); + Game::entityManager->SerializeEntity(user); } } From 76d31871996bbe24d402be54964b598982937297 Mon Sep 17 00:00:00 2001 From: jadebenn Date: Sat, 18 Nov 2023 20:20:58 -0600 Subject: [PATCH 05/10] actually check if the player can afford to dig --- dScripts/02_server/Map/General/PetDigServer.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dScripts/02_server/Map/General/PetDigServer.cpp b/dScripts/02_server/Map/General/PetDigServer.cpp index 3aa62fce..bb057627 100644 --- a/dScripts/02_server/Map/General/PetDigServer.cpp +++ b/dScripts/02_server/Map/General/PetDigServer.cpp @@ -109,12 +109,14 @@ void PetDigServer::OnUse(Entity* self, Entity* user) { if (!petComponent) return; if(petComponent->GetIsReadyToDig()) { // TODO: Add handling of the "first time" dig message - petComponent->SetTreasureTime(2.0f); - auto* destroyableComponent = user->GetComponent(); if (!destroyableComponent) return; auto imagination = destroyableComponent->GetImagination(); + if (imagination == 0) return; // TODO: Check if there was special behavior for this in the live game + + petComponent->SetTreasureTime(2.0f); // TODO: Get rid of this magic number + imagination -= 1; // TODO: Get rid of this magic number destroyableComponent->SetImagination(imagination); Game::entityManager->SerializeEntity(user); From c8b624c3dd313fa9c0457451392d403a7db6f03b Mon Sep 17 00:00:00 2001 From: jadebenn Date: Sun, 19 Nov 2023 14:06:28 -0600 Subject: [PATCH 06/10] minor changes --- dScripts/02_server/Map/General/PetDigServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dScripts/02_server/Map/General/PetDigServer.cpp b/dScripts/02_server/Map/General/PetDigServer.cpp index bb057627..d6071023 100644 --- a/dScripts/02_server/Map/General/PetDigServer.cpp +++ b/dScripts/02_server/Map/General/PetDigServer.cpp @@ -113,7 +113,7 @@ void PetDigServer::OnUse(Entity* self, Entity* user) { if (!destroyableComponent) return; auto imagination = destroyableComponent->GetImagination(); - if (imagination == 0) return; // TODO: Check if there was special behavior for this in the live game + if (imagination == 0) return; // TODO: Check if there was special behavior for this in the live game (PR_NEED_IMAGINATION) petComponent->SetTreasureTime(2.0f); // TODO: Get rid of this magic number From e835eb39660d43654d4a1f4400837ac0d74a821e Mon Sep 17 00:00:00 2001 From: jadebenn Date: Sun, 19 Nov 2023 16:46:27 -0600 Subject: [PATCH 07/10] Fixed pet emotes not playing --- dCommon/dEnums/ePetStatus.h | 18 ---- dGame/dComponents/PetComponent.cpp | 34 ++++---- dGame/dComponents/PetComponent.h | 40 +++++++-- dGame/dGameMessages/GameMessages.cpp | 34 ++++---- dGame/dUtilities/SlashCommandHandler.cpp | 83 +++++++++++++------ .../02_server/Map/General/PetDigServer.cpp | 2 +- docs/Commands.md | 1 + 7 files changed, 130 insertions(+), 82 deletions(-) delete mode 100644 dCommon/dEnums/ePetStatus.h diff --git a/dCommon/dEnums/ePetStatus.h b/dCommon/dEnums/ePetStatus.h deleted file mode 100644 index 04c9c9b9..00000000 --- a/dCommon/dEnums/ePetStatus.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef __EPETSTATUS__H__ -#define __EPETSTATUS__H__ - -#include - -enum ePetStatus : uint32_t { - NONE, - UNKNOWN1 = 0x1, - UNKNOWN2 = 0x2, - UNKNOWN3 = 0x4, - UNKNOWN4 = 0x8, - BEING_TAMED = 0x10, - IS_NOT_WAITING = 0x20, // Right name? - used to be decimal 20 - PLAY_SPAWN_ANIM = 0x80, - TAMEABLE = 0x4000000 -}; - -#endif //!__EPETSTATUS__H__ diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index 2d364378..7d896316 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -19,7 +19,6 @@ #include "ePetTamingNotifyType.h" #include "eUseItemResponse.h" #include "ePlayerFlag.h" -#include "ePetStatus.h" #include "Game.h" #include "dConfig.h" @@ -81,7 +80,7 @@ PetComponent::PetComponent(Entity* parent, uint32_t componentId): Component(pare m_Timer = 0; m_TimerAway = 0; m_DatabaseId = LWOOBJID_EMPTY; - m_Status = ePetStatus::TAMEABLE; // Tameable + m_Status = PetStatus::TAMEABLE; // Tameable m_Ability = PetAbilityType::Invalid; m_StartPosition = NiPoint3::ZERO; m_MovementAI = nullptr; @@ -382,7 +381,7 @@ void PetComponent::Update(float deltaTime) { return; } - if (m_TresureTime > 0.0f) { + if (m_TresureTime > 0.0f) { //TODO: Find better trigger InteractDig(deltaTime); return; } @@ -450,7 +449,7 @@ void PetComponent::Update(float deltaTime) { if (distance < 5 * 5) { m_Interaction = closestTresure->GetObjectID(); - Command(NiPoint3::ZERO, LWOOBJID_EMPTY, 1, 202, true); + Command(NiPoint3::ZERO, LWOOBJID_EMPTY, 1, PetEmote::Bounce , true); // Plays 'bounce' animation SetIsReadyToDig(true); @@ -478,20 +477,20 @@ void PetComponent::SetIsReadyToDig(bool isReady) { if (isReady) { LOG("Dig state reached!"); //m_Interaction = closestTresure->GetObjectID(); - SetAbility(PetAbilityType::JumpOnObject); - SetStatus(ePetStatus::IS_NOT_WAITING); // Treasure dig status + //SetAbility(PetAbilityType::JumpOnObject); + SetStatus(PetStatus::IS_NOT_WAITING); // Treasure dig status m_ReadyToDig = true; } else { LOG("Dig state ended!"); //m_Interaction = LWOOBJID_EMPTY; - SetAbility(PetAbilityType::Invalid); + //SetAbility(PetAbilityType::Invalid); SetStatus(0); // TODO: Check status m_ReadyToDig = false; } } -void PetComponent::InteractDig(float deltaTime) { //Should I rename to InteractDig? +void PetComponent::InteractDig(float deltaTime) { LOG("Pet digging!"); auto* tresure = Game::entityManager->GetEntity(m_Interaction); @@ -773,7 +772,7 @@ void PetComponent::ClientExitTamingMinigame(bool voluntaryExit) { currentActivities.erase(m_Tamer); - SetStatus(ePetStatus::TAMEABLE); + SetStatus(PetStatus::TAMEABLE); m_Tamer = LWOOBJID_EMPTY; m_Timer = 0; @@ -824,7 +823,7 @@ void PetComponent::ClientFailTamingMinigame() { currentActivities.erase(m_Tamer); - SetStatus(ePetStatus::TAMEABLE); + SetStatus(PetStatus::TAMEABLE); m_Tamer = LWOOBJID_EMPTY; m_Timer = 0; @@ -1024,10 +1023,7 @@ void PetComponent::Release() { void PetComponent::Command(NiPoint3 position, LWOOBJID source, int32_t commandType, int32_t typeId, bool overrideObey) { auto* owner = GetOwner(); - - if (owner == nullptr) { - return; - } + if (!owner) return; if (commandType == 1) { // Emotes @@ -1151,3 +1147,13 @@ void PetComponent::LoadPetNameFromModeration() { void PetComponent::SetPreconditions(std::string& preconditions) { m_Preconditions = new PreconditionExpression(preconditions); } + +void PetComponent::StartInteractDig() { + //m_InInteract = true; + m_TresureTime = 2.0f; //TODO: Remove magic number + Command(NiPoint3::ZERO, LWOOBJID_EMPTY, 1, PetEmote::DigTreasure , true); +} + +void PetComponent::EndInteractDig() { + //m_InInteract = false; +} \ No newline at end of file diff --git a/dGame/dComponents/PetComponent.h b/dGame/dComponents/PetComponent.h index 60038cb7..4ec0ef29 100644 --- a/dGame/dComponents/PetComponent.h +++ b/dGame/dComponents/PetComponent.h @@ -6,6 +6,24 @@ #include "Preconditions.h" #include "eReplicaComponentType.h" +enum PetStatus : uint32_t { + NONE, + UNKNOWN1 = 0x1, + UNKNOWN2 = 0x2, + UNKNOWN3 = 0x4, + UNKNOWN4 = 0x8, + BEING_TAMED = 0x10, + IS_NOT_WAITING = 0x20, // Right name? - used to be decimal 20 + PLAY_SPAWN_ANIM = 0x80, + TAMEABLE = 0x4000000 +}; + +enum PetEmote : int32_t { + ActivateSwitch = 201, + DigTreasure, + Bounce +}; + enum class PetAbilityType { Invalid, @@ -29,12 +47,6 @@ public: void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; void Update(float deltaTime) override; - /** - * Handles the pet dig interaction - * @param deltaTime time elapsed - */ - void InteractDig(float deltaTime); - /** * Handles an OnUse event from another entity, initializing the pet taming minigame if this pet is untamed. * @param originator the entity that triggered the event @@ -189,6 +201,22 @@ public: */ bool GetIsReadyToDig() { return m_ReadyToDig; }; + /** + * Start the dig interaction + */ + void StartInteractDig(); + + /** + * Handles the pet dig interaction + * @param deltaTime time elapsed + */ + void InteractDig(float deltaTime); + + /** + * End the dig interaction + */ + void EndInteractDig(); + /** * Sets pet's treasure timer * @param digTime float representing the treasure dig time in seconds diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 7fb9c259..1a6d112b 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -5017,28 +5017,28 @@ void GameMessages::HandlePlayEmote(RakNet::BitStream* inStream, Entity* entity) std::string sAnimationName = "deaded"; //Default name in case we fail to get the emote MissionComponent* missionComponent = entity->GetComponent(); - if (!missionComponent) return; + if (missionComponent) { + if (targetID != LWOOBJID_EMPTY) { + auto* targetEntity = Game::entityManager->GetEntity(targetID); - if (targetID != LWOOBJID_EMPTY) { - auto* targetEntity = Game::entityManager->GetEntity(targetID); + LOG_DEBUG("Emote target found (%d)", targetEntity != nullptr); - LOG_DEBUG("Emote target found (%d)", targetEntity != nullptr); + if (targetEntity != nullptr) { + targetEntity->OnEmoteReceived(emoteID, entity); + missionComponent->Progress(eMissionTaskType::EMOTE, emoteID, targetID); + } + } else { + LOG_DEBUG("Target ID is empty, using backup"); + const auto scriptedEntities = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPT); - if (targetEntity != nullptr) { - targetEntity->OnEmoteReceived(emoteID, entity); - missionComponent->Progress(eMissionTaskType::EMOTE, emoteID, targetID); - } - } else { - LOG_DEBUG("Target ID is empty, using backup"); - const auto scriptedEntities = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPT); + const auto& referencePoint = entity->GetPosition(); - const auto& referencePoint = entity->GetPosition(); + for (auto* scripted : scriptedEntities) { + if (Vector3::DistanceSquared(scripted->GetPosition(), referencePoint) > 5.0f * 5.0f) continue; - for (auto* scripted : scriptedEntities) { - if (Vector3::DistanceSquared(scripted->GetPosition(), referencePoint) > 5.0f * 5.0f) continue; - - scripted->OnEmoteReceived(emoteID, entity); - missionComponent->Progress(eMissionTaskType::EMOTE, emoteID, scripted->GetObjectID()); + scripted->OnEmoteReceived(emoteID, entity); + missionComponent->Progress(eMissionTaskType::EMOTE, emoteID, scripted->GetObjectID()); + } } } diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 96085ecd..fbda3b67 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -680,32 +680,6 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit entity->GetCharacter()->SetPlayerFlag(flagId, false); } - if (chatCommand == "setpetstatus" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { - if (args.size() == 0) { - ChatPackets::SendSystemMessage(sysAddr, u"Too few arguments!"); - return; - } - - uint32_t petStatus; - if (!GeneralUtils::TryParse(args[0], petStatus)) { - ChatPackets::SendSystemMessage(sysAddr, u"Invalid pet status!"); - return; - } - - // Determine if player has a pet summoned - auto* petComponent = PetComponent::GetActivePet(entity->GetObjectID()); - if (!petComponent) { - ChatPackets::SendSystemMessage(sysAddr, u"No active pet found!"); - return; - } - - petComponent->SetStatus(petStatus); - //Game::entityManager->SerializeEntity(petComponent->GetParentEntity()); - - std::u16string msg = u"Set pet status to " + (GeneralUtils::to_u16string(petStatus)); - ChatPackets::SendSystemMessage(sysAddr, msg); - } - if (chatCommand == "resetmission" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { if (args.size() == 0) return; @@ -733,6 +707,63 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } + // Pet status utility + if (chatCommand == "setpetstatus" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { + if (args.size() == 0) { + ChatPackets::SendSystemMessage(sysAddr, u"Too few arguments!"); + return; + } + + uint32_t petStatus; + if (!GeneralUtils::TryParse(args[0], petStatus)) { + ChatPackets::SendSystemMessage(sysAddr, u"Invalid pet status!"); + return; + } + + // Determine if player has a pet summoned + auto* petComponent = PetComponent::GetActivePet(entity->GetObjectID()); + if (!petComponent) { + ChatPackets::SendSystemMessage(sysAddr, u"No active pet found!"); + return; + } + + petComponent->SetStatus(petStatus); + //Game::entityManager->SerializeEntity(petComponent->GetParentEntity()); + + std::u16string msg = u"Set pet status to " + (GeneralUtils::to_u16string(petStatus)); + ChatPackets::SendSystemMessage(sysAddr, msg); + } + + //Pet command utility + if (chatCommand == "petcommand" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { + if (args.size() < 2) { + ChatPackets::SendSystemMessage(sysAddr, u"Too few arguments!"); + return; + } + + int32_t commandType; + if (!GeneralUtils::TryParse(args[0], commandType)) { + ChatPackets::SendSystemMessage(sysAddr, u"Invalid command type!"); + return; + } + + int32_t typeId; + if (!GeneralUtils::TryParse(args[1], typeId)) { + ChatPackets::SendSystemMessage(sysAddr, u"Invalid command type id!"); + return; + } + + // Determine if player has a pet summoned + auto* petComponent = PetComponent::GetActivePet(entity->GetObjectID()); + if (!petComponent) { + ChatPackets::SendSystemMessage(sysAddr, u"No active pet found!"); + return; + } + + petComponent->Command(NiPoint3::ZERO, LWOOBJID_EMPTY, commandType, typeId, true); + } + + if (chatCommand == "playeffect" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 3) { int32_t effectID = 0; diff --git a/dScripts/02_server/Map/General/PetDigServer.cpp b/dScripts/02_server/Map/General/PetDigServer.cpp index d6071023..67109de8 100644 --- a/dScripts/02_server/Map/General/PetDigServer.cpp +++ b/dScripts/02_server/Map/General/PetDigServer.cpp @@ -115,7 +115,7 @@ void PetDigServer::OnUse(Entity* self, Entity* user) { auto imagination = destroyableComponent->GetImagination(); if (imagination == 0) return; // TODO: Check if there was special behavior for this in the live game (PR_NEED_IMAGINATION) - petComponent->SetTreasureTime(2.0f); // TODO: Get rid of this magic number + petComponent->StartInteractDig(); imagination -= 1; // TODO: Get rid of this magic number destroyableComponent->SetImagination(imagination); diff --git a/docs/Commands.md b/docs/Commands.md index 71a3da43..b669175d 100644 --- a/docs/Commands.md +++ b/docs/Commands.md @@ -81,6 +81,7 @@ These commands are primarily for development and testing. The usage of many of t |list-spawns|`/list-spawns`|Lists all the character spawn points in the zone. Additionally, this command will display the current scene that plays when the character lands in the next zone, if there is one.|8| |locrow|`/locrow`|Prints the your current position and rotation information to the console.|8| |lookup|`/lookup `|Searches through the Objects table in the client SQLite database for items whose display name, name, or description contains the query. Query can be multiple words delimited by spaces.|8| +|petcommand|`/petcommand `|Sends pet command to pet with given command type and type ID.|8| |playanimation|`/playanimation `|Plays animation with given ID. Alias: `/playanim`.|8| |playeffect|`/playeffect `|Plays an effect.|8| |playlvlfx|`/playlvlfx`|Plays the level up animation on your character.|8| From 23664c0a9b8eaedb116304a43e29a949529ae70a Mon Sep 17 00:00:00 2001 From: jadebenn Date: Sun, 19 Nov 2023 17:31:31 -0600 Subject: [PATCH 08/10] updated pet command functionality --- dGame/dComponents/PetComponent.cpp | 8 +++++- dGame/dUtilities/SlashCommandHandler.cpp | 31 +++++++++++++++++++++--- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index 7d896316..1ab06833 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -381,7 +381,7 @@ void PetComponent::Update(float deltaTime) { return; } - if (m_TresureTime > 0.0f) { //TODO: Find better trigger + if (m_TresureTime > 0.0f) { //TODO: Find better trigger? InteractDig(deltaTime); return; } @@ -1037,6 +1037,12 @@ void PetComponent::Command(NiPoint3 position, LWOOBJID source, int32_t commandTy if (owner->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { ChatPackets::SendSystemMessage(owner->GetSystemAddress(), u"Commmand Type: " + (GeneralUtils::to_u16string(commandType)) + u" - Type Id: " + (GeneralUtils::to_u16string(typeId))); } + + // Add movement functionality + if (position != NiPoint3::ZERO) { + m_MovementAI->SetDestination(position); + m_Timer = 9; //Is this setting how long until the next update tick? + } } LWOOBJID PetComponent::GetOwnerId() const { diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index fbda3b67..21f45cd2 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -736,19 +736,19 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit //Pet command utility if (chatCommand == "petcommand" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { - if (args.size() < 2) { + if (args.size() < 5) { ChatPackets::SendSystemMessage(sysAddr, u"Too few arguments!"); return; } int32_t commandType; - if (!GeneralUtils::TryParse(args[0], commandType)) { + if (!GeneralUtils::TryParse(args[0+3], commandType)) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid command type!"); return; } int32_t typeId; - if (!GeneralUtils::TryParse(args[1], typeId)) { + if (!GeneralUtils::TryParse(args[1+3], typeId)) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid command type id!"); return; } @@ -760,7 +760,30 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - petComponent->Command(NiPoint3::ZERO, LWOOBJID_EMPTY, commandType, typeId, true); + //Determine the positional coordinates + NiPoint3 commandPos{}; + float x, y, z; + if (!GeneralUtils::TryParse(args[0], x)) { + ChatPackets::SendSystemMessage(sysAddr, u"Invalid x."); + return; + } + + if (!GeneralUtils::TryParse(args[1], y)) { + ChatPackets::SendSystemMessage(sysAddr, u"Invalid y."); + return; + } + + if (!GeneralUtils::TryParse(args[2], z)) { + ChatPackets::SendSystemMessage(sysAddr, u"Invalid z."); + return; + } + + // Set command position + commandPos.SetX(x); + commandPos.SetY(y); + commandPos.SetZ(z); + + petComponent->Command(commandPos, entity->GetObjectID(), commandType, typeId, true); } From 81d8c187ea5233c88ea396be14195dc296aa7f1d Mon Sep 17 00:00:00 2001 From: jadebenn Date: Tue, 21 Nov 2023 20:16:17 -0600 Subject: [PATCH 09/10] mission fix redo --- dGame/dComponents/PetComponent.cpp | 9 ++--- dGame/dGameMessages/GameMessages.cpp | 52 ++++++++++++++-------------- 2 files changed, 28 insertions(+), 33 deletions(-) diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index 1ab06833..f979def4 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -368,15 +368,12 @@ void PetComponent::Update(float deltaTime) { } auto* owner = GetOwner(); - if (owner == nullptr) { m_Parent->Kill(); - return; } m_MovementAI = m_Parent->GetComponent(); - if (m_MovementAI == nullptr) { return; } @@ -390,7 +387,6 @@ void PetComponent::Update(float deltaTime) { NiPoint3 position = m_MovementAI->GetParent()->GetPosition(); float distanceToOwner = Vector3::DistanceSquared(position, destination); - if (distanceToOwner > 50 * 50 || m_TimerAway > 5) { m_MovementAI->Warp(destination); @@ -437,7 +433,6 @@ void PetComponent::Update(float deltaTime) { const bool digUnlocked = missionComponent->GetMissionState(842) == eMissionState::COMPLETE; Entity* closestTresure = PetDigServer::GetClosestTresure(position); - if (closestTresure != nullptr && digUnlocked) { // Skeleton Dragon Pat special case for bone digging if (closestTresure->GetLOT() == 12192 && m_Parent->GetLOT() != 13067) { @@ -449,7 +444,7 @@ void PetComponent::Update(float deltaTime) { if (distance < 5 * 5) { m_Interaction = closestTresure->GetObjectID(); - Command(NiPoint3::ZERO, LWOOBJID_EMPTY, 1, PetEmote::Bounce , true); // Plays 'bounce' animation + Command(NiPoint3::ZERO, LWOOBJID_EMPTY, 1, PetEmote::Bounce, true); // Plays 'bounce' animation SetIsReadyToDig(true); @@ -1157,7 +1152,7 @@ void PetComponent::SetPreconditions(std::string& preconditions) { void PetComponent::StartInteractDig() { //m_InInteract = true; m_TresureTime = 2.0f; //TODO: Remove magic number - Command(NiPoint3::ZERO, LWOOBJID_EMPTY, 1, PetEmote::DigTreasure , true); + Command(NiPoint3::ZERO, LWOOBJID_EMPTY, 1, PetEmote::DigTreasure, true); } void PetComponent::EndInteractDig() { diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 1a6d112b..4777631d 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -5016,32 +5016,6 @@ void GameMessages::HandlePlayEmote(RakNet::BitStream* inStream, Entity* entity) if (emoteID == 0) return; std::string sAnimationName = "deaded"; //Default name in case we fail to get the emote - MissionComponent* missionComponent = entity->GetComponent(); - if (missionComponent) { - if (targetID != LWOOBJID_EMPTY) { - auto* targetEntity = Game::entityManager->GetEntity(targetID); - - LOG_DEBUG("Emote target found (%d)", targetEntity != nullptr); - - if (targetEntity != nullptr) { - targetEntity->OnEmoteReceived(emoteID, entity); - missionComponent->Progress(eMissionTaskType::EMOTE, emoteID, targetID); - } - } else { - LOG_DEBUG("Target ID is empty, using backup"); - const auto scriptedEntities = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPT); - - const auto& referencePoint = entity->GetPosition(); - - for (auto* scripted : scriptedEntities) { - if (Vector3::DistanceSquared(scripted->GetPosition(), referencePoint) > 5.0f * 5.0f) continue; - - scripted->OnEmoteReceived(emoteID, entity); - missionComponent->Progress(eMissionTaskType::EMOTE, emoteID, scripted->GetObjectID()); - } - } - } - CDEmoteTableTable* emotes = CDClientManager::Instance().GetTable(); if (emotes) { CDEmoteTable* emote = emotes->GetEmote(emoteID); @@ -5049,6 +5023,32 @@ void GameMessages::HandlePlayEmote(RakNet::BitStream* inStream, Entity* entity) } RenderComponent::PlayAnimation(entity, sAnimationName); + + MissionComponent* missionComponent = entity->GetComponent(); + if (!missionComponent) return; + + if (targetID != LWOOBJID_EMPTY) { + auto* targetEntity = Game::entityManager->GetEntity(targetID); + + LOG_DEBUG("Emote target found (%d)", targetEntity != nullptr); + + if (targetEntity != nullptr) { + targetEntity->OnEmoteReceived(emoteID, entity); + missionComponent->Progress(eMissionTaskType::EMOTE, emoteID, targetID); + } + } else { + LOG_DEBUG("Target ID is empty, using backup"); + const auto scriptedEntities = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPT); + + const auto& referencePoint = entity->GetPosition(); + + for (auto* scripted : scriptedEntities) { + if (Vector3::DistanceSquared(scripted->GetPosition(), referencePoint) > 5.0f * 5.0f) continue; + + scripted->OnEmoteReceived(emoteID, entity); + missionComponent->Progress(eMissionTaskType::EMOTE, emoteID, scripted->GetObjectID()); + } + } } void GameMessages::HandleModularBuildConvertModel(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { From 57a1c05e98c3869164bb98e24a7c5ad480a699a0 Mon Sep 17 00:00:00 2001 From: jadebenn Date: Tue, 21 Nov 2023 21:19:30 -0600 Subject: [PATCH 10/10] update loop cleanup --- dGame/dComponents/PetComponent.cpp | 54 ++++++++++++++---------------- dGame/dComponents/PetComponent.h | 6 ++++ 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index f979def4..de5a7ef3 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -341,42 +341,18 @@ void PetComponent::Update(float deltaTime) { } if (m_Owner == LWOOBJID_EMPTY) { - if (m_Tamer != LWOOBJID_EMPTY) { - if (m_Timer > 0) { - m_Timer -= deltaTime; - - if (m_Timer <= 0) { - m_Timer = 0; - - ClientFailTamingMinigame(); - } - } - } else { - if (m_Timer > 0) { - m_Timer -= deltaTime; - - if (m_Timer <= 0) { - Wander(); - Game::entityManager->SerializeEntity(m_Parent); - } - } else { - m_Timer = 5; - } - } - + UpdateUnowned(deltaTime); return; } auto* owner = GetOwner(); - if (owner == nullptr) { + if (!owner) { m_Parent->Kill(); return; } m_MovementAI = m_Parent->GetComponent(); - if (m_MovementAI == nullptr) { - return; - } + if (!m_MovementAI) return; if (m_TresureTime > 0.0f) { //TODO: Find better trigger? InteractDig(deltaTime); @@ -404,7 +380,6 @@ void PetComponent::Update(float deltaTime) { if (m_Timer > 0) { m_Timer -= deltaTime; - return; } @@ -468,6 +443,29 @@ skipTresure: m_Timer = 1; } +void PetComponent::UpdateUnowned(float deltaTime) { + if (m_Tamer != LWOOBJID_EMPTY) { + if (m_Timer > 0) { + m_Timer -= deltaTime; + + if (m_Timer <= 0) { + m_Timer = 0; + + ClientFailTamingMinigame(); + } + } + } + else { + if (m_Timer > 0) { + m_Timer -= deltaTime; + + if (m_Timer <= 0) Wander(); + } else { + m_Timer = 5; + } + } +} + void PetComponent::SetIsReadyToDig(bool isReady) { if (isReady) { LOG("Dig state reached!"); diff --git a/dGame/dComponents/PetComponent.h b/dGame/dComponents/PetComponent.h index 4ec0ef29..57f4a01f 100644 --- a/dGame/dComponents/PetComponent.h +++ b/dGame/dComponents/PetComponent.h @@ -47,6 +47,12 @@ public: void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; void Update(float deltaTime) override; + /** + * Handles updates for unowned pets + * @param deltaTime time since last update + */ + void UpdateUnowned(float deltaTime); + /** * Handles an OnUse event from another entity, initializing the pet taming minigame if this pet is untamed. * @param originator the entity that triggered the event