feat: fire events for loot rolls, trade windows, and duels

Add missing addon events for three gameplay systems:

Loot rolls:
- START_LOOT_ROLL fires on SMSG_LOOT_START_ROLL with slot and countdown
- LOOT_SLOT_CLEARED fires when a loot item is removed (SMSG_LOOT_REMOVED)

Trade:
- TRADE_REQUEST when another player initiates a trade
- TRADE_SHOW when the trade window opens
- TRADE_CLOSED when trade is cancelled, declined, or completed
- TRADE_ACCEPT_UPDATE when the trade partner accepts

Duels:
- DUEL_REQUESTED with challenger name on incoming duel challenge
- DUEL_FINISHED when a duel completes or is cancelled
This commit is contained in:
Kelsi 2026-03-21 02:57:00 -07:00
parent 7105672f06
commit 3b8165cbef

View file

@ -2420,6 +2420,8 @@ void GameHandler::handlePacket(network::Packet& packet) {
pendingLootRoll_.rollStartedAt = std::chrono::steady_clock::now(); pendingLootRoll_.rollStartedAt = std::chrono::steady_clock::now();
LOG_INFO("SMSG_LOOT_START_ROLL: item=", itemId, " (", pendingLootRoll_.itemName, LOG_INFO("SMSG_LOOT_START_ROLL: item=", itemId, " (", pendingLootRoll_.itemName,
") slot=", slot, " voteMask=0x", std::hex, (int)voteMask, std::dec); ") slot=", slot, " voteMask=0x", std::hex, (int)voteMask, std::dec);
if (addonEventCallback_)
addonEventCallback_("START_LOOT_ROLL", {std::to_string(slot), std::to_string(countdown)});
break; break;
} }
@ -14261,6 +14263,7 @@ void GameHandler::handleDuelRequested(network::Packet& packet) {
} }
LOG_INFO("SMSG_DUEL_REQUESTED: challenger=0x", std::hex, duelChallengerGuid_, LOG_INFO("SMSG_DUEL_REQUESTED: challenger=0x", std::hex, duelChallengerGuid_,
" flag=0x", duelFlagGuid_, std::dec, " name=", duelChallengerName_); " flag=0x", duelFlagGuid_, std::dec, " name=", duelChallengerName_);
if (addonEventCallback_) addonEventCallback_("DUEL_REQUESTED", {duelChallengerName_});
} }
void GameHandler::handleDuelComplete(network::Packet& packet) { void GameHandler::handleDuelComplete(network::Packet& packet) {
@ -14273,6 +14276,7 @@ void GameHandler::handleDuelComplete(network::Packet& packet) {
addSystemChatMessage("The duel was cancelled."); addSystemChatMessage("The duel was cancelled.");
} }
LOG_INFO("SMSG_DUEL_COMPLETE: started=", static_cast<int>(started)); LOG_INFO("SMSG_DUEL_COMPLETE: started=", static_cast<int>(started));
if (addonEventCallback_) addonEventCallback_("DUEL_FINISHED", {});
} }
void GameHandler::handleDuelWinner(network::Packet& packet) { void GameHandler::handleDuelWinner(network::Packet& packet) {
@ -22280,6 +22284,8 @@ void GameHandler::handleLootRemoved(network::Packet& packet) {
sfx->playLootItem(); sfx->playLootItem();
} }
currentLoot.items.erase(it); currentLoot.items.erase(it);
if (addonEventCallback_)
addonEventCallback_("LOOT_SLOT_CLEARED", {std::to_string(slotIndex + 1)});
break; break;
} }
} }
@ -25749,6 +25755,7 @@ void GameHandler::handleTradeStatus(network::Packet& packet) {
} }
tradeStatus_ = TradeStatus::PendingIncoming; tradeStatus_ = TradeStatus::PendingIncoming;
addSystemChatMessage(tradePeerName_ + " wants to trade with you."); addSystemChatMessage(tradePeerName_ + " wants to trade with you.");
if (addonEventCallback_) addonEventCallback_("TRADE_REQUEST", {});
break; break;
} }
case 2: // OPEN_WINDOW case 2: // OPEN_WINDOW
@ -25758,22 +25765,27 @@ void GameHandler::handleTradeStatus(network::Packet& packet) {
peerTradeGold_ = 0; peerTradeGold_ = 0;
tradeStatus_ = TradeStatus::Open; tradeStatus_ = TradeStatus::Open;
addSystemChatMessage("Trade window opened."); addSystemChatMessage("Trade window opened.");
if (addonEventCallback_) addonEventCallback_("TRADE_SHOW", {});
break; break;
case 3: // CANCELLED case 3: // CANCELLED
case 12: // CLOSE_WINDOW case 12: // CLOSE_WINDOW
resetTradeState(); resetTradeState();
addSystemChatMessage("Trade cancelled."); addSystemChatMessage("Trade cancelled.");
if (addonEventCallback_) addonEventCallback_("TRADE_CLOSED", {});
break; break;
case 9: // REJECTED — other player clicked Decline case 9: // REJECTED — other player clicked Decline
resetTradeState(); resetTradeState();
addSystemChatMessage("Trade declined."); addSystemChatMessage("Trade declined.");
if (addonEventCallback_) addonEventCallback_("TRADE_CLOSED", {});
break; break;
case 4: // ACCEPTED (partner accepted) case 4: // ACCEPTED (partner accepted)
tradeStatus_ = TradeStatus::Accepted; tradeStatus_ = TradeStatus::Accepted;
addSystemChatMessage("Trade accepted. Awaiting other player..."); addSystemChatMessage("Trade accepted. Awaiting other player...");
if (addonEventCallback_) addonEventCallback_("TRADE_ACCEPT_UPDATE", {});
break; break;
case 8: // COMPLETE case 8: // COMPLETE
addSystemChatMessage("Trade complete!"); addSystemChatMessage("Trade complete!");
if (addonEventCallback_) addonEventCallback_("TRADE_CLOSED", {});
resetTradeState(); resetTradeState();
break; break;
case 7: // BACK_TO_TRADE (unaccepted after a change) case 7: // BACK_TO_TRADE (unaccepted after a change)