Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 53 additions & 45 deletions addons/database/fnc_eh_fired_client.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -54,42 +54,50 @@ if (_muzzleDisplay isEqualTo "") then {
_muzzleDisplay = getText(configFile >> "CfgWeapons" >> _weapon >> "displayName");
};


// set variables
// firedAt: refers to timing, i.e. frame number and unixNano timestamp
// firedBy: shooter info
// positions: each registered point of the projectile's path
// firedWith: weapon and ammo info
_projectile setVariable [QGVARMAIN(dataHash), createHashMapFromArray [
["firedFrame", EGVAR(recorder,captureFrameNo)],
["firedTime", [":TIMESTAMP:", []] call EFUNC(extension,sendData)],
["firerID", _firerOcapId],
["vehicleID", _vehicleOcapId],
["vehicleRole", _vehicleRole],
["remoteControllerID", _remoteControllerOcapId],
["weapon", _weapon],
["weaponDisplay", getText(configFile >> "CfgWeapons" >> _weapon >> "displayName")],
["muzzle", _muzzle],
["muzzleDisplay", _muzzleDisplay],
["magazine", _magazine],
["magazineDisplay", getText(configFile >> "CfgMagazines" >> _magazine >> "displayName")],
["ammo", _ammo],
["fireMode", _mode],
["positions", [
[
[":TIMESTAMP:", []] call EFUNC(extension,sendData),
EGVAR(recorder,captureFrameNo),
(getPosASL _projectile) joinString ","
]
]],
["initialVelocity",
(velocity _projectile) joinString ","
],
["hitParts", []],
["sim", getText(configFile >> "CfgAmmo" >> _ammo >> "simulation")],
["isSub", false]
]];

// Projectile data array structure:
// 0: firedFrame
// 1: firedTime (diag_tickTime)
// 2: firerID
// 3: vehicleID
// 4: vehicleRole
// 5: remoteControllerID
// 6: weapon
// 7: weaponDisplay
// 8: muzzle
// 9: muzzleDisplay
// 10: magazine
// 11: magazineDisplay
// 12: ammo
// 13: fireMode
// 14: positions [[tickTime, frame, "x,y,z"], ...]
// 15: initialVelocity
// 16: hitParts [[hitOcapId, component, "x,y,z", frame], ...]
// 17: sim
// 18: isSub

private _data = [
EGVAR(recorder,captureFrameNo), // 0: firedFrame
diag_tickTime, // 1: firedTime
_firerOcapId, // 2: firerID
_vehicleOcapId, // 3: vehicleID
_vehicleRole, // 4: vehicleRole
_remoteControllerOcapId, // 5: remoteControllerID
_weapon, // 6: weapon
getText(configFile >> "CfgWeapons" >> _weapon >> "displayName"), // 7: weaponDisplay
_muzzle, // 8: muzzle
_muzzleDisplay, // 9: muzzleDisplay
_magazine, // 10: magazine
getText(configFile >> "CfgMagazines" >> _magazine >> "displayName"), // 11: magazineDisplay
_ammo, // 12: ammo
_mode, // 13: fireMode
[[diag_tickTime, EGVAR(recorder,captureFrameNo), (getPosASL _projectile) joinString ","]], // 14: positions
(velocity _projectile) joinString ",", // 15: initialVelocity
[], // 16: hitParts
getText(configFile >> "CfgAmmo" >> _ammo >> "simulation"), // 17: sim
false // 18: isSub
];

_projectile setVariable [QGVARMAIN(projectileData), _data];

// the simulation type of this ammo will determine how we handle it.
// "ShotGrenade" // M67
Expand All @@ -103,17 +111,17 @@ _projectile setVariable [QGVARMAIN(dataHash), createHashMapFromArray [
// "ShotSubmunition" // Hind minigun, cluster artillery

// carryover variables to submunitions
if (getText(configFile >> "CfgAmmo" >> _ammo >> "simulation") isEqualTo "ShotSubmunition") then {
if ((_data select 17) isEqualTo "ShotSubmunition") then {
_projectile addEventHandler ["SubmunitionCreated", {
params ["_projectile", "_submunitionProjectile"];
_submunitionProjectile setVariable [QGVARMAIN(dataHash), _projectile getVariable QGVARMAIN(dataHash)];
private _hash = _submunitionProjectile getVariable QGVARMAIN(dataHash);
_hash set ["isSub", true];
(_hash get "positions") pushBack [
[":TIMESTAMP:", []] call EFUNC(extension,sendData),
EGVAR(recorder,captureFrameNo),
getPosASL _submunitionProjectile
];
private _data = +(_projectile getVariable QGVARMAIN(projectileData));
_data set [18, true]; // isSub = true
(_data select 14) pushBack [
diag_tickTime,
EGVAR(recorder,captureFrameNo),
(getPosASL _submunitionProjectile) joinString ","
];
_submunitionProjectile setVariable [QGVARMAIN(projectileData), _data];
// add the rest of EHs to submunition
[_submunitionProjectile] call FUNCMAIN(addBulletEH);
}];
Expand Down
77 changes: 44 additions & 33 deletions addons/database/fnc_eh_fired_clientBullet.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,18 @@ if (isNil "_projectile") exitWith {
WARNING("Projectile EHs: _projectile is nil");
};

// Projectile data array indices:
// 14: positions
// 16: hitParts
// 17: sim
// 18: isSub

// first, we need to verify simtype & whether this was a submunition or not.
// if this is NOT a deployed submunition itself but the simType of the ammo is "ShotSubmunition", then we need to skip the Deleted EH and leave the Deleted registration to the submunition itself. This will ensure we're tracking start to finish multiple actual projectiles from things like shotguns, cluster artillery, mixed-belt machineguns, etc.
private _hash = _projectile getVariable QGVARMAIN(dataHash);
private _data = _projectile getVariable QGVARMAIN(projectileData);
if (
_hash get "sim" isEqualTo "ShotSubmunition" &&
{_hash get "isSub" isEqualTo false}
(_data select 17) isEqualTo "ShotSubmunition" &&
{(_data select 18) isEqualTo false}
) exitWith {};

// HitExplosion
Expand All @@ -31,24 +37,25 @@ _projectile addEventHandler ["HitExplosion", {
// skip if no components were hit
if (count _hitThings isEqualTo 0) exitWith {};

private _data = _projectile getVariable QGVARMAIN(projectileData);

// many hit components for these events, so we'll sort them by radius (_x#3) largest to smallest and keep the top 5
private _hitThings = _hitThings apply {[_x#3, _x#2]};
_hitThings sort true;
_hitThings = _hitThings select [0, 5 min (count _hitThings)];
// add data, _x#1 will be the component name
((_projectile getVariable QGVARMAIN(dataHash)) get "hitParts") pushBack [
(_data select 16) pushBack [
_hitOcapId,
_hitThings apply {_x#1},
(getPosASL _projectile) joinString ",",
EGVAR(recorder,captureFrameNo)
];
// add pos
((_projectile getVariable QGVARMAIN(dataHash)) get "positions") pushBack [
[":TIMESTAMP:", []] call EFUNC(extension,sendData),
EGVAR(recorder,captureFrameNo),
(getPosASL _projectile) joinString ","
];
(_data select 14) pushBack [
diag_tickTime,
EGVAR(recorder,captureFrameNo),
(getPosASL _projectile) joinString ","
];
}];

// HitPart
Expand All @@ -67,19 +74,21 @@ _projectile addEventHandler ["HitPart", {
// skip if no components were hit
if (count _hitThings isEqualTo 0) exitWith {};

private _data = _projectile getVariable QGVARMAIN(projectileData);

// add hit data
((_projectile getVariable QGVARMAIN(dataHash)) get "hitParts") pushBack [
(_data select 16) pushBack [
_hitOcapId,
_component,
(getPosASL _projectile) joinString ",",
EGVAR(recorder,captureFrameNo)
];
// add pos
((_projectile getVariable QGVARMAIN(dataHash)) get "positions") pushBack [
[":TIMESTAMP:", []] call EFUNC(extension,sendData),
EGVAR(recorder,captureFrameNo),
_pos joinString ","
];
(_data select 14) pushBack [
diag_tickTime,
EGVAR(recorder,captureFrameNo),
_pos joinString ","
];
}];

// Deflected
Expand All @@ -88,12 +97,13 @@ _projectile addEventHandler ["Deflected", {
params ["_projectile", "_pos", "_velocity", "_hitObject"];
TRACE_4("Deflected",_projectile,_pos,_velocity,_hitObject);

private _data = _projectile getVariable QGVARMAIN(projectileData);
// just log position
((_projectile getVariable QGVARMAIN(dataHash)) get "positions") pushBack [
[":TIMESTAMP:", []] call EFUNC(extension,sendData),
EGVAR(recorder,captureFrameNo),
_pos joinString ","
];
(_data select 14) pushBack [
diag_tickTime,
EGVAR(recorder,captureFrameNo),
_pos joinString ","
];
}];

// END EHs
Expand All @@ -104,26 +114,27 @@ _projectile addEventHandler ["Explode", {
params ["_projectile", "_pos", "_velocity"];
TRACE_3("Explode",_projectile,_pos,_velocity);

private _data = _projectile getVariable QGVARMAIN(projectileData);
// just log position
((_projectile getVariable QGVARMAIN(dataHash)) get "positions") pushBack [
[":TIMESTAMP:", []] call EFUNC(extension,sendData),
EGVAR(recorder,captureFrameNo),
_pos joinString ","
];
(_data select 14) pushBack [
diag_tickTime,
EGVAR(recorder,captureFrameNo),
_pos joinString ","
];
}];

// Deleted
// Tracks a projectile that was deleted, either by a script or by the game. The final processing call that'll send data to the server for processing.
_projectile addEventHandler ["Deleted", {
params ["_projectile"];
private _hash = _projectile getVariable QGVARMAIN(dataHash);
(_hash get "positions") pushBack [
[":TIMESTAMP:", []] call EFUNC(extension,sendData),
EGVAR(recorder,captureFrameNo),
(getPosASL _projectile) joinString ","
];
TRACE_1("Projectile hash",_hash);
[QGVARMAIN(handleFiredManData), [_hash]] call CBA_fnc_serverEvent;
private _data = _projectile getVariable QGVARMAIN(projectileData);
(_data select 14) pushBack [
diag_tickTime,
EGVAR(recorder,captureFrameNo),
(getPosASL _projectile) joinString ","
];
TRACE_1("Projectile data",_data);
[QGVARMAIN(handleFiredManData), [_data]] call CBA_fnc_serverEvent;
}];

TRACE_1("Finished applying EH",_projectile);
Expand Down
12 changes: 5 additions & 7 deletions addons/database/fnc_eh_fired_server.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,11 @@

// Finally, we'll add a CBA Event Handler to take in the pre-processed fired data here on the server and send it to the extension.
[QGVARMAIN(handleFiredManData), {
params ["_hash"];
// Receive hashmap from server, hc, or client.
// Try encoding JSON
private _json = [_hash] call CBA_fnc_encodeJSON;
TRACE_1("Sending fired data JSON to extension",_json);
_json spawn {
params ["_data"];
// Receive array from server, hc, or client.
TRACE_1("Sending fired data to extension",_data);
_data spawn {
sleep 2;
[":PROJECTILE:", [_this]] call EFUNC(extension,sendData);
[":PROJECTILE:", _this] call EFUNC(extension,sendData);
};
}] call CBA_fnc_addEventHandler;
Loading