Skip to content

Commit 971ac83

Browse files
authored
fix: use HandleDamage for explosive kill weapon attribution (#68)
* fix: use HandleDamage for explosive kill weapon attribution lastFired is a per-killer variable that gets overwritten by any subsequent fire event. This makes it unreliable for explosive kills where there is a temporal gap between detonation and the kill handler reading the value (e.g. player fires weapon after placing mine but before mine detonates and kills). Instead, add a HandleDamage EH to tracked units that stores the ammo classname on the victim. At kill time, check if the damage ammo indicates an explosive (indirectHitRange > 1) and derive the display name from CfgAmmo config. Fall back to lastFired for bullet kills where it works correctly. - Add HandleDamage EH via CBA Class EH with Local EH lifecycle - Read lastDamageAmmo from victim in kill handler - Check for explosive ammo before existing lastFired logic - Remove redundant lastFired override from ACE Explode EH * add debug logging for kill weapon attribution KILL_DEBUG: logs victim, instigator, lastDamageAmmo, lastFired, and resolved eventText for every kill when debug mode is enabled. WEAPON_EXPLOSIVE: logs when HandleDamage ammo is used for explosive kill attribution instead of lastFired. * make kill attribution debug logs unconditional for dev testing * switch debug logs to diag_log for RPT output * remove dev debug logging for kill attribution
1 parent 3854cde commit 971ac83

4 files changed

Lines changed: 57 additions & 6 deletions

File tree

addons/recorder/fnc_aceExplosives.sqf

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,6 @@ _explosive addEventHandler ["Explode", {
6767

6868
_data params ["_explosiveDisp", "_unit", "_placedPos", "_markName", "_int"];
6969

70-
// Set unit who placed's lastFired var as the explosive so kills are registered to the explosive
71-
// Broadcast to server (owner 2) so kill handler can read it
72-
_unit setVariable [QGVARMAIN(lastFired), ["", _explosiveDisp, ""], 2];
73-
7470
if (GVARMAIN(isDebug)) then {
7571
format["Removed explosive placed marker, %1, %2", _markName, _explosiveDisp] SYSCHAT;
7672
OCAPEXTLOG(ARR3("Removed explosive placed marker",_markName,_explosiveDisp));

addons/recorder/fnc_eh_fired_server.sqf

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,16 @@ missionNamespace setVariable [QFUNCMAIN(addBulletEH), FUNC(eh_fired_clientBullet
4646
}];
4747
_entity setVariable [QGVARMAIN(firedManEHExists), true];
4848
_entity setVariable [QGVARMAIN(firedManEH), _id];
49+
50+
// HandleDamage stores the ammo classname on the victim for kill attribution
51+
private _hdId = _entity addEventHandler ["HandleDamage", {
52+
params ["_unit", "", "", "", "_projectile"];
53+
if (_projectile isNotEqualTo "" && {_projectile isNotEqualTo (_unit getVariable [QGVARMAIN(lastDamageAmmo), ""])}) then {
54+
_unit setVariable [QGVARMAIN(lastDamageAmmo), _projectile, 2];
55+
};
56+
}];
57+
_entity setVariable [QGVARMAIN(handleDamageEHExists), true];
58+
_entity setVariable [QGVARMAIN(handleDamageEH), _hdId];
4959
} else {
5060
[_entity, {
5161
private _id = _this addEventHandler ["FiredMan", {
@@ -55,6 +65,15 @@ missionNamespace setVariable [QFUNCMAIN(addBulletEH), FUNC(eh_fired_clientBullet
5565
}];
5666
_this setVariable [QGVARMAIN(firedManEHExists), true];
5767
_this setVariable [QGVARMAIN(firedManEH), _id];
68+
69+
private _hdId = _this addEventHandler ["HandleDamage", {
70+
params ["_unit", "", "", "", "_projectile"];
71+
if (_projectile isNotEqualTo "" && {_projectile isNotEqualTo (_unit getVariable [QGVARMAIN(lastDamageAmmo), ""])}) then {
72+
_unit setVariable [QGVARMAIN(lastDamageAmmo), _projectile, 2];
73+
};
74+
}];
75+
_this setVariable [QGVARMAIN(handleDamageEHExists), true];
76+
_this setVariable [QGVARMAIN(handleDamageEH), _hdId];
5877
}] remoteExec ["call", owner _entity];
5978
};
6079

@@ -67,13 +86,19 @@ missionNamespace setVariable [QFUNCMAIN(addBulletEH), FUNC(eh_fired_clientBullet
6786
// If the unit is NO LONGER local, remove the EH and the CBA EH.
6887
// We need to see if it exists already.
6988
private _firedManEHExists = _entity getVariable [QGVARMAIN(firedManEHExists), false];
89+
private _handleDamageEHExists = _entity getVariable [QGVARMAIN(handleDamageEHExists), false];
7090

7191
// If the unit is NO LONGER local, and the EH exists, remove it.
7292
if (!_isLocal && _firedManEHExists) then {
7393
_entity removeEventHandler ["FiredMan", _entity getVariable QGVARMAIN(firedManEH)];
7494
_entity setVariable [QGVARMAIN(firedManEHExists), false];
7595
_entity setVariable [QGVARMAIN(firedManEH), nil];
7696
};
97+
if (!_isLocal && _handleDamageEHExists) then {
98+
_entity removeEventHandler ["HandleDamage", _entity getVariable QGVARMAIN(handleDamageEH)];
99+
_entity setVariable [QGVARMAIN(handleDamageEHExists), false];
100+
_entity setVariable [QGVARMAIN(handleDamageEH), nil];
101+
};
77102

78103
// If the unit is NOW local and the EH doesn't exist, add it.
79104
if (_isLocal && !_firedManEHExists) then {
@@ -86,6 +111,16 @@ missionNamespace setVariable [QFUNCMAIN(addBulletEH), FUNC(eh_fired_clientBullet
86111
_entity setVariable [QGVARMAIN(firedManEHExists), true];
87112
_entity setVariable [QGVARMAIN(firedManEH), _id];
88113
};
114+
if (_isLocal && !_handleDamageEHExists) then {
115+
private _hdId = _entity addEventHandler ["HandleDamage", {
116+
params ["_unit", "", "", "", "_projectile"];
117+
if (_projectile isNotEqualTo "" && {_projectile isNotEqualTo (_unit getVariable [QGVARMAIN(lastDamageAmmo), ""])}) then {
118+
_unit setVariable [QGVARMAIN(lastDamageAmmo), _projectile, 2];
119+
};
120+
}];
121+
_entity setVariable [QGVARMAIN(handleDamageEHExists), true];
122+
_entity setVariable [QGVARMAIN(handleDamageEH), _hdId];
123+
};
89124
}];
90125

91126
// for the class event handler,

addons/recorder/fnc_eh_killed.sqf

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,9 @@ if !(_victim getvariable [QGVARMAIN(isKilled),false]) then {
7171
_killerId = _instigator getVariable [QGVARMAIN(id), -1];
7272
if (_killerId == -1) exitWith {};
7373

74-
private _eventText = [_instigator] call FUNC(getEventWeaponText);
74+
private _lastDamageAmmo = _victim getVariable [QGVARMAIN(lastDamageAmmo), ""];
75+
private _eventText = [_instigator, _lastDamageAmmo] call FUNC(getEventWeaponText);
76+
7577
private _killerInfo = [];
7678
// if (_instigator isKindOf "CAManBase") then {
7779
_killerInfo = [

addons/recorder/fnc_getEventWeaponText.sqf

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Author:
2727
---------------------------------------------------------------------------- */
2828
#include "script_component.hpp"
2929

30-
params ["_instigator"];
30+
params ["_instigator", ["_damageAmmo", ""]];
3131

3232
if (isNull _instigator) exitWith {["", "", ""]};
3333

@@ -40,6 +40,24 @@ if !(_instigator call CBA_fnc_isPerson) then {
4040
};
4141
};
4242

43+
// Check HandleDamage ammo for explosive kills (mines, placed explosives)
44+
// Only for on-foot instigators — vehicle kills use turret weapon info below
45+
private _explosiveWeaponText = [];
46+
if (_damageAmmo isNotEqualTo "" && {_instigator call CBA_fnc_isPerson} && {isNull objectParent _instigator}) then {
47+
private _indirectHitRange = getNumber(configFile >> "CfgAmmo" >> _damageAmmo >> "indirectHitRange");
48+
if (_indirectHitRange > 1) then {
49+
private _mag = getText(configFile >> "CfgAmmo" >> _damageAmmo >> "defaultMagazine");
50+
private _magDisp = getText(configFile >> "CfgMagazines" >> _mag >> "displayName");
51+
if (_magDisp isEqualTo "") then {
52+
_magDisp = getText(configFile >> "CfgAmmo" >> _damageAmmo >> "displayName");
53+
};
54+
if (_magDisp isNotEqualTo "") then {
55+
_explosiveWeaponText = ["", _magDisp, ""];
56+
};
57+
};
58+
};
59+
if (_explosiveWeaponText isNotEqualTo []) exitWith {_explosiveWeaponText};
60+
4361
if (_instigator call CBA_fnc_isPerson) then {
4462
private _personalWeapon = {
4563
(_instigator weaponstate (currentWeapon _instigator)) params ["_weapon", "_muzzle", "_mode", "_magazine"];

0 commit comments

Comments
 (0)