From 5734ef85e80664899dc83099190ab604f9f310e8 Mon Sep 17 00:00:00 2001 From: jadebenn Date: Sat, 18 Nov 2023 18:43:47 -0600 Subject: [PATCH] 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: