diff --git a/src/worldmarkers/addon/WorldMarkers.lua b/src/worldmarkers/addon/WorldMarkers.lua index 5ed5caf..f3ddeb4 100644 --- a/src/worldmarkers/addon/WorldMarkers.lua +++ b/src/worldmarkers/addon/WorldMarkers.lua @@ -82,11 +82,16 @@ end -- Broadcast helpers -- ============================================================================= +-- Encode floats as integers (*1000) to avoid locale-dependent decimal separators. +-- Receivers divide by 1000. Sub-millimeter precision loss is irrelevant for markers. +local function encodeCoord(v) return math.floor(v * 1000) end +local function decodeCoord(v) return v / 1000 end + local function broadcastPlace(index, x, y, z, areaId) clearSyncState() local ch = getChannel() if not ch then return end - local msg = "P:" .. index .. ":" .. x .. ":" .. y .. ":" .. z .. ":" .. areaId + local msg = "P:" .. index .. ":" .. encodeCoord(x) .. ":" .. encodeCoord(y) .. ":" .. encodeCoord(z) .. ":" .. areaId SendAddonMessage(MSG_PREFIX, msg, ch) end @@ -111,7 +116,7 @@ local function broadcastAllDefs() for i = 1, NUM_MARKERS do local x, y, z, areaId = GetWorldMarker(i) if x then - local msg = "SF:" .. i .. ":" .. x .. ":" .. y .. ":" .. z .. ":" .. areaId + local msg = "SF:" .. i .. ":" .. encodeCoord(x) .. ":" .. encodeCoord(y) .. ":" .. encodeCoord(z) .. ":" .. areaId SendAddonMessage(MSG_PREFIX, msg, ch) end end @@ -220,7 +225,7 @@ local function parseMarkerFields(parts) local z = tonumber(parts[5]) local areaId = tonumber(parts[6]) if idx and x and y and z and areaId then - return idx, x, y, z, areaId + return idx, decodeCoord(x), decodeCoord(y), decodeCoord(z), areaId end return nil end diff --git a/src/worldmarkers/worldmarkers.zig b/src/worldmarkers/worldmarkers.zig index 106fa2a..874e2ad 100644 --- a/src/worldmarkers/worldmarkers.zig +++ b/src/worldmarkers/worldmarkers.zig @@ -103,6 +103,9 @@ const RESPAWN_CHECK_INTERVAL_MS: u32 = 1000; var last_zombie_tick: u32 = 0; const ZOMBIE_CHECK_INTERVAL_MS: u32 = 3000; +// Group-leave detection: clear markers when player drops to solo. +var was_in_group: bool = false; + // Entities playing their Decay animation before destruction. // Cleaned up every frame by tickAnimations (via OnWorldUpdate hook). const MAX_DESPAWNING = 8; @@ -541,6 +544,15 @@ const HOLD_QUEUE_DELAY_MS: u32 = 2000; fn tickAnimations() void { const now = GetTickCount(); + // Group-leave detection: leader GUID is set for both party and raid. + // When it drops to zero the player left the group — clear all markers. + const in_group = wow.readGUID(o.LEADER_GUID) != 0; + if (was_in_group and !in_group) { + log.print("left group, clearing all markers\n"); + clearAllMarkers(); + } + was_in_group = in_group; + cleanupDespawning(); // Queue Hold animation for freshly-created markers