Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hearing - Improve and cleanup code #9933

Merged
merged 15 commits into from
May 24, 2024
Merged
10 changes: 1 addition & 9 deletions addons/hearing/CfgEventHandlers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,7 @@ class Extended_PreInit_EventHandlers {

class Extended_PostInit_EventHandlers {
class ADDON {
clientinit = QUOTE(call COMPILE_SCRIPT(XEH_postInit));
};
};

class Extended_Init_EventHandlers {
class CAManBase {
class GVAR(AddEarPlugs) {
serverInit = QUOTE(_this call FUNC(addEarPlugs));
};
init = QUOTE(call COMPILE_SCRIPT(XEH_postInit));
};
};

Expand Down
14 changes: 13 additions & 1 deletion addons/hearing/XEH_postInit.sqf
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
#include "script_component.hpp"

if (isServer) then {
GVAR(cacheMaxAmmoLoudness) = createHashMap;

["CBA_settingsInitialized", {
TRACE_1("settingInit - server",GVAR(EnableCombatDeafness));
// Only run PFEH and install event handlers if combat deafness is enabled
if (!GVAR(EnableCombatDeafness)) exitWith {};

["CAManBase", "Init", LINKFUNC(addEarPlugs), true, [], true] call CBA_fnc_addClassEventHandler;
}] call CBA_fnc_addEventHandler;
};

if (!hasInterface) exitWith {};

#include "initKeybinds.inc.sqf"

GVAR(cacheAmmoLoudness) = call CBA_fnc_createNamespace;
GVAR(cacheAmmoLoudness) = createHashMap;

GVAR(deafnessDV) = 0;
GVAR(deafnessPrior) = 0;
Expand Down
84 changes: 58 additions & 26 deletions addons/hearing/functions/fnc_addEarPlugs.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -15,53 +15,85 @@
* Public: No
*/

// only run this after the settings are initialized
if !(EGVAR(common,settingsInitFinished)) exitWith {
// Only run this after the settings are initialized
if (!EGVAR(common,settingsInitFinished)) exitWith {
EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(addEarPlugs), _this];
};

// Exit if hearing is disabled or if autoAdd is disabled
if (!GVAR(enableCombatDeafness) || {GVAR(autoAddEarplugsToUnits) == 0}) exitWith {};

params ["_unit"];
TRACE_2("params",_unit,typeOf _unit);

// Exit if hearing is disabled OR autoAdd is disabled OR soldier has earplugs already in (persistence scenarios)
if (!GVAR(enableCombatDeafness) || {GVAR(autoAddEarplugsToUnits) == 0} || {[_unit] call FUNC(hasEarPlugsIn)}) exitWith {};
// Exit if soldier already has earplugs (in ears (persistence scenarios) or inventory)
if (_unit call FUNC(hasEarPlugsIn) || {[_unit, "ACE_EarPlugs"] call EFUNC(common,hasItem)}) exitWith {};

// Add earplugs if enabled for everyone or if the soldier has a rocket launcher
if (GVAR(autoAddEarplugsToUnits) == 2 || {(secondaryWeapon _unit) != ""}) exitWith {
TRACE_1("has launcher - adding",_unit);
_unit addItem "ACE_EarPlugs";
};

// otherwise add earplugs if the soldier has a big rifle
if ((primaryWeapon _unit) == "") exitWith {};
// Otherwise add earplugs if the soldier has a big rifle
private _weapon = primaryWeapon _unit;

(primaryWeaponMagazine _unit) params [["_magazine", ""]];
if (_magazine == "") exitWith {};
if (_weapon == "") exitWith {};

private _cfgMagazine = configFile >> "CfgMagazines" >> _magazine;
// Cache maximum loadness for future calls
LinkIsGrim marked this conversation as resolved.
Show resolved Hide resolved
private _maxLoudness = GVAR(cacheMaxAmmoLoudness) getOrDefaultCall [_weapon, {
private _cfgMagazines = configFile >> "CfgMagazines";

private _initSpeed = getNumber (_cfgMagazine >> "initSpeed");
private _ammo = getText (_cfgMagazine >> "ammo");
private _count = getNumber (_cfgMagazine >> "count");
// Get the weapon's compatible magazines, so that all magazines are cached
private _maxLoudness = selectMax ((compatibleMagazines _weapon) apply {
private _magazine = _x;
private _cfgMagazine = _cfgMagazines >> _magazine;
private _ammo = getText (_cfgMagazine >> "ammo");

private _cfgAmmo = configFile >> "CfgAmmo";
GVAR(cacheAmmoLoudness) getOrDefaultCall [_magazine, {
private _cfgAmmo = configFile >> "CfgAmmo";
private _initSpeed = getNumber (configFile >> "CfgMagazines" >> _magazine >> "initSpeed");
johnb432 marked this conversation as resolved.
Show resolved Hide resolved
private _ammoConfig = _cfgAmmo >> _ammo;
private _caliber = getNumber (_ammoConfig >> "ACE_caliber");

private _caliber = getNumber (_cfgAmmo >> _ammo >> "ACE_caliber");
_caliber = call {
if (_ammo isKindOf ["ShellBase", _cfgAmmo]) exitWith { 80 };
if (_ammo isKindOf ["RocketBase", _cfgAmmo]) exitWith { 200 };
if (_ammo isKindOf ["MissileBase", _cfgAmmo]) exitWith { 600 };
if (_ammo isKindOf ["SubmunitionBase", _cfgAmmo]) exitWith { 80 };
[_caliber, 6.5] select (_caliber <= 0);
};
private _loudness = (_caliber ^ 1.25 / 10) * (_initspeed / 1000) / 5;
_caliber = switch (true) do {
// If explicilty defined, use ACE_caliber
case (inheritsFrom (_ammoConfig >> "ACE_caliber") isEqualTo _ammoConfig): {_caliber};
johnb432 marked this conversation as resolved.
Show resolved Hide resolved
case (_ammo isKindOf ["ShellBase", _cfgAmmo]): {80};
case (_ammo isKindOf ["RocketBase", _cfgAmmo]): {200};
case (_ammo isKindOf ["MissileBase", _cfgAmmo]): {600};
case (_ammo isKindOf ["SubmunitionBase", _cfgAmmo]): {80};
default {[_caliber, 6.5] select (_caliber <= 0)};
};

private _loudness = (_caliber ^ 1.25 / 10) * (_initspeed / 1000) / 5;
TRACE_5("building cache",_ammo,_magazine,_initSpeed,_caliber,_loudness);

_loudness
}, true];
});

// ace_gunbag_fnc_isMachineGun
private _config = _weapon call CBA_fnc_getItemConfig;

// Definition of a machine gun by BIS_fnc_itemType
private _cursor = getText (_config >> "cursor");

if (toLowerANSI _cursor in ["", "emptycursor"]) then {
_cursor = getText (_config >> "cursorAim");
};

// If unit has a machine gun boost effective loudness 50%
if (_cursor == "MG") then {
_maxLoudness = _maxLoudness * 1.5;
};

//If unit has a machine gun boost effective loudness 50%
if (_count >= 50) then {_loudness = _loudness * 1.5};
_maxLoudness
}, true];

TRACE_2("primaryWeapon",_unit,_loudness);
TRACE_3("primaryWeapon",_unit,_weapon,_maxLoudness);

if (_loudness > 0.2) then {
if (_maxLoudness > 0.2) then {
TRACE_1("loud gun - adding",_unit);
_unit addItem "ACE_EarPlugs";
};
116 changes: 56 additions & 60 deletions addons/hearing/functions/fnc_firedNear.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,25 @@
* Handles deafness due to large-caliber weapons going off near the player.
*
* Arguments:
* 0: Unit - Object the event handler is assigned to <OBJECT>
* 1: Firer: Object - Object which fires a weapon near the unit <OBJECT>
* 2: Distance - Distance in meters between the unit and firer <NUMBER>
* 3: weapon - Fired weapon <STRING>
* 4: muzzle - Muzzle that was used (not used) <STRING>
* 5: mode - Current mode of the fired weapon (not used) <STRING>
* 6: ammo - Ammo used <STRING>
* 0: Object the event handler is assigned to <OBJECT> (unused)
* 1: Object which fires a weapon near the unit <OBJECT>
* 2: Distance in meters between the unit and firer <NUMBER>
* 3: Weapon <STRING>
* 4: Muzzle <STRING>
* 5: Current mode of the fired weapon <STRING> (unused)
* 6: Ammo <STRING>
* 7: Unit that fired the weapon <STRING>
*
* Return Value:
* None
*
* Example:
* [clientFiredNearEvent] call ace_hearing_fnc_firedNear
* [player, player, 10, "arifle_MX_ACO_pointer_F", "arifle_MX_ACO_pointer_F", "single", "B_65x39_Caseless"] call ace_hearing_fnc_firedNear
* [player, player, 10, "arifle_MX_ACO_pointer_F", "arifle_MX_ACO_pointer_F", "single", "B_65x39_Caseless", player] call ace_hearing_fnc_firedNear
*
* Public: No
*/

params ["_object", "_firer", "_distance", "_weapon", "", "", "_ammo"];
params ["", "_firer", "_distance", "_weapon", "_muzzle", "", "_ammo", "_gunner"];

if (_weapon in ["Throw", "Put"]) exitWith {};
if (_distance > 50) exitWith {};
Expand All @@ -32,62 +32,58 @@ private _vehAttenuation = [GVAR(playerVehAttenuation), 1] select (
);
private _distance = 1 max _distance;

private _silencer = switch (_weapon) do {
case (primaryWeapon _firer) : {(primaryWeaponItems _firer) select 0};
case (secondaryWeapon _firer) : {(secondaryWeaponItems _firer) select 0};
case (handgunWeapon _firer) : {(handgunItems _firer) select 0};
default {""};
private _magazine = if (_gunner == _firer) then {
// Unit that is firing is on foot
private _weaponItems = weaponsItems [_firer, true];
private _index = _weaponItems findIf {(_x select 0) == _weapon};

if (_index == -1) exitWith {""};

_weaponItems = _weaponItems select _index;

// Check if the secondary muzzle was fired; If not, assume it's the primary muzzle
if (_weaponItems select 5 param [2, ""] == _muzzle) then {
_weaponItems select 5 param [0, ""]
} else {
_weaponItems select 4 param [0, ""]
};
} else {
// Unit that is firing is in a vehicle
_firer currentMagazineTurret (_firer unitTurret _gunner)
};

if (_magazine == "") exitWith {
TRACE_5("No mag for weapon/ammo??",_weapon,_muzzle,_ammo,_firer,_gunner);
};

private _audibleFireCoef = 1;
if (_silencer != "") then {
_audibleFireCoef = getNumber (configFile >> "CfgWeapons" >> _silencer >> "ItemInfo" >> "AmmoCoef" >> "audibleFire");
private _suppressor = _weaponItems select 1;
johnb432 marked this conversation as resolved.
Show resolved Hide resolved

if (_suppressor != "") then {
_audibleFireCoef = getNumber (configFile >> "CfgWeapons" >> _suppressor >> "ItemInfo" >> "AmmoCoef" >> "audibleFire");
};

private _loudness = GVAR(cacheAmmoLoudness) getVariable (format ["%1%2",_weapon,_ammo]);
if (isNil "_loudness") then {
private _muzzles = getArray (configFile >> "CfgWeapons" >> _weapon >> "muzzles");
private _weaponMagazines = getArray (configFile >> "CfgWeapons" >> _weapon >> "magazines");
{
if (_x != "this") then {
private _muzzleMagazines = getArray (configFile >> "CfgWeapons" >> _weapon >> _x >> "magazines");
_weaponMagazines append _muzzleMagazines;
};
} forEach _muzzles;
{
private _ammoType = getText(configFile >> "CfgMagazines" >> _x >> "ammo");
_weaponMagazines set [_forEachIndex, [_x, _ammoType]];
} forEach _weaponMagazines;

private _magazine = "";
{
_x params ["_magazineType", "_ammoType"];
if (_ammoType == _ammo) exitWith {
_magazine = _magazineType;
};
} forEach _weaponMagazines;

if (_magazine == "") then {
_loudness = 0;
TRACE_2("No mag for Weapon/Ammo??",_weapon,_ammo);
} else {
private _initSpeed = getNumber(configFile >> "CfgMagazines" >> _magazine >> "initSpeed");
private _caliber = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ACE_caliber");
_caliber = call {
// If explicilty defined, use ACE_caliber
if ((count configProperties [(configFile >> "CfgAmmo" >> _ammo), "configName _x == 'ACE_caliber'", false]) == 1) exitWith {_caliber};
if (_ammo isKindOf ["ShellBase", (configFile >> "CfgAmmo")]) exitWith { 80 };
if (_ammo isKindOf ["RocketBase", (configFile >> "CfgAmmo")]) exitWith { 200 };
if (_ammo isKindOf ["MissileBase", (configFile >> "CfgAmmo")]) exitWith { 600 };
if (_ammo isKindOf ["SubmunitionBase", (configFile >> "CfgAmmo")]) exitWith { 80 };
[_caliber, 6.5] select (_caliber <= 0)
};

_loudness = (_caliber ^ 1.25 / 10) * (_initspeed / 1000) / 5;
TRACE_6("building cache",_weapon,_ammo,_magazine,_initSpeed,_caliber,_loudness);
private _loudness = GVAR(cacheAmmoLoudness) getOrDefaultCall [_magazine, {
private _cfgAmmo = configFile >> "CfgAmmo";
private _initSpeed = getNumber (configFile >> "CfgMagazines" >> _magazine >> "initSpeed");
private _ammoConfig = _cfgAmmo >> _ammo;
private _caliber = getNumber (_ammoConfig >> "ACE_caliber");

_caliber = switch (true) do {
// If explicilty defined, use ACE_caliber
case (inheritsFrom (_ammoConfig >> "ACE_caliber") isEqualTo _ammoConfig): {_caliber};
case (_ammo isKindOf ["ShellBase", _cfgAmmo]): {80};
case (_ammo isKindOf ["RocketBase", _cfgAmmo]): {200};
case (_ammo isKindOf ["MissileBase", _cfgAmmo]): {600};
case (_ammo isKindOf ["SubmunitionBase", _cfgAmmo]): {80};
default {[_caliber, 6.5] select (_caliber <= 0)};
};
GVAR(cacheAmmoLoudness) setVariable [(format ["%1%2",_weapon,_ammo]), _loudness];
};

private _loudness = (_caliber ^ 1.25 / 10) * (_initspeed / 1000) / 5;
TRACE_5("building cache",_ammo,_magazine,_initSpeed,_caliber,_loudness);

_loudness
}, true];

_loudness = _loudness * _audibleFireCoef;
private _strength = _vehAttenuation * (_loudness - (_loudness / 50 * _distance)); // linear drop off
Expand Down