From 898ae024f050f71dc1de95b84aaa322fea7ab7fa Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Wed, 30 Sep 2026 07:45:56 -0500 Subject: [PATCH] feat(loot): a picked up item says which object it dropped from Live's AddItemToInventoryClientSync for a picked up drop had _Metric_Souce_LOT_Int in its extra info on all 2,344 live pickups: the LOT of the DropClientLoot's source object, 1 when a player was the source (activity rewards and chests, which drop from the player). DLU sent none. The drop remembers its source object's LOT when it is registered for the player, and the pickup sends it. A source object already gone when it drops sends no key. Package contents keep sending none, as live's did. Co-Authored-By: Claude Opus 5.5 --- dGame/Entity.cpp | 7 ++++++- dGame/dUtilities/Loot.h | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 71bf23434..76e6f46c8 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -1537,7 +1537,10 @@ void Entity::PickupItem(const LWOOBJID& objectID) const { } EconomyLedger::RecordMapEvent(IEconomyLedger::eMapEvent::POWERUP_PICKUPS, info.lot, GetPosition(), 1, this); } else { - inv->AddItem(info.lot, info.count, eLootSourceType::PICKUP, eInventoryType::INVALID, {}, LWOOBJID_EMPTY, true, false, LWOOBJID_EMPTY, eInventoryType::INVALID, 1); + // Live told the client which object the item dropped from (all 2,344 live pickups of a dropped item) + LootMetrics metrics{}; + if (info.sourceLot != 0) metrics.sourceLot = info.sourceLot; + inv->AddItem(info.lot, info.count, eLootSourceType::PICKUP, eInventoryType::INVALID, {}, LWOOBJID_EMPTY, true, false, LWOOBJID_EMPTY, eInventoryType::INVALID, 1, false, -1, metrics); } droppedLoot.erase(objectID); @@ -2118,10 +2121,12 @@ bool Entity::MsgRequestServerObjectInfo(GameMessages::RequestServerObjectInfoEve bool Entity::MsgDropClientLoot(GameMessages::DropClientLootEvent& event) { const auto& dropLootMsg = event.msg; if (dropLootMsg.item != LOT_NULL && dropLootMsg.item != 0) { + const auto* const source = Game::entityManager->GetEntity(dropLootMsg.sourceID); Loot::Info info{ .id = dropLootMsg.lootID, .lot = dropLootMsg.item, .count = dropLootMsg.count, + .sourceLot = source ? source->GetLOT() : 0, }; AddLootItem(info); } diff --git a/dGame/dUtilities/Loot.h b/dGame/dUtilities/Loot.h index f6bb0bd92..c2eba6e4a 100644 --- a/dGame/dUtilities/Loot.h +++ b/dGame/dUtilities/Loot.h @@ -20,6 +20,9 @@ namespace Loot { LWOOBJID id = 0; LOT lot = 0; int32_t count = 0; + // The LOT of the object it dropped from (1 when a player was the source), 0 when that object was not found. + // Sent back as the item's source when it is picked up (LootMetrics::sourceLot). + LOT sourceLot = 0; }; using Return = std::map;