diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index 2df5d371f..661022417 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -1879,6 +1879,11 @@ void InventoryComponent::UpdatePetXml(tinyxml2::XMLDocument& document) { petInventoryElement->DeleteChildren(); + // The client reads a as its active pet's database ID (LWOPetControlComponent::LoadFromSaveData 0x00c18120). The + // charxml is only read when the player loads, when no pet is out yet (a pet is summoned again after the load and + // registers itself), so live wrote a="0" on every character (226 live charxmls) + petInventoryElement->SetAttribute("a", 0); + for (const auto& pet : m_Pets) { auto* petElement = document.NewElement("p"); @@ -1886,6 +1891,8 @@ void InventoryComponent::UpdatePetXml(tinyxml2::XMLDocument& document) { petElement->SetAttribute("l", pet.second.lot); petElement->SetAttribute("m", pet.second.moderationState); petElement->SetAttribute("n", pet.second.name.c_str()); + // The taming type: the client sets it to 0 for every pet added (AddPetToPlayer in + // LWOPetControlComponent::HandleMessage 0x00d0fe00) and live saved 0 for every pet petElement->SetAttribute("t", 0); petInventoryElement->LinkEndChild(petElement); diff --git a/tests/dGameTests/dComponentsTests/CharacterSaveFieldsTests.cpp b/tests/dGameTests/dComponentsTests/CharacterSaveFieldsTests.cpp index 9feb23612..6cc9c85f8 100644 --- a/tests/dGameTests/dComponentsTests/CharacterSaveFieldsTests.cpp +++ b/tests/dGameTests/dComponentsTests/CharacterSaveFieldsTests.cpp @@ -9,6 +9,8 @@ #include "GameMessages.h" #include "MissionComponent.h" #include "SkillComponent.h" +#include "InventoryComponent.h" +#include "DatabasePet.h" #include "CDSkillBehaviorTable.h" #include "CDClientManager.h" #include "eMissionLockState.h" @@ -163,3 +165,18 @@ TEST_F(CharacterSaveFieldsTests, SkillCooldownsMissingInOldSave) { skills->UpdateXml(doc); EXPECT_EQ(Print(doc), R"()"); } + +// : live wrote the active pet as 0 on every character (the charxml is read at load, before any pet is out), +// and each pet's taming type t as 0. Old saves without a load as before. +TEST_F(CharacterSaveFieldsTests, PetsAsLiveWroteThem) { + CDClientDatabase::ExecuteDML("CREATE TABLE ComponentsRegistry (id INTEGER, component_type INTEGER, component_id INTEGER);"); + tinyxml2::XMLDocument doc; + Parse(doc, R"(

)"); + + Entity player(29, info); + auto* const inventory = player.AddComponent(-1); + inventory->LoadXml(doc); // the pets load first; there is no here + EXPECT_EQ(inventory->GetDatabasePet(1152921510000000001LL).lot, 3254); + inventory->UpdateXml(doc); + EXPECT_EQ(Print(doc), R"(

)"); +}