fix(ace): gate ACE explosives placement on locality#117
Conversation
ace_explosives_place is a CBA global event that fires on every machine. On a dedicated server the explosive's position has not yet network-synced when the event fires, so getPosASL returns 0,0,~0 and the recording shows the charge at the map origin. Gate the listener body on `local _explosive` so only the placer — who owns the object with the authoritative position — packages and ships the data via CBA_fnc_serverEvent. This matches the vanilla mine path in fnc_eh_fired_client.sqf.
There was a problem hiding this comment.
Code Review
This pull request introduces a locality check in fnc_aceExplosives.sqf to ensure that only the machine where an explosive is local processes the placement event, preventing incorrect position data (0,0,0) on dedicated servers. The reviewer noted that gating the entire function prevents lifecycle event handlers from being registered on other machines, which could lead to lost tracking if the object's locality changes (e.g., due to a player disconnect). It is recommended to restrict the locality check to the data transmission logic while allowing event handler registration to proceed globally.
Per review feedback: addEventHandler is local, so registering EHs only on the placer means tracking breaks if locality transfers (e.g. placer disconnect). Move the locality check to gate just the :PLACED:CREATE: send — EH registration now happens on every machine, and whichever one owns the object at event-time fires its local EH.
|
Addressed in ba2e734 — moved the locality check to gate only the |
Locality check on the placer was wrong: ace_explosives_place fires before the explosive's position has synced on the server (getPosASL returns 0,0,~0 immediately, correct after ~1s), and OCAP_recorder_captureFrameNo only exists on the server, so a client-side send produced no valid :PLACED:CREATE: at all. Send from the server, delayed by 1s via CBA_fnc_waitAndExecute. This matches the empirical timing the user reported. Lifecycle EHs remain registered on every machine so locality transfers don't lose tracking.
|
Reworked in 327d7ca. The locality fix was wrong — the log showed no New approach: send from the server with a 1s Caveat to flag: there's now a 1s window between placement and the |
Drop the incorrect rationale about captureFrameNo being server-only; clients receive it via publicVariable. The reason for the server-side delayed send is simpler: getPosASL needs ~1s on the server to reflect the settled position after ace_explosives_place fires.
|
Correction: you're right, What we actually know empirically: with The server-only + 1s delay fix still stands on the simpler grounds you originally flagged: getPosASL on the server needs ~1s to reflect the settled position. Cleaned up the misleading comment in 0c9eeb9. |
Summary
ace_explosives_placeis a CBA global event, so the listener body ran on every machine. On a dedicated server the explosive's position is not yet network-synced when the event fires —getPosASLreturns0,0,~0. The placer's client has the correct position immediately.local _explosiveso only the placer (which owns the object with the authoritative position) packages the data and forwards it viaCBA_fnc_serverEvent. Same pattern as the vanilla mine path infnc_eh_fired_client.sqf.Test plan
:PLACED:CREATE:arrives with the real position (not0,0,...).:PLACED:EVENT:detonated/deletedstill fires (lifecycle EHs are added on the placer's machine, same machine that already ran them before this change).