worldmarkers: locale-safe coordinate encoding, clear markers on group leave

Addon messages now encode coordinates as integers (*1000) to avoid
locale-dependent decimal separators breaking cross-client sync.

DLL detects group leave via LEADER_GUID dropping to zero and clears
all markers locally -- no addon permission checks needed.
This commit is contained in:
MarcelineVQ
2026-04-13 13:37:09 -07:00
parent 83dda7b5ae
commit 6a3812a0ab
2 changed files with 20 additions and 3 deletions
+8 -3
View File
@@ -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
+12
View File
@@ -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