diff --git a/src/game/spline_packet.cpp b/src/game/spline_packet.cpp index d31f7c24..9a6b624d 100644 --- a/src/game/spline_packet.cpp +++ b/src/game/spline_packet.cpp @@ -299,9 +299,10 @@ bool parseWotlkMoveUpdateSpline( packet.setReadPos(prePointCount); return false; } - // Proximity check: if entity position is known, reject endpoints that - // are implausibly far from it (catches misinterpreted compressed data). - if (entityPos.x != 0.0f || entityPos.y != 0.0f || entityPos.z != 0.0f) { + // Proximity check: if entity position is known (not the default 0,0,0 + // sentinel), reject endpoints that are implausibly far from it. + float posLenSq = entityPos.x * entityPos.x + entityPos.y * entityPos.y + entityPos.z * entityPos.z; + if (posLenSq > 1.0f) { float dx = epX - entityPos.x; float dy = epY - entityPos.y; float dz = epZ - entityPos.z; diff --git a/src/game/transport_path_repository.cpp b/src/game/transport_path_repository.cpp index 87ad5836..a9edfe01 100644 --- a/src/game/transport_path_repository.cpp +++ b/src/game/transport_path_repository.cpp @@ -315,12 +315,13 @@ bool TransportPathRepository::loadTransportAnimationDBC(pipeline::AssetManager* // Negate X and Y before converting to canonical (Z=height stays the same). glm::vec3 canonical = core::coords::serverToCanonical(glm::vec3(-pos.x, -pos.y, pos.z)); - // CRITICAL: Detect if serverToCanonical is zeroing nonzero inputs + // Skip waypoints where serverToCanonical zeroes nonzero inputs if ((pos.x != 0.0f || pos.y != 0.0f || pos.z != 0.0f) && (canonical.x == 0.0f && canonical.y == 0.0f && canonical.z == 0.0f)) { - LOG_ERROR("serverToCanonical ZEROED! entry=", transportEntry, + LOG_ERROR("serverToCanonical ZEROED — skipping waypoint! entry=", transportEntry, " server=(", pos.x, ",", pos.y, ",", pos.z, ")", " → canon=(", canonical.x, ",", canonical.y, ",", canonical.z, ")"); + continue; } // Debug waypoint conversion for first transport (entry 2074) diff --git a/src/rendering/world_map/layers/zone_highlight_layer.cpp b/src/rendering/world_map/layers/zone_highlight_layer.cpp index 7b459496..5c544ef7 100644 --- a/src/rendering/world_map/layers/zone_highlight_layer.cpp +++ b/src/rendering/world_map/layers/zone_highlight_layer.cpp @@ -172,10 +172,6 @@ void ZoneHighlightLayer::render(const LayerContext& ctx) { float mv = (mousePos.y - ctx.imgMin.y) / ctx.displayH; if (mu >= 0.0f && mu <= 1.0f && mv >= 0.0f && mv <= 1.0f) { - // Undo the -0.15 vertical offset applied during continent rendering - constexpr float kVOffset = -0.15f; - mv -= kVOffset; - // Screen UV → world coordinates float wowX = cLeft - mu * cDenomU; float wowY = cTop - mv * cDenomV; diff --git a/src/rendering/world_map/world_map_facade.cpp b/src/rendering/world_map/world_map_facade.cpp index 9213790c..5b40329d 100644 --- a/src/rendering/world_map/world_map_facade.cpp +++ b/src/rendering/world_map/world_map_facade.cpp @@ -590,6 +590,7 @@ void WorldMapFacade::Impl::renderImGuiOverlay(const glm::vec3& playerRenderPos, ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); + ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); // Bug fix: pass nullptr instead of &open so ImGui's X-button doesn't // set open=false directly — that bypasses cleanup (userMapOverride, @@ -979,19 +980,17 @@ void WorldMapFacade::Impl::renderImGuiOverlay(const glm::vec3& playerRenderPos, // • Full stretch (like WoW original): hlW = displayW, hlH = displayH // • Shift glow position: adjust hlX offset // - float hlW,hlH,hlX, hlY; + // Render highlight as a square (side = displayH) to preserve + // the 1:1 aspect of the 512×512 glow textures at any resolution. + float hlW = displayH; + float hlH = displayH; + float hlX, hlY; if (cosmicLabel == "azeroth") { - hlW = displayW * 0.90f; // width of highlight rect (= square) - hlH = displayH * 0.985f; // height of highlight rect (= square) - - hlX = imgMax.x - hlW; // flush right - hlY = imgMax.y - hlH; // flush bottom + title bar + hlX = imgMax.x - hlW; // flush right (glow sits in right-center of texture) + hlY = imgMin.y; // flush top } else { - hlW = displayW * 0.86f; // width of highlight rect (= square) - hlH = displayH * 0.91f; // height of highlight rect (= square) - - hlX = imgMin.x + displayW * 0.02f; // flush left - hlY = imgMax.y - displayH * 0.95f; // flush bottom + hlX = imgMin.x; // flush left (glow sits in left-center of texture) + hlY = imgMin.y; // flush top } if (zoneHighlightLayer) { @@ -1064,7 +1063,7 @@ void WorldMapFacade::Impl::renderImGuiOverlay(const glm::vec3& playerRenderPos, } ImGui::End(); - ImGui::PopStyleVar(2); // WindowPadding + ItemSpacing + ImGui::PopStyleVar(3); // WindowPadding + ItemSpacing + WindowBorderSize } } // namespace world_map diff --git a/src/ui/chat_panel.cpp b/src/ui/chat_panel.cpp index 77db55b3..179e415d 100644 --- a/src/ui/chat_panel.cpp +++ b/src/ui/chat_panel.cpp @@ -672,6 +672,7 @@ int ChatPanel::inputTextCallback(ImGuiInputTextCallbackData* data) { if (!self->tabCompleter_.isActive() || self->tabCompleter_.getPrefix() != lowerPrefix) { std::vector candidates; auto* gh = self->cachedGameHandler_; + if (!gh) return 0; for (const auto& m : gh->getPartyData().members) { if (m.name.empty()) continue; std::string lname = m.name; @@ -803,7 +804,7 @@ void ChatPanel::setupCallbacks(game::GameHandler& gameHandler) { void ChatPanel::insertChatLink(const std::string& link) { if (link.empty()) return; size_t curLen = strlen(chatInputBuffer_); - if (curLen + link.size() + 1 < sizeof(chatInputBuffer_)) { + if (curLen + link.size() + 1 <= sizeof(chatInputBuffer_)) { strncat(chatInputBuffer_, link.c_str(), sizeof(chatInputBuffer_) - curLen - 1); chatInputMoveCursorToEnd_ = true; refocusChatInput_ = true;