From 16fc3ebfdf74bea90803930f172167c2ad8683f9 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Fri, 27 Mar 2026 17:41:37 -0700 Subject: [PATCH] feat: target frame right-click context menu; add equipment diagnostic logging Target frame: add Follow, Clear Target, and Set Raid Mark submenu to the right-click context menu (Inspect, Trade, Duel were already present). Equipment diagnostics: add LOG_INFO traces to updateOtherPlayerVisibleItems() and emitOtherPlayerEquipment() to debug why other players appear naked. Logs the visible item entry IDs received from the server and the resolved displayIds from itemInfoCache. Check the log for "emitOtherPlayerEquipment" to see if entries arrive as zeros (server not sending fields) or if displayIds are zero (item templates not cached yet). --- src/game/game_handler.cpp | 21 ++++++++++++++++++++- src/ui/game_screen.cpp | 27 +++++++++++++++++++++++---- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/game/game_handler.cpp b/src/game/game_handler.cpp index d0a793d3..db638d70 100644 --- a/src/game/game_handler.cpp +++ b/src/game/game_handler.cpp @@ -15185,6 +15185,16 @@ void GameHandler::updateOtherPlayerVisibleItems(uint64_t guid, const std::mapsecond; } + int nonZero = 0; + for (uint32_t e : newEntries) { if (e != 0) nonZero++; } + if (nonZero > 0) { + LOG_INFO("updateOtherPlayerVisibleItems: guid=0x", std::hex, guid, std::dec, + " nonZero=", nonZero, + " head=", newEntries[0], " shoulders=", newEntries[2], + " chest=", newEntries[4], " legs=", newEntries[6], + " mainhand=", newEntries[15], " offhand=", newEntries[16]); + } + bool changed = false; auto& old = otherPlayerVisibleItemEntries_[guid]; if (old != newEntries) { @@ -15221,17 +15231,26 @@ void GameHandler::emitOtherPlayerEquipment(uint64_t guid) { std::array displayIds{}; std::array invTypes{}; bool anyEntry = false; + int resolved = 0, unresolved = 0; for (int s = 0; s < 19; s++) { uint32_t entry = it->second[s]; if (entry == 0) continue; anyEntry = true; auto infoIt = itemInfoCache_.find(entry); - if (infoIt == itemInfoCache_.end()) continue; + if (infoIt == itemInfoCache_.end()) { unresolved++; continue; } displayIds[s] = infoIt->second.displayInfoId; invTypes[s] = static_cast(infoIt->second.inventoryType); + resolved++; } + LOG_INFO("emitOtherPlayerEquipment: guid=0x", std::hex, guid, std::dec, + " entries=", (anyEntry ? "yes" : "none"), + " resolved=", resolved, " unresolved=", unresolved, + " head=", displayIds[0], " shoulders=", displayIds[2], + " chest=", displayIds[4], " legs=", displayIds[6], + " mainhand=", displayIds[15], " offhand=", displayIds[16]); + playerEquipmentCallback_(guid, displayIds, invTypes); otherPlayerVisibleDirty_.erase(guid); diff --git a/src/ui/game_screen.cpp b/src/ui/game_screen.cpp index cfb06a5d..2d92d2e3 100644 --- a/src/ui/game_screen.cpp +++ b/src/ui/game_screen.cpp @@ -4234,11 +4234,17 @@ void GameScreen::renderTargetFrame(game::GameHandler& gameHandler) { // Right-click context menu on target frame if (ImGui::BeginPopupContextItem("##TargetFrameCtx")) { + const bool isPlayer = (target->getType() == game::ObjectType::PLAYER); + const uint64_t tGuid = target->getGuid(); + ImGui::TextDisabled("%s", name.c_str()); ImGui::Separator(); + if (ImGui::MenuItem("Set Focus")) - gameHandler.setFocus(target->getGuid()); - if (target->getType() == game::ObjectType::PLAYER) { + gameHandler.setFocus(tGuid); + if (ImGui::MenuItem("Clear Target")) + gameHandler.clearTarget(); + if (isPlayer) { ImGui::Separator(); if (ImGui::MenuItem("Whisper")) { selectedChatType = 4; @@ -4246,12 +4252,14 @@ void GameScreen::renderTargetFrame(game::GameHandler& gameHandler) { whisperTargetBuffer[sizeof(whisperTargetBuffer) - 1] = '\0'; refocusChatInput = true; } + if (ImGui::MenuItem("Follow")) + gameHandler.followTarget(); if (ImGui::MenuItem("Invite to Group")) gameHandler.inviteToGroup(name); if (ImGui::MenuItem("Trade")) - gameHandler.initiateTrade(target->getGuid()); + gameHandler.initiateTrade(tGuid); if (ImGui::MenuItem("Duel")) - gameHandler.proposeDuel(target->getGuid()); + gameHandler.proposeDuel(tGuid); if (ImGui::MenuItem("Inspect")) { gameHandler.inspectTarget(); showInspectWindow_ = true; @@ -4262,6 +4270,17 @@ void GameScreen::renderTargetFrame(game::GameHandler& gameHandler) { if (ImGui::MenuItem("Ignore")) gameHandler.addIgnore(name); } + ImGui::Separator(); + if (ImGui::BeginMenu("Set Raid Mark")) { + for (int mi = 0; mi < 8; ++mi) { + if (ImGui::MenuItem(kRaidMarkNames[mi])) + gameHandler.setRaidMark(tGuid, static_cast(mi)); + } + ImGui::Separator(); + if (ImGui::MenuItem("Clear Mark")) + gameHandler.setRaidMark(tGuid, 0xFF); + ImGui::EndMenu(); + } ImGui::EndPopup(); }