diff --git a/src/main.zig b/src/main.zig index 92f9b62..59aca01 100644 --- a/src/main.zig +++ b/src/main.zig @@ -100,7 +100,8 @@ fn registerLuaFunctions() void { // User-facing functions stay global registerFunction("WorldMarker", @intFromPtr(&markers.luaWorldMarker)); registerFunction("ClearWorldMarker", @intFromPtr(&markers.luaClearWorldMarker)); - registerFunction("CanSetWorldMarkers", @intFromPtr(&markers.luaCanSetMarkers)); + registerFunction("GetWorldMarker", @intFromPtr(&markers.luaGetWorldMarker)); + registerFunction("CanSetWorldMarker", @intFromPtr(&markers.luaCanSetMarkers)); // Internal functions in WorldMarkers table (via luaL_openlib) const lib = [_]lua.LuaReg{ diff --git a/src/markers/addon/WorldMarkers.lua b/src/markers/addon/WorldMarkers.lua index 74f9fd3..a66a701 100644 --- a/src/markers/addon/WorldMarkers.lua +++ b/src/markers/addon/WorldMarkers.lua @@ -19,7 +19,7 @@ BINDING_HEADER_WORLDMARKERS = "World Markers" -- Permission model: ALL permission checks are enforced DLL-side. -- WorldMarker/ClearWorldMarker: DLL checks local player is leader/assist. -- SetMarkerDef/ClearMarkerDef: DLL checks sender name against roster. --- CanSetWorldMarkers(): DLL returns 1 if local player has permission. +-- CanSetWorldMarker(): DLL returns 1 if local player has permission. -- ============================================================================= local MSG_PREFIX = "WMark" @@ -109,7 +109,7 @@ local function broadcastAllDefs() local ch = getChannel() if not ch then return end for i = 1, NUM_MARKERS do - local x, y, z, areaId = WorldMarkers.GetMarkerDef(i) + local x, y, z, areaId = GetWorldMarker(i) if x then local msg = "SF:" .. i .. ":" .. x .. ":" .. y .. ":" .. z .. ":" .. areaId SendAddonMessage(MSG_PREFIX, msg, ch) @@ -155,23 +155,21 @@ end local RawWorldMarker = WorldMarker function WorldMarker(index, ...) - local ok = RawWorldMarker(index, unpack(arg)) - if not ok then + local x, y, z, areaId = RawWorldMarker(index, unpack(arg)) + if x == nil then showDenyMessage() return end - if ok < 0 then + if x < 0 and (y == nil) then showFailMessage() return end denyCount = 0 local ch = getChannel() if ch then - local x, y, z, areaId = WorldMarkers.GetMarkerDef(index) - if x then - broadcastPlace(index, x, y, z, areaId) - end + broadcastPlace(index, x, y, z, areaId) end + return x, y, z, areaId end local RawClearWorldMarker = ClearWorldMarker @@ -222,7 +220,7 @@ local function onAddonMessage(prefix, message, channel, sender) local cmd = parts[1] if cmd == "SR" then - if CanSetWorldMarkers() then + if CanSetWorldMarker() then broadcastAllDefs() end return @@ -266,7 +264,7 @@ local function broadcastSyncRequest() local ch = getChannel() if not ch then return end startSyncing() - local cmd = CanSetWorldMarkers() and "LSR" or "SR" + local cmd = CanSetWorldMarker() and "LSR" or "SR" SendAddonMessage(MSG_PREFIX, cmd, ch) end @@ -310,7 +308,7 @@ rosterTimer:SetScript("OnUpdate", function() rosterTimer:Hide() rosterTimer.pending = false rosterTimer.extensions = 0 - if CanSetWorldMarkers() then + if CanSetWorldMarker() then broadcastAllDefs() end end diff --git a/src/markers/markers.zig b/src/markers/markers.zig index 4a83f4a..f008b31 100644 --- a/src/markers/markers.zig +++ b/src/markers/markers.zig @@ -525,8 +525,8 @@ fn clearAllMarkers() void { // Lua API // ============================================================================= -/// Lua: local ok = WorldMarker(index [, x, y, z | "unitId"]) -/// Returns 1 on success, nil on permission denied, -1 on placement failure. +/// Lua: local x,y,z,areaId = WorldMarker(index [, x, y, z | "unitId"]) +/// Returns x,y,z,areaId on success, nil on permission denied, -1 on placement failure. pub fn luaWorldMarker(L: lua.State) callconv(.c) u32 { if (!canSetMarkers()) { con.print("[worldmarkers] WorldMarker: no permission\n"); @@ -553,7 +553,10 @@ pub fn luaWorldMarker(L: lua.State) callconv(.c) u32 { const x: f32 = @floatCast(lua.tonumber(L, 2)); const y: f32 = @floatCast(lua.tonumber(L, 3)); const z: f32 = @floatCast(lua.tonumber(L, 4)); - _ = placeMarker(index, .{ .x = x, .y = y, .z = z }); + if (!placeMarker(index, .{ .x = x, .y = y, .z = z })) { + lua.pushnumber(L, -1.0); + return 1; + } } else if (nargs >= 2 and lua.isstring(L, 2)) { const unit_id = lua.tostring(L, 2) orelse { con.print("[worldmarkers] WorldMarker: invalid unit string\n"); @@ -565,18 +568,23 @@ pub fn luaWorldMarker(L: lua.State) callconv(.c) u32 { lua.pushnumber(L, -1.0); return 1; }; - _ = placeMarker(index, pos); + if (!placeMarker(index, pos)) { + lua.pushnumber(L, -1.0); + return 1; + } } else { const pos = getCursorTerrainPosition() orelse { con.print("[worldmarkers] no terrain under cursor\n"); lua.pushnumber(L, -1.0); return 1; }; - _ = placeMarker(index, pos); + if (!placeMarker(index, pos)) { + lua.pushnumber(L, -1.0); + return 1; + } } - lua.pushnumber(L, 1.0); - return 1; + return pushMarkerDef(L, index); } /// Lua: local ok = ClearWorldMarker([index]) @@ -756,16 +764,8 @@ pub fn luaClearMarkerDef(L: lua.State) callconv(.c) u32 { return 0; } -/// Lua: local x, y, z, areaId = GetMarkerDef(index) -/// Returns position and area ID for an active marker def, or nil if inactive. -pub fn luaGetMarkerDef(L: lua.State) callconv(.c) u32 { - const nargs = lua.gettop(L); - if (nargs < 1 or !lua.isnumber(L, 1)) return 0; - - const raw_index = @as(i32, @intFromFloat(lua.tonumber(L, 1))); - if (raw_index < 1 or raw_index > NUM_MARKERS) return 0; - const index: usize = @intCast(raw_index - 1); - +/// Push x, y, z, areaId for a marker slot, or return 0 (nil) if inactive. +fn pushMarkerDef(L: lua.State, index: usize) u32 { if (!marker_defs[index].active) return 0; lua.pushnumber(L, @floatCast(marker_defs[index].pos.x)); @@ -775,6 +775,24 @@ pub fn luaGetMarkerDef(L: lua.State) callconv(.c) u32 { return 4; } +/// Lua: local x, y, z, areaId = GetWorldMarker(index) +/// Returns position and area ID for an active marker, or nil if empty. +pub fn luaGetWorldMarker(L: lua.State) callconv(.c) u32 { + const nargs = lua.gettop(L); + if (nargs < 1 or !lua.isnumber(L, 1)) return 0; + + const raw_index = @as(i32, @intFromFloat(lua.tonumber(L, 1))); + if (raw_index < 1 or raw_index > NUM_MARKERS) return 0; + + return pushMarkerDef(L, @intCast(raw_index - 1)); +} + +/// Lua: local x, y, z, areaId = WorldMarkers.GetMarkerDef(index) +/// Internal alias kept for addon sync protocol compatibility. +pub fn luaGetMarkerDef(L: lua.State) callconv(.c) u32 { + return luaGetWorldMarker(L); +} + /// Lua: local ok = CanSetWorldMarkers() /// Returns 1 if the local player has permission (leader/assist), nil otherwise. /// Used by the addon for broadcast/sync decisions.