mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-02 10:53:44 +00:00
fix(pets): the backpack lets go of a pet that went away on its own
Issue 539. When a pet is sent away the client greys its backpack item out again by looking the item up by the ID in MarkInventoryItemAsActive (LWOInventoryComponent_Common::SendMessage 0x00d54b90). The pet kept the item ID it was summoned with, but items get new IDs when they move, so the lookup could miss and the item stayed marked active; the pet's item is now looked up by its subkey when the pet goes away. Sending a pet away also sent AddPetToPlayer with an empty pet. The client never removes anything on that message, it adds a new entry to its pet list (LWOPetControlComponent::HandleMessage 0x00d0fe00), so it left an empty pet behind; live did not send it (2014 captures) and it is no longer sent. RegisterPetID with no pet already clears the active pet and hides the pet menu. The imagination drain kept going after it had sent the pet away (and took another point of imagination); it stops there now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1045,6 +1045,9 @@ void PetComponent::AddDrainImaginationTimer(bool fromTaming) {
|
||||
const auto* playerDestroyableComponent = owner->GetComponent<DestroyableComponent>();
|
||||
if (!playerDestroyableComponent) return;
|
||||
|
||||
// Already going back to the backpack
|
||||
if (m_Despawning) return;
|
||||
|
||||
// If we are out of imagination despawn the pet.
|
||||
if (playerDestroyableComponent->GetImagination() == 0) {
|
||||
this->Deactivate();
|
||||
@@ -1055,6 +1058,8 @@ void PetComponent::AddDrainImaginationTimer(bool fromTaming) {
|
||||
requirementsResponse.target = playerEntity->GetObjectID();
|
||||
requirementsResponse.eUseResponse = eUseItemResponse::NoImaginationForPet;
|
||||
requirementsResponse.SendToClient(playerEntity->GetSystemAddress());
|
||||
// The pet is gone: no more draining
|
||||
return;
|
||||
}
|
||||
|
||||
this->AddDrainImaginationTimer();
|
||||
@@ -1081,23 +1086,18 @@ void PetComponent::Deactivate() {
|
||||
|
||||
if (owner == nullptr) return;
|
||||
|
||||
// The client looks the item up by this ID to grey it out again (LWOInventoryComponent_Common::SendMessage), and
|
||||
// items get new IDs when they move, so use the ID the pet's item has now
|
||||
auto* const inventoryComponent = owner->GetComponent<InventoryComponent>();
|
||||
const auto* const item = inventoryComponent ? inventoryComponent->FindItemBySubKey(m_DatabaseId) : nullptr;
|
||||
|
||||
GameMessages::MarkInventoryItemAsActive markActive;
|
||||
markActive.target = m_Owner;
|
||||
markActive.bActive = false;
|
||||
markActive.iType = eUnequippableActiveType::PET;
|
||||
markActive.itemID = m_ItemId;
|
||||
markActive.itemID = item ? item->GetId() : m_ItemId;
|
||||
markActive.Send(owner->GetSystemAddress());
|
||||
|
||||
{
|
||||
GameMessages::AddPetToPlayer msg;
|
||||
msg.target = m_Owner;
|
||||
msg.iElementalType = 0;
|
||||
msg.name = u"";
|
||||
msg.petDBID = LWOOBJID_EMPTY;
|
||||
msg.petLOT = LOT_NULL;
|
||||
msg.Send(owner->GetSystemAddress());
|
||||
}
|
||||
|
||||
{
|
||||
GameMessages::RegisterPetID msg;
|
||||
msg.target = m_Owner;
|
||||
|
||||
Reference in New Issue
Block a user