From 1a74ed676bb2a7b618f273574b52c4ede0d0ad59 Mon Sep 17 00:00:00 2001 From: jadebenn Date: Sun, 19 Nov 2023 16:46:27 -0600 Subject: [PATCH] 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 4cddebff..39634a28 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -5018,28 +5018,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 75af4c96..49eb056e 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -697,32 +697,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; @@ -750,6 +724,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 0ba7d86e..1312ede0 100644 --- a/docs/Commands.md +++ b/docs/Commands.md @@ -82,6 +82,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|