diff --git a/AUTHORS.txt b/AUTHORS.txt index bff0039f5c7..4fd35f29276 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -124,6 +124,7 @@ Hybrid V Hypoxic JasperRab JDT +JetfireBlack john681611 JoramD Joe DeShon diff --git a/addons/goggles/CfgGlasses.hpp b/addons/goggles/CfgGlasses.hpp index 2f3a02ef240..61489b128b6 100644 --- a/addons/goggles/CfgGlasses.hpp +++ b/addons/goggles/CfgGlasses.hpp @@ -212,12 +212,58 @@ class CfgGlasses { ACE_Protection = 1; ACE_Overlay_Angle = 180; }; + class G_AirPurifyingRespirator_01_F: G_AirPurifyingRespirator_01_base_F { + ACE_RespiratorFilterPair = "G_AirPurifyingRespirator_01_nofilter_F"; + }; + class G_AirPurifyingRespirator_01_nofilter_F: G_AirPurifyingRespirator_01_F { + ACE_RespiratorFilterPair = "G_AirPurifyingRespirator_01_F"; + ACE_RespiratorHoseList[] = { + {"B_CombinationUnitRespirator_01_F", {0, "a3\supplies_f_enoch\bags\data\b_cur_01_co.paa", "a3\supplies_f_enoch\bags\data\b_cur_01_co.paa", ""}}, + {"B_SCBA_01_F", {0, "a3\supplies_f_enoch\bags\data\b_scba_01_co.paa", ""}} + }; + }; + class G_AirPurifyingRespirator_02_base_F: G_AirPurifyingRespirator_01_base_F { ACE_Overlay = "a3\ui_f_enoch\data\objects\data\optics_APR_02_CA.paa"; }; + class G_AirPurifyingRespirator_02_black_F: G_AirPurifyingRespirator_02_base_F { + ACE_RespiratorFilterPair = "G_AirPurifyingRespirator_02_black_nofilter_F"; + }; + class G_AirPurifyingRespirator_02_black_nofilter_F: G_AirPurifyingRespirator_02_black_F { + ACE_RespiratorFilterPair = "G_AirPurifyingRespirator_02_black_F"; + ACE_RespiratorHoseList[] = { + {"B_CombinationUnitRespirator_01_F", {0, "a3\supplies_f_enoch\bags\data\b_cur_01_co.paa", "a3\supplies_f_enoch\bags\data\b_cur_01_co.paa", ""}}, + {"B_SCBA_01_F", {0, "a3\supplies_f_enoch\bags\data\b_scba_01_co.paa", ""}} + }; + }; + class G_AirPurifyingRespirator_02_olive_F: G_AirPurifyingRespirator_02_base_F { + ACE_RespiratorFilterPair = "G_AirPurifyingRespirator_02_olive_nofilter_F"; + }; + class G_AirPurifyingRespirator_02_olive_nofilter_F: G_AirPurifyingRespirator_02_olive_F { + ACE_RespiratorFilterPair = "G_AirPurifyingRespirator_02_olive_F"; + ACE_RespiratorHoseList[] = { + {"B_CombinationUnitRespirator_01_F", {0, "a3\supplies_f_enoch\bags\data\b_cur_01_co.paa", "a3\supplies_f_enoch\bags\data\b_cur_01_co.paa", ""}}, + {"B_SCBA_01_F", {0, "a3\supplies_f_enoch\bags\data\b_scba_01_co.paa", ""}} + }; + }; + class G_AirPurifyingRespirator_02_sand_F: G_AirPurifyingRespirator_02_base_F { + ACE_RespiratorFilterPair = "G_AirPurifyingRespirator_02_sand_nofilter_F"; + }; + class G_AirPurifyingRespirator_02_sand_nofilter_F: G_AirPurifyingRespirator_02_sand_F { + ACE_RespiratorFilterPair = "G_AirPurifyingRespirator_02_sand_F"; + ACE_RespiratorHoseList[] = { + {"B_CombinationUnitRespirator_01_F", {0, "a3\supplies_f_enoch\bags\data\b_cur_01_co.paa", "a3\supplies_f_enoch\bags\data\b_cur_01_co.paa", ""}}, + {"B_SCBA_01_F", {0, "a3\supplies_f_enoch\bags\data\b_scba_01_co.paa", ""}} + }; + }; + class G_RegulatorMask_base_F: None { ACE_Overlay = "a3\ui_f_enoch\data\objects\data\optics_regulator_ca.paa"; ACE_OverlayCracked = ""; ACE_Overlay_Angle = 180; + ACE_RespiratorHoseList[] = { + {"B_CombinationUnitRespirator_01_F", {0, "a3\supplies_f_enoch\bags\data\b_cur_01_co.paa", "", "a3\supplies_f_enoch\bags\data\b_cur_01_co.paa"}}, + {"B_SCBA_01_F", {0, "", "a3\supplies_f_enoch\bags\data\b_scba_01_co.paa"}} + }; }; }; diff --git a/addons/goggles/CfgVehicles.hpp b/addons/goggles/CfgVehicles.hpp index 68506d3269f..dd64a50c909 100644 --- a/addons/goggles/CfgVehicles.hpp +++ b/addons/goggles/CfgVehicles.hpp @@ -9,7 +9,33 @@ class CfgVehicles { statement = QUOTE(call FUNC(clearGlasses)); exceptions[] = {"isNotInside", "isNotSitting", "isNotSwimming", "isNotEscorting"}; }; + class GVAR(respiratorConnect) { + displayName = CSTRING(Respirator_Connect); + condition = QUOTE('combo' call FUNC(respiratorConditions)); + statement = QUOTE(call FUNC(respiratorConnect)); + exceptions[] = {"isNotInside", "isNotSitting", "isNotSwimming", "isNotEscorting"}; + }; + class GVAR(respiratorDisconnect) { + displayName = CSTRING(Respirator_Disconnect); + condition = QUOTE('hose' call FUNC(respiratorConditions)); + statement = QUOTE(call FUNC(respiratorDisconnect)); + exceptions[] = {"isNotInside", "isNotSitting", "isNotSwimming", "isNotEscorting"}; + }; + class GVAR(respiratorFilter) { + displayName = CSTRING(Respirator_Filters); + condition = QUOTE('mask' call FUNC(respiratorConditions)); + statement = QUOTE(call FUNC(respiratorFilter)); + exceptions[] = {"isNotInside", "isNotSitting", "isNotSwimming", "isNotEscorting"}; + }; }; }; }; + class Bag_Base; + class B_SCBA_01_base_F: Bag_Base { + ACE_RespiratorHoseTextures[] = {0,"",""}; + }; + + class B_CombinationUnitRespirator_01_Base_F: Bag_Base { + ACE_RespiratorHoseTextures[] = {0,"","",""}; + }; }; diff --git a/addons/goggles/XEH_PREP.hpp b/addons/goggles/XEH_PREP.hpp index 1716bdf58d5..795ed7bc464 100644 --- a/addons/goggles/XEH_PREP.hpp +++ b/addons/goggles/XEH_PREP.hpp @@ -22,6 +22,12 @@ PREP(canWipeGlasses); PREP(clearGlasses); PREP(getExplosionIndex); +// respirator +PREP(respiratorConditions); +PREP(respiratorConnect); +PREP(respiratorDisconnect); +PREP(respiratorFilter); + // eventhandlers PREP(handleExplosion); PREP(handleFired); diff --git a/addons/goggles/XEH_preInit.sqf b/addons/goggles/XEH_preInit.sqf index 894773534a4..de0eed0e02d 100644 --- a/addons/goggles/XEH_preInit.sqf +++ b/addons/goggles/XEH_preInit.sqf @@ -7,5 +7,8 @@ PREP_RECOMPILE_START; PREP_RECOMPILE_END; #include "initSettings.inc.sqf" +GVAR(respiratorPairs) = createHashMap; +GVAR(respiratorHoseList) = createHashMap; +GVAR(respiratorHoseTextures) = createHashMap; ADDON = true; diff --git a/addons/goggles/functions/fnc_respiratorConditions.sqf b/addons/goggles/functions/fnc_respiratorConditions.sqf new file mode 100644 index 00000000000..4f5e2110ff5 --- /dev/null +++ b/addons/goggles/functions/fnc_respiratorConditions.sqf @@ -0,0 +1,68 @@ +#include "..\script_component.hpp" +/* + * Author: JetfireBlack + * Checks if respirator interactions should be shown based on equipment combinations + * + * Arguments: + * 0: Mode + * + * Return Value: + * Should interaction be shown? + * + * Example: + * "combo" call ace_goggles_fnc_respiratorConditions + * + * Public: No + */ + +private _unit = ACE_player; + +if (!local _unit) exitWith {false}; + +private _mode = _this; + +private _goggles = goggles _unit; +private _backpack = backpackContainer _unit; +private _backpackType = backpack _unit; +private _objectTextures = getObjectTextures _backpack; +private _showAction = false; + +// retrieve paired respirator and add to cache if not present. +private _respiratorPair = GVAR(respiratorPairs) getOrDefault [_goggles, getText (configFile >> "CfgGlasses" >> _goggles >> "ACE_RespiratorFilterPair"), true]; + +// retrieve paired backpacks with textures and add to cache if not present. +private _respiratorHoseList = GVAR(respiratorHoseList) getOrDefault [_goggles, createHashMapFromArray getArray (configFile >> "CfgGlasses" >> _goggles >> "ACE_RespiratorHoseList"), true]; + +// fallback for backpacks with hoses without valid mask (like when switching goggles) +private _respiratorHoseTextures = GVAR(respiratorHoseTextures) getOrDefault [_backpackType, getArray (configFile >> "CfgVehicles" >> _backpackType >> "ACE_RespiratorHoseTextures"), true]; + +private _fnc_checkHose = { + private _hoseConnected = false; + { + if (_x isEqualType 0) then {continue}; + if (_objectTextures#_forEachIndex isNotEqualTo "") exitWith {_hoseConnected = true}; + } forEach (GVAR(respiratorHoseList) get _goggles getOrDefault [_backpackType, GVAR(respiratorHoseTextures) get _backpackType]); + _hoseConnected; +}; + +switch _mode do { + // only show when appropriate respirator and backpack are worn + case "combo": { + if !(_backpackType in _respiratorHoseList) exitWith {}; + if (call _fnc_checkHose) exitWith {}; + _showAction = true; + }; + // always show when wearing mask with filters + case "mask": { + if (_respiratorPair isEqualTo "") exitWith {}; + if (call _fnc_checkHose) exitWith {}; + _showAction = true; + }; + // shown only when hose is present regardless of respirator (Arma does not dynamically remove the hose) + case "hose": { + if !(call _fnc_checkHose) exitWith {}; + _showAction = true; + }; + default {}; +}; +_showAction; diff --git a/addons/goggles/functions/fnc_respiratorConnect.sqf b/addons/goggles/functions/fnc_respiratorConnect.sqf new file mode 100644 index 00000000000..c46dce44fa1 --- /dev/null +++ b/addons/goggles/functions/fnc_respiratorConnect.sqf @@ -0,0 +1,30 @@ +#include "..\script_component.hpp" +/* + * Author: JetfireBlack + * Connects appropriate backpack hose + * + * Arguments: + * 0: Optional unit (default: ACE_player) + * + * Return Value: + * None + * + * Examples: + * [player] call ace_goggles_fnc_respiratorConnect + * call ace_goggles_fnc_respiratorConnect + * + * Public: Yes + */ + +params [["_unit", ACE_player, [objNull]]]; + +if (!local _unit) exitWith {}; + +private _goggles = goggles _unit; +private _backpack = backpackContainer _unit; +private _backpackType = backpack _unit; + +{ + if (_x isEqualType 0) then {continue}; + _backpack setObjectTextureGlobal [_forEachIndex, _x]; +} forEach (GVAR(respiratorHoseList) get _goggles get _backpackType); diff --git a/addons/goggles/functions/fnc_respiratorDisconnect.sqf b/addons/goggles/functions/fnc_respiratorDisconnect.sqf new file mode 100644 index 00000000000..5a15c5b06ef --- /dev/null +++ b/addons/goggles/functions/fnc_respiratorDisconnect.sqf @@ -0,0 +1,30 @@ +#include "..\script_component.hpp" +/* + * Author: JetfireBlack + * Hides backpack hose + * + * Arguments: + * 0: Optional unit (default: ACE_player) + * + * Return Value: + * None + * + * Examples: + * [player] call ace_goggles_fnc_respiratorDisconnect + * call ace_goggles_fnc_respiratorDisconnect + * + * Public: Yes + */ + +params [["_unit", ACE_player, [objNull]]]; + +if (!local _unit) exitWith {}; + +private _goggles = goggles _unit; +private _backpack = backpackContainer _unit; +private _backpackType = backpack _unit; + +{ + if (_x isEqualType 0) then {continue}; + _backpack setObjectTextureGlobal [_forEachIndex, ""]; +} forEach (GVAR(respiratorHoseList) get _goggles getOrDefault [_backpackType, GVAR(respiratorHoseTextures) get _backpackType]); diff --git a/addons/goggles/functions/fnc_respiratorFilter.sqf b/addons/goggles/functions/fnc_respiratorFilter.sqf new file mode 100644 index 00000000000..48614f5226b --- /dev/null +++ b/addons/goggles/functions/fnc_respiratorFilter.sqf @@ -0,0 +1,25 @@ +#include "..\script_component.hpp" +/* + * Author: JetfireBlack + * Toggles respirator filter + * + * Arguments: + * 0: Optional unit (default: ACE_player) + * + * Return Value: + * None + * + * Examples: + * [player] call ace_goggles_fnc_respiratorFilter + * call ace_goggles_fnc_respiratorFilter + * + * Public: Yes + */ + +params [["_unit", ACE_player, [objNull]]]; + +if (!local _unit) exitWith {}; + +private _goggles = goggles _unit; + +_unit linkItem (GVAR(respiratorPairs) get _goggles); diff --git a/addons/goggles/stringtable.xml b/addons/goggles/stringtable.xml index 044cad0d812..c90b61b7aec 100644 --- a/addons/goggles/stringtable.xml +++ b/addons/goggles/stringtable.xml @@ -17,6 +17,18 @@ 护目镜 Gözlük + + Connect Respirator + Atemschutzgerät Verbinden + + + Disconnect Respirator + Atemschutzgerät Trennen + + + Toggle Filters + Atemschutzfilter Montieren/Demontieren + Show Goggles Overlay Afficher la superposition des lunettes