From 76ba428b87f7cf899a3361f12381820dd26b6187 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Wed, 18 Mar 2026 00:39:32 -0700 Subject: [PATCH] fix: /target command selects nearest matching entity Previously used arbitrary map-iteration order (last match), meaning '/target Kobold' might target a far-away enemy instead of the closest. Now computes squared distance for every prefix-matching entity and keeps the nearest one, matching WoW's own /target behaviour. --- src/ui/game_screen.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/ui/game_screen.cpp b/src/ui/game_screen.cpp index c3eed8d6..0b5306da 100644 --- a/src/ui/game_screen.cpp +++ b/src/ui/game_screen.cpp @@ -6200,11 +6200,17 @@ void GameScreen::sendChatMessage(game::GameHandler& gameHandler) { } if (cmdLower == "target" && spacePos != std::string::npos) { - // Search visible entities for name match (case-insensitive prefix) + // Search visible entities for name match (case-insensitive prefix). + // Among all matches, pick the nearest living unit to the player. std::string targetArg = command.substr(spacePos + 1); std::string targetArgLower = targetArg; for (char& c : targetArgLower) c = static_cast(std::tolower(static_cast(c))); uint64_t bestGuid = 0; + float bestDist = std::numeric_limits::max(); + const auto& pmi = gameHandler.getMovementInfo(); + const float playerX = pmi.x; + const float playerY = pmi.y; + const float playerZ = pmi.z; for (const auto& [guid, entity] : gameHandler.getEntityManager().getEntities()) { if (!entity || entity->getType() == game::ObjectType::OBJECT) continue; std::string name; @@ -6217,8 +6223,14 @@ void GameScreen::sendChatMessage(game::GameHandler& gameHandler) { std::string nameLower = name; for (char& c : nameLower) c = static_cast(std::tolower(static_cast(c))); if (nameLower.find(targetArgLower) == 0) { - bestGuid = guid; - if (nameLower == targetArgLower) break; // Exact match wins + float dx = entity->getX() - playerX; + float dy = entity->getY() - playerY; + float dz = entity->getZ() - playerZ; + float dist = dx*dx + dy*dy + dz*dz; + if (dist < bestDist) { + bestDist = dist; + bestGuid = guid; + } } } if (bestGuid) {