@@ -131,30 +131,75 @@ GVAR(trackedPlacedObjects) = createHashMap;
131131// allowFireOnLoad, ACE creates a temporary AI agent as gunner when the seat is
132132// empty (solo mortar use) — this agent has no OCAP ID.
133133// The dedup guard in eh_fired_client prevents double-tracking when both fire.
134- [" StaticWeapon" , " Fired" , {
135- params [" _vehicle" , " _weapon" , " _muzzle" , " _mode" , " _ammo" , " _magazine" , " _projectile" ];
134+ //
135+ // Like FiredMan above, the Fired EH must live on the machine that owns the
136+ // vehicle. We use the same Init + Local + remoteExec pattern: add on init,
137+ // transfer on locality change. Only eh_fired_client is called (not eh_firedMan)
138+ // because eh_firedMan is server-only and the EH may run on a client.
139+ // eh_fired_client already handles weapon attribution (lastFired) via broadcast,
140+ // and ACE CSW handles setShotParents for its own projectiles.
141+ [" StaticWeapon" , " init" , {
142+ params [" _entity" ];
136143
137- if (! local _vehicle ) exitWith {};
144+ if (local _entity ) then {
145+ private _id = _entity addEventHandler [" Fired" , {
146+ params [" _vehicle" , " _weapon" , " _muzzle" , " _mode" , " _ammo" , " _magazine" , " _projectile" ];
147+ if (! isNil {_projectile getVariable QGVARMAIN(projectileData)}) exitWith {};
148+ private _firer = gunner _vehicle ;
149+ if (isNull _firer ) exitWith {};
150+ if ((_firer getVariable [QGVARMAIN(id), - 1 ]) isEqualTo - 1 ) then {
151+ private _reloader = _vehicle getVariable [" ace_csw_reloader" , objNull ];
152+ if (! isNull _reloader ) then { _firer = _reloader ; };
153+ };
154+ [_firer , _weapon , _muzzle , _mode , _ammo , _magazine , _projectile , _vehicle ] call FUNC(eh_fired_client);
155+ }];
156+ _entity setVariable [QGVARMAIN(staticFiredEHExists), true ];
157+ _entity setVariable [QGVARMAIN(staticFiredEH), _id ];
158+ } else {
159+ [_entity , {
160+ private _id = _this addEventHandler [" Fired" , {
161+ params [" _vehicle" , " _weapon" , " _muzzle" , " _mode" , " _ammo" , " _magazine" , " _projectile" ];
162+ if (! isNil {_projectile getVariable QGVARMAIN(projectileData)}) exitWith {};
163+ private _firer = gunner _vehicle ;
164+ if (isNull _firer ) exitWith {};
165+ if ((_firer getVariable [QGVARMAIN(id), - 1 ]) isEqualTo - 1 ) then {
166+ private _reloader = _vehicle getVariable [" ace_csw_reloader" , objNull ];
167+ if (! isNull _reloader ) then { _firer = _reloader ; };
168+ };
169+ [_firer , _weapon , _muzzle , _mode , _ammo , _magazine , _projectile , _vehicle ] call FUNC(eh_fired_client);
170+ }];
171+ _this setVariable [QGVARMAIN(staticFiredEHExists), true ];
172+ _this setVariable [QGVARMAIN(staticFiredEH), _id ];
173+ }] remoteExec [" call" , owner _entity ];
174+ };
138175
139- // If FiredMan already handled this projectile, skip
140- if (! isNil {_projectile getVariable QGVARMAIN(projectileData)}) exitWith {};
176+ _entity addEventHandler [" Local" , {
177+ params [" _entity" , " _isLocal" ];
178+ private _staticFiredEHExists = _entity getVariable [QGVARMAIN(staticFiredEHExists), false ];
141179
142- private _firer = gunner _vehicle ;
143- if (isNull _firer ) exitWith {};
180+ if (! _isLocal && _staticFiredEHExists ) then {
181+ _entity removeEventHandler [" Fired" , _entity getVariable QGVARMAIN(staticFiredEH)];
182+ _entity setVariable [QGVARMAIN(staticFiredEHExists), false ];
183+ _entity setVariable [QGVARMAIN(staticFiredEH), nil ];
184+ };
144185
145- // ACE CSW agent fallback: when the gunner is a temporary agent (no OCAP ID),
146- // the actual operator is stored as ace_csw_reloader on the vehicle.
147- if ((_firer getVariable [QGVARMAIN(id), - 1 ]) isEqualTo - 1 ) then {
148- private _reloader = _vehicle getVariable [" ace_csw_reloader" , objNull ];
149- if (! isNull _reloader ) then {
150- _firer = _reloader ;
186+ if (_isLocal && ! _staticFiredEHExists ) then {
187+ private _id = _entity addEventHandler [" Fired" , {
188+ params [" _vehicle" , " _weapon" , " _muzzle" , " _mode" , " _ammo" , " _magazine" , " _projectile" ];
189+ if (! isNil {_projectile getVariable QGVARMAIN(projectileData)}) exitWith {};
190+ private _firer = gunner _vehicle ;
191+ if (isNull _firer ) exitWith {};
192+ if ((_firer getVariable [QGVARMAIN(id), - 1 ]) isEqualTo - 1 ) then {
193+ private _reloader = _vehicle getVariable [" ace_csw_reloader" , objNull ];
194+ if (! isNull _reloader ) then { _firer = _reloader ; };
195+ };
196+ [_firer , _weapon , _muzzle , _mode , _ammo , _magazine , _projectile , _vehicle ] call FUNC(eh_fired_client);
197+ }];
198+ _entity setVariable [QGVARMAIN(staticFiredEHExists), true ];
199+ _entity setVariable [QGVARMAIN(staticFiredEH), _id ];
151200 };
152- };
201+ }] ;
153202
154- // Forward to existing handlers with FiredMan-compatible params
155- private _params = [_firer , _weapon , _muzzle , _mode , _ammo , _magazine , _projectile , _vehicle ];
156- _params call FUNC(eh_fired_client);
157- _params call FUNC(eh_firedMan);
158203}, true , [], true ] call CBA_fnc_addClassEventHandler ;
159204
160205
0 commit comments