fix: quest objective GOs never granted credit — REPORT_USE skipped for chests

CMSG_GAMEOBJ_REPORT_USE was only sent for non-chest GOs. Chest-type
(type=3) and name-matched chest-like GOs (Bundle of Wood, etc.) went
through a separate path that sent CMSG_GAMEOBJ_USE + CMSG_LOOT but
skipped REPORT_USE. On AzerothCore, REPORT_USE triggers the server-side
HandleGameobjectReportUse which calls GossipHello on the GO script —
this is where many quest objective scripts grant credit.

Restructured so CMSG_GAMEOBJ_USE is sent first for all GO types,
then chest-like GOs additionally send CMSG_LOOT, and REPORT_USE fires
for everything except mailboxes.
This commit is contained in:
Kelsi 2026-03-29 22:04:23 -07:00
parent f23a7c06d9
commit c1c28d4216

View file

@ -6213,39 +6213,37 @@ void GameHandler::performGameObjectInteractionNow(uint64_t guid) {
" entry=", goEntry, " type=", goType, " entry=", goEntry, " type=", goType,
" name='", goName, "' chestLike=", chestLike, " isMailbox=", isMailbox); " name='", goName, "' chestLike=", chestLike, " isMailbox=", isMailbox);
// Always send CMSG_GAMEOBJ_USE first — this triggers the server-side
// GameObject::Use() handler for all GO types.
auto usePacket = GameObjectUsePacket::build(guid);
socket->send(usePacket);
lastInteractedGoGuid_ = guid;
if (chestLike) { if (chestLike) {
// For chest-like GOs: send CMSG_GAMEOBJ_USE (opens the chest) followed // Chest-like GOs also need a CMSG_LOOT to open the loot window.
// immediately by CMSG_LOOT (requests loot contents). Both sent in the // Sent in the same frame: USE transitions the GO to lootable state,
// same frame so the server processes them sequentially: USE transitions // then LOOT requests the contents.
// the GO to lootable state, then LOOT reads the contents.
auto usePacket = GameObjectUsePacket::build(guid);
socket->send(usePacket);
lootTarget(guid); lootTarget(guid);
lastInteractedGoGuid_ = guid; } else if (isMailbox) {
} else { LOG_INFO("Mailbox interaction: opening mail UI and requesting mail list");
// Non-chest GOs (doors, buttons, quest givers, etc.): use CMSG_GAMEOBJ_USE mailboxGuid_ = guid;
auto packet = GameObjectUsePacket::build(guid); mailboxOpen_ = true;
socket->send(packet); hasNewMail_ = false;
lastInteractedGoGuid_ = guid; selectedMailIndex_ = -1;
showMailCompose_ = false;
refreshMailList();
}
if (isMailbox) { // CMSG_GAMEOBJ_REPORT_USE triggers GO AI scripts (SmartAI, ScriptAI) which
LOG_INFO("Mailbox interaction: opening mail UI and requesting mail list"); // is where many quest objectives grant credit. Previously this was only sent
mailboxGuid_ = guid; // for non-chest GOs, so chest-type quest objectives (Bundle of Wood, etc.)
mailboxOpen_ = true; // never triggered the server-side quest credit script.
hasNewMail_ = false; if (!isMailbox) {
selectedMailIndex_ = -1; const auto* table = getActiveOpcodeTable();
showMailCompose_ = false; if (table && table->hasOpcode(Opcode::CMSG_GAMEOBJ_REPORT_USE)) {
refreshMailList(); network::Packet reportUse(wireOpcode(Opcode::CMSG_GAMEOBJ_REPORT_USE));
} reportUse.writeUInt64(guid);
socket->send(reportUse);
// CMSG_GAMEOBJ_REPORT_USE for GO AI scripts (quest givers, etc.)
if (!isMailbox) {
const auto* table = getActiveOpcodeTable();
if (table && table->hasOpcode(Opcode::CMSG_GAMEOBJ_REPORT_USE)) {
network::Packet reportUse(wireOpcode(Opcode::CMSG_GAMEOBJ_REPORT_USE));
reportUse.writeUInt64(guid);
socket->send(reportUse);
}
} }
} }
} }