feat(loot): rewards, purchases, mail and trades say where items came from

The other item sources live marked in AddItemToInventoryClientSync's extra
info, with the keys and values live sent:
- mission and achievement rewards: _Metric_Mission_ID_Int and source LOT 1,
  the player (225 of 225 live rewards)
- activity rewards: _Metric_Activity_ID_Int and the activity object's LOT
- vendor purchases: the vendor's LOT and _Metric_Currency_Delta_Int, the coins
  paid as a negative number (left out when the item costs no coins)
- mail attachments: _Metric_Mail_ID_Int64
- traded items: _Metric_Transaction_ID_Int64, the trade's ID

Loot::GiveLoot gains overloads that pass them on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-30 07:46:05 -05:00
parent 898ae024f0
commit ed2d329781
6 changed files with 43 additions and 11 deletions

View File

@@ -189,7 +189,8 @@ void Trade::Complete() {
recordCoins(m_CoinsA, characterA->GetID(), characterB->GetID());
recordCoins(m_CoinsB, characterB->GetID(), characterA->GetID());
const auto giveItems = [zone](const std::vector<TradeItem>& items, InventoryComponent* from, MissionComponent* fromMissions,
const auto tradeId = m_TradeId;
const auto giveItems = [zone, tradeId](const std::vector<TradeItem>& items, InventoryComponent* from, MissionComponent* fromMissions,
InventoryComponent* to, const LWOOBJID fromCharacter, const LWOOBJID toCharacter) {
for (const auto& tradeItem : items) {
auto* itemToRemove = from->FindItemById(tradeItem.itemId);
@@ -204,9 +205,12 @@ void Trade::Complete() {
const auto bound = itemToRemove->GetBound();
itemToRemove->SetCount(itemToRemove->GetCount() - tradeItem.itemCount);
fromMissions->Progress(eMissionTaskType::GATHER, tradeItem.itemLot, LWOOBJID_EMPTY, "", -static_cast<int32_t>(tradeItem.itemCount));
// Live sent the trade's ID with the traded items
ReceiveItemOptions options{};
options.metrics.transactionId = tradeId;
const auto received = whole
? to->ReceiveItem(LWOOBJID_EMPTY, tradeItem.itemLot, tradeItem.itemCount, eLootSourceType::TRADE, config, subKey, bound)
: to->ReceiveItem(LWOOBJID_EMPTY, tradeItem.itemLot, tradeItem.itemCount, eLootSourceType::TRADE);
? to->ReceiveItem(LWOOBJID_EMPTY, tradeItem.itemLot, tradeItem.itemCount, eLootSourceType::TRADE, config, subKey, bound, options)
: to->ReceiveItem(LWOOBJID_EMPTY, tradeItem.itemLot, tradeItem.itemCount, eLootSourceType::TRADE, {}, LWOOBJID_EMPTY, false, options);
EconomyLedger::RecordTransfer({ .method = IEconomyLedger::eTransferMethod::TRADE, .itemId = tradeItem.itemId, .newItemId = received.id,
.lot = tradeItem.itemLot, .count = tradeItem.itemCount, .fromCharacter = fromCharacter, .toCharacter = toCharacter, .zone = zone,