From 63e85d396d64a2bf74513cf88b1baeeccfcece8f Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Sun, 27 Sep 2026 08:41:28 -0500 Subject: [PATCH] fix(pets): tamed pandas and crabs leave their spawn groups The live server scripts (l_fv_panda_server.lua, l_crab_server.lua, in the client's res/scripts) take a tamed pet out of the groups it was spawned into: the panda leaves "pandas" and "panda", the crab "crab". The panda spawner counts "pandas" (at most five) and "panda" (one per player), so tamed pandas used to keep counting against both. Entity gets RemoveFromGroup for it. The dig and object pet scripts keep their TODO: their live server scripts are not shipped with the client. Co-Authored-By: Claude Opus 5.5 --- dGame/Entity.cpp | 4 ++++ dGame/Entity.h | 1 + dScripts/ai/FV/FvPandaServer.cpp | 4 +++- dScripts/client/ai/PR/CrabServer.cpp | 3 ++- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index d4ca9a0df..99218896c 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -1935,6 +1935,10 @@ void Entity::AddToGroup(const std::string& group) { } } +void Entity::RemoveFromGroup(const std::string& group) { + std::erase(m_Groups, group); +} + void Entity::RetroactiveVaultSize() const { auto* const inventoryComponent = GetComponent(); if (!inventoryComponent) return; diff --git a/dGame/Entity.h b/dGame/Entity.h index 275aea2ce..946bc335a 100644 --- a/dGame/Entity.h +++ b/dGame/Entity.h @@ -212,6 +212,7 @@ public: void CancelTimer(const std::string& name); void AddToGroup(const std::string& group); + void RemoveFromGroup(const std::string& group); bool IsPlayer() const; std::unordered_map& GetComponents() { return m_Components; } // TODO: Remove diff --git a/dScripts/ai/FV/FvPandaServer.cpp b/dScripts/ai/FV/FvPandaServer.cpp index f29f7f2ee..59b294fa1 100644 --- a/dScripts/ai/FV/FvPandaServer.cpp +++ b/dScripts/ai/FV/FvPandaServer.cpp @@ -17,7 +17,9 @@ void FvPandaServer::OnNotifyPetTamingMinigame(Entity* self, Entity* tamer, ePetT } else if (type == ePetTamingNotifyType::QUIT || type == ePetTamingNotifyType::FAILED) { self->Smash(); } else if (type == ePetTamingNotifyType::SUCCESS) { - // TODO: Remove from groups + // A tamed panda no longer counts against the spawner's limit or the tamer's one panda (live script) + self->RemoveFromGroup("pandas"); + self->RemoveFromGroup("panda" + std::to_string(tamer->GetObjectID())); auto* character = tamer->GetCharacter(); if (character != nullptr) { diff --git a/dScripts/client/ai/PR/CrabServer.cpp b/dScripts/client/ai/PR/CrabServer.cpp index 6cdc2de8c..450d9bb4f 100644 --- a/dScripts/client/ai/PR/CrabServer.cpp +++ b/dScripts/client/ai/PR/CrabServer.cpp @@ -37,7 +37,8 @@ void CrabServer::OnNotifyPetTamingMinigame(Entity* self, Entity* tamer, ePetTami auto* petComponent = self->GetComponent(); if (petComponent == nullptr) return; - // TODO: Remove custom group? + // The live script takes the tamed crab out of its tamer's group + self->RemoveFromGroup("crab" + std::to_string(tamer->GetObjectID())); // Command the pet to the player as it may otherwise go to its spawn point which is non existant // petComponent->Command(NiPoint3Constant::ZERO, LWOOBJID_EMPTY, 6, 202, true); }