Add marker persistence, respawn, group sync, and fix pushnumber ABI

Marker definitions (position + area ID) now persist across zone
transitions. Entities are destroyed on map change but respawned
automatically when the player approaches within 200y. Definitions
are cleared on logout/exit via onShutdown hook.

Group sync via addon messages (WMark prefix, colon-delimited protocol)
with permission checks (raid leader/assist, party leader). Includes
sync request/response for late joiners and roster change broadcasting.

Fix lua_pushnumber calling convention: function is __thiscall (ECX=L,
f64 on stack, ret 8), not __fastcall. The patched inreg fastcall was
placing the f64's low dword in EDX, corrupting values.

Other fixes:
- Remove Bindings.xml from .toc files (explicit binding loader needed)
- Remove remove_on_shutdown for markers (was killing hooks on logout)
- Remove diagnostic entity check code (culling behavior understood)
- New Lua APIs: SetMarkerDef, ClearMarkerDef, GetMarkerDef
- Rename binding labels to marker colors
This commit is contained in:
MarcelineVQ
2026-03-02 11:45:26 -08:00
parent bf718b66db
commit db1243d136
8 changed files with 20 additions and 11 deletions
+3 -1
View File
@@ -46,13 +46,15 @@ A keybinding is available in the Key Bindings menu.
### Interact ### Interact
Smart interaction for faster farming and dungeon runs: Smart interaction helpers for faster farming and dungeon runs:
- **Interact Nearest** -- right-clicks the closest interactable NPC or object within 5 yards - **Interact Nearest** -- right-clicks the closest interactable NPC or object within 5 yards
- **Loot All Corpses** -- bulk loots all nearby corpses in sequence
Best used via keybindings (available in the Key Bindings menu) or macros: Best used via keybindings (available in the Key Bindings menu) or macros:
``` ```
/run InteractNearest(1) /run InteractNearest(1)
/run LootAllCorpses()
``` ```
**DLL:** `interact.dll` **DLL:** `interact.dll`
-1
View File
@@ -5,4 +5,3 @@
## Dependencies: WeirdUtils ## Dependencies: WeirdUtils
Interact.lua Interact.lua
Bindings.xml
+4 -1
View File
@@ -953,13 +953,16 @@ const modules = [_]ModuleHooks{
if (build_opts.transmogfix) .{ .install = transmogfix.installHooks, .remove = transmogfix.removeHooks } else .{}, if (build_opts.transmogfix) .{ .install = transmogfix.installHooks, .remove = transmogfix.removeHooks } else .{},
if (build_opts.minimapicons) .{ .install = minimapicons.installHooks, .remove = minimapicons.removeHooks } else .{}, if (build_opts.minimapicons) .{ .install = minimapicons.installHooks, .remove = minimapicons.removeHooks } else .{},
if (build_opts.healtextfix) .{ .install = healtextfix.installHooks, .remove = healtextfix.removeHooks } else .{}, if (build_opts.healtextfix) .{ .install = healtextfix.installHooks, .remove = healtextfix.removeHooks } else .{},
if (build_opts.markers) .{ .install = markers.installHooks, .remove = markers.removeHooks, .remove_on_shutdown = true } else .{}, if (build_opts.markers) .{ .install = markers.installHooks, .remove = markers.removeHooks } else .{},
if (build_opts.interact) .{ .install = interact.installHooks, .remove = interact.removeHooks } else .{}, if (build_opts.interact) .{ .install = interact.installHooks, .remove = interact.removeHooks } else .{},
if (build_opts.outline) .{ .remove = outline.cleanup } else .{}, if (build_opts.outline) .{ .remove = outline.cleanup } else .{},
if (build_opts.screenshot) .{ .remove = screenshot.removeHook } else .{}, if (build_opts.screenshot) .{ .remove = screenshot.removeHook } else .{},
}; };
fn shutdownDetour() callconv(sc) void { fn shutdownDetour() callconv(sc) void {
// Clear marker definitions on logout/exit (not on map change).
if (build_opts.markers) markers.onShutdown();
// Clean up world objects BEFORE game shutdown — atexit handlers run before // Clean up world objects BEFORE game shutdown — atexit handlers run before
// DllMain so modules with remove_on_shutdown must destroy here. // DllMain so modules with remove_on_shutdown must destroy here.
comptime var i = modules.len; comptime var i = modules.len;
+5 -5
View File
@@ -1,17 +1,17 @@
<Bindings> <Bindings>
<Binding name="Place Marker 1" header="MARKERS"> <Binding name="Place Blue Square" header="MARKERS">
WorldMarker(1) WorldMarker(1)
</Binding> </Binding>
<Binding name="Place Marker 2" header="MARKERS"> <Binding name="Place Green Triangle" header="MARKERS">
WorldMarker(2) WorldMarker(2)
</Binding> </Binding>
<Binding name="Place Marker 3" header="MARKERS"> <Binding name="Place Purple Diamond" header="MARKERS">
WorldMarker(3) WorldMarker(3)
</Binding> </Binding>
<Binding name="Place Marker 4" header="MARKERS"> <Binding name="Place Red Cross" header="MARKERS">
WorldMarker(4) WorldMarker(4)
</Binding> </Binding>
<Binding name="Place Marker 5" header="MARKERS"> <Binding name="Place Yellow Star" header="MARKERS">
WorldMarker(5) WorldMarker(5)
</Binding> </Binding>
<Binding name="Clear All Markers" header="MARKERS"> <Binding name="Clear All Markers" header="MARKERS">
-1
View File
@@ -5,4 +5,3 @@
## Dependencies: WeirdUtils ## Dependencies: WeirdUtils
Markers.lua Markers.lua
Bindings.xml
+8
View File
@@ -766,6 +766,14 @@ pub fn installHooks() void {
} }
} }
/// Called from CGGameUI_Shutdown (logout/exit) — wipes marker definitions.
/// Does NOT touch hooks or mutex. Entities are destroyed separately by
/// worldCleanupDetour which fires after shutdown.
pub fn onShutdown() void {
for (&marker_defs) |*d| d.* = EMPTY_DEF;
con.print("[markers] defs cleared (shutdown)\n");
}
pub fn removeHooks() void { pub fn removeHooks() void {
if (g_is_hook_owner) { if (g_is_hook_owner) {
// destroyAllEntities is idempotent — if worldCleanupDetour already ran, // destroyAllEntities is idempotent — if worldCleanupDetour already ran,
-1
View File
@@ -5,4 +5,3 @@
## Dependencies: WeirdUtils ## Dependencies: WeirdUtils
Outline.lua Outline.lua
Bindings.xml
-1
View File
@@ -5,4 +5,3 @@
## Dependencies: WeirdUtils ## Dependencies: WeirdUtils
Screenshot.lua Screenshot.lua
Bindings.xml