diff --git a/addons/common/XEH_preInit.sqf b/addons/common/XEH_preInit.sqf index bb2a0c6810a..af16bfc23df 100644 --- a/addons/common/XEH_preInit.sqf +++ b/addons/common/XEH_preInit.sqf @@ -35,7 +35,7 @@ ACE_COUNTERS = []; GVAR(statusEffects) = createHashMap; -GVAR(setHearingCapabilityMap) = []; +GVAR(setHearingCapabilityMap) = createHashMap; [] call FUNC(setupLocalUnitsHandler); // Add local units event handlers (ace_common_localUnits) diff --git a/addons/common/functions/fnc_setHearingCapability.sqf b/addons/common/functions/fnc_setHearingCapability.sqf index 45858278c13..de2eaa99771 100644 --- a/addons/common/functions/fnc_setHearingCapability.sqf +++ b/addons/common/functions/fnc_setHearingCapability.sqf @@ -1,12 +1,13 @@ #include "..\script_component.hpp" /* - * Author: Glowbal + * Author: Glowbal, BaerMitUmlaut * Handle set volume calls. Will use the lowest available volume setting. * * Arguments: * 0: ID * 1: Settings * 2: Add (true) or remove (false) (default: true) + * 3: Volume fade duration (default: 0) * * Return Value: * None @@ -17,40 +18,26 @@ * Public: Yes */ -params ["_id", "_setting", ["_add", true]]; +params ["_id", "_setting", ["_add", true], ["_fadeDuration", 0]]; -private _exists = false; -private _lowestVolume = 1; +_id = toLowerANSI _id; -GVAR(setHearingCapabilityMap) = GVAR(setHearingCapabilityMap) select { - _x params ["_xID", "_xSetting"]; - if (_id == _xID) then { - _exists = true; - if (_add) then { - _x set [1, _setting]; - _lowestVolume = _lowestVolume min _setting; - true - } else { - false - }; - } else { - _lowestVolume = _lowestVolume min _xSetting; - true - }; +// Save setting +if (_add) then { + GVAR(setHearingCapabilityMap) set [_id, _setting]; +} else { + GVAR(setHearingCapabilityMap) deleteAt _id; }; -if (!_exists && _add) then { - _lowestVolume = _lowestVolume min _setting; - GVAR(setHearingCapabilityMap) pushBack [_id, _setting]; -}; +private _lowestVolume = selectMin values GVAR(setHearingCapabilityMap); -// in game sounds -0 fadeSound _lowestVolume; -0 fadeRadio _lowestVolume; +// In-game sounds +_fadeDuration fadeSound _lowestVolume; +_fadeDuration fadeRadio _lowestVolume; if (GVAR(allowFadeMusic)) then { - 0 fadeMusic _lowestVolume; + _fadeDuration fadeMusic _lowestVolume; }; -// Set Radio mod variables. +// Set radio mod variables ACE_player setVariable ["tf_globalVolume", _lowestVolume]; if (!isNil "acre_api_fnc_setGlobalVolume") then { [_lowestVolume^0.33] call acre_api_fnc_setGlobalVolume; }; diff --git a/addons/fieldmanual/CfgHints.hpp b/addons/fieldmanual/CfgHints.hpp index 6f5b0c8efef..9020df1a40a 100644 --- a/addons/fieldmanual/CfgHints.hpp +++ b/addons/fieldmanual/CfgHints.hpp @@ -106,22 +106,30 @@ class CfgHints { description = CSTRING(Items_EarPlugs_Description); tip = "Hearing Wiki"; }; - class ACE_EntrenchingTool: ACE_FieldManual_Base { + class ACE_EHP: ACE_FieldManual_Base { logicalOrder = 11; + arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_EHP' call FUNC(getItemName))}; + displayName = "%14"; + displayNameShort = CSTRING(Items_EHP_ShortName); + description = CSTRING(Items_EHP_Description); + tip = "Hearing Wiki"; + }; + class ACE_EntrenchingTool: ACE_FieldManual_Base { + logicalOrder = 12; arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_EntrenchingTool' call FUNC(getItemName))}; displayName = "%14"; displayNameShort = CSTRING(Items_EntrenchingTool_ShortName); description = CSTRING(Items_EntrenchingTool_Description); }; class ACE_Flashlights: ACE_FieldManual_Base { - logicalOrder = 12; + logicalOrder = 13; displayName = CSTRING(Items_Flashlights_DisplayName); displayNameShort = CSTRING(Items_Flashlights_ShortName); description = CSTRING(Items_Flashlights_Description); tip = "Flashlights Wiki"; }; class ACE_FortifyTool: ACE_FieldManual_Base { - logicalOrder = 13; + logicalOrder = 14; arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_Fortify' call FUNC(getItemName))}; displayName = "%14"; displayNameShort = CSTRING(Items_FortifyTool_ShortName); @@ -129,7 +137,7 @@ class CfgHints { tip = "Fortify Wiki"; }; class ACE_HuntIR_Monitor: ACE_FieldManual_Base { - logicalOrder = 14; + logicalOrder = 15; arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_HuntIR_monitor' call FUNC(getItemName))}; displayName = "%14"; displayNameShort = CSTRING(Items_HuntIR_Monitor_ShortName); @@ -137,14 +145,14 @@ class CfgHints { tip = "HuntIR Wiki"; }; class ACE_IR_Strobe: ACE_FieldManual_Base { - logicalOrder = 15; + logicalOrder = 16; arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_IR_Strobe_Item' call FUNC(getItemName))}; displayName = "%14"; displayNameShort = CSTRING(Items_IR_Strobe_ShortName); description = CSTRING(Items_IR_Strobe_Description); }; class ACE_Kestrel4500: ACE_FieldManual_Base { - logicalOrder = 16; + logicalOrder = 17; arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_Kestrel4500' call FUNC(getItemName))}; displayName = "%14"; displayNameShort = CSTRING(Items_Kestrel4500_ShortName); @@ -152,7 +160,7 @@ class CfgHints { tip = "Kestrel 4500 Wiki"; }; class ACE_Lockpick: ACE_FieldManual_Base { - logicalOrder = 17; + logicalOrder = 18; arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_key_lockpick' call FUNC(getItemName))}; displayName = "%14"; displayNameShort = CSTRING(Items_Lockpick_ShortName); @@ -160,14 +168,14 @@ class CfgHints { tip = "Vehicle Lock Wiki"; }; class ACE_MapTools: ACE_FieldManual_Base { - logicalOrder = 18; + logicalOrder = 19; arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_MapTools' call FUNC(getItemName))}; displayName = "%14"; displayNameShort = CSTRING(Items_MapTools_ShortName); description = CSTRING(Items_MapTools_Description); }; class ACE_MicroDAGR: ACE_FieldManual_Base { - logicalOrder = 19; + logicalOrder = 20; arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_microDAGR' call FUNC(getItemName))}; displayName = "%14"; displayNameShort = CSTRING(Items_MicroDAGR_ShortName); @@ -176,20 +184,20 @@ class CfgHints { }; // Combine all range tables under one roof [mortar, artillery, rifle] class ACE_RangeTables: ACE_FieldManual_Base { - logicalOrder = 20; + logicalOrder = 21; displayName = CSTRING(Items_RangeTables_DisplayName); displayNameShort = CSTRING(Items_RangeTables_ShortName); description = CSTRING(Items_RangeTables_Description); tip = "Rangecard Wiki"; }; class ACE_Ropes: ACE_FieldManual_Base { - logicalOrder = 21; + logicalOrder = 22; displayName = CSTRING(Items_Ropes_DisplayName); displayNameShort = CSTRING(Items_Ropes_ShortName); description = CSTRING(Items_Ropes_Description); }; class ACE_Sandbag: ACE_FieldManual_Base { - logicalOrder = 22; + logicalOrder = 23; arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_Sandbag_empty' call FUNC(getItemName))}; displayName = "%14"; displayNameShort = CSTRING(Items_Sandbag_ShortName); @@ -197,7 +205,7 @@ class CfgHints { tip = "Sandbag Wiki"; }; class ACE_SpareBarrels: ACE_FieldManual_Base { - logicalOrder = 23; + logicalOrder = 24; arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_SpareBarrel_Item' call FUNC(getItemName))}; displayName = "%14"; displayNameShort = CSTRING(Items_SpareBarrels_ShortName); @@ -205,14 +213,14 @@ class CfgHints { tip = "Overheating Wiki"; }; class ACE_SprayPaint: ACE_FieldManual_Base { - logicalOrder = 24; + logicalOrder = 25; displayName = CSTRING(Items_SprayPaint_DisplayName); displayNameShort = CSTRING(Items_SprayPaint_ShortName); description = CSTRING(Items_SprayPaint_Description); tip = "Tagging Wiki"; }; class ACE_Tripod: ACE_FieldManual_Base { - logicalOrder = 25; + logicalOrder = 26; arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_Tripod' call FUNC(getItemName))}; displayName = "%14"; displayNameShort = CSTRING(Items_Tripod_ShortName); @@ -220,7 +228,7 @@ class CfgHints { tip = "Tripod Wiki"; }; class ACE_UAVBattery: ACE_FieldManual_Base { - logicalOrder = 26; + logicalOrder = 27; arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_UAVBattery' call FUNC(getItemName))}; displayName = "%14"; displayNameShort = CSTRING(Items_UAVBattery_ShortName); @@ -228,14 +236,14 @@ class CfgHints { tip = "UAV Battery Wiki"; }; class ACE_VehicleKey: ACE_FieldManual_Base { - logicalOrder = 27; + logicalOrder = 28; displayName = CSTRING(Items_VehicleKey_DisplayName); displayNameShort = CSTRING(Items_VehicleKey_ShortName); description = CSTRING(Items_VehicleKey_Description); tip = "Vehicle Lock Wiki"; }; class ACE_Wirecutter: ACE_FieldManual_Base { - logicalOrder = 28; + logicalOrder = 29; arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_wirecutter' call FUNC(getItemName))}; displayName = "%14"; displayNameShort = CSTRING(Items_Wirecutter_ShortName); diff --git a/addons/fieldmanual/stringtable.xml b/addons/fieldmanual/stringtable.xml index 73551b4a341..c617d67de6a 100644 --- a/addons/fieldmanual/stringtable.xml +++ b/addons/fieldmanual/stringtable.xml @@ -284,6 +284,12 @@ 청력을 보호합니다 聴覚の保護 + + %3Electronic Hearing Protection (EHP)%4 helps prevent hearing damage from repeat loud noises near a soldier. Differently from %3Ear Plugs%4, volume is only reduced when necessary. %3EHP%4 can also be built-in to certain types of %3Headgear%4 and %3Facewear%4.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Put on Electronic Hearing Protection%4. + + + Protect Your Hearing, Electronically + The %3Entrenching Tool%4 allows soldiers to dig trenches to help defend their position. The soldier must be on soil in order to dig a trench.<br/><br/>%3Usage:%4<br/>%2Equip an %3Entrenching Tool%4.<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Select the type of trench you wish to build. La %3Pala de Trincheras%4 permite a los soldados excavar trincheras para ayudarles a defender su posición. El soldado debe estar sobre tierra para poder excavar una trinchera.<br/><br/>%3Uso:%4<br/>%2Equipar la %3Pala de Trincheras%4.<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Seleccionar el tipo de trinchera que quieres construir. @@ -440,7 +446,7 @@ 三角測量で位置を特定 - The %3MicroDAGR GPS%4 is an advanced version of the %3DAGR%4. It provides position, navigation, and timing (PNT) data to include:<br/>%2Compass and heading<br/>%2Date and hour synced to the mission<br/>%2Elevation (relative to sea level)<br/>%2Current speed<br/>%2GPS with topographic and satellite view<br/>%2Creating, naming, and deleting waypoints<br/>%2Friendly identification (Requires ACE BLUFOR Tracker Setting)<br/>Connection to the Vector-21 Rangefinder for data import (waypoint creation and grid reference of ranged targets)<br/><br/>%3Usage:%4<br/>%2For usage instructions, please visit the dedicated %3MicroDAGR%4 wiki. + The %3MicroDAGR GPS%4 is an advanced version of the %3DAGR%4. It provides position, navigation, and timing (PNT) data to include:<br/>%2Compass and heading<br/>%2Date and hour synced to the mission<br/>%2Elevation (relative to sea level)<br/>%2Current speed<br/>%2GPS with topographic and satellite view<br/>%2Creating, naming, and deleting waypoints<br/>%2Friendly identification (Requires ACE BLUFOR Tracker Setting)<br/>%2Connection to the Vector-21 Rangefinder for data import (waypoint creation and grid reference of ranged targets)<br/><br/>%3Usage:%4<br/>%2For usage instructions, please visit the dedicated %3MicroDAGR%4 wiki. El %3GPS MicroDAGR%4 es una versión avanzada del %3DAGR%4. Provee de posicionamiento, navegación y datos de temporización (PNT) que incluye:<br/>%2Brújula y dirección<br/>%2Fecha y hora sincronizada con la misión<br/>%2Elevación (relativa al nivel del mar)<br/>%2Velocidad actual<br/>%2GPS con vista topográfica y satelital<br/>%2Creación, nombrado y borrado de puntos de ruta<br/>%2Identificación de aliados (Requiere la opción de ACE BLUFOR Tracker)<br/>Conexión con el telémetro Vector-21 para importación de datos (creación de puntos de ruta y referenciado en eje de coordenada para objetivos a distancia)<br/><br/>%3Uso:%4<br/>%2Para instrucciones de uso, por favor visita la Wiki dedicada de %3MicroDAGR%4. Il %3GPS MicroDAGR%4 è una versione avanzata del %3DAGR%4. Esso mostra dati su posizione, navigazione e tempismo (PNT), includendo:<br/>%2Bussola e azimut<br/>%2Data e ora sincronizzate con la missione<br/>%2Elevazione (dal livello del mare)<br/>%2Velocità attuale<br/>%2GPS con visuale topografica e satellitare<br/>%2Creazione, rinomina e rimozione di waypoint<br/>%2Identificazione di alleati (Richiede Impostazioni ACE BLUFOR Tracker)<br/>Connessione al Telemetro Vector-21 per importazione di dati (creazione waypoint e indicazione di griglia su bersagli puntati)<br/><br/>%3Utilizzo:%4<br/>%2Per informazioni sull'utilizzo sei pregato di visitare la pagina wiki dedicata al %3MicroDAGR%4. %3MicroDAGR GPS%4 jest zaawansowaną wersją %3DAGR%4. Dostarcza dane oparte o pozycję, nawigację, i czas (PNT): <br/>%2Kompas i kierunek<br/>%2Datę i godzinę zsynchronizowaną z misją<br/>%2Elewację (relatywną do poziomu morza)<br/>%2Obecną prędkość<br/>%2GPS z widokiem topograficznym i satelitarnym<br/>%2Tworzenie, nazywanie oraz usuwanie waypointów<br/>%2Identyfikację sojuszników (Wymaga ACE BLUFOR Tracker)<br/>Połączenie do dalmierza Vector-21 w celu importu danych (waypointy i współrzędne zmierzonego celu)<br/><br/>%3Użycie: %4<br/>%2Po instrukcję użycia odwiedź %3MicroDAGR%4 wiki. diff --git a/addons/hearing/ACE_Arsenal_Stats.hpp b/addons/hearing/ACE_Arsenal_Stats.hpp index 0ab83eed601..a83d274f8a2 100644 --- a/addons/hearing/ACE_Arsenal_Stats.hpp +++ b/addons/hearing/ACE_Arsenal_Stats.hpp @@ -3,19 +3,23 @@ class EGVAR(arsenal,stats) { class ACE_hearingProtection: statBase { scope = 2; priority = 2; - stats[] = {QGVAR(protection)}; - displayName= CSTRING(statHearingProtection); + stats[] = {QGVAR(protection), QGVAR(hasEHP)}; + displayName = CSTRING(statHearingProtection); showBar = 1; - barStatement = QUOTE([ARR_3((_this select 0) select 0,_this select 1,[ARR_3([ARR_2(0,1)],[ARR_2(0.01,1)],false)])] call EFUNC(arsenal,statBarStatement_default)); - tabs[] = {{6}, {}}; + condition = QUOTE([ARR_2(_this select 0,_this select 1)] call EFUNC(arsenal,statCondition_existsAny)); + barStatement = QUOTE([ARR_2(_this select 0,_this select 1)] call FUNC(statBarStatement_hearingProtection)); + showText = 1; + textStatement = QUOTE(_this select 1 call FUNC(statTextStatement_hearingProtection)); + tabs[] = {{6, 7}, {}}; }; class ACE_volumeMuffling: statBase { scope = 2; priority = 1.75; stats[] = {QGVAR(lowerVolume)}; - displayName= CSTRING(statHearingLowerVolume); + displayName = CSTRING(statHearingLowerVolume); showBar = 1; + condition = QUOTE([ARR_2(_this select 0,_this select 1)] call EFUNC(arsenal,statCondition_existsAll)); barStatement = QUOTE([ARR_3((_this select 0) select 0,_this select 1,[ARR_3([ARR_2(0,1)],[ARR_2(0.01,1)],false)])] call EFUNC(arsenal,statBarStatement_default)); - tabs[] = {{6}, {}}; + tabs[] = {{6, 7}, {}}; }; }; diff --git a/addons/hearing/CfgEventHandlers.hpp b/addons/hearing/CfgEventHandlers.hpp index 59cd1b36296..9fc1be4aee7 100644 --- a/addons/hearing/CfgEventHandlers.hpp +++ b/addons/hearing/CfgEventHandlers.hpp @@ -23,3 +23,36 @@ class Extended_Respawn_EventHandlers { }; }; }; + +class Extended_Killed_EventHandlers { + class Car { + class ADDON { + killed = QUOTE(_this call FUNC(handleVehicleKilled)); + }; + }; + class Tank { + class ADDON { + killed = QUOTE(_this call FUNC(handleVehicleKilled)); + }; + }; + class Motorcycle { + class ADDON { + killed = QUOTE(_this call FUNC(handleVehicleKilled)); + }; + }; + class Helicopter { + class ADDON { + killed = QUOTE(_this call FUNC(handleVehicleKilled)); + }; + }; + class Plane { + class ADDON { + killed = QUOTE(_this call FUNC(handleVehicleKilled)); + }; + }; + class Ship_F { + class ADDON { + killed = QUOTE(_this call FUNC(handleVehicleKilled)); + }; + }; +}; diff --git a/addons/hearing/CfgVehicles.hpp b/addons/hearing/CfgVehicles.hpp index 636184ecd22..182c0ccb46f 100644 --- a/addons/hearing/CfgVehicles.hpp +++ b/addons/hearing/CfgVehicles.hpp @@ -5,7 +5,7 @@ class CfgVehicles { class ACE_Equipment { class ACE_PutInEarplugs { displayName = CSTRING(EarPlugs_On); - condition = QUOTE(GVAR(enableCombatDeafness) && {!(_player call FUNC(hasEarPlugsIn)) && {[ARR_2(_player,'ACE_EarPlugs')] call EFUNC(common,hasItem)}}); + condition = QUOTE(GVAR(enableCombatDeafness) && {!(_player getVariable [ARR_2('ACE_hasEarPlugsIn',false)]) && {[ARR_2(_player,'ACE_EarPlugs')] call EFUNC(common,hasItem)}}); exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting"}; statement = QUOTE([ARR_2(_player,true)] call FUNC(putInEarPlugs)); showDisabled = 0; @@ -13,12 +13,28 @@ class CfgVehicles { }; class ACE_RemoveEarplugs { displayName = CSTRING(EarPlugs_Off); - condition = QUOTE(GVAR(enableCombatDeafness) && {_player call FUNC(hasEarPlugsIn)}); + condition = QUOTE(GVAR(enableCombatDeafness) && {_player getVariable [ARR_2('ACE_hasEarPlugsIn',false)]}); exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting"}; statement = QUOTE([ARR_2(_player,true)] call FUNC(removeEarPlugs)); showDisabled = 0; icon = QPATHTOF(UI\ACE_earplugs_x_ca.paa); }; + class ACE_PutOnEHP { + displayName = CSTRING(ElectronicHearingProtection_On); + condition = QUOTE([_player] call FUNC(canPutOnEHP)); + exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting"}; + statement = QUOTE([ARR_2(_player,true)] call FUNC(putOnEHP)); + showDisabled = 0; + icon = "\A3\Characters_F_Orange\Headgear\Data\UI\icon_H_EarProtectors_black_F_CA.paa"; + }; + class ACE_RemoveEHP { + displayName = CSTRING(ElectronicHearingProtection_Off); + condition = QUOTE(GVAR(EnableCombatDeafness) && {_player getVariable [ARR_2('ACE_hasEHP',false)]}); + exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting"}; + statement = QUOTE([ARR_2(_player,true)] call FUNC(removeEHP)); + showDisabled = 0; + icon = "\A3\Characters_F_Orange\Headgear\Data\UI\icon_H_EarProtectors_black_F_CA.paa"; + }; }; }; }; @@ -32,60 +48,70 @@ class CfgVehicles { class Box_NATO_Support_F: NATO_Box_Base { class TransportItems { MACRO_ADDITEM(ACE_EarPlugs,12); + MACRO_ADDITEM(ACE_EHP,12); }; }; class B_supplyCrate_F: ReammoBox_F { class TransportItems { MACRO_ADDITEM(ACE_EarPlugs,12); + MACRO_ADDITEM(ACE_EHP,12); }; }; class Box_East_Support_F: EAST_Box_Base { class TransportItems { MACRO_ADDITEM(ACE_EarPlugs,12); + MACRO_ADDITEM(ACE_EHP,12); }; }; class O_supplyCrate_F: B_supplyCrate_F { class TransportItems { MACRO_ADDITEM(ACE_EarPlugs,12); + MACRO_ADDITEM(ACE_EHP,12); }; }; class Box_IND_Support_F: IND_Box_Base { class TransportItems { MACRO_ADDITEM(ACE_EarPlugs,12); + MACRO_ADDITEM(ACE_EHP,12); }; }; class Box_FIA_Support_F: FIA_Box_Base_F { class TransportItems { MACRO_ADDITEM(ACE_EarPlugs,12); + MACRO_ADDITEM(ACE_EHP,12); }; }; class I_supplyCrate_F: B_supplyCrate_F { class TransportItems { MACRO_ADDITEM(ACE_EarPlugs,12); + MACRO_ADDITEM(ACE_EHP,12); }; }; class IG_supplyCrate_F: ReammoBox_F { class TransportItems { MACRO_ADDITEM(ACE_EarPlugs,12); + MACRO_ADDITEM(ACE_EHP,12); }; }; class C_supplyCrate_F: ReammoBox_F { class TransportItems { MACRO_ADDITEM(ACE_EarPlugs,12); + MACRO_ADDITEM(ACE_EHP,12); }; }; class ACE_Box_Misc: Box_NATO_Support_F { class TransportItems { MACRO_ADDITEM(ACE_EarPlugs,12); + MACRO_ADDITEM(ACE_EHP,12); }; }; diff --git a/addons/hearing/CfgWeapons.hpp b/addons/hearing/CfgWeapons.hpp index 8cef02edfd8..1f80544ea7f 100644 --- a/addons/hearing/CfgWeapons.hpp +++ b/addons/hearing/CfgWeapons.hpp @@ -14,6 +14,18 @@ class CfgWeapons { }; }; + class ACE_EHP: ACE_ItemCore { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(ElectronicHearingProtection_Name); + descriptionShort = CSTRING(ElectronicHearingProtection_Description); + model = "\A3\Characters_F_Orange\Headgear\H_EarProtectors_F.p3d"; + picture = "\A3\Characters_F_Orange\Headgear\Data\UI\icon_H_EarProtectors_black_F_CA.paa"; + scope = 2; + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 8.4; // 380g, based on 3M Peltor + }; + }; + class H_HelmetB; class H_HelmetCrew_B: H_HelmetB { diff --git a/addons/hearing/XEH_PREP.hpp b/addons/hearing/XEH_PREP.hpp index 64161300d3e..f2b70b8ab53 100644 --- a/addons/hearing/XEH_PREP.hpp +++ b/addons/hearing/XEH_PREP.hpp @@ -1,13 +1,18 @@ PREP(addEarPlugs); +PREP(canPutOnEHP); PREP(earRinging); PREP(explosion); PREP(firedNear); PREP(getAmmoLoudness); PREP(handleRespawn); -PREP(hasEarPlugsIn); +PREP(handleVehicleKilled); PREP(moduleHearing); PREP(putInEarPlugs); +PREP(putOnEHP); PREP(removeEarPlugs); +PREP(removeEHP); +PREP(statBarStatement_hearingProtection); +PREP(statTextStatement_hearingProtection); PREP(updateHearingProtection); PREP(updatePlayerVehAttenuation); PREP(updateVolume); diff --git a/addons/hearing/XEH_postInit.sqf b/addons/hearing/XEH_postInit.sqf index 0ced6cad9c2..3108161900b 100644 --- a/addons/hearing/XEH_postInit.sqf +++ b/addons/hearing/XEH_postInit.sqf @@ -50,6 +50,7 @@ GVAR(time3) = 0; GVAR(damageCoefficent) = 1; GVAR(volumeAttenuation) = 1; GVAR(lastPlayerVehicle) = objNull; +GVAR(ehpTimeout) = -1; ["CBA_settingsInitialized", { TRACE_1("settingInit - client",GVAR(enableCombatDeafness)); @@ -97,6 +98,6 @@ GVAR(lastPlayerVehicle) = objNull; GVAR(deafnessPrior) = 0; GVAR(time3) = 0; - UPDATE_HEARING_EARPLUGS call FUNC(updateHearingProtection); + UPDATE_HEARING call FUNC(updateHearingProtection); }, true] call CBA_fnc_addPlayerEventHandler; }] call CBA_fnc_addEventHandler; diff --git a/addons/hearing/XEH_preInit.sqf b/addons/hearing/XEH_preInit.sqf index eb9636a12c2..36d2159e8c9 100644 --- a/addons/hearing/XEH_preInit.sqf +++ b/addons/hearing/XEH_preInit.sqf @@ -19,6 +19,15 @@ PREP_RECOMPILE_END; [QGVAR(updateVolume), true, _unit] call CBA_fnc_targetEvent; }; }; + + if (_extendedInfo getOrDefault ["ace_ehp", false]) then { + _unit setVariable ["ACE_hasEHP", true, true]; + + // Only force update volume if unit is a player (including remote controlled) + if (_unit call EFUNC(common,isPlayer)) then { + [QGVAR(updateVolume), true, _unit] call CBA_fnc_targetEvent; + }; + }; }] call CBA_fnc_addEventHandler; ["CBA_loadoutGet", { @@ -27,6 +36,10 @@ PREP_RECOMPILE_END; if (_unit getVariable ["ACE_hasEarPlugsIn", false]) then { _extendedInfo set ["ace_earplugs", true] }; + + if (_unit getVariable ["ACE_hasEHP", false]) then { + _extendedInfo set ["ace_ehp", true] + }; }] call CBA_fnc_addEventHandler; ADDON = true; diff --git a/addons/hearing/config.cpp b/addons/hearing/config.cpp index ba6674b9db0..fcdef40324b 100644 --- a/addons/hearing/config.cpp +++ b/addons/hearing/config.cpp @@ -4,7 +4,7 @@ class CfgPatches { class ADDON { name = COMPONENT_NAME; units[] = {}; - weapons[] = {"ACE_EarPlugs"}; + weapons[] = {"ACE_EarPlugs", "ACE_EHP"}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_interaction"}; author = ECSTRING(common,ACETeam); diff --git a/addons/hearing/functions/fnc_addEarPlugs.sqf b/addons/hearing/functions/fnc_addEarPlugs.sqf index 11999f77378..c0bd6b92d83 100644 --- a/addons/hearing/functions/fnc_addEarPlugs.sqf +++ b/addons/hearing/functions/fnc_addEarPlugs.sqf @@ -27,7 +27,7 @@ params ["_unit"]; 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 {}; +if ((_unit getVariable ["ACE_hasEarPlugsIn", false]) || {[_unit, "ACE_EarPlugs"] call EFUNC(common,hasItem)}) exitWith {}; // Add earplugs if enabled for everyone or if the unit has a rocket launcher if (GVAR(autoAddEarplugsToUnits) == 2 || {(secondaryWeapon _unit) != ""}) exitWith { diff --git a/addons/hearing/functions/fnc_canPutOnEHP.sqf b/addons/hearing/functions/fnc_canPutOnEHP.sqf new file mode 100644 index 00000000000..01f327ac1ec --- /dev/null +++ b/addons/hearing/functions/fnc_canPutOnEHP.sqf @@ -0,0 +1,23 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut + * Checks if the unit can put on electronic hearing protection. + * + * Arguments: + * 0: Unit + * + * Return Value: + * True if unit can put on electronic hearing protection, otherwise false. + * + * Example: + * [player] call ace_hearing_fnc_canPutOnEHP + * + * Public: No + */ +params ["_unit"]; + +GVAR(enableCombatDeafness) +&& {!(_unit getVariable ["ACE_hasEHP", false])} +&& {[_unit, "ACE_EHP"] call EFUNC(common,hasItem)} +&& {(headgear _unit == "") || {getNumber (configFile >> "CfgWeapons" >> headgear _unit >> QGVAR(hasEHP)) == 0}} +&& {(goggles _unit == "") || {getNumber (configFile >> "CfgGlasses" >> goggles _unit >> QGVAR(hasEHP)) == 0}} diff --git a/addons/hearing/functions/fnc_earRinging.sqf b/addons/hearing/functions/fnc_earRinging.sqf index 57888e90a2e..70f9f6015f9 100644 --- a/addons/hearing/functions/fnc_earRinging.sqf +++ b/addons/hearing/functions/fnc_earRinging.sqf @@ -23,4 +23,23 @@ if (!GVAR(enabledForZeusUnits) && {player != ACE_player}) exitWith {}; TRACE_2("adding",_strength * GVAR(damageCoefficent),GVAR(deafnessDV)); +// Handle volume reduction by electronic hearing protection +if ( + _strength >= EHP_MIN_STRENGTH + && {ACE_player getVariable ["ACE_hasEHP", false] || {ACE_player getVariable ["ACE_hasBuiltInEHP", false]}} +) then { + if (GVAR(ehpTimeout) == -1) then { + [QGVAR(ehp), EHP_REDUCTION * GVAR(volumeAttenuation), true] call EFUNC(common,setHearingCapability); + + [{ + CBA_missionTime >= GVAR(ehpTimeout) + }, { + [QGVAR(ehp), 1, true, EHP_FADE_IN] call EFUNC(common,setHearingCapability); + GVAR(ehpTimeout) = -1; + }] call CBA_fnc_waitUntilAndExecute; + }; + + GVAR(ehpTimeout) = CBA_missionTime + EHP_TIMEOUT; +}; + GVAR(deafnessDV) = GVAR(deafnessDV) + (_strength * GVAR(damageCoefficent)); diff --git a/addons/hearing/functions/fnc_handleRespawn.sqf b/addons/hearing/functions/fnc_handleRespawn.sqf index 54d4730eda2..957f38a3f93 100644 --- a/addons/hearing/functions/fnc_handleRespawn.sqf +++ b/addons/hearing/functions/fnc_handleRespawn.sqf @@ -27,11 +27,15 @@ private _respawn = [0] call BIS_fnc_missionRespawnType; // If respawn is not group or side: if (_respawn <= 3) then { - // Remove earplugs if they have them: + // Remove earplugs & EHP if they have them if (_unit getVariable ["ACE_hasEarPlugsIn", false]) then { TRACE_1("had EarPlugs in - removing",_unit); _unit setVariable ["ACE_hasEarPlugsIn", false, true]; }; + if (_unit getVariable ["ACE_hasEHP", false]) then { + TRACE_1("had EHP on - removing",_unit); + _unit setVariable ["ACE_hasEHP", false, true]; + }; }; // Re-add if they need them diff --git a/addons/hearing/functions/fnc_handleVehicleKilled.sqf b/addons/hearing/functions/fnc_handleVehicleKilled.sqf new file mode 100644 index 00000000000..08e44ed194c --- /dev/null +++ b/addons/hearing/functions/fnc_handleVehicleKilled.sqf @@ -0,0 +1,64 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut + * Handles the explosion noise when a vehicle is destroyed. + * + * Arguments: + * 0: Vehicle + * 1: Killer + * 2: Instigator + * 3: Use effects + * + * Return Value: + * None + * + * Example: + * [vehicle player, player, player, true] call ace_hearing_fnc_handleVehicleKilled + * + * Public: No + */ +params ["_vehicle", "", "", "_useEffects"]; + +if (!_useEffects) exitWith {}; + +private _distance = (ACE_player distance _vehicle) max 1; +if (_distance > 50) exitWith {}; + +// Calculate explosion power +// This formula was once revealed to me in a dream +private _cfg = configOf _vehicle; +private _explosionPower = getNumber (_cfg >> "secondaryExplosion"); +if (_explosionPower == 0) exitWith {}; + +if (_explosionPower < 0) then { + private _fuelCargoPower = (getFuelCargo _vehicle max 0) * getNumber (_cfg >> "transportFuel") * 0.1; + private _fuelPower = fuel _vehicle * getNumber (_cfg >> "fuelCapacity") * 0.1; + + private _ammoCargoPower = (getAmmoCargo _vehicle max 0) * getNumber (_cfg >> "transportAmmo") * 0.05; + private _ammoPower = 0; + private _magCache = createHashMap; + { + _x params ["_magClass", "_count"]; + private _hit = _magCache getOrDefaultCall [_magClass, { + private _ammo = getText (configFile >> "CfgMagazines" >> _magClass >> "ammo"); + getNumber (configFile >> "CfgAmmo" >> _ammo >> "hit") + }, true]; + + _ammoPower = _ammoPower + _hit * _count * 0.015; + } forEach magazinesAmmoFull _vehicle; + + _explosionPower = abs _explosionPower * (_ammoCargoPower + _fuelCargoPower + _fuelPower + _ammoPower); +}; + +private _powerCoef = getNumber (_cfg >> "fuelExplosionPower"); + +// A low explosion power causes no immediate audible explosion +// Number + coef mechanics found through extensive testing +if (_explosionPower > 6.25 * _powerCoef) then { + // Calculate effective strength for player + private _vehAttenuation = [GVAR(playerVehAttenuation), 1] select (isNull objectParent ACE_player || {isTurnedOut ACE_player}); + + private _effect = getText (_cfg >> "explosionEffect"); + private _strength = [VEHICLE_EXPLOSION_STRENGTH, VEHICLE_EXPLOSION_BIG_STRENGTH] select (toLower _effect in ["fuelexplosionbig", "fuelcapacitorexplosion"]); + (_vehAttenuation * _strength / _distance) call FUNC(earRinging); +}; diff --git a/addons/hearing/functions/fnc_hasEarPlugsIn.sqf b/addons/hearing/functions/fnc_hasEarPlugsIn.sqf deleted file mode 100644 index a94f0fe47e0..00000000000 --- a/addons/hearing/functions/fnc_hasEarPlugsIn.sqf +++ /dev/null @@ -1,20 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: commy2 - * Check if the unit has earplugs put in. - * - * Arguments: - * 0: Unit - * - * Return Value: - * Has Earplugs in - * - * Example: - * player call ace_hearing_fnc_hasEarPlugsIn - * - * Public: No - */ - -params ["_unit"]; - -_unit getVariable ["ACE_hasEarPlugsIn", false] diff --git a/addons/hearing/functions/fnc_putInEarplugs.sqf b/addons/hearing/functions/fnc_putInEarplugs.sqf index 535ad7af01d..cb425226fd8 100644 --- a/addons/hearing/functions/fnc_putInEarplugs.sqf +++ b/addons/hearing/functions/fnc_putInEarplugs.sqf @@ -31,5 +31,4 @@ if (_displayHint) then { // Force an immediate volume update true call FUNC(updateVolume); - -UPDATE_HEARING_EARPLUGS call FUNC(updateHearingProtection); +UPDATE_HEARING call FUNC(updateHearingProtection); diff --git a/addons/hearing/functions/fnc_putOnEHP.sqf b/addons/hearing/functions/fnc_putOnEHP.sqf new file mode 100644 index 00000000000..8bb055884d4 --- /dev/null +++ b/addons/hearing/functions/fnc_putOnEHP.sqf @@ -0,0 +1,34 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut + * Puts on electronic hearing protection. + * + * Arguments: + * 0: Unit + * 1: Display hint (default: false) + * + * Return Value: + * None + * + * Example: + * [player, false] call ace_hearing_fnc_putOnEHP + * + * Public: No + */ + +if (!GVAR(enableCombatDeafness)) exitWith {}; + +params ["_unit", ["_displayHint", false]]; + +// Plugs in inventory, putting them in +_unit removeItem "ACE_EHP"; + +_unit setVariable ["ACE_hasEHP", true, true]; + +if (_displayHint) then { + [LLSTRING(ElectronicHearingProtection_Are_On)] call EFUNC(common,displayTextStructured); +}; + +// Force an immediate volume update +true call FUNC(updateVolume); +UPDATE_HEARING call FUNC(updateHearingProtection); diff --git a/addons/hearing/functions/fnc_removeEHP.sqf b/addons/hearing/functions/fnc_removeEHP.sqf new file mode 100644 index 00000000000..37d3d114f7e --- /dev/null +++ b/addons/hearing/functions/fnc_removeEHP.sqf @@ -0,0 +1,39 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut + * Takes off electronic hearing protection. + * + * Arguments: + * 0: Unit + * 1: Display hint (default: false) + * + * Return Value: + * None + * + * Example: + * [player, false] call ace_hearing_fnc_removeEHP + * + * Public: No + */ + +if (!GVAR(enableCombatDeafness)) exitWith {}; + +params ["_unit", ["_displayHint", false]]; + +// Inventory full +if !([_unit, "ACE_EHP"] call CBA_fnc_canAddItem) exitWith { + [LELSTRING(common,Inventory_Full)] call EFUNC(common,displayTextStructured); +}; + +// Plugs already in and removing them. +_unit addItem "ACE_EHP"; + +_unit setVariable ["ACE_hasEHP", false, true]; + +if (_displayHint) then { + [LLSTRING(ElectronicHearingProtection_Are_Off)] call EFUNC(common,displayTextStructured); +}; + +// Force an immediate volume update +true call FUNC(updateVolume); +UPDATE_HEARING call FUNC(updateHearingProtection); diff --git a/addons/hearing/functions/fnc_removeEarplugs.sqf b/addons/hearing/functions/fnc_removeEarplugs.sqf index 2d6cffb02e9..18e8256aa23 100644 --- a/addons/hearing/functions/fnc_removeEarplugs.sqf +++ b/addons/hearing/functions/fnc_removeEarplugs.sqf @@ -36,5 +36,4 @@ if (_displayHint) then { // Force an immediate volume update true call FUNC(updateVolume); - -UPDATE_HEARING_EARPLUGS call FUNC(updateHearingProtection); +UPDATE_HEARING call FUNC(updateHearingProtection); diff --git a/addons/hearing/functions/fnc_statBarStatement_hearingProtection.sqf b/addons/hearing/functions/fnc_statBarStatement_hearingProtection.sqf new file mode 100644 index 00000000000..729c39c5790 --- /dev/null +++ b/addons/hearing/functions/fnc_statBarStatement_hearingProtection.sqf @@ -0,0 +1,22 @@ +#include "..\script_component.hpp" +/* + * Author: LinkIsGrim + * Bar statement for hearing protection. + * + * Arguments: + * 0: Stats + * 1: Item config path + * + * Return Value: + * Bar statement + * + * Public: No +*/ + +params ["_stats", "_config", "_args"]; + +if (getNumber (_config >> (_stats # 1)) == 1) exitWith { + 1 +}; + +[_stats select 0, _config, [[0, 1], [0.01, 1], false]] call EFUNC(arsenal,statBarStatement_default) diff --git a/addons/hearing/functions/fnc_statTextStatement_hearingProtection.sqf b/addons/hearing/functions/fnc_statTextStatement_hearingProtection.sqf new file mode 100644 index 00000000000..19a9fa4145e --- /dev/null +++ b/addons/hearing/functions/fnc_statTextStatement_hearingProtection.sqf @@ -0,0 +1,17 @@ +#include "..\script_component.hpp" +/* + * Author: LinkIsGrim + * Text statement for hearing protection. + * + * Arguments: + * 0: Item config path + * + * Return Value: + * Stat Text + * + * Public: No +*/ + +params ["_config"]; + +["", LLSTRING(statEHP)] select (getNumber (_config >> QGVAR(hasEHP))) diff --git a/addons/hearing/functions/fnc_updateHearingProtection.sqf b/addons/hearing/functions/fnc_updateHearingProtection.sqf index b4584a567a8..d1b06af9b48 100644 --- a/addons/hearing/functions/fnc_updateHearingProtection.sqf +++ b/addons/hearing/functions/fnc_updateHearingProtection.sqf @@ -10,7 +10,7 @@ * None * * Example: - * UPDATE_HEARING_EARPLUGS call ace_hearing_fnc_updateHearingProtection + * UPDATE_HEARING call ace_hearing_fnc_updateHearingProtection * * Public: No */ @@ -25,13 +25,16 @@ if (isNull ACE_player) exitWith { params ["_slot"]; TRACE_1("",_slot); -if !(_slot in [UPDATE_HEARING_EARPLUGS, TYPE_GOGGLE, TYPE_HEADGEAR]) exitWith {}; +if !(_slot in [UPDATE_HEARING, TYPE_GOGGLE, TYPE_HEADGEAR]) exitWith {}; -// Handle Earplugs -private _hasEarPlugsIn = ACE_player call FUNC(hasEarPlugsIn); +// Handle ACE items +private _hasEarPlugsIn = ACE_player getVariable ["ACE_hasEarPlugsIn", false]; GVAR(damageCoefficent) = [1, 0.25] select _hasEarPlugsIn; GVAR(volumeAttenuation) = [1, GVAR(earplugsVolume)] select _hasEarPlugsIn; +private _hasEHPOn = ACE_player getVariable ["ACE_hasEHP", false]; +private _hasBuiltInEHP = false; + // Handle Headgear private _headgear = headgear ACE_player; @@ -43,6 +46,8 @@ if (_headgear != "") then { private _attenuation = getNumber (_heargearConfig >> QGVAR(lowerVolume)) min 1; GVAR(volumeAttenuation) = GVAR(volumeAttenuation) * (1 - _attenuation); + + _hasBuiltInEHP = _hasBuiltInEHP || { getNumber (_heargearConfig >> QGVAR(hasEHP)) > 0 }; }; // Handle Goggles @@ -56,4 +61,18 @@ if (_goggles != "") then { private _attenuation = getNumber (_gogglesConfig >> QGVAR(lowerVolume)) min 1; GVAR(volumeAttenuation) = GVAR(volumeAttenuation) * (1 - _attenuation); + + _hasBuiltInEHP = _hasBuiltInEHP || { getNumber (_gogglesConfig >> QGVAR(hasEHP)) > 0 }; +}; + +// Unequip electronic hearing protection when gear has one built in +if (_hasEHPOn && _hasBuiltInEHP) then { + [ACE_player, false] call FUNC(removeEHP); +}; + +// Handle electronic hearing protection - effect can only be applied once +if (_hasEHPOn || _hasBuiltInEHP) then { + GVAR(damageCoefficent) = GVAR(damageCoefficent) * 0.25; }; + +ACE_player setVariable ["ACE_hasBuiltInEHP", _hasBuiltInEHP]; diff --git a/addons/hearing/functions/fnc_updateVolume.sqf b/addons/hearing/functions/fnc_updateVolume.sqf index bb1d57e3c14..32ae063663f 100644 --- a/addons/hearing/functions/fnc_updateVolume.sqf +++ b/addons/hearing/functions/fnc_updateVolume.sqf @@ -42,10 +42,11 @@ if (!_updateVolumeOnly) then { GVAR(time3) = CBA_missionTime; + private _effectsVolume = getAudioOptionVolumes#0; if (GVAR(deafnessDV) > 19.75) then { - playSound (["ACE_Combat_Deafness_Heavy", "ACE_Combat_Deafness_Heavy_NoRing"] select GVAR(disableEarRinging)); + playSoundUI [["ACE_Combat_Deafness_Heavy", "ACE_Combat_Deafness_Heavy_NoRing"] select GVAR(disableEarRinging), _effectsVolume]; } else { - playSound (["ACE_Combat_Deafness_Medium", "ACE_Combat_Deafness_Medium_NoRing"] select GVAR(disableEarRinging)); + playSoundUI [["ACE_Combat_Deafness_Medium", "ACE_Combat_Deafness_Medium_NoRing"] select GVAR(disableEarRinging), _effectsVolume]; }; }; diff --git a/addons/hearing/initKeybinds.inc.sqf b/addons/hearing/initKeybinds.inc.sqf index d1299661986..b8c3d5f5dc5 100644 --- a/addons/hearing/initKeybinds.inc.sqf +++ b/addons/hearing/initKeybinds.inc.sqf @@ -2,13 +2,13 @@ // Conditions: specific if !([ACE_player, objNull, ["isNotSwimming", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {false}; - if (GVAR(enableCombatDeafness) && {!(ACE_player call FUNC(hasEarPlugsIn))} && {[ACE_player, "ACE_EarPlugs"] call EFUNC(common,hasItem)}) exitWith { + if (GVAR(enableCombatDeafness) && {!(ACE_player getVariable ["ACE_hasEarPlugsIn", false])} && {[ACE_player, "ACE_EarPlugs"] call EFUNC(common,hasItem)}) exitWith { [ACE_player, true] call FUNC(putInEarPlugs); true // return }; - if (GVAR(enableCombatDeafness) && {ACE_player call FUNC(hasEarPlugsIn)}) exitWith { + if (GVAR(enableCombatDeafness) && {ACE_player getVariable ["ACE_hasEarPlugsIn", false]}) exitWith { [ACE_player, true] call FUNC(removeEarPlugs); true // return @@ -16,3 +16,22 @@ false // return }] call CBA_fnc_addKeybind; // UNBOUND + +["ACE3 Equipment", QGVAR(putOrRemoveEHP), LLSTRING(PutOrRemoveEHP), { + // Conditions: specific + if !([ACE_player, objNull, ["isNotSwimming", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {false}; + + if ([ACE_player] call FUNC(canPutOnEHP)) exitWith { + [ACE_player, true] call FUNC(putOnEHP); + + true // return + }; + + if (GVAR(enableCombatDeafness) && {ACE_player getVariable ["ACE_hasEHP", false]}) exitWith { + [ACE_player, true] call FUNC(removeEHP); + + true // return + }; + + false // return +}] call CBA_fnc_addKeybind; // UNBOUND diff --git a/addons/hearing/script_component.hpp b/addons/hearing/script_component.hpp index a211922087d..f30c20471d6 100644 --- a/addons/hearing/script_component.hpp +++ b/addons/hearing/script_component.hpp @@ -17,4 +17,14 @@ #include "\z\ace\addons\main\script_macros.hpp" #include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp" -#define UPDATE_HEARING_EARPLUGS -1 +#define UPDATE_HEARING -1 + +// Electronic hearing protection FX +#define EHP_REDUCTION 0.125 +#define EHP_MIN_STRENGTH 0.07 +#define EHP_TIMEOUT 0.7 +#define EHP_FADE_IN 0.1 + +// Vehicle explosion hearing damage +#define VEHICLE_EXPLOSION_STRENGTH 200 +#define VEHICLE_EXPLOSION_BIG_STRENGTH 500 diff --git a/addons/hearing/script_macros_hearingProtection.hpp b/addons/hearing/script_macros_hearingProtection.hpp index 377560247ee..1c4a30a3a1a 100644 --- a/addons/hearing/script_macros_hearingProtection.hpp +++ b/addons/hearing/script_macros_hearingProtection.hpp @@ -1,4 +1,4 @@ #define HEARING_PROTECTION_OPEN EGVAR(hearing,protection) = 0; EGVAR(hearing,lowerVolume) = 0 #define HEARING_PROTECTION_VICCREW EGVAR(hearing,protection) = 0.85; EGVAR(hearing,lowerVolume) = 0.6 #define HEARING_PROTECTION_EARMUFF EGVAR(hearing,protection) = 0.75; EGVAR(hearing,lowerVolume) = 0.5 -#define HEARING_PROTECTION_PELTOR EGVAR(hearing,protection) = 0.75; EGVAR(hearing,lowerVolume) = 0 +#define HEARING_PROTECTION_PELTOR EGVAR(hearing,protection) = 0.75; EGVAR(hearing,lowerVolume) = 0; EGVAR(hearing,hasEHP) = 1 diff --git a/addons/hearing/stringtable.xml b/addons/hearing/stringtable.xml index 46be3272c85..82f2a7ca563 100644 --- a/addons/hearing/stringtable.xml +++ b/addons/hearing/stringtable.xml @@ -133,6 +133,30 @@ Kulak Tıkacı Tak Füldugó berakva + + Electronic Hearing Protection taken off + Elektronischer Gehörschutz abgesetzt + + + Electronic Hearing Protection put on + Elektronischer Gehörschutz aufgesetzt + + + Electronic Hearing Protection protects the wearer from hearing damage without reducing situational awareness. + Elektronischer Gehörschutz schützt den Träger vor Hörschäden, ohne dass sein Situationsbewusstsein eingeschränkt wird. + + + Electronic Hearing Protection + Elektronischer Gehörschutz + + + Take off Electronic Hearing Protection + Elektronischen Gehörschutz absetzen + + + Put on Electronic Hearing Protection + Elektronischen Gehörschutz aufsetzen + Reduces the hearing ability as the player takes hearing damage Snižuje schopnost sluchu pokud dojde k jeho poškození hlasitou a blízkou střelbou @@ -213,6 +237,10 @@ Kulak Tıkacın Yok Nincsen füldugód + + Put on/take off Electronic Hearing Protection + Elektronischer Gehörschutz aufsetzen/absetzen + Put/take out earplugs Mettre/enlever les bouchons @@ -369,6 +397,9 @@ 聽力保護 听力保护 + + ELECTRONIC + Volume when unconscious. Hlasitost během ztráty vědomí. diff --git a/docs/wiki/class-names.md b/docs/wiki/class-names.md index 0dcf014da16..7d3b425a58b 100644 --- a/docs/wiki/class-names.md +++ b/docs/wiki/class-names.md @@ -161,6 +161,7 @@ ACE_gunbag_Tan | Gunbag | Backpack | Class Name | In-Game Name | Type | ---------- | --------- | --------- ACE_EarPlugs | Earplugs | ACE_ItemCore | +ACE_EHP | Electronic Hearing Protection | ACE_ItemCore | ### HuntIR `Added in 3.1.1` diff --git a/docs/wiki/development/ace3-config-entries.md b/docs/wiki/development/ace3-config-entries.md index 8ff22438a10..8c7f1e43d34 100644 --- a/docs/wiki/development/ace3-config-entries.md +++ b/docs/wiki/development/ace3-config-entries.md @@ -129,6 +129,7 @@ ace_nextmodeclass ace_modedescription ace_hearing_protection ace_hearing_lowerVolume +ace_hearing_hasEHP ``` diff --git a/docs/wiki/framework/hearing-framework.md b/docs/wiki/framework/hearing-framework.md index a6748b77898..4e1131d4a45 100644 --- a/docs/wiki/framework/hearing-framework.md +++ b/docs/wiki/framework/hearing-framework.md @@ -17,8 +17,9 @@ version: ```cpp class CfgWeapons { class MyHelmet { - ace_hearing_protection = 0.80; // Protection against deafening (0 to 1, higher means more protection) - ace_hearing_lowerVolume = 0.60; // Muffling of the sound (0 to 1, higher means more muffling) + ace_hearing_protection = 0.80; // Protection against deafening (0 to 1, higher means more protection) + ace_hearing_lowerVolume = 0.60; // Muffling of the sound (0 to 1, higher means more muffling) + ace_hearing_hasEHP = 1; // Is electronic hearing protection (0 to disable, 1 to enable) }; }; ```