Skip to content

Commit

Permalink
Hearing - Improve and cleanup code (acemod#9933)
Browse files Browse the repository at this point in the history
Co-authored-by: Jouni Järvinen <rautamiekka@users.noreply.github.com>
Co-authored-by: PabstMirror <pabstmirror@gmail.com>
Co-authored-by: Grim <69561145+LinkIsGrim@users.noreply.github.com>
  • Loading branch information
4 people authored and blake8090 committed Aug 18, 2024
1 parent 682ebee commit c9ff9d1
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 96 deletions.
1 change: 1 addition & 0 deletions addons/hearing/XEH_PREP.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ PREP(addEarPlugs);
PREP(earRinging);
PREP(explosionNear);
PREP(firedNear);
PREP(getAmmoLoudness);
PREP(handleRespawn);
PREP(hasEarPlugsIn);
PREP(moduleHearing);
Expand Down
2 changes: 1 addition & 1 deletion addons/hearing/XEH_postInit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ if (!hasInterface) exitWith {};

#include "initKeybinds.inc.sqf"

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

GVAR(deafnessDV) = 0;
GVAR(deafnessPrior) = 0;
Expand Down
60 changes: 33 additions & 27 deletions addons/hearing/functions/fnc_addEarPlugs.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Called on unit initialization. Adds earplugs if the unit is equipped with either a really loud primary weapon or a rocket launcher.
*
* Arguments:
* 0: A Soldier <Object>
* 0: Unit <Object>
*
* Return Value:
* None
Expand All @@ -15,9 +15,9 @@
* Public: No
*/

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

// Exit if hearing is disabled or if autoAdd is disabled
Expand All @@ -29,42 +29,48 @@ TRACE_2("params",_unit,typeOf _unit);
// Exit if the unit 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
// Add earplugs if enabled for everyone or if the unit 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 unit has a big rifle
private _weapon = primaryWeapon _unit;

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

private _cfgMagazine = configFile >> "CfgMagazines" >> _magazine;
if (isNil QGVAR(cacheMaxAmmoLoudness)) then {
GVAR(cacheMaxAmmoLoudness) = createHashMap;
};

private _initSpeed = getNumber (_cfgMagazine >> "initSpeed");
private _ammo = getText (_cfgMagazine >> "ammo");
private _count = getNumber (_cfgMagazine >> "count");
// Cache maximum loudness for future calls
private _maxLoudness = GVAR(cacheMaxAmmoLoudness) getOrDefaultCall [_weapon, {
// Get the weapon's compatible magazines, so that all magazines are cached
// From all the loudness factors, take the max
private _maxLoudness = selectMax ((compatibleMagazines _weapon) apply {_x call FUNC(getAmmoLoudness)});

private _cfgAmmo = configFile >> "CfgAmmo";
// ace_gunbag_fnc_isMachineGun
private _config = _weapon call CBA_fnc_getItemConfig;

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;
// 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";
};
1 change: 0 additions & 1 deletion addons/hearing/functions/fnc_explosionNear.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ params ["_unit", "_damage"];
TRACE_2("explosion near player",_unit,_damage);

private _strength = (0 max _damage) * 30;
if (_strength < 0.01) exitWith {};

// Call inmediately, as it will get pick up later anyway by the update thread
[_strength] call FUNC(earRinging);
97 changes: 30 additions & 67 deletions addons/hearing/functions/fnc_firedNear.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -4,97 +4,60 @@
* 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>
* 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", "_mode", "_ammo", "_gunner"];

if (_weapon in ["Throw", "Put"]) exitWith {};
if (_distance > 50) exitWith {};

private _vehAttenuation = [GVAR(playerVehAttenuation), 1] select (
(ACE_player == (vehicle ACE_player)) || {isTurnedOut ACE_player}
);
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 {""};
};

_distance = 1 max _distance;
private _audibleFireCoef = 1;
if (_silencer != "") then {
_audibleFireCoef = getNumber (configFile >> "CfgWeapons" >> _silencer >> "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;
// Unit that fired is on foot
private _magazine = if (_gunner == _firer) then {
// Check if the unit has a suppressor
private _suppressor = (_firer weaponAccessories _weapon) select 0;

private _magazine = "";
{
_x params ["_magazineType", "_ammoType"];
if (_ammoType == _ammo) exitWith {
_magazine = _magazineType;
};
} forEach _weaponMagazines;
if (_suppressor != "") then {
_audibleFireCoef = getNumber (configFile >> "CfgWeapons" >> _suppressor >> "ItemInfo" >> "AmmoCoef" >> "audibleFire");
};

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)
};
(_firer weaponState _muzzle) select 3
} else {
// Unit that fired is in a vehicle
(weaponState [_firer, _firer unitTurret _gunner, _weapon, _muzzle, _mode]) select 3
};

_loudness = (_caliber ^ 1.25 / 10) * (_initspeed / 1000) / 5;
TRACE_6("building cache",_weapon,_ammo,_magazine,_initSpeed,_caliber,_loudness);
};
GVAR(cacheAmmoLoudness) setVariable [(format ["%1%2",_weapon,_ammo]), _loudness];
if (_magazine == "") exitWith {
TRACE_5("No mag for weapon/ammo??",_weapon,_muzzle,_ammo,_firer,_gunner);
};

TRACE_6("mag",_magazine,_weapon,_muzzle,_ammo,_firer,_gunner);

private _vehAttenuation = [GVAR(playerVehAttenuation), 1] select (isNull objectParent ACE_player || {isTurnedOut ACE_player});
private _loudness = _magazine call FUNC(getAmmoLoudness);

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

TRACE_1("result",_strength);

if (_strength < 0.01) exitWith {};

// Call inmediately, as it will get pick up later anyway by the update thread
[_strength] call FUNC(earRinging);
44 changes: 44 additions & 0 deletions addons/hearing/functions/fnc_getAmmoLoudness.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "..\script_component.hpp"
/*
* Author: KoffeinFlummi, commy2, johnb43
* Get the loudness of ammo.
* However, because `initSpeed` is a magazine attribute, the magazine name needs to be used instead of the ammo.
*
* Arguments:
* 0: Magazine <STRING>
*
* Return Value:
* None
*
* Example:
* "30Rnd_65x39_caseless_mag" call ace_hearing_fnc_getAmmoLoudness
*
* Public: No
*/

params ["_magazine"];

GVAR(cacheAmmoLoudness) getOrDefaultCall [_magazine, {
private _magazineConfig = configFile >> "CfgMagazines" >> _magazine;
private _ammo = getText (_magazineConfig >> "ammo");
private _initSpeed = getNumber (_magazineConfig >> "initSpeed");

private _cfgAmmo = configFile >> "CfgAmmo";
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)};
};

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

_loudness
}, true]

0 comments on commit c9ff9d1

Please sign in to comment.