diff --git a/.hemtt/launch.toml b/.hemtt/launch.toml index ff6bdadd3b9..22ca0704a1d 100644 --- a/.hemtt/launch.toml +++ b/.hemtt/launch.toml @@ -3,6 +3,18 @@ workshop = [ "450814997", # CBA_A3 ] +[adt] +extends = "default" +workshop = [ + "3499977893", # ADT +] + +[zen] +extends = "default" +workshop = [ + "1779063631", # ZEN +] + [rhs] extends = "default" workshop = [ @@ -26,22 +38,29 @@ workshop = [ "1369691841", # Community Factions Project ] -[wardrobe] +[aegis] extends = "default" +workshop = [ + "949252631", # Aegis +] +dlc = [ + "ws", # Western Sahara +] + +[wardrobe] +extends = "adt" mission = "Wardrobe.VR" workshop = [ - "3499977893", # Advanced Developer Tools "1779063631", # ZEN # "751965892", # ACRE -# "623475643", # eden enhanced +# "623475643", # 3den Enhanced ] [sogns] -extends = "default" +extends = "adt" dlc = ["vn"] workshop = [ "623475643", # 3den Enhanced - "3499977893", # Advanced Developer Tools "3083451905", # S.O.G. Nickel Steel "1779063631", # Zeus Enhanced ] diff --git a/addons/compat_aegis/compat_aegis_smoke/CfgGlasses.hpp b/addons/compat_aegis/compat_aegis_smoke/CfgGlasses.hpp new file mode 100644 index 00000000000..86bb1af563b --- /dev/null +++ b/addons/compat_aegis/compat_aegis_smoke/CfgGlasses.hpp @@ -0,0 +1,41 @@ +class CfgGlasses { + class None; + + class G_Combat_Goggles_blk_F: None { + ace_smoke_eyes_protection = 1; + }; + + class G_Balaclava_light_blk_F: None { + ace_smoke_breathing_protection = 0.4; + }; + class G_Balaclava_light_G_blk_F: G_Balaclava_light_blk_F { + ace_smoke_eyes_protection = 1; + }; + class G_Balaclava_light_eaf_F; + class G_Balaclava_light_G_eaf_F: G_Balaclava_light_eaf_F { + ace_smoke_eyes_protection = 1; + }; + class G_Balaclava_light_mtp_F; + class G_Balaclava_light_G_mtp_F: G_Balaclava_light_mtp_F { + ace_smoke_eyes_protection = 1; + }; + class G_Balaclava_light_tropic_F; + class G_Balaclava_light_G_tropic_F: G_Balaclava_light_tropic_F { + ace_smoke_eyes_protection = 1; + }; + class G_Balaclava_light_wdl_F; + class G_Balaclava_light_G_wdl_F: G_Balaclava_light_wdl_F { + ace_smoke_eyes_protection = 1; + }; + + class G_Balaclava_TI_blk_F: None { + ace_smoke_breathing_protection = 0.4; + }; + class G_Balaclava_TI_G_blk_F: G_Balaclava_TI_blk_F { + ace_smoke_eyes_protection = 1; + }; + class G_Balaclava_TI_tna_F; + class G_Balaclava_TI_G_tna_F: G_Balaclava_TI_tna_F { + ace_smoke_eyes_protection = 1; + }; +}; diff --git a/addons/compat_aegis/compat_aegis_smoke/config.cpp b/addons/compat_aegis/compat_aegis_smoke/config.cpp new file mode 100644 index 00000000000..be9c09f88c5 --- /dev/null +++ b/addons/compat_aegis/compat_aegis_smoke/config.cpp @@ -0,0 +1,24 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "A3_Aegis_Characters_F_Aegis_Facewear", + "ace_smoke", + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"BrettMayson"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + // this prevents any patched class from requiring this addon + addonRootClass = "A3_Characters_F"; + }; +}; + +#include "CfgGlasses.hpp" diff --git a/addons/compat_aegis/compat_aegis_smoke/script_component.hpp b/addons/compat_aegis/compat_aegis_smoke/script_component.hpp new file mode 100644 index 00000000000..cafc3b0288d --- /dev/null +++ b/addons/compat_aegis/compat_aegis_smoke/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT smoke +#define SUBCOMPONENT_BEAUTIFIED Smoke +#include "..\script_component.hpp" diff --git a/addons/compat_cup_units/compat_cup_smoke/CfgGlasses.hpp b/addons/compat_cup_units/compat_cup_smoke/CfgGlasses.hpp new file mode 100644 index 00000000000..3b9c71bf637 --- /dev/null +++ b/addons/compat_cup_units/compat_cup_smoke/CfgGlasses.hpp @@ -0,0 +1,80 @@ +#define PROTECT(var1,eyes,breathing) class var1: None { \ + ace_smoke_eyes_protection = eyes; \ + ace_smoke_breathing_protection = breathing; \ +} + +class CfgGlasses { + class None; + + class CUP_RUS_Balaclava_blk: None { + ace_smoke_breathing_protection = 0.4; + }; + + class CUP_G_Ratnik_Balaclava_base: None { + ace_smoke_breathing_protection = 0.4; + }; + + PROTECT(CUP_G_ESS_BLK_Dark,1,0); + PROTECT(CUP_G_ESS_BLK_Ember,1,0); + PROTECT(CUP_G_ESS_BLK,1,0); + PROTECT(CUP_G_ESS_CBR_Dark,1,0); + PROTECT(CUP_G_ESS_CBR_Ember,1,0); + PROTECT(CUP_G_ESS_CBR,1,0); + PROTECT(CUP_G_ESS_RGR_Dark,1,0); + PROTECT(CUP_G_ESS_RGR_Ember,1,0); + PROTECT(CUP_G_ESS_RGR,1,0); + PROTECT(CUP_G_ESS_KHK_Dark,1,0); + PROTECT(CUP_G_ESS_KHK_Ember,1,0); + PROTECT(CUP_G_ESS_KHK,1,0); + PROTECT(CUP_G_ESS_BLK_Facewrap_Black,1,0.4); + PROTECT(CUP_G_ESS_RGR_Facewrap_Ranger,1,0.4); + PROTECT(CUP_G_ESS_CBR_Facewrap_Red,1,0.4); + PROTECT(CUP_G_ESS_RGR_Facewrap_Skull,1,0.4); + PROTECT(CUP_G_ESS_KHK_Facewrap_Tan,1,0.4); + PROTECT(CUP_G_ESS_RGR_Facewrap_Tropical,1,0.4); + PROTECT(CUP_G_ESS_KHK_Facewrap_White,1,0.4); + PROTECT(CUP_G_ESS_BLK_Facewrap_Black_GPS,1,0.4); + PROTECT(CUP_G_ESS_BLK_Scarf_Blk,1,0); + PROTECT(CUP_G_ESS_BLK_Scarf_Grn,1,0); + PROTECT(CUP_G_ESS_BLK_Scarf_Red,1,0); + PROTECT(CUP_G_ESS_KHK_Scarf_Tan,1,0); + PROTECT(CUP_G_ESS_BLK_Scarf_White,1,0); + PROTECT(CUP_G_ESS_BLK_Scarf_Face_Blk,1,0.4); + PROTECT(CUP_G_ESS_BLK_Scarf_Face_Grn,1,0.4); + PROTECT(CUP_G_ESS_BLK_Scarf_Face_Red,1,0.4); + PROTECT(CUP_G_ESS_KHK_Scarf_Face_Tan,1,0.4); + PROTECT(CUP_G_ESS_BLK_Scarf_Face_White,1,0.4); + PROTECT(CUP_G_ESS_BLK_Scarf_Blk_Beard,1,0); + PROTECT(CUP_G_ESS_BLK_Scarf_Blk_Beard_Blonde,1,0); + PROTECT(CUP_G_ESS_BLK_Scarf_Grn_Beard,1,0); + PROTECT(CUP_G_ESS_BLK_Scarf_Grn_Beard_Blonde,1,0); + PROTECT(CUP_G_ESS_BLK_Scarf_Red_Beard,1,0); + PROTECT(CUP_G_ESS_BLK_Scarf_Red_Beard_Blonde,1,0); + PROTECT(CUP_G_ESS_KHK_Scarf_Tan_Beard,1,0); + PROTECT(CUP_G_ESS_KHK_Scarf_Tan_Beard_Blonde,1,0); + PROTECT(CUP_G_ESS_BLK_Scarf_White_Beard,1,0); + PROTECT(CUP_G_ESS_BLK_Scarf_White_Beard_Blonde,1,0); + PROTECT(CUP_G_ESS_BLK_Scarf_Grn_GPS,1,0); + PROTECT(CUP_G_ESS_KHK_Scarf_Tan_GPS,1,0); + PROTECT(CUP_G_ESS_BLK_Scarf_White_GPS,1,0); + PROTECT(CUP_G_ESS_BLK_Scarf_Face_Grn_GPS,1,0.4); + PROTECT(CUP_G_ESS_KHK_Scarf_Face_Tan_GPS,1,0.4); + PROTECT(CUP_G_ESS_BLK_Scarf_Face_White_GPS,1,0.4); + PROTECT(CUP_G_ESS_BLK_Scarf_Grn_GPS_Beard,1,0); + PROTECT(CUP_G_ESS_BLK_Scarf_Grn_GPS_Beard_Blonde,1,0); + PROTECT(CUP_G_ESS_KHK_Scarf_Tan_GPS_Beard,1,0); + PROTECT(CUP_G_ESS_KHK_Scarf_Tan_GPS_Beard_Blonde,1,0); + PROTECT(CUP_G_ESS_BLK_Scarf_White_GPS_Beard,1,0); + PROTECT(CUP_G_ESS_BLK_Scarf_White_GPS_Beard_Blonde,1,0); + PROTECT(CUP_G_PMC_Facewrap_Black_Glasses_Dark_Headset,0,0.4); + PROTECT(CUP_G_PMC_Facewrap_Black_Glasses_Dark,0,0.4); + PROTECT(CUP_PMC_Facewrap_Black,0,0.4); + PROTECT(CUP_G_PMC_Facewrap_Tan_Glasses_Dark_Headset,0,0.4); + PROTECT(CUP_G_PMC_Facewrap_Tropical_Glasses_Dark_Headset,0,0.4); + PROTECT(CUP_G_PMC_Facewrap_Winter_Glasses_Dark_Headset,0,0.4); + PROTECT(CUP_G_Scarf_Face_Blk,0,0.4); + PROTECT(CUP_G_Scarf_Face_Grn,0,0.4); + PROTECT(CUP_G_Scarf_Face_Red,0,0.4); + PROTECT(CUP_G_Scarf_Face_Tan,0,0.4); + PROTECT(CUP_G_Scarf_Face_White,0,0.4); +}; diff --git a/addons/compat_cup_units/compat_cup_smoke/config.cpp b/addons/compat_cup_units/compat_cup_smoke/config.cpp new file mode 100644 index 00000000000..6f833154da5 --- /dev/null +++ b/addons/compat_cup_units/compat_cup_smoke/config.cpp @@ -0,0 +1,23 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "ace_smoke", + "CUP_Creatures_Military_RussiaModern_Headgear", + "CUP_Creatures_Military_USArmy", + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"BrettMayson"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgGlasses.hpp" diff --git a/addons/compat_cup_units/compat_cup_smoke/script_component.hpp b/addons/compat_cup_units/compat_cup_smoke/script_component.hpp new file mode 100644 index 00000000000..cafc3b0288d --- /dev/null +++ b/addons/compat_cup_units/compat_cup_smoke/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT smoke +#define SUBCOMPONENT_BEAUTIFIED Smoke +#include "..\script_component.hpp" diff --git a/addons/compat_ws/compat_ws_smoke/CfgWeapons.hpp b/addons/compat_ws/compat_ws_smoke/CfgWeapons.hpp new file mode 100644 index 00000000000..2a3303d8713 --- /dev/null +++ b/addons/compat_ws/compat_ws_smoke/CfgWeapons.hpp @@ -0,0 +1,11 @@ +class CfgWeapons { + class lxWS_H_turban_01_black; + class lxWS_H_turban_03_black: lxWS_H_turban_01_black { + ace_smoke_breathing_protection = 0.4; + }; + + class H_Shemag_khk; + class H_turban_02_mask_black_lxws: H_Shemag_khk { + ace_smoke_breathing_protection = 0.4; + }; +}; diff --git a/addons/compat_ws/compat_ws_smoke/config.cpp b/addons/compat_ws/compat_ws_smoke/config.cpp new file mode 100644 index 00000000000..61a8c70dfcc --- /dev/null +++ b/addons/compat_ws/compat_ws_smoke/config.cpp @@ -0,0 +1,24 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "data_f_lxWS_Loadorder", + "ace_smoke", + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"BrettMayson"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + // this prevents any patched class from requiring this addon + addonRootClass = "A3_Characters_F"; + }; +}; + +#include "CfgWeapons.hpp" diff --git a/addons/compat_ws/compat_ws_smoke/script_component.hpp b/addons/compat_ws/compat_ws_smoke/script_component.hpp new file mode 100644 index 00000000000..cafc3b0288d --- /dev/null +++ b/addons/compat_ws/compat_ws_smoke/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT smoke +#define SUBCOMPONENT_BEAUTIFIED Smoke +#include "..\script_component.hpp" diff --git a/addons/hearing/stringtable.xml b/addons/hearing/stringtable.xml index 9eab8e109cb..3ced27a2450 100644 --- a/addons/hearing/stringtable.xml +++ b/addons/hearing/stringtable.xml @@ -491,36 +491,36 @@ ЕЛЕКТРОННИЙ - Volume muffling - Snížení hlasitosti - Atténuation du volume - Atenuación de volumen - Attenuazione del volume - Tłumienie głośności - Abafamento de Volume - Глушение звука + Volume Muffling + Snížení Hlasitosti + Atténuation Du Volume + Atenuación De Volumen + Attenuazione Del Volume + Tłumienie Głośności + Abafamento De Volume + Глушение Звука Lautstärkedämpfung 소리 차음도 音量の抑制 進低音量 降低音量 - Глушіння звуку + Глушіння Звуку - Hearing protection - Ochrana sluchu - Protection auditive - Protección auditiva - Protezione uditiva - Ochrona słuchu + Hearing Protection + Ochrana Sluchu + Protection Auditive + Protección Auditiva + Protezione Uditiva + Ochrona Słuchu Proteção Auditiva - Защита слуха + Защита Слуха Gehörschutz 청력 보호 聴覚保護 聽力保護 听力保护 - Захист слуху + Захист Слуху Volume when unconscious. diff --git a/addons/medical_vitals/functions/fnc_addSpO2DutyFactor.sqf b/addons/medical_vitals/functions/fnc_addSpO2DutyFactor.sqf index 0c85ae3fa55..69573b9dff9 100644 --- a/addons/medical_vitals/functions/fnc_addSpO2DutyFactor.sqf +++ b/addons/medical_vitals/functions/fnc_addSpO2DutyFactor.sqf @@ -16,6 +16,10 @@ * Public: No */ params [["_id", "", [""]], ["_factor", 1, [0, {}]]]; -if (_id == "" || {_factor isEqualTo 1}) exitWith {}; +if (_id == "") exitWith {}; + +if (_factor isEqualTo 1) exitWith { + [_id] call FUNC(removeSpO2DutyFactor); +}; GVAR(spo2DutyList) set [_id, _factor]; diff --git a/addons/smoke/$PBOPREFIX$ b/addons/smoke/$PBOPREFIX$ new file mode 100644 index 00000000000..830debaa3c8 --- /dev/null +++ b/addons/smoke/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\smoke diff --git a/addons/smoke/ACE_Arsenal_Stats.hpp b/addons/smoke/ACE_Arsenal_Stats.hpp new file mode 100644 index 00000000000..313b9f6ee11 --- /dev/null +++ b/addons/smoke/ACE_Arsenal_Stats.hpp @@ -0,0 +1,20 @@ +class EGVAR(arsenal,stats) { + class statBase; + class GVAR(breathing_protection): statBase { + scope = 2; + displayName = CSTRING(statBreatingProtection); + showBar = 1; + condition = QUOTE(getNumber (_this select 1 >> QQGVAR(Breathing_Protection)) > 0); + barStatement = QUOTE(getNumber (_this select 1 >> QQGVAR(Breathing_Protection))); + tabs[] = {{6,7}, {}}; + }; + + class GVAR(eyes_protection): statBase { + scope = 2; + displayName = CSTRING(statEyesProtection); + showBar = 1; + condition = QUOTE(getNumber (_this select 1 >> QQGVAR(Eyes_Protection)) > 0); + barStatement = QUOTE(getNumber (_this select 1 >> QQGVAR(Eyes_Protection))); + tabs[] = {{6,7}, {}}; + }; +}; diff --git a/addons/smoke/CfgEventHandlers.hpp b/addons/smoke/CfgEventHandlers.hpp new file mode 100644 index 00000000000..e90bed419e7 --- /dev/null +++ b/addons/smoke/CfgEventHandlers.hpp @@ -0,0 +1,15 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_preStart)); + }; +}; +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_preInit)); + }; +}; +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_postInit)); + }; +}; diff --git a/addons/smoke/CfgGlasses.hpp b/addons/smoke/CfgGlasses.hpp new file mode 100644 index 00000000000..d7ee9a1f65d --- /dev/null +++ b/addons/smoke/CfgGlasses.hpp @@ -0,0 +1,53 @@ +class CfgGlasses { + class None; + + class G_AirPurifyingRespirator_01_base_F: None { + GVAR(Eyes_Protection) = 1; + GVAR(Breathing_Protection) = 1; + }; + + class G_Balaclava_blk: None { + GVAR(Breathing_Protection) = 0.2; + }; + class G_Balaclava_combat: G_Balaclava_blk { + GVAR(Eyes_Protection) = 1; + }; + class G_Balaclava_lowprofile: G_Balaclava_blk { + GVAR(Eyes_Protection) = 1; + }; + + class G_Combat: None { + GVAR(Eyes_Protection) = 1; + }; + class G_Lowprofile: None { + GVAR(Eyes_Protection) = 1; + }; + + class G_RegulatorMask_base_F: None { + GVAR(Eyes_Protection) = 1; + GVAR(Breathing_Protection) = 1; + }; + + class G_Respirator_base_F: None { + GVAR(Breathing_Protection) = 0.8; + }; + + class G_EyeProtectors_base_F: None { + GVAR(Eyes_Protection) = 0.2; + }; + + class G_Balaclava_TI_blk_F: None { + GVAR(Breathing_Protection) = 0.4; + }; + class G_Balaclava_TI_G_blk_F: G_Balaclava_TI_blk_F { + GVAR(Eyes_Protection) = 1; + }; + class G_Balaclava_TI_tna_F; + class G_Balaclava_TI_G_tna_F: G_Balaclava_TI_tna_F { + GVAR(Eyes_Protection) = 1; + }; + + class G_Blindfold_01_base_F: None { + GVAR(Eyes_Protection) = 0.6; + }; +}; diff --git a/addons/smoke/CfgVehicles.hpp b/addons/smoke/CfgVehicles.hpp new file mode 100644 index 00000000000..a19a9caa88b --- /dev/null +++ b/addons/smoke/CfgVehicles.hpp @@ -0,0 +1,67 @@ +class CfgVehicles { + class Truck_01_base_F; + class B_Truck_01_transport_F: Truck_01_base_F { + ace_smoke_seats[] = { + {0}, // Driver is enclosed + {1, 1}, // Gunners are exposed + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} + }; + }; + + class Heli_Transport_04_base_F; + class O_Heli_Transport_04_bench_F: Heli_Transport_04_base_F { + ace_smoke_seats[] = { + {0}, // Pilot is enclosed + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1}, // Crew is enclosed, passengers are exposed + }; + }; + + class Heli_light_03_base_F; + class Heli_light_03_unarmed_base_F: Heli_light_03_base_F { + ace_smoke_seats[] = {0}; // All seats are enclosed + }; + + class Heli_Light_02_base_F; + class Heli_Light_02_dynamicLoadout_base_F: Heli_Light_02_base_F { + ace_smoke_seats[] = {0}; // All seats are enclosed + }; + + class Heli_Attack_01_base_F; + class Heli_Attack_01_dynamicLoadout_base_F: Heli_Attack_01_base_F { + ace_smoke_seats[] = {0}; // All seats are enclosed + }; + + class Helicopter_Base_H; + class Heli_Transport_02_base_F: Helicopter_Base_H { + ace_smoke_seats[] = {0}; // All seats are enclosed + }; + + class Car_F; + class Offroad_01_base_F: Car_F { + ace_smoke_seats[] = {1}; // All seats are exposed + }; + class Hatchback_01_base_F: Car_F { + ace_smoke_seats[] = {1}; + }; + class SUV_01_base_F: Car_F { + ace_smoke_seats[] = {1}; + }; + class Van_01_base_F: Car_F { + ace_smoke_seats[] = {1}; + }; + class Van_02_base_F: Car_F { + ace_smoke_seats[] = {1}; + }; + class Tractor_01_base_F: Car_F { + ace_smoke_seats[] = {1}; + }; + + class Truck_02_base_F; + class C_Truck_02_covered_F: Truck_02_base_F { + ace_smoke_seats[] = { + {0}, // Driver is enclosed + {1, 1}, // Gunners are exposed + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} + }; + }; +}; diff --git a/addons/smoke/CfgWeapons.hpp b/addons/smoke/CfgWeapons.hpp new file mode 100644 index 00000000000..74fc3494864 --- /dev/null +++ b/addons/smoke/CfgWeapons.hpp @@ -0,0 +1,17 @@ +class CfgWeapons { + class H_HelmetB; + class H_HelmetO_ViperSP_hex_F: H_HelmetB { + GVAR(Eyes_Protection) = 1; + }; + + class H_PilotHelmetFighter_B: H_HelmetB { + GVAR(Breathing_Protection) = 1; + GVAR(Eyes_Protection) = 1; + }; + + class H_HelmetB_camo; + class H_RacingHelmet_1_F: H_HelmetB_camo { + GVAR(Breathing_Protection) = 0.3; + GVAR(Eyes_Protection) = 0.7; + }; +}; diff --git a/addons/smoke/XEH_PREP.hpp b/addons/smoke/XEH_PREP.hpp new file mode 100644 index 00000000000..059e0c6264b --- /dev/null +++ b/addons/smoke/XEH_PREP.hpp @@ -0,0 +1,4 @@ +PREP(isInSmoke); +PREP(isOpenVehicle); +PREP(isOpenSeat); +PREP(pfh); diff --git a/addons/smoke/XEH_postInit.sqf b/addons/smoke/XEH_postInit.sqf new file mode 100644 index 00000000000..4fa37ee6348 --- /dev/null +++ b/addons/smoke/XEH_postInit.sqf @@ -0,0 +1,17 @@ +#include "script_component.hpp" + +if (!hasInterface) exitWith {}; +GVAR(ppHandleDynamicBlur) = ppEffectCreate ["DynamicBlur", 500]; +GVAR(ppHandleColorCorrections) = ppEffectCreate ["ColorCorrections", 1500]; +GVAR(ppHandleDynamicBlur) ppEffectEnable GVAR(enabled); +GVAR(ppHandleColorCorrections) ppEffectEnable GVAR(enabled); + +["loadout", { + params ["_unit"]; + if !(local _unit) exitWith {}; + private _config = configFile >> "CfgGlasses" >> goggles _unit; + private _breathing = getNumber (_config >> QGVAR(Breathing_Protection)); + _unit setVariable [QGVAR(breathingProtection), _breathing, true]; + private _eyes = getNumber (_config >> QGVAR(Eyes_Protection)); + _unit setVariable [QGVAR(eyesProtection), _eyes, true]; +}, true] call CBA_fnc_addPlayerEventHandler; diff --git a/addons/smoke/XEH_preInit.sqf b/addons/smoke/XEH_preInit.sqf new file mode 100644 index 00000000000..61eb91c6dc1 --- /dev/null +++ b/addons/smoke/XEH_preInit.sqf @@ -0,0 +1,13 @@ +#include "script_component.hpp" + +ADDON = false; + +#include "XEH_PREP.hpp" + +#include "initSettings.inc.sqf" + +GVAR(pfh) = -1; +GVAR(openVehicleCache) = createHashMap; +GVAR(openSeatCache) = createHashMap; + +ADDON = true; diff --git a/addons/smoke/XEH_preStart.sqf b/addons/smoke/XEH_preStart.sqf new file mode 100644 index 00000000000..a51262a37b9 --- /dev/null +++ b/addons/smoke/XEH_preStart.sqf @@ -0,0 +1,2 @@ +#include "script_component.hpp" +#include "XEH_PREP.hpp" diff --git a/addons/smoke/config.cpp b/addons/smoke/config.cpp new file mode 100644 index 00000000000..bfe59b1f77e --- /dev/null +++ b/addons/smoke/config.cpp @@ -0,0 +1,18 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = QUOTE(COMPONENT); + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_main"}; + VERSION_CONFIG; + }; +}; + +#include "ACE_Arsenal_Stats.hpp" +#include "CfgEventHandlers.hpp" +#include "CfgGlasses.hpp" +#include "CfgVehicles.hpp" +#include "CfgWeapons.hpp" diff --git a/addons/smoke/functions/fnc_isInSmoke.sqf b/addons/smoke/functions/fnc_isInSmoke.sqf new file mode 100644 index 00000000000..d9d9fc09860 --- /dev/null +++ b/addons/smoke/functions/fnc_isInSmoke.sqf @@ -0,0 +1,47 @@ +#include "..\script_component.hpp" +/* + * Author: BrettMayson + * Check if a unit is in smoke (or any thick particle effect that has `blockAIVisibility`) + * + * Arguments: + * 0: Unit + * + * Return Value: + * Is the unit in smoke? + * + * Example: + * [player] call ace_smoke_fnc_isInSmoke + * + * Public: Yes + */ + +params [["_unit", objNull, [objNull]]]; + +private _vehicle = objectParent _unit; + +if (!isNull _vehicle && {!([_vehicle, _unit] call FUNC(isOpenSeat))}) exitWith { false }; + +private _coverage = 0; + +private _eyePos = eyePos _unit; +private _positions = [ + [_eyePos, _eyePos vectorAdd [5, 0, 0], _unit], + [_eyePos, _eyePos vectorAdd [-5, 0, 0], _unit], + [_eyePos, _eyePos vectorAdd [0, 5, 0], _unit], + [_eyePos, _eyePos vectorAdd [0, -5, 0], _unit] +]; + +{ + private _intersect = lineIntersectsSurfaces _x; + if (_intersect isNotEqualTo []) then { + _x set [1, _intersect select 0]; + } else { + _x set [1, [_x#1,0,objNull]]; + }; + if ((_x#0) distance (_x#1#0) < 0.1) then { + _coverage = _coverage + 1; + } else { + _coverage = _coverage + ([objectParent _unit, "VIEW", _x#1#2] checkVisibility [_x#0, _x#1#0]); + }; +} forEach _positions; +_coverage < ((count _positions) / 3) diff --git a/addons/smoke/functions/fnc_isOpenSeat.sqf b/addons/smoke/functions/fnc_isOpenSeat.sqf new file mode 100644 index 00000000000..23ce4941775 --- /dev/null +++ b/addons/smoke/functions/fnc_isOpenSeat.sqf @@ -0,0 +1,68 @@ +#include "..\script_component.hpp" +/* + * Author: BrettMayson + * Check if a seat is open and thus susceptible to smoke entering, may not be accurate for vehicles with top coverings + * + * Arguments: + * 0: Vehicle + * 1: Unit + * + * Return Value: + * Is the seat open? + * + * Example: + * [_vehicle, _unit] call ace_smoke_fnc_isOpenSeat + * + * Public: Yes + */ + +params [ + ["_vehicle", objNull, [objNull]], + ["_unit", objNull, [objNull]] +]; + +if (_vehicle isEqualTo objNull || _unit isEqualTo objNull) exitWith { true }; + +if (isTurnedOut _unit) exitWith { true }; + +private _class = typeOf _vehicle; + +private _key = _vehicle unitTurret _unit; +if (count _key >= 1) then { + _key = [_key select 0]; +} else { + _key = [-2, _vehicle getCargoIndex _unit]; +}; + +private _open = -1; +if (_class in GVAR(openSeatCache)) then { + private _cache = GVAR(openSeatCache) get _class; + if (_key in _cache) then { + _open = _cache get _key; + }; +}; +if (_open isNotEqualTo -1) exitWith { _open }; + +private _config = getArray (configOf _vehicle >> QGVAR(seats)); +if (_config isNotEqualTo []) exitWith { + if (typeName _config == "SCALAR") exitWith { _config == 1 }; + private _path = switch (_key select 0) do { + case -2: { [2, _key select 1] }; // cargo + case -1: { [0, 0] }; // driver + default { [1, _key select 0] }; // turret + }; + private _subConfig = _config select (_path select 0); + if (typeName _subConfig == "SCALAR") exitWith { _subConfig == 1 }; + _subConfig select (_path select 1) == 1 +}; + +if ([_vehicle] call FUNC(isOpenVehicle)) exitWith { true }; + +private _eyePos = eyePos _unit; +private _intersect = lineIntersectsSurfaces [_eyePos, _eyePos vectorAdd [0, 0, 1], _unit]; +private _open = (_intersect findIf { _x#2 == _vehicle }) == -1; // No intersection with vehicle roof + +private _cache = GVAR(openSeatCache) getOrDefaultCall [_class, { createHashMap }, true]; +_cache set [_key, _open]; + +_open diff --git a/addons/smoke/functions/fnc_isOpenVehicle.sqf b/addons/smoke/functions/fnc_isOpenVehicle.sqf new file mode 100644 index 00000000000..5c8e1ca3e43 --- /dev/null +++ b/addons/smoke/functions/fnc_isOpenVehicle.sqf @@ -0,0 +1,38 @@ +#include "..\script_component.hpp" +/* + * Author: BrettMayson + * Check if a vehicle is open and thus susceptible to smoke entering + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * Is the vehicle open? + * + * Example: + * [vehicle player] call ace_smoke_fnc_isOpenVehicle + * + * Public: Yes + */ + +params [ + ["_vehicle", objNull, [objNull]] +]; + +if (_vehicle isEqualTo objNull) exitWith { true }; + +private _class = typeOf _vehicle; + +if (_class in GVAR(openVehicleCache)) exitWith { GVAR(openVehicleCache) get _class }; + +private _attenuation = getText(configFile >> "CfgVehicles" >> _class >> "attenuationEffectType"); +if (_attenuation == "") exitWith { true }; + +private _attenuation = configFile >> "AttenuationEffects" >> _attenuation; +private _open = [0,1] findIf { + private _equalizer = getArray(_attenuation >> format ["Equalizer%1", _x] >> "gain"); + _equalizer isEqualTo [1,1,1,1] +} != -1; + +GVAR(openVehicleCache) set [_class, _open]; +_open diff --git a/addons/smoke/functions/fnc_pfh.sqf b/addons/smoke/functions/fnc_pfh.sqf new file mode 100644 index 00000000000..8ceb3c72e78 --- /dev/null +++ b/addons/smoke/functions/fnc_pfh.sqf @@ -0,0 +1,82 @@ +#include "..\script_component.hpp" +/* + * Author: BrettMayson + * Per Frame Handler that updates smoke effects on units + * + * Arguments: + * 0: Unit + * + * Return Value: + * Nothing + * + * Example: + * [{ + * [player] call ace_smoke_fnc_pfh + * }] call CBA_fnc_addPerFrameHandler + * + * Public: No + */ + +params ["_unit"]; + +if (isGamePaused) exitWith {}; + +#define EFFECT_RATE 0.3 +#define RECOVERY_RATE -0.075 + +private _isInSmoke = [_unit] call FUNC(isInSmoke); + +private _change = (if (_isInSmoke) then { + EFFECT_RATE * GVAR(effectFactor) +} else { + RECOVERY_RATE * GVAR(recoveryFactor) +}) * diag_deltaTime * (1 / PFH_INTERVAL); + +private _fnc_updateLevel = { + params ["_level", "_protect"]; + private _innerChange = if (_protect == 1 && _isInSmoke) then { + RECOVERY_RATE * GVAR(recoveryFactor) * diag_deltaTime * (1 / PFH_INTERVAL) + } else { + _change + }; + private _newLevel = (_level + _innerChange) min 1 max 0; + if (_protect != 0 && _protect != 1) then { + _newLevel = _newLevel * (1 - _protect); + }; + _newLevel +}; + +// Eyes +private _levelEyes = _unit getVariable [QGVAR(eyesLevel), 0]; +private _eyesProtect = _unit getVariable [QGVAR(eyesProtection), 0]; +_levelEyes = [_levelEyes, _eyesProtect] call _fnc_updateLevel; +_unit setVariable [QGVAR(eyesLevel), _levelEyes]; + +private _dynamicBlurValue = linearConversion [0.05, 1, _levelEyes, 0, 0.8, true]; +private _colorCorrectionsValue = linearConversion [0.05, 1, _levelEyes, 1, 0.6, true]; + +if (_unit == ace_player) then { + GVAR(ppHandleDynamicBlur) ppEffectAdjust [_dynamicBlurValue]; + GVAR(ppHandleColorCorrections) ppEffectAdjust [1,1,0,[0,0,0,0],[0.8, 0.8, 0.8, _colorCorrectionsValue],[1,1,1,0]]; + + GVAR(ppHandleDynamicBlur) ppEffectCommit PFH_INTERVAL; + GVAR(ppHandleColorCorrections) ppEffectCommit PFH_INTERVAL; +}; + +// Breathing +private _levelBreathing = _unit getVariable [QGVAR(breathingLevel), 0]; +private _breathProtect = _unit getVariable [QGVAR(breathingProtection), 0]; +_levelBreathing = [_levelBreathing, _breathProtect] call _fnc_updateLevel; +_unit setVariable [QGVAR(breathingLevel), _levelBreathing]; + +if !(isNil "ace_medical_vitals_fnc_addSpO2DutyFactor") then { + private _breathingEffectiveness = linearConversion [0.2, 1, _levelBreathing, 1, 0.6, true]; + [QUOTE(ADDON), _breathingEffectiveness] call ace_medical_vitals_fnc_addSpO2DutyFactor; +}; + +// Event +private _smoked = _unit getVariable [QGVAR(smoked), false]; +if (_isInSmoke != _smoked) then { + _unit setVariable [QGVAR(smoked), _isInSmoke, true]; + [QGVAR(smoked), _isInSmoke] call CBA_fnc_localEvent; +}; diff --git a/addons/smoke/initSettings.inc.sqf b/addons/smoke/initSettings.inc.sqf new file mode 100644 index 00000000000..5ca5a3be275 --- /dev/null +++ b/addons/smoke/initSettings.inc.sqf @@ -0,0 +1,47 @@ +private _category = format ["ACE %1", localize LSTRING(DisplayName)]; + +[ + QGVAR(enabled), "CHECKBOX", + [LSTRING(enabled_DisplayName), LSTRING(enabled_Description)], + _category, + true, + 1, + { + [QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged); + if (!hasInterface) exitWith {}; + GVAR(ppHandleDynamicBlur) ppEffectEnable _this; + GVAR(ppHandleColorCorrections) ppEffectEnable _this; + if (_this) then { + if (GVAR(pfh) == -1) then { + GVAR(pfh) = [{ + [ace_player] call FUNC(pfh); + }, PFH_INTERVAL] call CBA_fnc_addPerFrameHandler; + }; + } else { + if (GVAR(pfh) != -1) then { + [GVAR(pfh)] call CBA_fnc_removePerFrameHandler; + GVAR(pfh) = -1; + }; + }; + } +] call CBA_fnc_addSetting; + +[ + QGVAR(effectFactor), "SLIDER", + [LSTRING(effectFactor_DisplayName), LSTRING(effectFactor_Description)], + _category, + [0, 1, 0.5, 0, true], + 1, + {[QGVAR(effectFactor), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(recoveryFactor), "SLIDER", + [LSTRING(recoveryFactor_DisplayName), LSTRING(recoveryFactor_Description)], + _category, + [0, 1, 0.5, 0, true], + 1, + {[QGVAR(recoveryFactor), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; diff --git a/addons/smoke/script_component.hpp b/addons/smoke/script_component.hpp new file mode 100644 index 00000000000..1e984dacf00 --- /dev/null +++ b/addons/smoke/script_component.hpp @@ -0,0 +1,19 @@ +#define COMPONENT smoke +#define COMPONENT_BEAUTIFIED Smoke +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_SMOKE + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_SMOKE + #define DEBUG_SETTINGS DEBUG_SETTINGS_SMOKE +#endif + +#include "\z\ace\addons\main\script_macros.hpp" + +#define PFH_INTERVAL 0.2 diff --git a/addons/smoke/stringtable.xml b/addons/smoke/stringtable.xml new file mode 100644 index 00000000000..e0706fbbc53 --- /dev/null +++ b/addons/smoke/stringtable.xml @@ -0,0 +1,149 @@ + + + + + Smoke Effects + Kouřové efekty + Effets de fumée + Efectos de humo + Effetti del fumo + Efekty dymu + Efeitos de Fumaça + Эффекты дыма + Rauch Effekte + 연기 효과 + 煙エフェクト + 烟雾效果 + 烟雾效果 + Ефекти диму + + + Adjusts the rate of smoke effect. Lower values increase the duration that can be spent in smoke. + Upravuje rychlost kouřového efektu. Nižší hodnoty prodlužují dobu, kterou lze strávit v kouři. + Modifie la vitesse de l'effet de fumée. Des valeurs plus basses augmentent la durée pendant laquelle on peut rester dans la fumée. + Ajusta la velocidad del efecto de humo. Los valores más bajos aumentan la duración que se puede pasar en el humo. + Regola la velocità dell'effetto fumo. Valori più bassi aumentano la durata che si può trascorrere nel fumo. + Dostosowuje szybkość efektu dymu. Niższe wartości zwiększają czas, jaki można spędzić w dymie. + Ajusta a taxa do efeito de fumaça. Valores mais baixos aumentam a duração que pode ser passada na fumaça. + Регулирует скорость эффекта дыма. Более низкие значения увеличивают продолжительность пребывания в дыму. + Passt die Geschwindigkeit des Raucheffekts an. Niedrigere Werte erhöhen die Dauer, die man im Rauch verbringen kann. + 연기 효과의 속도를 조정합니다. 낮은 값은 연기 속에서 보낼 수 있는 시간을 늘립니다. + 煙エフェクトの速度を調整します。値が低いほど、煙の中で過ごせる時間が長くなります。 + 调整烟雾效果的速率。较低的值会增加在烟雾中停留的时间。 + 调整烟雾效果的速率。较低的值会增加在烟雾中停留的时间。 + Регулює швидкість ефекту диму. Нижчі значення збільшують тривалість перебування в диму. + + + Effect Factor + Faktor efektu + Facteur d'effet + Factor de efecto + Fattore di effetto + Czynnik efektu + Fator de Efeito + Коэффициент эффекта + Effekt Faktor + 효과 계수 + エフェクトファクター + 效果系数 + 效果系数 + Фактор ефекту + + + Enable / Disable Smoke Effects + Povolit / Zakázat kouřové efekty + Activer / Désactiver les effets de fumée + Activar / Desactivar los efectos de humo + Abilita / Disabilita gli effetti del fumo + Włącz / Wyłącz efekty dymu + Ativar / Desativar Efeitos de Fumaça + Включить / Выключить эффекты дыма + Rauch Effekte Ein- / Ausschalten + 연기 효과 활성화 / 비활성화 + 煙エフェクトの有効化 / 無効化 + 启用 / 禁用 烟雾效果 + 启用 / 禁用 烟雾效果 + Увімкнути / Вимкнути ефекти диму + + + Enabled + Povoleno + Activé + Activada + Abilitata + Włączone + Ativado + Включена + Aktiv + 활성화 + 有効化 + 啟用 + 启用 + Увімкнено + + + Adjusts the rate of recovery from smoke effects. Higher values increase the rate of recovery after leaving smoke. + Upravuje rychlost zotavení z kouřových efektů. Vyšší hodnoty zvyšují rychlost zotavení po opuštění kouře. + Modifie la vitesse de récupération des effets de fumée. Des valeurs plus élevées augmentent la vitesse de récupération après avoir quitté la fumée. + Ajusta la velocidad de recuperación de los efectos del humo. Los valores más altos aumentan la velocidad de recuperación después de salir del humo. + Regola la velocità di recupero dagli effetti del fumo. Valori più alti aumentano la velocità di recupero dopo aver lasciato il fumo. + Dostosowuje szybkość regeneracji po efektach dymu. Wyższe wartości zwiększają szybkość regeneracji po opuszczeniu dymu. + Ajusta a taxa de recuperação dos efeitos da fumaça. Valores mais altos aumentam a taxa de recuperação após sair da fumaça. + Регулирует скорость восстановления от эффектов дыма. Более высокие значения увеличивают скорость восстановления после выхода из дыма. + Passt die Erholungsgeschwindigkeit von Raucheffekten an. Höhere Werte erhöhen die Erholungsrate nach dem Verlassen des Rauchs. + 연기 효과에서 회복 속도를 조정합니다. 높은 값은 연기를 떠난 후 회복 속도를 증가시킵니다. + 煙エフェクトからの回復速度を調整します。値が高いほど、煙から離れた後の回復速度が速くなります。 + 调整从烟雾效果中恢复的速率。较高的值会增加离开烟雾后的恢复速率。 + 调整从烟雾效果中恢复的速率。较高的值会增加离开烟雾后的恢复速率。 + Регулює швидкість відновлення від ефектів диму. Вищі значення збільшують швидкість відновлення після виходу з диму. + + + Recovery Factor + Faktor zotavení + Facteur de récupération + Factor de recuperación + Fattore di recupero + Czynnik regeneracji + Fator de Recuperação + Коэффициент восстановления + Erholungsfaktor + 회복 계수 + 回復ファクター + 恢复系数 + 恢复系数 + Фактор відновлення + + + Breathing Protection + Ochrana dýchání + Protection respiratoire + Protección respiratoria + Protezione respiratoria + Ochrona oddychania + Proteção Respiratória + Защита дыхания + Atemschutz + 호흡 보호 + 呼吸保護 + 呼吸保护 + 呼吸保护 + Захист дихання + + + Eye Protection + Ochrana očí + Protection des yeux + Protección ocular + Protezione degli occhi + Ochrona oczu + Proteção Ocular + Защита глаз + Augenschutz + 눈 보호 + 目の保護 + 眼睛保护 + 眼睛保护 + Захист очей + + +