From fe61d6acce789883a079f5b46155858fdbe755b5 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Wed, 11 Mar 2026 23:19:48 -0700 Subject: [PATCH] Add corpse direction indicator on minimap for ghost players When the player is a ghost, shows a small X marker at the corpse position on the minimap. If the corpse is off-screen, draws an edge arrow on the minimap border pointing toward it. --- include/game/game_handler.hpp | 8 +++++ src/ui/game_screen.cpp | 68 +++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/include/game/game_handler.hpp b/include/game/game_handler.hpp index 870e774c..dadc30ae 100644 --- a/include/game/game_handler.hpp +++ b/include/game/game_handler.hpp @@ -899,6 +899,14 @@ public: float dz = movementInfo.z - corpseZ_; return std::sqrt(dx*dx + dy*dy + dz*dz); } + /** Corpse position in canonical WoW coords (X=north, Y=west). + * Returns false if no corpse data or on a different map. */ + bool getCorpseCanonicalPos(float& outX, float& outY) const { + if (corpseMapId_ == 0 || currentMapId_ != corpseMapId_) return false; + outX = corpseY_; // server Y = canonical X (north) + outY = corpseX_; // server X = canonical Y (west) + return true; + } /** Send CMSG_RECLAIM_CORPSE; noop if not a ghost or not near corpse. */ void reclaimCorpse(); void releaseSpirit(); diff --git a/src/ui/game_screen.cpp b/src/ui/game_screen.cpp index 8f6c0224..e59444fe 100644 --- a/src/ui/game_screen.cpp +++ b/src/ui/game_screen.cpp @@ -10751,6 +10751,74 @@ void GameScreen::renderMinimapMarkers(game::GameHandler& gameHandler) { } } + // Corpse direction indicator — shown when player is a ghost + if (gameHandler.isPlayerGhost()) { + float corpseCanX = 0.0f, corpseCanY = 0.0f; + if (gameHandler.getCorpseCanonicalPos(corpseCanX, corpseCanY)) { + glm::vec3 corpseRender = core::coords::canonicalToRender(glm::vec3(corpseCanX, corpseCanY, 0.0f)); + float csx = 0.0f, csy = 0.0f; + bool onMap = projectToMinimap(corpseRender, csx, csy); + + if (onMap) { + // Draw a small skull-like X marker at the corpse position + const float r = 5.0f; + drawList->AddCircleFilled(ImVec2(csx, csy), r + 1.0f, IM_COL32(0, 0, 0, 140), 12); + drawList->AddCircle(ImVec2(csx, csy), r + 1.0f, IM_COL32(200, 200, 220, 220), 12, 1.5f); + // Draw an X in the circle + drawList->AddLine(ImVec2(csx - 3.0f, csy - 3.0f), ImVec2(csx + 3.0f, csy + 3.0f), + IM_COL32(180, 180, 220, 255), 1.5f); + drawList->AddLine(ImVec2(csx + 3.0f, csy - 3.0f), ImVec2(csx - 3.0f, csy + 3.0f), + IM_COL32(180, 180, 220, 255), 1.5f); + // Tooltip on hover + ImVec2 mouse = ImGui::GetMousePos(); + float mdx = mouse.x - csx, mdy = mouse.y - csy; + if (mdx * mdx + mdy * mdy < 64.0f) { + float dist = gameHandler.getCorpseDistance(); + if (dist >= 0.0f) + ImGui::SetTooltip("Your corpse (%.0f yd)", dist); + else + ImGui::SetTooltip("Your corpse"); + } + } else { + // Corpse is outside minimap — draw an edge arrow pointing toward it + float dx = corpseRender.x - playerRender.x; + float dy = corpseRender.y - playerRender.y; + // Rotate delta into minimap frame (same as projectToMinimap) + float rx = -(dx * cosB + dy * sinB); + float ry = dx * sinB - dy * cosB; + float len = std::sqrt(rx * rx + ry * ry); + if (len > 0.001f) { + float nx = rx / len; + float ny = ry / len; + // Place arrow at the minimap edge + float edgeR = mapRadius - 7.0f; + float ax = centerX + nx * edgeR; + float ay = centerY + ny * edgeR; + // Arrow pointing outward (toward corpse) + float arrowLen = 6.0f; + float arrowW = 3.5f; + ImVec2 tip(ax + nx * arrowLen, ay + ny * arrowLen); + ImVec2 left(ax - ny * arrowW - nx * arrowLen * 0.4f, + ay + nx * arrowW - ny * arrowLen * 0.4f); + ImVec2 right(ax + ny * arrowW - nx * arrowLen * 0.4f, + ay - nx * arrowW - ny * arrowLen * 0.4f); + drawList->AddTriangleFilled(tip, left, right, IM_COL32(180, 180, 240, 230)); + drawList->AddTriangle(tip, left, right, IM_COL32(0, 0, 0, 180), 1.0f); + // Tooltip on hover + ImVec2 mouse = ImGui::GetMousePos(); + float mdx = mouse.x - ax, mdy = mouse.y - ay; + if (mdx * mdx + mdy * mdy < 100.0f) { + float dist = gameHandler.getCorpseDistance(); + if (dist >= 0.0f) + ImGui::SetTooltip("Your corpse (%.0f yd)", dist); + else + ImGui::SetTooltip("Your corpse"); + } + } + } + } + } + // Scroll wheel over minimap → zoom in/out { float wheel = ImGui::GetIO().MouseWheel;