diff --git a/addons/cargo/functions/fnc_loadItem.sqf b/addons/cargo/functions/fnc_loadItem.sqf index 2930075d2a..8589afdc3e 100644 --- a/addons/cargo/functions/fnc_loadItem.sqf +++ b/addons/cargo/functions/fnc_loadItem.sqf @@ -101,6 +101,17 @@ if (_item isEqualType objNull) then { // Some objects below water will take damage over time, eventually becoming "water logged" and unfixable (because of negative z attach) [_item, "blockDamage", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); + + // Prevent UAVs from firing + private _UAVCrew = _item call EFUNC(common,getVehicleUAVCrew); + + if (_UAVCrew isNotEqualTo []) then { + { + [_x, true] call EFUNC(common,disableAiUAV); + } forEach _UAVCrew; + + _item setVariable [QGVAR(isUAV), _UAVCrew, true]; + }; }; }; diff --git a/addons/common/XEH_PREP.hpp b/addons/common/XEH_PREP.hpp index 3a5838a230..5b85d63dda 100644 --- a/addons/common/XEH_PREP.hpp +++ b/addons/common/XEH_PREP.hpp @@ -43,6 +43,7 @@ PREP(deviceKeyFindValidIndex); PREP(deviceKeyRegisterNew); PREP(deprecateComponent); PREP(disableAI); +PREP(disableAiUAV); PREP(disableUserInput); PREP(displayIcon); PREP(displayText); diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index b569a4608e..8b7568f75e 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -133,6 +133,30 @@ _object lockInventory (_set > 0); }] call CBA_fnc_addEventHandler; +[QGVAR(disableAiUAV), { + params ["_unit", "_disable"]; + + if (_disable) then { + private _features = ["AUTOTARGET", "TARGET", "WEAPONAIM"/*, "FIREWEAPON"*/, "RADIOPROTOCOL"]; // TODO: Uncomment in 2.18 + + // Save current status + _unit setVariable [QGVAR(featuresAiUAV), _features apply {[_x, _unit checkAIFeature _x]}]; + + { + _unit enableAIFeature [_x, false]; + } forEach _features; + } else { + // Restore previous status + private _features = _unit getVariable [QGVAR(featuresAiUAV), []]; + + { + _unit enableAIFeature [_x select 0, _x select 1]; + } forEach _features; + + _unit setVariable [QGVAR(featuresAiUAV), nil]; + }; +}] call CBA_fnc_addEventHandler; + //Add a fix for BIS's zeus remoteControl module not reseting variables on DC when RC a unit //This variable is used for isPlayer checks if (isServer) then { diff --git a/addons/common/functions/fnc_disableAiUAV.sqf b/addons/common/functions/fnc_disableAiUAV.sqf new file mode 100644 index 0000000000..195e3ed2dc --- /dev/null +++ b/addons/common/functions/fnc_disableAiUAV.sqf @@ -0,0 +1,45 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Disables/Enables UAV AI crew members, can be run on any machine and is applied globally. + * + * Arguments: + * 0: Unit + * 1: Disable AI + * + * Return Value: + * None + * + * Example: + * [cursorObject, true] call ace_common_fnc_disableAiUAV + * + * Public: No + */ + +params [["_unit", objNull, [objNull]], ["_disable", true, [false]]]; + +// Allow disabling of Zeus remote controlled units +if (!alive _unit || {isPlayer _unit} || {!unitIsUAV _unit}) exitWith {}; + +if (_disable) then { + // Ignore if already disabled + if (!isNil "_jipID") exitWith {}; + + // Disable shooting and targeting on every machine + // Give predefined JIP ID, in case of simultaneous executions on different machines + private _jipID = [QGVAR(disableAiUAV), [_unit, _disable], QGVAR(disableAiUAV_) + hashValue _unit] call CBA_fnc_globalEventJIP; + [_jipID, _unit] call CBA_fnc_removeGlobalEventJIP; + + _unit setVariable [QGVAR(disableAiUavJipID), _jipID, true]; +} else { + // Restore shooting and targeting to each client's individual state prior to disabling + private _jipID = _unit getVariable QGVAR(disableAiUavJipID); + + if (isNil "_jipID") exitWith {}; + + _jipID call CBA_fnc_removeGlobalEventJIP; + + _unit setVariable [QGVAR(disableAiUavJipID), nil, true]; + + [QGVAR(disableAiUAV), [_unit, _disable]] call CBA_fnc_globalEvent; +}; diff --git a/addons/common/functions/fnc_getWeaponModes.sqf b/addons/common/functions/fnc_getWeaponModes.sqf index c1ca241cab..42a29681f2 100644 --- a/addons/common/functions/fnc_getWeaponModes.sqf +++ b/addons/common/functions/fnc_getWeaponModes.sqf @@ -1,34 +1,45 @@ #include "..\script_component.hpp" /* - * Author: commy2 + * Author: commy2, johnb43 * Get the available firing modes of a weapon. Will ignore the AI helper modes. * * Arguments: * 0: Weapon + * 1: Muzzle (default: weapon) * * Return Value: * Firing Modes * * Example: - * ["gun"] call ace_common_fnc_getWeaponModes + * "arifle_AK12_F" call ace_common_fnc_getWeaponModes * * Public: Yes */ -params [["_weapon", "", [""]]]; +params [["_weapon", "", [""]], ["_muzzle", nil, [""]]]; private _config = configFile >> "CfgWeapons" >> _weapon; +if (!isNil "_muzzle") then { + _config = _config >> _muzzle +}; + +if (!isClass _config) exitWith { + [] // return +}; + private _modes = []; { if (getNumber (_config >> _x >> "showToPlayer") == 1) then { - _modes pushBack _x; - }; - - if (_x == "this") then { - _modes pushBack _weapon; + if (_x == "this") then { + _modes pushBack (configName _config); + } else { + if (isClass (_config >> _x)) then { + _modes pushBack (configName (_config >> _x)); + }; + }; }; } forEach getArray (_config >> "modes"); -_modes +_modes // return diff --git a/addons/compat_rhs_afrf3/CfgWeapons.hpp b/addons/compat_rhs_afrf3/CfgWeapons.hpp index a6def44c40..a25d1f7cd0 100644 --- a/addons/compat_rhs_afrf3/CfgWeapons.hpp +++ b/addons/compat_rhs_afrf3/CfgWeapons.hpp @@ -108,19 +108,7 @@ class CfgWeapons { EGVAR(overpressure,offset) = 1.65; }; - class H_HelmetB; - class rhs_tsh4: H_HelmetB { - HEARING_PROTECTION_VICCREW; - }; - - class rhs_6b47_bare; - class rhs_6b48: rhs_6b47_bare { - HEARING_PROTECTION_VICCREW; - }; - - class rhs_zsh7a: H_HelmetB { - HEARING_PROTECTION_VICCREW; - }; + class rhs_zsh7a; class rhs_zsh7a_alt: rhs_zsh7a { ACE_Protection = 1; }; @@ -133,22 +121,6 @@ class CfgWeapons { ACE_Protection = 1; }; - class rhs_gssh18: H_HelmetB { - HEARING_PROTECTION_EARMUFF; - }; - - class rhs_6b47; - class rhs_6b47_6m2: rhs_6b47 { - HEARING_PROTECTION_PELTOR; - }; - class rhs_6b47_6m2_1: rhs_6b47 { - HEARING_PROTECTION_PELTOR; - }; - - class rhs_6m2: H_HelmetB { - HEARING_PROTECTION_PELTOR; - }; - class rhs_weap_d81; class rhs_weap_2a70: rhs_weap_d81 { // "Low pressure" 100mm cannon EGVAR(overpressure,range) = 15; diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_hearing/CfgWeapons.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_hearing/CfgWeapons.hpp new file mode 100644 index 0000000000..04edf4d754 --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_hearing/CfgWeapons.hpp @@ -0,0 +1,28 @@ +class CfgWeapons { + class H_HelmetB; + class rhs_tsh4: H_HelmetB { + HEARING_PROTECTION_VICCREW; + }; + class rhs_zsh7a: H_HelmetB { + HEARING_PROTECTION_VICCREW; + }; + class rhs_gssh18: H_HelmetB { + HEARING_PROTECTION_EARMUFF; + }; + class rhs_6m2: H_HelmetB { + HEARING_PROTECTION_PELTOR; + }; + + class rhs_6b47; + class rhs_6b47_6m2: rhs_6b47 { + HEARING_PROTECTION_PELTOR; + }; + class rhs_6b47_6m2_1: rhs_6b47 { + HEARING_PROTECTION_PELTOR; + }; + + class rhs_6b47_bare; + class rhs_6b48: rhs_6b47_bare { + HEARING_PROTECTION_VICCREW; + }; +}; diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_hearing/config.cpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_hearing/config.cpp new file mode 100644 index 0000000000..4a8056bf0c --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_hearing/config.cpp @@ -0,0 +1,19 @@ +#include "script_component.hpp" +#include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp" + +class CfgPatches { + class SUBADDON { + addonRootClass = QUOTE(COMPONENT); + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhs_main_loadorder", + "ace_hearing" + }; + skipWhenMissingDependencies = 1; + VERSION_CONFIG; + }; +}; + +#include "CfgWeapons.hpp" diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_hearing/script_component.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_hearing/script_component.hpp new file mode 100644 index 0000000000..8edb825af3 --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_hearing/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT hearing +#define SUBCOMPONENT_BEAUTIFIED Hearing +#include "..\script_component.hpp" diff --git a/addons/compat_rhs_afrf3/config.cpp b/addons/compat_rhs_afrf3/config.cpp index 44fcd30fcb..8bf5668485 100644 --- a/addons/compat_rhs_afrf3/config.cpp +++ b/addons/compat_rhs_afrf3/config.cpp @@ -1,5 +1,4 @@ #include "script_component.hpp" -#include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp" class CfgPatches { class ADDON { @@ -7,7 +6,7 @@ class CfgPatches { units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"rhs_main_loadorder"}; + requiredAddons[] = {"ace_common", "rhs_main_loadorder"}; author = ECSTRING(common,ACETeam); authors[] = {"Ruthberg", "GitHawk", "BaerMitUmlaut", "commy2", "Skengman2"}; url = ECSTRING(main,URL); diff --git a/addons/compat_rhs_gref3/config.cpp b/addons/compat_rhs_gref3/config.cpp index f2e7aeacde..84717435be 100644 --- a/addons/compat_rhs_gref3/config.cpp +++ b/addons/compat_rhs_gref3/config.cpp @@ -6,7 +6,7 @@ class CfgPatches { units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"rhsgref_main_loadorder"}; + requiredAddons[] = {"ace_common", "rhsgref_main_loadorder"}; skipWhenMissingDependencies = 1; author = ECSTRING(common,ACETeam); authors[] = {"PabstMirror", "Ruthberg", "Anton"}; diff --git a/addons/compat_rhs_saf3/config.cpp b/addons/compat_rhs_saf3/config.cpp index 75ee4f5530..71340640ce 100644 --- a/addons/compat_rhs_saf3/config.cpp +++ b/addons/compat_rhs_saf3/config.cpp @@ -6,7 +6,7 @@ class CfgPatches { units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"rhssaf_main_loadorder"}; + requiredAddons[] = {"ace_common", "rhssaf_main_loadorder"}; skipWhenMissingDependencies = 1; author = ECSTRING(common,ACETeam); authors[] = {}; diff --git a/addons/compat_rhs_usf3/CfgWeapons.hpp b/addons/compat_rhs_usf3/CfgWeapons.hpp index 46ac7e56ba..50b09c760f 100644 --- a/addons/compat_rhs_usf3/CfgWeapons.hpp +++ b/addons/compat_rhs_usf3/CfgWeapons.hpp @@ -206,170 +206,7 @@ class CfgWeapons { EGVAR(overpressure,offset) = 0.9; }; - // Fast Helmets - class rhsusf_opscore_01; - class rhsusf_opscore_ut_pelt_nsw: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_aor1_pelt: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_aor1_pelt_nsw: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_bk_pelt: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_fg_pelt: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_fg_pelt_nsw: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_fg_pelt_cam: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_paint_pelt: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_paint_pelt_nsw: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_paint_pelt_nsw_cam: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_aor2_pelt: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_aor2_pelt_nsw: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_ut_pelt: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_ut_pelt_cam: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_ut_pelt_nsw_cam: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_mc_pelt: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_mc_pelt_nsw: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_cover; - class rhsusf_opscore_mc_cover_pelt_nsw: rhsusf_opscore_cover { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_mc_cover_pelt: rhsusf_opscore_cover { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_mc_cover_pelt_cam: rhsusf_opscore_cover { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_rg_cover_pelt: rhsusf_opscore_cover { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_coy_cover_pelt: rhsusf_opscore_cover { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_mar_01; - class rhsusf_opscore_mar_ut_pelt: rhsusf_opscore_mar_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_mar_fg_pelt: rhsusf_opscore_mar_01 { - HEARING_PROTECTION_PELTOR; - }; - - // ACH Helmets - class rhsusf_ach_helmet_ocp; - class rhsusf_ach_bare_des_headset: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_bare_des_headset_ess: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_bare_headset: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_bare_headset_ess: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_bare_semi_headset: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_bare_semi_headset_ess: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_bare_tan_headset: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_bare_tan_headset_ess: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_bare_wood_headset: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_bare_wood_headset_ess: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_helmet_headset_ocp: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_helmet_headset_ess_ocp: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - - // ACVC Helmets - class rhsusf_cvc_helmet: rhsusf_opscore_01 { - HEARING_PROTECTION_VICCREW; - }; - - // MICH Helmets - class rhsusf_mich_bare; - class rhsusf_mich_bare_alt: rhsusf_mich_bare { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_mich_bare_norotos; - class rhsusf_mich_bare_norotos_alt: rhsusf_mich_bare_norotos { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_mich_bare_norotos_arc; - class rhsusf_mich_bare_norotos_arc_alt: rhsusf_mich_bare_norotos_arc { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_mich_bare_semi; - class rhsusf_mich_bare_alt_semi: rhsusf_mich_bare_semi { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_mich_bare_norotos_semi; - class rhsusf_mich_bare_norotos_alt_semi: rhsusf_mich_bare_norotos_semi { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_mich_bare_norotos_arc_semi: rhsusf_mich_bare_norotos_alt_semi { - HEARING_PROTECTION_OPEN; - }; - class rhsusf_mich_bare_norotos_arc_alt_semi: rhsusf_mich_bare_norotos_arc_semi { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_mich_bare_tan; - class rhsusf_mich_bare_alt_tan: rhsusf_mich_bare_tan { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_mich_bare_norotos_tan; - class rhsusf_mich_bare_norotos_alt_tan: rhsusf_mich_bare_norotos_tan { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_mich_bare_norotos_arc_tan; - class rhsusf_mich_bare_norotos_arc_alt_tan: rhsusf_mich_bare_norotos_arc_tan { - HEARING_PROTECTION_PELTOR; - }; - - class rhsusf_hgu56p: rhsusf_opscore_01 { - HEARING_PROTECTION_VICCREW; - }; + class rhsusf_hgu56p; class rhsusf_hgu56p_visor: rhsusf_hgu56p { ACE_Protection = 1; }; @@ -420,13 +257,9 @@ class CfgWeapons { class rhsusf_hgu56p_mask_black_skull: rhsusf_hgu56p_visor_mask_black_skull { ACE_Protection = 0; }; - class rhsusf_ihadss: rhsusf_opscore_01 { - HEARING_PROTECTION_VICCREW; - }; class H_HelmetB; class RHS_jetpilot_usaf: H_HelmetB { ACE_Protection = 1; - HEARING_PROTECTION_VICCREW; }; }; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_hearing/CfgWeapons.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_hearing/CfgWeapons.hpp new file mode 100644 index 0000000000..f0571e876f --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_hearing/CfgWeapons.hpp @@ -0,0 +1,174 @@ +class CfgWeapons { + // Fast Helmets + class rhsusf_opscore_01; + class rhsusf_opscore_ut_pelt_nsw: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_aor1_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_aor1_pelt_nsw: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_bk_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_fg_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_fg_pelt_nsw: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_fg_pelt_cam: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_paint_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_paint_pelt_nsw: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_paint_pelt_nsw_cam: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_aor2_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_aor2_pelt_nsw: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_ut_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_ut_pelt_cam: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_ut_pelt_nsw_cam: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_mc_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_mc_pelt_nsw: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_cover; + class rhsusf_opscore_mc_cover_pelt_nsw: rhsusf_opscore_cover { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_mc_cover_pelt: rhsusf_opscore_cover { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_mc_cover_pelt_cam: rhsusf_opscore_cover { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_rg_cover_pelt: rhsusf_opscore_cover { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_coy_cover_pelt: rhsusf_opscore_cover { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_mar_01; + class rhsusf_opscore_mar_ut_pelt: rhsusf_opscore_mar_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_mar_fg_pelt: rhsusf_opscore_mar_01 { + HEARING_PROTECTION_PELTOR; + }; + + // ACH Helmets + class rhsusf_ach_helmet_ocp; + class rhsusf_ach_bare_des_headset: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_des_headset_ess: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_headset: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_headset_ess: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_semi_headset: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_semi_headset_ess: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_tan_headset: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_tan_headset_ess: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_wood_headset: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_wood_headset_ess: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_helmet_headset_ocp: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_helmet_headset_ess_ocp: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + + // ACVC Helmets + class rhsusf_cvc_helmet: rhsusf_opscore_01 { + HEARING_PROTECTION_VICCREW; + }; + + // MICH Helmets + class rhsusf_mich_bare; + class rhsusf_mich_bare_alt: rhsusf_mich_bare { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_norotos; + class rhsusf_mich_bare_norotos_alt: rhsusf_mich_bare_norotos { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_norotos_arc; + class rhsusf_mich_bare_norotos_arc_alt: rhsusf_mich_bare_norotos_arc { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_semi; + class rhsusf_mich_bare_alt_semi: rhsusf_mich_bare_semi { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_norotos_semi; + class rhsusf_mich_bare_norotos_alt_semi: rhsusf_mich_bare_norotos_semi { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_norotos_arc_semi: rhsusf_mich_bare_norotos_alt_semi { + HEARING_PROTECTION_OPEN; + }; + class rhsusf_mich_bare_norotos_arc_alt_semi: rhsusf_mich_bare_norotos_arc_semi { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_tan; + class rhsusf_mich_bare_alt_tan: rhsusf_mich_bare_tan { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_norotos_tan; + class rhsusf_mich_bare_norotos_alt_tan: rhsusf_mich_bare_norotos_tan { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_norotos_arc_tan; + class rhsusf_mich_bare_norotos_arc_alt_tan: rhsusf_mich_bare_norotos_arc_tan { + HEARING_PROTECTION_PELTOR; + }; + + class rhsusf_hgu56p: rhsusf_opscore_01 { + HEARING_PROTECTION_VICCREW; + }; + class rhsusf_ihadss: rhsusf_opscore_01 { + HEARING_PROTECTION_VICCREW; + }; + + class H_HelmetB; + class RHS_jetpilot_usaf: H_HelmetB { + HEARING_PROTECTION_VICCREW; + }; +}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_hearing/config.cpp b/addons/compat_rhs_usf3/compat_rhs_usf3_hearing/config.cpp new file mode 100644 index 0000000000..e52454b184 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_hearing/config.cpp @@ -0,0 +1,19 @@ +#include "script_component.hpp" +#include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp" + +class CfgPatches { + class SUBADDON { + addonRootClass = QUOTE(COMPONENT); + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhsusf_main_loadorder", + "ace_hearing" + }; + skipWhenMissingDependencies = 1; + VERSION_CONFIG; + }; +}; + +#include "CfgWeapons.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_hearing/script_component.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_hearing/script_component.hpp new file mode 100644 index 0000000000..8edb825af3 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_hearing/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT hearing +#define SUBCOMPONENT_BEAUTIFIED Hearing +#include "..\script_component.hpp" diff --git a/addons/compat_rhs_usf3/config.cpp b/addons/compat_rhs_usf3/config.cpp index 73b4723b2c..b28a08b22e 100644 --- a/addons/compat_rhs_usf3/config.cpp +++ b/addons/compat_rhs_usf3/config.cpp @@ -1,5 +1,4 @@ #include "script_component.hpp" -#include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp" class CfgPatches { class ADDON { @@ -7,7 +6,7 @@ class CfgPatches { units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"rhsusf_main_loadorder"}; + requiredAddons[] = {"ace_common", "rhsusf_main_loadorder"}; skipWhenMissingDependencies = 1; author = ECSTRING(common,ACETeam); authors[] = {"Ruthberg", "GitHawk", "BaerMitUmlaut", "Fyuran"}; diff --git a/addons/dogtags/CfgEventHandlers.hpp b/addons/dogtags/CfgEventHandlers.hpp index 2a3f71f852..f6503c2479 100644 --- a/addons/dogtags/CfgEventHandlers.hpp +++ b/addons/dogtags/CfgEventHandlers.hpp @@ -3,11 +3,13 @@ class Extended_PreStart_EventHandlers { init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; + class Extended_PreInit_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; + class Extended_PostInit_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); diff --git a/addons/dogtags/CfgVehicles.hpp b/addons/dogtags/CfgVehicles.hpp index cc56410699..56be52b53e 100644 --- a/addons/dogtags/CfgVehicles.hpp +++ b/addons/dogtags/CfgVehicles.hpp @@ -4,7 +4,7 @@ class CfgVehicles { class ACE_Actions { class ACE_Dogtag { displayName = CSTRING(itemName); - condition = QUOTE([ARR_2(_player,_target)] call FUNC(canTakeDogtag)); + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canCheckDogtag)); statement = ""; exceptions[] = {"isNotSwimming", "isNotInside"}; showDisabled = 0; diff --git a/addons/dogtags/CfgWeapons.hpp b/addons/dogtags/CfgWeapons.hpp index 0f795d8d08..ac73ee68f7 100644 --- a/addons/dogtags/CfgWeapons.hpp +++ b/addons/dogtags/CfgWeapons.hpp @@ -16,8 +16,8 @@ class CfgWeapons { author = ECSTRING(common,ACETeam); scope = 0; displayName = CSTRING(itemName); - model = QUOTE(PATHTOF(data\ace_dogtag.p3d)); - picture = QUOTE(PATHTOF(data\dogtagSingle.paa)); + model = QPATHTOF(data\ace_dogtag.p3d); + picture = QPATHTOF(data\dogtagSingle.paa); class ItemInfo: CBA_MiscItem_ItemInfo { mass = 0; //too small to for 1 ? }; diff --git a/addons/dogtags/XEH_PREP.hpp b/addons/dogtags/XEH_PREP.hpp index a34a04a982..9ff33a26a2 100644 --- a/addons/dogtags/XEH_PREP.hpp +++ b/addons/dogtags/XEH_PREP.hpp @@ -1,13 +1,11 @@ - PREP(addDogtagActions); -PREP(addDogtagItem); PREP(bloodType); PREP(canCheckDogtag); PREP(canTakeDogtag); PREP(checkDogtag); +PREP(disableFactionDogtags); PREP(getDogtagData); PREP(getDogtagItem); PREP(showDogtag); PREP(ssn); PREP(takeDogtag); -PREP(disableFactionDogtags); diff --git a/addons/dogtags/XEH_postInit.sqf b/addons/dogtags/XEH_postInit.sqf index 6e676671ae..3ced843f47 100644 --- a/addons/dogtags/XEH_postInit.sqf +++ b/addons/dogtags/XEH_postInit.sqf @@ -1,9 +1,5 @@ #include "script_component.hpp" -[QGVAR(showDogtag), LINKFUNC(showDogtag)] call CBA_fnc_addEventHandler; -[QGVAR(getDogtagItem), LINKFUNC(getDogtagItem)] call CBA_fnc_addEventHandler; -[QGVAR(addDogtagItem), LINKFUNC(addDogtagItem)] call CBA_fnc_addEventHandler; - if (hasInterface || isServer) then { [QGVAR(broadcastDogtagInfo), { GVAR(dogtagsData) set _this; @@ -18,69 +14,29 @@ if (hasInterface || isServer) then { [QGVAR(broadcastDogtagInfo), [_x, _y], _clientOwner] call CBA_fnc_ownerEvent; } forEach GVAR(dogtagsData); }] call CBA_fnc_addEventHandler; + + [QGVAR(getDogtagItem), LINKFUNC(getDogtagItem)] call CBA_fnc_addEventHandler; } else { // To be here, hasInterface must be true [QGVAR(requestSyncDogtagDataJIP), clientOwner] call CBA_fnc_serverEvent; }; }; -// Add actions and event handlers only if ace_medical is enabled -// - Adding actions via config would create a dependency -["CBA_settingsInitialized", { - if !(GETEGVAR(medical,enabled,false)) exitWith {}; +if (hasInterface) then { + // If the arsenal is loaded, show the custom names for dog tags when in the arsenal + if (["ace_arsenal"] call EFUNC(common,isModLoaded)) then { + [QEGVAR(arsenal,rightPanelFilled), { + params ["_display", "_leftPanelIDC", "_rightPanelIDC"]; - if (hasInterface) then { - private _checkTagAction = [ - "ACE_CheckDogtag", - format ["%1: %2", localize LSTRING(itemName), localize LSTRING(checkDogtag)], - QPATHTOF(data\dogtag_icon_ca.paa), - {[_player,_target] call FUNC(checkDogtag)}, - {!isNil {_target getVariable QGVAR(dogtagData)}} - ] call EFUNC(interact_menu,createAction); + if !(_leftPanelIDC in [2010, 2012, 2014] && {_rightPanelIDC == 38}) exitWith {}; - ["ACE_bodyBagObject", 0, ["ACE_MainActions"], _checkTagAction, true] call EFUNC(interact_menu,addActionToClass); - - private _takeTagAction = [ - "ACE_TakeDogtag", - format ["%1: %2", localize LSTRING(itemName), localize LSTRING(takeDogtag)], - QPATHTOF(data\dogtag_icon_ca.paa), - {[_player,_target] call FUNC(takeDogtag)}, - {(!isNil {_target getVariable QGVAR(dogtagData)}) && {((_target getVariable [QGVAR(dogtagTaken), objNull]) != _target)}} - ] call EFUNC(interact_menu,createAction); - - ["ACE_bodyBagObject", 0, ["ACE_MainActions"], _takeTagAction, true] call EFUNC(interact_menu,addActionToClass); - }; - - if (isServer) then { - ["ace_placedInBodyBag", { - params ["_target", "_bodyBag", "_isGrave"]; - if (_isGrave) exitWith {}; - TRACE_2("ace_placedInBodyBag eh",_target,_bodyBag); - - private _dogTagData = [_target] call FUNC(getDogtagData); - _bodyBag setVariable [QGVAR(dogtagData), _dogTagData, true]; - - if ((_target getVariable [QGVAR(dogtagTaken), objNull]) == _target) then { - _bodyBag setVariable [QGVAR(dogtagTaken), _bodyBag, true]; - }; - }] call CBA_fnc_addEventHandler; - }; -}] call CBA_fnc_addEventHandler; - -// If the arsenal is loaded, show the custom names for dog tags when in the arsenal -if (["ace_arsenal"] call EFUNC(common,isModLoaded)) then { - [QEGVAR(arsenal,rightPanelFilled), { - params ["_display", "_leftPanelIDC", "_rightPanelIDC"]; - - if (_leftPanelIDC in [2010, 2012, 2014] && {_rightPanelIDC == 38}) then { - LOG("passed"); private _rightPanel = _display displayCtrl 15; private _cfgWeapons = configFile >> "CfgWeapons"; - private _item = ""; - private _dogtagData = []; + + TRACE_1("passed",_rightPanel); for "_i" from 0 to (lnbSize _rightPanel select 0) - 1 do { - _item = _rightPanel lnbData [_i, 0]; + private _item = _rightPanel lnbData [_i, 0]; if (_item isKindOf ["ACE_dogtag", _cfgWeapons]) then { private _name = (GVAR(dogtagsData) getOrDefault [_item, []]) param [0, ""]; @@ -93,27 +49,71 @@ if (["ace_arsenal"] call EFUNC(common,isModLoaded)) then { _rightPanel lnbSetText [[_i, 1], [LLSTRING(itemName), ": ", _name] joinString ""]; }; }; - }; - }] call CBA_fnc_addEventHandler; + }] call CBA_fnc_addEventHandler; + }; + + // Add context menu option + [ + "ACE_dogtag", + ["GROUND", "CARGO", "CONTAINER"], + LLSTRING(checkItem), + nil, + QPATHTOF(data\dogtag_icon_ca.paa), + [ + {true}, + {true} + ], + { + [GVAR(dogtagsData) getOrDefault [_this select 2, []]] call FUNC(showDogtag); + + false + } + ] call CBA_fnc_addItemContextMenuOption; }; -// Add context menu option -[ - "ACE_dogtag", - ["GROUND", "CARGO", "CONTAINER"], - LLSTRING(checkItem), - nil, - QPATHTOF(data\dogtag_icon_ca.paa), - [ - {true}, - {true} - ], - { - [GVAR(dogtagsData) getOrDefault [_this select 2, []]] call FUNC(showDogtag); +// Add actions and event handlers only if ace_medical is enabled +// - Adding actions via config would create a dependency +["CBA_settingsInitialized", { + if !(GETEGVAR(medical,enabled,false)) exitWith {}; - false - } -] call CBA_fnc_addItemContextMenuOption; + if (hasInterface) then { + private _checkTagAction = [ + "ACE_CheckDogtag", + format ["%1: %2", LLSTRING(itemName), LLSTRING(checkDogtag)], + QPATHTOF(data\dogtag_icon_ca.paa), + {[_player, _target] call FUNC(checkDogtag)}, + {!isNil {_target getVariable QGVAR(dogtagData)}} + ] call EFUNC(interact_menu,createAction); -// Disable dogtags for civilians + ["ACE_bodyBagObject", 0, ["ACE_MainActions"], _checkTagAction, true] call EFUNC(interact_menu,addActionToClass); + + private _takeTagAction = [ + "ACE_TakeDogtag", + format ["%1: %2", LLSTRING(itemName), LLSTRING(takeDogtag)], + QPATHTOF(data\dogtag_icon_ca.paa), + {[_player, _target] call FUNC(takeDogtag)}, + {(!isNil {_target getVariable QGVAR(dogtagData)}) && {((_target getVariable [QGVAR(dogtagTaken), objNull]) != _target)}} + ] call EFUNC(interact_menu,createAction); + + ["ACE_bodyBagObject", 0, ["ACE_MainActions"], _takeTagAction, true] call EFUNC(interact_menu,addActionToClass); + }; + + if (isServer) then { + ["ace_placedInBodyBag", { + params ["_target", "_bodyBag", "_isGrave"]; + + if (_isGrave) exitWith {}; + TRACE_2("ace_placedInBodyBag eh",_target,_bodyBag); + + private _dogtagData = _target call FUNC(getDogtagData); + _bodyBag setVariable [QGVAR(dogtagData), _dogtagData, true]; + + if ((_target getVariable [QGVAR(dogtagTaken), objNull]) == _target) then { + _bodyBag setVariable [QGVAR(dogtagTaken), _bodyBag, true]; + }; + }] call CBA_fnc_addEventHandler; + }; +}] call CBA_fnc_addEventHandler; + +// Disable dog tags for civilians "CIV_F" call FUNC(disableFactionDogtags); diff --git a/addons/dogtags/functions/fnc_addDogtagActions.sqf b/addons/dogtags/functions/fnc_addDogtagActions.sqf index b41cce1be8..9b2f3147b5 100644 --- a/addons/dogtags/functions/fnc_addDogtagActions.sqf +++ b/addons/dogtags/functions/fnc_addDogtagActions.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: SzwedzikPL, mharis001 - * Returns children actions for checking dogtags in player's inventory. + * Returns children actions for checking dog tags in the player's inventory. * * Arguments: * 0: Player @@ -10,7 +10,7 @@ * Actions * * Example: - * [_player] call ace_dogtags_fnc_addDogtagActions + * player call ace_dogtags_fnc_addDogtagActions * * Public: No */ @@ -23,14 +23,21 @@ private _fnc_getActions = { { private _config = _cfgWeapons >> _x; - if (getNumber (_config >> QGVAR(tagID)) > 0) then { - private _displayName = getText (_config >> "displayName"); - private _picture = getText (_config >> "picture"); - private _action = [_x, _displayName, _picture, { - [GVAR(dogtagsData) getOrDefault [_this select 2, []]] call FUNC(showDogtag); - }, {true}, {}, _x] call EFUNC(interact_menu,createAction); - _actions pushBack [_action, [], _player]; + if (getNumber (_config >> QGVAR(tagID)) > 0) then { + _actions pushBack [ + [ + _x, + getText (_config >> "displayName"), + getText (_config >> "picture"), + {[GVAR(dogtagsData) getOrDefault [_this select 2, []]] call FUNC(showDogtag)}, + {true}, + {}, + _x + ] call EFUNC(interact_menu,createAction), + [], + _player + ]; }; } forEach (_player call EFUNC(common,uniqueItems)); diff --git a/addons/dogtags/functions/fnc_addDogtagItem.sqf b/addons/dogtags/functions/fnc_addDogtagItem.sqf deleted file mode 100644 index 6979299db3..0000000000 --- a/addons/dogtags/functions/fnc_addDogtagItem.sqf +++ /dev/null @@ -1,38 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: SzwedzikPL - * Adds dogtag item to unit (triggered by server). - * - * Arguments: - * 0: Item class - * 1: Dogtag data - * - * Return Value: - * None - * - * Example: - * ["itemClass", ["name", "610-27-5955", "A POS"]] call ace_dogtags_fnc_addDogtagItem - * - * Public: No - */ - -params ["_item", "_dogtagData"]; - -if (_item == "") exitWith {}; - -// Verify that the unit has inventory space, otherwise drop the dogtag on the ground -[ace_player, _item, true] call CBA_fnc_addItem; - -_dogtagData params ["_name"]; - -// If data doesn't exist or body has no name, set name as "unknown" -if (_name == "") then { - _name = LELSTRING(common,unknown); -}; - -private _displayText = format [localize LSTRING(takeDogtagSuccess), _name]; - -// display message -[{ - [_this, 2.5] call EFUNC(common,displayTextStructured); -}, _displayText, DOGTAG_SHOW_DELAY] call CBA_fnc_waitAndExecute; diff --git a/addons/dogtags/functions/fnc_bloodType.sqf b/addons/dogtags/functions/fnc_bloodType.sqf index 5e03c586fa..53b6007370 100644 --- a/addons/dogtags/functions/fnc_bloodType.sqf +++ b/addons/dogtags/functions/fnc_bloodType.sqf @@ -1,16 +1,16 @@ #include "..\script_component.hpp" /* * Author: commy2 - * Reports a blood type depending on the units name. + * Reports a blood type depending on the unit's name. * * Arguments: - * 0: Name of a unit + * 0: Unit name * * Return Value: * A random blood type * * Example: - * _bloodType = ["name"] call ace_dogtags_fnc_bloodType + * "name" call ace_dogtags_fnc_bloodType * * Public: No */ diff --git a/addons/dogtags/functions/fnc_canCheckDogtag.sqf b/addons/dogtags/functions/fnc_canCheckDogtag.sqf index 98d437cbac..a5ed987fc0 100644 --- a/addons/dogtags/functions/fnc_canCheckDogtag.sqf +++ b/addons/dogtags/functions/fnc_canCheckDogtag.sqf @@ -1,26 +1,26 @@ #include "..\script_component.hpp" /* * Author: SzwedzikPL - * Checks if dogtag can be checked. + * Checks if the target's dog tag can be checked by the unit. * * Arguments: - * 0: Player + * 0: Player (not used) * 1: Target * * Return Value: - * True if dogtag can be checked + * If dog tag can be checked * * Example: - * _canCheck = [player, unit] call ace_dogtags_fnc_canCheckDogtag + * [player, cursorObject] call ace_dogtags_fnc_canCheckDogtag * * Public: No */ -params ["_player", "_target"]; +params ["", "_target"]; if (isNull _target) exitWith {false}; -// check if disabled for faction +// Check if disabled for faction if ((faction _target) in GVAR(disabledFactions)) exitWith {false}; !(_target call EFUNC(common,isAwake)) diff --git a/addons/dogtags/functions/fnc_canTakeDogtag.sqf b/addons/dogtags/functions/fnc_canTakeDogtag.sqf index 5f0a6d1afe..c56db0b893 100644 --- a/addons/dogtags/functions/fnc_canTakeDogtag.sqf +++ b/addons/dogtags/functions/fnc_canTakeDogtag.sqf @@ -1,17 +1,17 @@ #include "..\script_component.hpp" /* * Author: SzwedzikPL - * Checks if dogtag can be taken. + * Checks if the target's dog tag can be taken by the unit. * * Arguments: * 0: Player * 1: Target * * Return Value: - * True if dogtag can be taken + * If dog tag can be taken * * Example: - * _canTake = [player, unit] call ace_dogtags_fnc_canTakeDogtag + * [player, cursorObject] call ace_dogtags_fnc_canTakeDogtag * * Public: No */ @@ -20,7 +20,10 @@ params ["_player", "_target"]; if (isNull _target) exitWith {false}; -// check if disabled for faction +// Check if disabled for faction if ((faction _target) in GVAR(disabledFactions)) exitWith {false}; -!(_target call EFUNC(common,isAwake)) && {_player canAdd ["ACE_dogtag_1", 1/*, true*/]} // Todo: Uncomment in 2.18 +// CBA_fnc_canAddItem doesn't account for mass 0 items and unit not having any containers +!(_target call EFUNC(common,isAwake)) && {(uniform _player + vest _player + backpack _player) != ""} && {[_player, "ACE_dogtag_1"] call CBA_fnc_canAddItem} +// Todo: Use code below in 2.18 +// _player canAdd ["ACE_dogtag_1", 1, true] diff --git a/addons/dogtags/functions/fnc_checkDogtag.sqf b/addons/dogtags/functions/fnc_checkDogtag.sqf index dcceb8c2c0..4b2f2d533f 100644 --- a/addons/dogtags/functions/fnc_checkDogtag.sqf +++ b/addons/dogtags/functions/fnc_checkDogtag.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: SzwedzikPL - * Checks unit dogtag. + * Checks the unit's dog tag. * * Arguments: * 0: Player @@ -11,17 +11,17 @@ * None * * Example: - * [player, unit] call ace_dogtags_fnc_checkDogtag + * [player, cursorObject] call ace_dogtags_fnc_checkDogtag * * Public: No */ params ["_player", "_target"]; -// animation +// Animation _player call EFUNC(common,goKneeling); -// sound +// Sound private _position = _target modelToWorldWorld (_target selectionPosition "neck"); playSound3D [ @@ -34,10 +34,8 @@ playSound3D [ 50 ]; -// display dogtag +// Display dog tag private _doubleTags = (_target getVariable [QGVAR(dogtagTaken), objNull]) != _target; -private _dogTagData = [_target] call FUNC(getDogTagData); +private _dogtagData = _target call FUNC(getDogtagData); -[{ - [QGVAR(showDogtag), _this] call CBA_fnc_localEvent; -}, [_dogTagData, _doubleTags], DOGTAG_SHOW_DELAY] call CBA_fnc_waitAndExecute; +[LINKFUNC(showDogtag), [_dogtagData, _doubleTags], DOGTAG_SHOW_DELAY] call CBA_fnc_waitAndExecute; diff --git a/addons/dogtags/functions/fnc_disableFactionDogtags.sqf b/addons/dogtags/functions/fnc_disableFactionDogtags.sqf index c4642ef4b5..b1ac145d9a 100644 --- a/addons/dogtags/functions/fnc_disableFactionDogtags.sqf +++ b/addons/dogtags/functions/fnc_disableFactionDogtags.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: commy2 - * Disable this faction from using dogtags. + * Disables this faction from using dog tags. * * Arguments: * 0: Faction diff --git a/addons/dogtags/functions/fnc_getDogtagData.sqf b/addons/dogtags/functions/fnc_getDogtagData.sqf index 6a850543fc..4aaf930fa2 100644 --- a/addons/dogtags/functions/fnc_getDogtagData.sqf +++ b/addons/dogtags/functions/fnc_getDogtagData.sqf @@ -1,19 +1,19 @@ #include "..\script_component.hpp" /* * Author: esteldunedain - * Get unit dogtag data. + * Gets unit's dog tag data. * * Arguments: * 0: Target * * Return Value: - * Dogtag Data + * Dog tag Data * 0: Name * 1: SSN * 2: Blood Type * * Example: - * _dogtagData = [unit, player] call ace_dogtags_fnc_getDogtagData + * player call ace_dogtags_fnc_getDogtagData * * Public: No */ @@ -21,17 +21,20 @@ params ["_target"]; // Check if the data was already created -private _dogTagData = _target getVariable QGVAR(dogtagData); -if (!isNil "_dogTagData") exitWith {_dogTagData}; +private _dogtagData = _target getVariable QGVAR(dogtagData); + +if (!isNil "_dogtagData") exitWith {_dogtagData}; // Create dog tag data once for the unit: nickname, code (eg. 135-13-900) and blood type private _targetName = [_target, false, true] call EFUNC(common,getName); -private _dogTagData = [ +private _dogtagData = [ _targetName, _targetName call FUNC(ssn), _targetName call FUNC(bloodType) ]; + // Store it -_target setVariable [QGVAR(dogtagData), _dogTagData, true]; -_dogTagData +_target setVariable [QGVAR(dogtagData), _dogtagData, true]; + +_dogtagData diff --git a/addons/dogtags/functions/fnc_getDogtagItem.sqf b/addons/dogtags/functions/fnc_getDogtagItem.sqf index e5f05eb19b..4f8cc94cc7 100644 --- a/addons/dogtags/functions/fnc_getDogtagItem.sqf +++ b/addons/dogtags/functions/fnc_getDogtagItem.sqf @@ -1,7 +1,8 @@ #include "..\script_component.hpp" /* * Author: SzwedzikPL - * Server: creates new dogtag item and send it to client. + * Server: Creates a new dog tag item and sends it to client. + * It broacasts the dog tag info to all machines with interfaces. * * Arguments: * 0: Player @@ -11,12 +12,12 @@ * None * * Example: - * [player, unit] call ace_dogtags_fnc_getDogtagItem + * [player, cursorObject] call ace_dogtags_fnc_getDogtagItem * * Public: No */ -if(!isServer) exitWith {}; +if (!isServer) exitWith {}; params ["_player", "_target"]; TRACE_2("getDogtagItem",_player,_target); @@ -28,7 +29,20 @@ if (GVAR(idCounter) > 999) exitWith {ERROR("Ran out of IDs");}; private _dogTagData = [_target] call FUNC(getDogTagData); private _item = format ["ACE_dogtag_%1", GVAR(idCounter)]; -[QGVAR(addDogtagItem), [_item, _dogTagData], [_player]] call CBA_fnc_targetEvent; - // Broadcast data globally, so that clients can use it where needed [QGVAR(broadcastDogtagInfo), [_item, _dogTagData]] call CBA_fnc_globalEvent; + +// Dog tags have no mass, so no need to check if it can fit in container, but check if unit has an inventory at all +[_player, _item, true] call CBA_fnc_addItem; + +private _name = _dogtagData param [0, ""]; + +// If data doesn't exist or body has no name, set name as "unknown" +if (_name == "") then { + _name = LELSTRING(common,unknown); +}; + +// Display message +[{ + [QEGVAR(common,displayTextStructured), [_this select 0, 2.5], _this select 1] call CBA_fnc_targetEvent; +}, [format [LLSTRING(takeDogtagSuccess), _name], _player], DOGTAG_SHOW_DELAY] call CBA_fnc_waitAndExecute; diff --git a/addons/dogtags/functions/fnc_showDogtag.sqf b/addons/dogtags/functions/fnc_showDogtag.sqf index 9e01bfc3cd..5de9a9fc62 100644 --- a/addons/dogtags/functions/fnc_showDogtag.sqf +++ b/addons/dogtags/functions/fnc_showDogtag.sqf @@ -1,10 +1,10 @@ #include "..\script_component.hpp" /* * Author: SzwedzikPL - * Shows dogtag. + * Shows dog tag. * * Arguments: - * 0: Dogtag data + * 0: Dog tag data * 1: Display as double tag * * Return Value: @@ -27,8 +27,10 @@ if (_doubleTags) then { } else { (QGVAR(tag) call BIS_fnc_rscLayer) cutRsc [QGVAR(singleTag), "PLAIN", 1, true]; }; -private _display = uiNamespace getvariable [QGVAR(tag), displayNull]; -if(isNull _display) exitWith {}; + +private _display = uiNamespace getVariable [QGVAR(tag), displayNull]; + +if (isNull _display) exitWith {}; private _control = _display displayCtrl 1001; _dogtagData params ["_name", "_code", "_bloodType"]; diff --git a/addons/dogtags/functions/fnc_ssn.sqf b/addons/dogtags/functions/fnc_ssn.sqf index 0ba3499c0b..794422ddd1 100644 --- a/addons/dogtags/functions/fnc_ssn.sqf +++ b/addons/dogtags/functions/fnc_ssn.sqf @@ -1,16 +1,16 @@ #include "..\script_component.hpp" /* * Author: kymckay - * Reports a social security number generated from the units name. + * Reports a social security number generated from the unit's name. * * Arguments: - * 0: Name of a unit + * 0: Unit name * * Return Value: * A random three/two/four format social security number * * Example: - * _ssn = ["AAA"] call ace_dogtags_fnc_ssn + * "name" call ace_dogtags_fnc_ssn * * Public: No */ @@ -18,19 +18,20 @@ params ["_name"]; private _chars = toArray _name; -private _length = count _chars; + // Warning, for strings containing non-latin characters, `_count _name` != `_count _chars` +private _length = count _chars; _chars pushBack _length; _length = _length + 1; private _remainder = 0; -private _nums = [0,0,0,0,0,0,0,0,0]; +private _nums = [0, 0, 0, 0, 0, 0, 0, 0, 0]; for "_index" from 0 to (8 max _length) do { private _inputChar = _chars select (_index % _length); - _nums set [(_index % 9), ((_nums select (_index % 9)) + _inputChar + _remainder) % 10]; + _nums set [_index % 9, ((_nums select (_index % 9)) + _inputChar + _remainder) % 10]; _remainder = (_inputChar + _remainder) % 256; }; -([_nums select [0,3],_nums select [3,2], _nums select [5,4]] apply { _x joinString "" }) joinString "-" +([_nums select [0, 3], _nums select [3, 2], _nums select [5, 4]] apply { _x joinString "" }) joinString "-" diff --git a/addons/dogtags/functions/fnc_takeDogtag.sqf b/addons/dogtags/functions/fnc_takeDogtag.sqf index 1972c91ee0..b374c27121 100644 --- a/addons/dogtags/functions/fnc_takeDogtag.sqf +++ b/addons/dogtags/functions/fnc_takeDogtag.sqf @@ -1,8 +1,8 @@ #include "..\script_component.hpp" /* * Author: SzwedzikPL - * If dogtag is not already taken triggers event on server. - * If dogtag already taken displays info about it. + * If the dog tag hasn't already been taken, it triggers an event on the server. + * If the dog tag has already been taken, it displays info about it. * * Arguments: * 0: Player @@ -12,17 +12,17 @@ * None * * Example: - * [player, unit] call ace_dogtags_fnc_takeDogtag + * [player, cursorObject] call ace_dogtags_fnc_takeDogtag * * Public: No */ params ["_player", "_target"]; -// animation +// Animation _player call EFUNC(common,goKneeling); -// sound +// Sound private _position = _target modelToWorldWorld (_target selectionPosition "neck"); playSound3D [ @@ -35,12 +35,11 @@ playSound3D [ 50 ]; -// display message +// Display message if ((_target getVariable [QGVAR(dogtagTaken), objNull]) == _target) then { - [{ - [_this, 2.5] call EFUNC(common,displayTextStructured); - }, localize LSTRING(dogtagAlreadyTaken), DOGTAG_SHOW_DELAY] call CBA_fnc_waitAndExecute; + [EFUNC(common,displayTextStructured), [LLSTRING(dogtagAlreadyTaken), 2.5], DOGTAG_SHOW_DELAY] call CBA_fnc_waitAndExecute; } else { _target setVariable [QGVAR(dogtagTaken), _target, true]; + [QGVAR(getDogtagItem), [_player, _target]] call CBA_fnc_serverEvent; }; diff --git a/addons/dragging/functions/fnc_carryObject.sqf b/addons/dragging/functions/fnc_carryObject.sqf index 29c807b894..579e6a0ac3 100644 --- a/addons/dragging/functions/fnc_carryObject.sqf +++ b/addons/dragging/functions/fnc_carryObject.sqf @@ -20,8 +20,9 @@ params ["_unit", "_target"]; TRACE_2("params",_unit,_target); // If in ViV cargo, unload it first -if (!isNull isVehicleCargo _target) then { - objNull setVehicleCargo _target; +// Warn user if it failed to unload (shouldn't happen) +if (!isNull isVehicleCargo _target && {!(objNull setVehicleCargo _target)}) then { + WARNING_1("ViV Unload Failed %1",_target); }; // Get attachTo offset and direction @@ -65,10 +66,10 @@ private _UAVCrew = _target call EFUNC(common,getVehicleUAVCrew); if (_UAVCrew isNotEqualTo []) then { { - _target deleteVehicleCrew _x; + [_x, true] call EFUNC(common,disableAiUAV); } forEach _UAVCrew; - _target setVariable [QGVAR(isUAV), true, true]; + _target setVariable [QGVAR(isUAV), _UAVCrew, true]; }; // Check everything diff --git a/addons/dragging/functions/fnc_carryObjectPFH.sqf b/addons/dragging/functions/fnc_carryObjectPFH.sqf index fcd0f05376..e0a58a26eb 100644 --- a/addons/dragging/functions/fnc_carryObjectPFH.sqf +++ b/addons/dragging/functions/fnc_carryObjectPFH.sqf @@ -73,8 +73,8 @@ if (_unit getHitPointDamage "HitLegs" >= 0.5) exitWith { _idPFH call CBA_fnc_removePerFrameHandler; }; -// Drop static if crew is in it (UAV crew deletion may take a few frames) -if (_target isKindOf "StaticWeapon" && {!(_target getVariable [QGVAR(isUAV), false])} && {(crew _target) isNotEqualTo []}) exitWith { +// Drop static if either non-UAV crew or new UAV crew is in it (ignore saved UAV crew) +if (_target isKindOf "StaticWeapon" && {((crew _target) - (_target getVariable [QGVAR(isUAV), []])) isNotEqualTo []}) exitWith { TRACE_2("static weapon crewed",_unit,_target); [_unit, _target] call FUNC(dropObject_carry); diff --git a/addons/dragging/functions/fnc_dragObject.sqf b/addons/dragging/functions/fnc_dragObject.sqf index 58631cdc5c..87272491da 100644 --- a/addons/dragging/functions/fnc_dragObject.sqf +++ b/addons/dragging/functions/fnc_dragObject.sqf @@ -20,8 +20,9 @@ params ["_unit", "_target"]; TRACE_2("params",_unit,_target); // If in ViV cargo, unload it first -if (!isNull isVehicleCargo _target) then { - objNull setVehicleCargo _target; +// Warn user if it failed to unload (shouldn't happen) +if (!isNull isVehicleCargo _target && {!(objNull setVehicleCargo _target)}) then { + WARNING_1("ViV Unload Failed %1",_target); }; // Get attachTo offset and direction. @@ -78,10 +79,10 @@ private _UAVCrew = _target call EFUNC(common,getVehicleUAVCrew); if (_UAVCrew isNotEqualTo []) then { { - _target deleteVehicleCrew _x; + [_x, true] call EFUNC(common,disableAiUAV); } forEach _UAVCrew; - _target setVariable [QGVAR(isUAV), true, true]; + _target setVariable [QGVAR(isUAV), _UAVCrew, true]; }; // Check everything diff --git a/addons/dragging/functions/fnc_dragObjectPFH.sqf b/addons/dragging/functions/fnc_dragObjectPFH.sqf index 7c3a6be307..249f3866bb 100644 --- a/addons/dragging/functions/fnc_dragObjectPFH.sqf +++ b/addons/dragging/functions/fnc_dragObjectPFH.sqf @@ -51,8 +51,8 @@ if (_unit distance _target > 10 && {(CBA_missionTime - _startTime) >= 1}) exitWi _idPFH call CBA_fnc_removePerFrameHandler; }; -// Drop static if crew is in it (UAV crew deletion may take a few frames) -if (_target isKindOf "StaticWeapon" && {!(_target getVariable [QGVAR(isUAV), false])} && {(crew _target) isNotEqualTo []}) exitWith { +// Drop static if either non-UAV crew or new UAV crew is in it (ignore saved UAV crew) +if (_target isKindOf "StaticWeapon" && {((crew _target) - (_target getVariable [QGVAR(isUAV), []])) isNotEqualTo []}) exitWith { TRACE_2("static weapon crewed",_unit,_target); [_unit, _target] call FUNC(dropObject); diff --git a/addons/dragging/functions/fnc_dropObject.sqf b/addons/dragging/functions/fnc_dropObject.sqf index 4115f28820..119eaf415a 100644 --- a/addons/dragging/functions/fnc_dropObject.sqf +++ b/addons/dragging/functions/fnc_dropObject.sqf @@ -80,16 +80,16 @@ if (_unit getVariable ["ACE_isUnconscious", false]) then { [_unit, "unconscious", 2] call EFUNC(common,doAnimation); }; -// Recreate UAV crew (add a frame delay or this may cause the vehicle to be moved to [0,0,0]) -if (_target getVariable [QGVAR(isUAV), false]) then { - _target setVariable [QGVAR(isUAV), nil, true]; +// Reenable UAV crew +private _UAVCrew = _target getVariable [QGVAR(isUAV), []]; - [{ - params ["_target"]; - if (!alive _target) exitWith {}; - TRACE_2("restoring uav crew",_target,getPosASL _target); - createVehicleCrew _target; - }, [_target]] call CBA_fnc_execNextFrame; +if (_UAVCrew isNotEqualTo []) then { + // Reenable AI + { + [_x, false] call EFUNC(common,disableAiUAV); + } forEach _UAVCrew; + + _target setVariable [QGVAR(isUAV), nil, true]; }; // Fixes not being able to move when in combat pace diff --git a/addons/dragging/functions/fnc_dropObject_carry.sqf b/addons/dragging/functions/fnc_dropObject_carry.sqf index ff6324e0f3..d244d93a2e 100644 --- a/addons/dragging/functions/fnc_dropObject_carry.sqf +++ b/addons/dragging/functions/fnc_dropObject_carry.sqf @@ -59,11 +59,12 @@ if (_target isKindOf "CAManBase" || {animationState _unit in CARRY_ANIMATIONS}) _unit removeWeapon "ACE_FakePrimaryWeapon"; // Reselect weapon and re-enable sprint -private _previousWeaponIndex = _unit getVariable [QGVAR(previousWeapon), -1]; -_unit setVariable [QGVAR(previousWeapon), nil, true]; +private _previousWeaponState = _unit getVariable QGVAR(previousWeapon); -if (_previousWeaponIndex != -1) then { - _unit action ["SwitchWeapon", _unit, _unit, _previousWeaponIndex]; +if (!isNil "_previousWeaponState") then { + _unit selectWeapon _previousWeaponState; + + _unit setVariable [QGVAR(previousWeapon), nil, true]; }; [_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); @@ -86,16 +87,16 @@ if !(_target isKindOf "CAManBase") then { [QEGVAR(common,fixFloating), _target, _target] call CBA_fnc_targetEvent; }; -// Recreate UAV crew (add a frame delay or this may cause the vehicle to be moved to [0,0,0]) -if (_target getVariable [QGVAR(isUAV), false]) then { - _target setVariable [QGVAR(isUAV), nil, true]; +// Reenable UAV crew +private _UAVCrew = _target getVariable [QGVAR(isUAV), []]; - [{ - params ["_target"]; - if (!alive _target) exitWith {}; - TRACE_2("restoring uav crew",_target,getPosASL _target); - createVehicleCrew _target; - }, [_target]] call CBA_fnc_execNextFrame; +if (_UAVCrew isNotEqualTo []) then { + // Reenable AI + { + [_x, false] call EFUNC(common,disableAiUAV); + } forEach _UAVCrew; + + _target setVariable [QGVAR(isUAV), nil, true]; }; // Reset mass diff --git a/addons/dragging/functions/fnc_getWeight.sqf b/addons/dragging/functions/fnc_getWeight.sqf index f6b93feca0..f6cb466165 100644 --- a/addons/dragging/functions/fnc_getWeight.sqf +++ b/addons/dragging/functions/fnc_getWeight.sqf @@ -11,7 +11,7 @@ * Weight * * Example: - * [cursorTarget] call ace_dragging_fnc_getWeight + * cursorTarget call ace_dragging_fnc_getWeight * * Public: No */ @@ -23,19 +23,20 @@ if (GVAR(weightCoefficient) == 0) exitWith {0}; private _weight = loadAbs _object; -if !(GVAR(skipContainerWeight)) then { +if (!GVAR(skipContainerWeight)) then { // Add the mass of the object itself // getMass handles PhysX mass, this should be 0 for SupplyX containers and WeaponHolders // Use originalMass in case we're checking weight for a carried object - _weight = _weight + ((_object getVariable [QGVAR(originalMass), getMass _object])); + _weight = _weight + (_object getVariable [QGVAR(originalMass), getMass _object]); }; -// Contents of backpacks get counted twice (https://github.com/acemod/ACE3/pull/8457#issuecomment-1062522447 and https://feedback.bistudio.com/T167469) -// This is a workaround until that is fixed on BI's end -{ - _x params ["", "_container"]; - _weight = _weight - (loadAbs _container); -} forEach (everyContainer _object); +// Fixed in https://feedback.bistudio.com/T167469 on 2.16 profiling branch and for 2.18 stable +if ((productVersion select 3) < 152017) then { + { + _x params ["", "_container"]; + _weight = _weight - (loadAbs _container); + } forEach (everyContainer _object); +}; // Mass in Arma isn't an exact amount but rather a volume/weight value // This attempts to work around that by making it a usable value (sort of) diff --git a/addons/dragging/functions/fnc_startCarryLocal.sqf b/addons/dragging/functions/fnc_startCarryLocal.sqf index 6ba2c68934..743a56e1f4 100644 --- a/addons/dragging/functions/fnc_startCarryLocal.sqf +++ b/addons/dragging/functions/fnc_startCarryLocal.sqf @@ -50,7 +50,7 @@ if (_target isKindOf "CAManBase") then { }; // Select primary, otherwise the carry animation actions don't work - _unit selectWeapon _primaryWeapon; + _unit selectWeapon _primaryWeapon; // This turns off lasers/lights // Move a bit closer and adjust direction when trying to pick up a person [QEGVAR(common,setDir), [_target, getDir _unit + 180], _target] call CBA_fnc_targetEvent; @@ -62,10 +62,11 @@ if (_target isKindOf "CAManBase") then { _timer = CBA_missionTime + 10; } else { // Select no weapon and stop sprinting - private _previousWeaponIndex = [_unit] call EFUNC(common,getFiremodeIndex); - _unit setVariable [QGVAR(previousWeapon), _previousWeaponIndex, true]; + if (currentWeapon _unit != "") then { + _unit setVariable [QGVAR(previousWeapon), (weaponState _unit) select [0, 3], true]; - _unit action ["SwitchWeapon", _unit, _unit, 299]; + _unit action ["SwitchWeapon", _unit, _unit, 299]; + }; [_unit, "AmovPercMstpSnonWnonDnon", 0] call EFUNC(common,doAnimation); diff --git a/addons/dragging/functions/fnc_startDragLocal.sqf b/addons/dragging/functions/fnc_startDragLocal.sqf index 22c7cecd24..de41d712a4 100644 --- a/addons/dragging/functions/fnc_startDragLocal.sqf +++ b/addons/dragging/functions/fnc_startDragLocal.sqf @@ -46,7 +46,10 @@ if (!GVAR(dragAndFire)) then { _primaryWeapon = "ACE_FakePrimaryWeapon"; }; - _unit selectWeapon _primaryWeapon; + // Keep the laser/light on if the weapon is already selected + if (currentWeapon _unit != _primaryWeapon) then { + _unit selectWeapon _primaryWeapon; + }; } else { // Making sure the unit is holding a primary weapon or handgun private _handgunWeapon = handgunWeapon _unit; diff --git a/addons/fire/XEH_postInit.sqf b/addons/fire/XEH_postInit.sqf index 641b74fffe..1050d75753 100644 --- a/addons/fire/XEH_postInit.sqf +++ b/addons/fire/XEH_postInit.sqf @@ -1,25 +1,25 @@ #include "script_component.hpp" -[QGVAR(burn), LINKFUNC(burn)] call CBA_fnc_addEventHandler; -[QGVAR(burnEffects), LINKFUNC(burnEffects)] call CBA_fnc_addEventHandler; -[QGVAR(burnSimulation), LINKFUNC(burnSimulation)] call CBA_fnc_addEventHandler; - -[QGVAR(playScream), { - params ["_scream", "_source"]; - - // Only play sound if enabled in settings and enabled for the unit - if (GVAR(enableScreams) && {_source getVariable [QGVAR(enableScreams), true]}) then { - _source say3D _scream; - }; -}] call CBA_fnc_addEventHandler; - -if (!isServer) exitWith {}; - ["CBA_settingsInitialized", { - TRACE_1("settingsInit",GVAR(enabled)); + TRACE_1("settingsInitialized",GVAR(enabled)); if (!GVAR(enabled)) exitWith {}; + [QGVAR(burn), LINKFUNC(burn)] call CBA_fnc_addEventHandler; + [QGVAR(burnEffects), LINKFUNC(burnEffects)] call CBA_fnc_addEventHandler; + [QGVAR(burnSimulation), LINKFUNC(burnSimulation)] call CBA_fnc_addEventHandler; + + [QGVAR(playScream), { + params ["_scream", "_source"]; + + // Only play sound if enabled in settings and enabled for the unit + if (GVAR(enableScreams) && {_source getVariable [QGVAR(enableScreams), true]}) then { + _source say3D _scream; + }; + }] call CBA_fnc_addEventHandler; + + if (!isServer) exitWith {}; + GVAR(fireSources) = createHashMap; [QGVAR(addFireSource), { diff --git a/addons/fire/ACE_Medical_Treatment_Actions.hpp b/addons/fire/compat_medical_engine/ACE_Medical_Treatment_Actions.hpp similarity index 100% rename from addons/fire/ACE_Medical_Treatment_Actions.hpp rename to addons/fire/compat_medical_engine/ACE_Medical_Treatment_Actions.hpp diff --git a/addons/fire/compat_medical_engine/config.cpp b/addons/fire/compat_medical_engine/config.cpp new file mode 100644 index 0000000000..cc4431b18f --- /dev/null +++ b/addons/fire/compat_medical_engine/config.cpp @@ -0,0 +1,20 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_medical_engine"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "ACE_Medical_Treatment_Actions.hpp" diff --git a/addons/fire/compat_medical_engine/script_component.hpp b/addons/fire/compat_medical_engine/script_component.hpp new file mode 100644 index 0000000000..b2ce8adc8d --- /dev/null +++ b/addons/fire/compat_medical_engine/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT medical_engine +#define SUBCOMPONENT_BEAUTIFIED Medical Engine +#include "..\script_component.hpp" diff --git a/addons/fire/config.cpp b/addons/fire/config.cpp index df2eb5cb79..7a13dd079b 100644 --- a/addons/fire/config.cpp +++ b/addons/fire/config.cpp @@ -1,20 +1,12 @@ #include "script_component.hpp" -#pragma hemtt flag pe23_ignore_has_include -#if __has_include("\z\ace\addons\nomedical\script_component.hpp") -#define PATCH_SKIP "No Medical" -#endif - -#ifdef PATCH_SKIP -ACE_PATCH_NOT_LOADED(ADDON,PATCH_SKIP) -#else class CfgPatches { class ADDON { name = COMPONENT_NAME; units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"ace_common", "ace_medical_engine"}; + requiredAddons[] = {"ace_common"}; author = ECSTRING(common,ACETeam); authors[] = {"commy2", "tcvm"}; url = ECSTRING(main,URL); @@ -25,7 +17,4 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgSounds.hpp" #include "CfgVehicles.hpp" -#include "ACE_Medical_Treatment_Actions.hpp" #include "RscTitles.hpp" - -#endif diff --git a/addons/fire/functions/fnc_burnSimulation.sqf b/addons/fire/functions/fnc_burnSimulation.sqf index b50afab5dc..ac98de5dda 100644 --- a/addons/fire/functions/fnc_burnSimulation.sqf +++ b/addons/fire/functions/fnc_burnSimulation.sqf @@ -148,19 +148,27 @@ params ["_unit", "_instigator"]; _unit call FUNC(burnReaction); }; - if (!isNull _instigator) then { - _unit setVariable [QEGVAR(medical,lastDamageSource), _instigator]; - _unit setVariable [QEGVAR(medical,lastInstigator), _instigator]; - }; - - // Common burn areas are the hands and face https://www.ncbi.nlm.nih.gov/pubmed/16899341/ - private _bodyPart = ["Head", "Body", "LeftArm", "RightArm", "LeftLeg", "RightLeg"] selectRandomWeighted [0.77, 0.5, 0.8, 0.8, 0.3, 0.3]; - - // Keep pain around unconciousness limit to allow for more fun interactions + // Keep pain around unconsciousness limit to allow for more fun interactions private _damageToAdd = [0.15, _intensity / BURN_MAX_INTENSITY] select (!alive _unit || {GET_PAIN_PERCEIVED(_unit) < (PAIN_UNCONSCIOUS + random 0.2)}); - // Use event directly, as ace_medical_fnc_addDamageToUnit requires unit to be alive - [QEGVAR(medical,woundReceived), [_unit, [[_damageToAdd, _bodyPart, _damageToAdd]], _instigator, "burn"]] call CBA_fnc_localEvent; + if (GETEGVAR(medical,enabled,false)) then { + if (!isNull _instigator) then { + _unit setVariable [QEGVAR(medical,lastDamageSource), _instigator]; + _unit setVariable [QEGVAR(medical,lastInstigator), _instigator]; + }; + + // Common burn areas are the hands and face https://www.ncbi.nlm.nih.gov/pubmed/16899341/ + private _bodyPart = ["Head", "Body", "LeftArm", "RightArm", "LeftLeg", "RightLeg"] selectRandomWeighted [0.77, 0.5, 0.8, 0.8, 0.3, 0.3]; + + // Use event directly, as ace_medical_fnc_addDamageToUnit requires unit to be alive + [QEGVAR(medical,woundReceived), [_unit, [[_damageToAdd, _bodyPart, _damageToAdd]], _instigator, "burn"]] call CBA_fnc_localEvent; + } else { + private _bodyParts = [["HitFace", "HitNeck", "HitHead"], ["HitPelvis", "HitAbdomen", "HitDiaphragm", "HitChest", "HitBody"], ["HitArms", "HitHands"], ["HitLegs"]] selectRandomWeighted [0.77, 0.5, 0.8, 0.3]; + + { + _unit setHitPointDamage [_x, (_unit getHitPointDamage _x) + _damageToAdd, true, _instigator, _instigator]; + } forEach _bodyParts; + }; _unit setVariable [QGVAR(intensity), _intensity, true]; // Globally sync intensity across all clients to make sure simulation is deterministic }; diff --git a/addons/fire/initSettings.inc.sqf b/addons/fire/initSettings.inc.sqf index edcd51a8a7..d9649c2ad9 100644 --- a/addons/fire/initSettings.inc.sqf +++ b/addons/fire/initSettings.inc.sqf @@ -5,7 +5,7 @@ LSTRING(Category_DisplayName), true, 1, - {[QGVAR(fireEnabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, + {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, true // Needs mission restart ] call CBA_fnc_addSetting; diff --git a/addons/fire/script_component.hpp b/addons/fire/script_component.hpp index ebb0002ff6..d79ca0d490 100644 --- a/addons/fire/script_component.hpp +++ b/addons/fire/script_component.hpp @@ -16,7 +16,14 @@ #endif #include "\z\ace\addons\main\script_macros.hpp" + +#pragma hemtt flag pe23_ignore_has_include +#if __has_include("\z\ace\addons\medical_engine\script_macros_medical.hpp") #include "\z\ace\addons\medical_engine\script_macros_medical.hpp" +#else +#define GET_PAIN_PERCEIVED(var) 0 +#define PAIN_UNCONSCIOUS 1 +#endif #define FIRE_MANAGER_PFH_DELAY 0.25 #define FLARE_SIZE_MODIFIER 5 diff --git a/addons/interaction/functions/fnc_canPush.sqf b/addons/interaction/functions/fnc_canPush.sqf index 28197d12cd..ff339d5952 100644 --- a/addons/interaction/functions/fnc_canPush.sqf +++ b/addons/interaction/functions/fnc_canPush.sqf @@ -10,7 +10,7 @@ * Can Push * * Example: - * [target] call ace_interaction_fnc_canPush + * cursorObject call ace_interaction_fnc_canPush * * Public: No */ @@ -19,4 +19,5 @@ params ["_target"]; alive _target && {getMass _target <= 2600 || getNumber (configOf _target >> QGVAR(canPush)) == 1} && -{vectorMagnitude velocity _target < 3} +{vectorMagnitude velocity _target < 3} && +{isNull isVehicleCargo _target} // Check if vehicle is loaded as ViV cargo diff --git a/addons/medical_engine/functions/fnc_lockUnconsciousSeat.sqf b/addons/medical_engine/functions/fnc_lockUnconsciousSeat.sqf index cc29e75cc1..8441df4ad8 100644 --- a/addons/medical_engine/functions/fnc_lockUnconsciousSeat.sqf +++ b/addons/medical_engine/functions/fnc_lockUnconsciousSeat.sqf @@ -11,7 +11,6 @@ * * Public: No */ -if (missionNamespace getVariable [QGVAR(disableSeatLocking), false]) exitWith {}; params ["_unit"]; private _vehicle = objectParent _unit; @@ -20,6 +19,13 @@ TRACE_3("lockUnconsciousSeat",_unit,_vehicle,lifeState _unit); if (isNull _vehicle) exitWith {}; if (alive _unit && {lifeState _unit != "INCAPACITATED"}) exitWith {}; +private _disable = missionNamespace getVariable [QGVAR(disableSeatLocking), false]; +if (_disable isEqualTo true || { + _disable isEqualType [] && { + (_disable findIf {_vehicle isKindOf _x}) != -1 + } +}) exitWith {}; + switch (true) do { case (_unit isEqualTo (driver _vehicle)): { _vehicle lockDriver true; diff --git a/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf b/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf index d721b0e4ae..c3dcc2cfe4 100644 --- a/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf +++ b/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Handles player getting into new vehicle. Loads PFEG for mortar display if it is a mortar. + * Handles player getting into new vehicle. Loads PFEG for mortar display if it is a mortar. * * Arguments: * 0: Player @@ -11,7 +11,7 @@ * None * * Example: - * [bob, mortar] call ace_mk6mortar_fnc_handlePlayerVehicleChanged; + * [player, cursorObject] call ace_mk6mortar_fnc_handlePlayerVehicleChanged * * Public: No */ @@ -24,83 +24,78 @@ if !(_newVehicle isKindOf "Mortar_01_base_F") exitWith {}; private _tubeWeaponName = (weapons _newVehicle) select 0; private _fireModes = getArray (configFile >> "CfgWeapons" >> _tubeWeaponName >> "modes"); -//Restore last firemode: -private _lastFireMode = _newVehicle getVariable [QGVAR(lastFireMode), -1]; -if (_lastFireMode != -1) then { - _player action ["SwitchWeapon", _newVehicle, _player, _lastFireMode]; +// Restore last firemode +private _lastSavedWeaponsInfo = _newVehicle getVariable QGVAR(lastFireMode); + +if (!isNil "_lastSavedWeaponsInfo") then { + _newVehicle selectWeaponTurret [_lastSavedWeaponsInfo select 0, [0], _lastSavedWeaponsInfo select 1, _lastSavedWeaponsInfo select 2]; }; [{ - params ["_args", "_pfID"]; - _args params ["_mortarVeh", "_fireModes"]; + params ["_mortarVeh", "_pfhID"]; - if ((vehicle ACE_player) != _mortarVeh) then { - [_pfID] call CBA_fnc_removePerFrameHandler; + if ((vehicle ACE_player) != _mortarVeh) exitWith { + _pfhID call CBA_fnc_removePerFrameHandler; + }; + + // Save firemode ('charge' from weaponstate) on vehicle + _mortarVeh setVariable [QGVAR(lastFireMode), (weaponState [_mortarVeh, [0]]) select [0, 3]]; + + if (shownArtilleryComputer && {!GVAR(allowComputerRangefinder)}) then { + // Don't like this solution, but it works + closeDialog 0; + [parseText "Computer Disabled"] call EFUNC(common,displayTextStructured); + }; + + private _display = uiNamespace getVariable ["ACE_Mk6_RscWeaponRangeArtillery", displayNull]; + + if (isNull _display) exitWith {}; // It may be null for the first frame + + // Hud should hidden in 3rd person + private _notGunnerView = cameraView != "GUNNER"; + private _useMils = _mortarVeh getVariable [QGVAR(useMils), true]; + + // Get aiming values from ace_artillerytables + // Note: it also handles displaying the "charge" level + private _realAzimuth = missionNamespace getVariable [QEGVAR(artillerytables,predictedAzimuth), -1]; + private _realElevation = missionNamespace getVariable [QEGVAR(artillerytables,predictedElevation), -1]; + + // Update Heading Display + if (_notGunnerView || !GVAR(allowCompass)) then { + (_display displayCtrl 80156) ctrlSetText ""; } else { - - private _useMils = _mortarVeh getVariable [QGVAR(useMils), true]; - - //Compute: 'charge' from weaponstate - private _currentFireMode = (weaponState [_mortarVeh, [0]]) select 2; - private _currentChargeMode = _fireModes find _currentFireMode; - - //Save firemode on vehicle: - _mortarVeh setVariable [QGVAR(lastFireMode), _currentChargeMode]; - - if (shownArtilleryComputer && {!GVAR(allowComputerRangefinder)}) then { - //Don't like this solution, but it works - closeDialog 0; - [parseText "Computer Disabled"] call EFUNC(common,displayTextStructured); - }; - - private _display = uiNamespace getVariable ["ACE_Mk6_RscWeaponRangeArtillery", displayNull]; - if (isNull _display) exitWith {}; //It may be null for the first frame - - //Hud should hidden in 3rd person - private _notGunnerView = cameraView != "GUNNER"; - - // Get aiming values from ace_artillerytables - // Note: it also handles displaying the "charge" level - private _realAzimuth = missionNamespace getVariable [QEGVAR(artillerytables,predictedAzimuth), -1]; - private _realElevation = missionNamespace getVariable [QEGVAR(artillerytables,predictedElevation), -1]; - - //Update Heading Display: - if (_notGunnerView || (!GVAR(allowCompass))) then { - (_display displayCtrl 80156) ctrlSetText ""; + if (_useMils) then { + (_display displayCtrl 80156) ctrlSetText str (((round (_realAzimuth * 6400 / 360)) + 6400) % 6400); } else { + (_display displayCtrl 80156) ctrlSetText str ((round (_realAzimuth + 360)) % 360); + }; + }; + + // Update CurrentElevation Display + if (_notGunnerView) then { + (_display displayCtrl 80175) ctrlSetText ""; + } else { + if (_useMils) then { + (_display displayCtrl 80175) ctrlSetText str ((round (_realElevation * 6400 / 360)) % 6400); + } else { + (_display displayCtrl 80175) ctrlSetText str (((round (_realElevation * 100)) / 100) % 360); + }; + }; + + // Update ElevationNeeded Display + if (_notGunnerView || !GVAR(allowComputerRangefinder)) then { + (_display displayCtrl 80176) ctrlSetText ""; + } else { + private _elevDeg = parseNumber ctrlText (_display displayCtrl 176); + if (_elevDeg <= 0) then { // Bad data means "----" out of range + (_display displayCtrl 80176) ctrlSetText (ctrlText (_display displayCtrl 176)); + } else { + _elevDeg = _elevDeg + (_realElevation - (parseNumber ctrlText (_display displayCtrl 175))); if (_useMils) then { - (_display displayCtrl 80156) ctrlSetText str (((round (_realAzimuth * 6400 / 360)) + 6400) % 6400); + (_display displayCtrl 80176) ctrlSetText str round ((round (_elevDeg * 6400 / 360)) % 6400); } else { - (_display displayCtrl 80156) ctrlSetText str ((round (_realAzimuth + 360)) % 360); - }; - }; - - //Update CurrentElevation Display - if (_notGunnerView) then { - (_display displayCtrl 80175) ctrlSetText ""; - } else { - if (_useMils) then { - (_display displayCtrl 80175) ctrlSetText str ((round (_realElevation * 6400 / 360)) % 6400); - } else { - (_display displayCtrl 80175) ctrlSetText str (((round (_realElevation * 100)) / 100) % 360); - }; - }; - - //Update ElevationNeeded Display: - if (_notGunnerView || (!GVAR(allowComputerRangefinder))) then { - (_display displayCtrl 80176) ctrlSetText ""; - } else { - private _elevDeg = parseNumber ctrlText (_display displayCtrl 176); - if (_elevDeg <= 0) then { //Bad data means "----" out of range - (_display displayCtrl 80176) ctrlSetText (ctrlText (_display displayCtrl 176)); - } else { - _elevDeg = _elevDeg + (_realElevation - (parseNumber ctrlText (_display displayCtrl 175))); - if (_useMils) then { - (_display displayCtrl 80176) ctrlSetText str round ((round (_elevDeg * 6400 / 360)) % 6400); - } else { - (_display displayCtrl 80176) ctrlSetText str (((round (_elevDeg * 100)) / 100) % 360); - }; + (_display displayCtrl 80176) ctrlSetText str (((round (_elevDeg * 100)) / 100) % 360); }; }; }; -}, 0, [_newVehicle, _fireModes]] call CBA_fnc_addPerFrameHandler; +}, 0, _newVehicle] call CBA_fnc_addPerFrameHandler; diff --git a/addons/quickmount/XEH_postInitClient.sqf b/addons/quickmount/XEH_postInitClient.sqf index 23c225f583..6dbd38742b 100644 --- a/addons/quickmount/XEH_postInitClient.sqf +++ b/addons/quickmount/XEH_postInitClient.sqf @@ -2,9 +2,8 @@ if (!hasInterface) exitWith {}; -["ACE3 Movement", QGVAR(mount), [localize LSTRING(KeybindName), localize LSTRING(KeybindDescription)], "", { +["ACE3 Movement", QGVAR(mount), [LLSTRING(KeybindName), LLSTRING(KeybindDescription)], "", { if (!dialog) then { - [] call FUNC(getInNearest); + call FUNC(getInNearest); }; - false }] call CBA_fnc_addKeybind; diff --git a/addons/quickmount/functions/fnc_getInNearest.sqf b/addons/quickmount/functions/fnc_getInNearest.sqf index 5e6c21eb36..52bc8cd220 100644 --- a/addons/quickmount/functions/fnc_getInNearest.sqf +++ b/addons/quickmount/functions/fnc_getInNearest.sqf @@ -1,131 +1,125 @@ #include "..\script_component.hpp" /* * Author: Kingsley - * Mount the player in the vehicle they are directly looking at based on their distance. + * Mounts the player in the vehicle they are directly looking at based on their distance. * * Arguments: - * 0: Target (Optional) + * 0: Target (default: objNull) * * Return Value: * None * * Example: - * [] call ace_quickmount_fnc_getInNearest; + * call ace_quickmount_fnc_getInNearest * * Public: No */ -if (!GVAR(enabled) || +if ( + !GVAR(enabled) || {isNull ACE_player} || - {vehicle ACE_player != ACE_player} || - {!alive ACE_player} || - {ACE_player getVariable ["ace_unconscious", false]} + {!isNull objectParent ACE_player} || + {!(ACE_player call EFUNC(common,isAwake))} ) exitWith {}; -params [["_interactionTarget", objNull, [objNull]]]; -TRACE_1("getInNearest",_interactionTarget); +params [["_target", objNull, [objNull]]]; +TRACE_1("getInNearest",_target); -private _start = ACE_player modelToWorldVisualWorld (ACE_player selectionPosition "pilot"); -private _end = (_start vectorAdd (getCameraViewDirection ACE_player vectorMultiply GVAR(distance))); -private _objects = lineIntersectsSurfaces [_start, _end, ACE_player]; -private _target = (_objects param [0, []]) param [2, objNull]; - -if ((isNull _target) && {alive _interactionTarget}) then { - _end = _start vectorAdd ((_start vectorFromTo (aimPos _interactionTarget)) vectorMultiply GVAR(distance)); - _objects = lineIntersectsSurfaces [_start, _end, ACE_player]; - TRACE_1("2nd ray attempt at interaction target aim pos",_objects); +// If target is not defined (e.g. keybind was used), search for valid target +if (isNull _target) then { + private _start = ACE_player modelToWorldVisualWorld (ACE_player selectionPosition "pilot"); + private _end = (_start vectorAdd (getCameraViewDirection ACE_player vectorMultiply GVAR(distance))); + private _objects = lineIntersectsSurfaces [_start, _end, ACE_player]; _target = (_objects param [0, []]) param [2, objNull]; }; -if (locked _target in [2,3] || {!simulationEnabled _target}) exitWith { - [localize LSTRING(VehicleLocked)] call EFUNC(common,displayTextStructured); - true +if (!alive _target) exitWith {}; + +if (locked _target >= 2 || {!simulationEnabled _target}) exitWith { + [LLSTRING(VehicleLocked)] call EFUNC(common,displayTextStructured); }; TRACE_2("",_target,typeOf _target); -if (!isNull _target && - {alive _target} && - {{_target isKindOf _x} count ["Air","LandVehicle","Ship","StaticMortar"] > 0} && - {([ACE_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith))} && - {speed _target <= GVAR(speed)} - ) then { +if ( + (speed _target > GVAR(speed)) || + {["Air", "LandVehicle", "Ship", "StaticMortar"] findIf {_target isKindOf _x} == -1} || + {!([ACE_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith))} +) exitWith {}; +private _seats = ["driver", "gunner", "commander", "cargo"]; +private _sortedSeats = [_seats select GVAR(priority)]; +_seats deleteAt GVAR(priority); +_sortedSeats append _seats; - if (GVAR(priority) > 3 || GVAR(priority) < 0) then { - GVAR(priority) = 0; - }; +private _fullCrew = fullCrew [_target, "", true]; - private _seats = ["Driver", "Gunner", "Commander", "Cargo"]; - private _sortedSeats = [_seats select GVAR(priority)]; - _seats deleteAt GVAR(priority); - _sortedSeats append _seats; +private _hasAction = false; +scopeName "SearchForSeat"; +{ + private _desiredRole = _x; - private _hasAction = false; - scopeName "SearchForSeat"; { - private _desiredRole = _x; - { - _x params ["_unit", "_role", "_cargoIndex", "_turretPath"]; - if ((isNull _unit) || {!alive _unit}) then { - private _effectiveRole = toLowerANSI _role; + _x params ["_unit", "_role", "_cargoIndex", "_turretPath"]; - if ((_effectiveRole in ["driver", "gunner"]) && {unitIsUAV _target}) exitWith {}; // Ignoring UAV Driver/Gunner - if ((_effectiveRole == "driver") && {(getNumber (configOf _target >> "hasDriver")) == 0}) exitWith {}; // Ignoring Non Driver (static weapons) + if (!alive _unit) then { + private _effectiveRole = _role; - // Seats can be locked independently of the main vehicle - if ((_role == "driver") && {lockedDriver _target}) exitWith {TRACE_1("lockedDriver",_x);}; - if ((_cargoIndex >= 0) && {_target lockedCargo _cargoIndex}) exitWith {TRACE_1("lockedCargo",_x);}; - if ((_turretPath isNotEqualTo []) && {_target lockedTurret _turretPath}) exitWith {TRACE_1("lockedTurret",_x);}; + if ((_effectiveRole in ["driver", "gunner"]) && {unitIsUAV _target}) exitWith {}; // Ignoring UAV Driver/Gunner + if ((_effectiveRole == "driver") && {(getNumber (configOf _target >> "hasDriver")) == 0}) exitWith {}; // Ignoring Non Driver (static weapons) - if (_effectiveRole == "turret") then { - private _turretConfig = [_target, _turretPath] call CBA_fnc_getTurret; - if (getNumber (_turretConfig >> "isCopilot") == 1) exitWith { - _effectiveRole = "driver"; - }; - if ( - _cargoIndex >= 0 // FFV - || {"" isEqualTo getText (_turretConfig >> "gun")} // turret without weapon - ) exitWith { - _effectiveRole = "cargo"; - }; - _effectiveRole = "gunner"; // door gunners / 2nd turret - }; - TRACE_2("",_effectiveRole,_x); - if (_effectiveRole != _desiredRole) exitWith {}; + // Seats can be locked independently of the main vehicle + if ((_effectiveRole == "driver") && {lockedDriver _target}) exitWith {TRACE_1("lockedDriver",_x);}; + if ((_cargoIndex >= 0) && {_target lockedCargo _cargoIndex}) exitWith {TRACE_1("lockedCargo",_x);}; + if ((_turretPath isNotEqualTo []) && {_target lockedTurret _turretPath}) exitWith {TRACE_1("lockedTurret",_x);}; - if (_turretPath isNotEqualTo []) then { - // Using GetInTurret seems to solve problems with incorrect GetInEH params when gunner/commander - ACE_player action ["GetInTurret", _target, _turretPath]; - TRACE_3("Geting In Turret",_x,_role,_turretPath); - } else { - if (_cargoIndex > -1) then { - // GetInCargo expects the index of the seat in the "cargo" array from fullCrew - // See description: https://community.bistudio.com/wiki/fullCrew - private _cargoActionIndex = -1; - { - if ((_x select 2) == _cargoIndex) exitWith {_cargoActionIndex = _forEachIndex}; - } forEach (fullCrew [_target, "cargo", true]); + if (_effectiveRole == "turret") then { + private _turretConfig = [_target, _turretPath] call CBA_fnc_getTurret; - ACE_player action ["GetInCargo", _target, _cargoActionIndex]; - TRACE_4("Geting In Cargo",_x,_role,_cargoActionIndex,_cargoIndex); - } else { - ACE_player action ["GetIn" + _role, _target]; - TRACE_2("Geting In",_x,_role); - }; + if (getNumber (_turretConfig >> "isCopilot") == 1) exitWith { + _effectiveRole = "driver"; }; - _hasAction = true; - breakTo "SearchForSeat"; + if ( + _cargoIndex >= 0 || // FFV + {getText (_turretConfig >> "gun") == ""} // Turret without weapon + ) exitWith { + _effectiveRole = "cargo"; + }; + + _effectiveRole = "gunner"; // Door gunners / 2nd turret }; - } forEach (fullCrew [_target, "", true]); - } forEach _sortedSeats; - if (!_hasAction) then { - TRACE_1("no empty seats",_hasAction); - [localize LSTRING(VehicleFull)] call EFUNC(common,displayTextStructured); - }; + TRACE_2("",_effectiveRole,_x); + + if (_effectiveRole != _desiredRole) exitWith {}; + + if (_turretPath isNotEqualTo []) then { + // Using GetInTurret seems to solve problems with incorrect GetInEH params when gunner/commander + ACE_player action ["GetInTurret", _target, _turretPath]; + TRACE_3("Getting In Turret",_x,_role,_turretPath); + } else { + if (_cargoIndex > -1) then { + // GetInCargo expects the index of the seat in the "cargo" array from fullCrew + // See description: https://community.bistudio.com/wiki/fullCrew + private _cargoActionIndex = (fullCrew [_target, "cargo", true]) findIf {(_x select 2) == _cargoIndex}; + + ACE_player action ["GetInCargo", _target, _cargoActionIndex]; + TRACE_4("Getting In Cargo",_x,_role,_cargoActionIndex,_cargoIndex); + } else { + ACE_player action ["GetIn" + _role, _target]; + TRACE_2("Getting In",_x,_role); + }; + }; + + _hasAction = true; + breakTo "SearchForSeat"; + }; + } forEach _fullCrew; +} forEach _sortedSeats; + +if (!_hasAction) then { + TRACE_1("no empty seats",_hasAction); + [LLSTRING(VehicleFull)] call EFUNC(common,displayTextStructured); }; - -true diff --git a/addons/rearm/script_component.hpp b/addons/rearm/script_component.hpp index 83d495bc38..1cc6379ff7 100644 --- a/addons/rearm/script_component.hpp +++ b/addons/rearm/script_component.hpp @@ -28,7 +28,9 @@ #define REARM_HOLSTER_WEAPON \ - _unit setVariable [QGVAR(selectedWeaponOnRearm), currentWeapon _unit]; \ + if (currentWeapon _unit != "") then { \ + _unit setVariable [QGVAR(selectedWeaponOnRearm), (weaponState _unit) select [0, 3]]; \ + }; \ TRACE_2("REARM_HOLSTER_WEAPON",_unit,currentWeapon _unit); \ _unit action ["SwitchWeapon", _unit, _unit, 299]; diff --git a/addons/repair/functions/fnc_repair.sqf b/addons/repair/functions/fnc_repair.sqf index 526b2d506b..ccb2e42dfd 100644 --- a/addons/repair/functions/fnc_repair.sqf +++ b/addons/repair/functions/fnc_repair.sqf @@ -149,10 +149,15 @@ if (_callbackProgress == "") then { // Player Animation private _callerAnim = [getText (_config >> "animationCaller"), getText (_config >> "animationCallerProne")] select (stance _caller == "PRONE"); private _loopAnim = (getNumber (_config >> "loopAnimation")) isEqualTo 1; -_caller setVariable [QGVAR(selectedWeaponOnrepair), currentWeapon _caller]; + +private _currentWeapon = currentWeapon _caller; + +if (_currentWeapon != "") then { + _caller setVariable [QGVAR(selectedWeaponOnrepair), (weaponState _caller) select [0, 3]]; +}; // Cannot use secondairy weapon for animation -if (currentWeapon _caller == secondaryWeapon _caller) then { +if (_currentWeapon == secondaryWeapon _caller) then { _caller selectWeapon (primaryWeapon _caller); }; diff --git a/addons/repair/functions/fnc_repair_failure.sqf b/addons/repair/functions/fnc_repair_failure.sqf index f9de2a8ae6..37b2c50447 100644 --- a/addons/repair/functions/fnc_repair_failure.sqf +++ b/addons/repair/functions/fnc_repair_failure.sqf @@ -38,9 +38,11 @@ if (vehicle _caller == _caller && {!(_caller call EFUNC(common,isSwimming))}) th _caller setVariable [QGVAR(repairCurrentAnimCaller), nil]; _caller setVariable [QGVAR(repairPrevAnimCaller), nil]; -private _weaponSelect = (_caller getVariable [QGVAR(selectedWeaponOnrepair), ""]); -if (_weaponSelect != "") then { +private _weaponSelect = _caller getVariable QGVAR(selectedWeaponOnrepair); + +if (!isNil "_weaponSelect") then { _caller selectWeapon _weaponSelect; + _caller setVariable [QGVAR(selectedWeaponOnrepair), nil]; } else { _caller action ["SwitchWeapon", _caller, _caller, 299]; }; diff --git a/addons/repair/functions/fnc_repair_success.sqf b/addons/repair/functions/fnc_repair_success.sqf index 6248082779..9da2b0c403 100644 --- a/addons/repair/functions/fnc_repair_success.sqf +++ b/addons/repair/functions/fnc_repair_success.sqf @@ -38,9 +38,11 @@ if (vehicle _caller == _caller && {!(_caller call EFUNC(common,isSwimming))}) th _caller setVariable [QGVAR(repairCurrentAnimCaller), nil]; _caller setVariable [QGVAR(repairPrevAnimCaller), nil]; -private _weaponSelect = (_caller getVariable [QGVAR(selectedWeaponOnrepair), ""]); -if (_weaponSelect != "") then { +private _weaponSelect = _caller getVariable QGVAR(selectedWeaponOnrepair); + +if (!isNil "_weaponSelect") then { _caller selectWeapon _weaponSelect; + _caller setVariable [QGVAR(selectedWeaponOnrepair), nil]; } else { _caller action ["SwitchWeapon", _caller, _caller, 299]; }; diff --git a/addons/respawn/functions/fnc_handleKilled.sqf b/addons/respawn/functions/fnc_handleKilled.sqf index 1383561f2c..eeca8f96e5 100644 --- a/addons/respawn/functions/fnc_handleKilled.sqf +++ b/addons/respawn/functions/fnc_handleKilled.sqf @@ -21,7 +21,7 @@ params ["_unit"]; // Saves the gear when the player! (and only him) is killed if (ACE_player == _unit && {GVAR(SavePreDeathGear)}) then { _unit setVariable [QGVAR(unitGear), [_unit] call CBA_fnc_getLoadout]; - _unit setVariable [QGVAR(activeWeaponAndMuzzle), [currentWeapon _unit, currentMuzzle _unit, currentWeaponMode _unit]]; + _unit setVariable [QGVAR(activeWeaponAndMuzzle), (weaponState _unit) select [0, 3]]; [QGVAR(saveGear), _unit] call CBA_fnc_localEvent; }; diff --git a/addons/respawn/functions/fnc_restoreGear.sqf b/addons/respawn/functions/fnc_restoreGear.sqf index afbc7def86..34c5918383 100644 --- a/addons/respawn/functions/fnc_restoreGear.sqf +++ b/addons/respawn/functions/fnc_restoreGear.sqf @@ -5,7 +5,8 @@ * * Arguments: * 0: Unit - * 1: All Gear based on return value of ACE_common_fnc_getAllGear + * 1: All Gear based on return value of ace_common_fnc_getAllGear + * 2: All weapon info needed for restoring previous weapon status * * Return Value: * None @@ -19,36 +20,12 @@ params ["_unit", "_allGear", "_activeWeaponAndMuzzle"]; TRACE_3("restoreGear",_unit,count _allGear,_activeWeaponAndMuzzle); -// restore all gear +// Restore all gear if (!isNil "_allGear") then { [_unit, _allGear] call CBA_fnc_setLoadout; }; -// restore the last active weapon, muzzle and weaponMode +// Restore the last active weapon, muzzle and weapon mode if (!isNil "_activeWeaponAndMuzzle") then { - // @todo, replace this with CBA_fnc_selectWeapon after next CBA update - _activeWeaponAndMuzzle params ["_activeWeapon", "_activeMuzzle", "_activeWeaponMode"]; - - if ( - (_activeMuzzle != "") && - {_activeMuzzle != _activeWeapon} && - {_activeMuzzle in getArray (configFile >> "CfgWeapons" >> _activeWeapon >> "muzzles")} - ) then { - _unit selectWeapon _activeMuzzle; - } else { - if (_activeWeapon != "") then { - _unit selectWeapon _activeWeapon; - }; - }; - - if (currentWeapon _unit != "") then { - private _index = 0; - - while { - _index < 299 && {currentWeaponMode _unit != _activeWeaponMode} - } do { - _unit action ["SwitchWeapon", _unit, _unit, _index]; - _index = _index + 1; - }; - }; + _unit selectWeapon _activeWeaponAndMuzzle; }; diff --git a/addons/sitting/functions/fnc_getRandomAnimation.sqf b/addons/sitting/functions/fnc_getRandomAnimation.sqf index ac8bd9e68d..b0aa2ba270 100644 --- a/addons/sitting/functions/fnc_getRandomAnimation.sqf +++ b/addons/sitting/functions/fnc_getRandomAnimation.sqf @@ -4,7 +4,7 @@ * Gets a random animations from the list. * * Arguments: - * None + * 0: Object to get animation pool from (default: objNull) * * Return Value: * Random Animation @@ -15,30 +15,42 @@ * Public: No */ +params [["_object", objNull, [objNull]]]; + +private _animations = []; + +if (!isNull _object) then { + _animations = getArray (configOf _object >> QGVAR(animations)); +}; + +if (_animations isEqualTo []) then { + _animations = [ + QGVAR(HubSittingChairA_idle1), + QGVAR(HubSittingChairA_idle2), + QGVAR(HubSittingChairA_idle3), + QGVAR(HubSittingChairA_move1), + QGVAR(HubSittingChairB_idle1), + QGVAR(HubSittingChairB_idle2), + QGVAR(HubSittingChairB_idle3), + QGVAR(HubSittingChairB_move1), + QGVAR(HubSittingChairC_idle1), + QGVAR(HubSittingChairC_idle2), + QGVAR(HubSittingChairC_idle3), + QGVAR(HubSittingChairC_move1), + QGVAR(HubSittingChairUA_idle1), + QGVAR(HubSittingChairUA_idle2), + QGVAR(HubSittingChairUA_idle3), + QGVAR(HubSittingChairUA_move1), + QGVAR(HubSittingChairUB_idle1), + QGVAR(HubSittingChairUB_idle2), + QGVAR(HubSittingChairUB_idle3), + QGVAR(HubSittingChairUB_move1), + QGVAR(HubSittingChairUC_idle1), + QGVAR(HubSittingChairUC_idle2), + QGVAR(HubSittingChairUC_idle3), + QGVAR(HubSittingChairUC_move1) + ]; +}; + // Select random animation from Animations Pool -selectRandom [ - QGVAR(HubSittingChairA_idle1), - QGVAR(HubSittingChairA_idle2), - QGVAR(HubSittingChairA_idle3), - QGVAR(HubSittingChairA_move1), - QGVAR(HubSittingChairB_idle1), - QGVAR(HubSittingChairB_idle2), - QGVAR(HubSittingChairB_idle3), - QGVAR(HubSittingChairB_move1), - QGVAR(HubSittingChairC_idle1), - QGVAR(HubSittingChairC_idle2), - QGVAR(HubSittingChairC_idle3), - QGVAR(HubSittingChairC_move1), - QGVAR(HubSittingChairUA_idle1), - QGVAR(HubSittingChairUA_idle2), - QGVAR(HubSittingChairUA_idle3), - QGVAR(HubSittingChairUA_move1), - QGVAR(HubSittingChairUB_idle1), - QGVAR(HubSittingChairUB_idle2), - QGVAR(HubSittingChairUB_idle3), - QGVAR(HubSittingChairUB_move1), - QGVAR(HubSittingChairUC_idle1), - QGVAR(HubSittingChairUC_idle2), - QGVAR(HubSittingChairUC_idle3), - QGVAR(HubSittingChairUC_move1) -] +selectRandom _animations diff --git a/addons/sitting/functions/fnc_sit.sqf b/addons/sitting/functions/fnc_sit.sqf index 70e028719b..033a1f4d2c 100644 --- a/addons/sitting/functions/fnc_sit.sqf +++ b/addons/sitting/functions/fnc_sit.sqf @@ -48,7 +48,7 @@ if (_multiSitting) then { }; // Get random animation and perform it (before moving player to ensure correct placement) -[_player, call FUNC(getRandomAnimation), 2] call EFUNC(common,doAnimation); // Correctly places when using non-transitional animations +[_player, [_seat] call FUNC(getRandomAnimation), 2] call EFUNC(common,doAnimation); // Correctly places when using non-transitional animations [_player, "", 1] call EFUNC(common,doAnimation); // Correctly applies animation's config values (such as disallow throwing of grenades, intercept keybinds... etc). TRACE_2("Sit pos and dir",_sitPosition,_sitDirection); diff --git a/addons/weaponselect/functions/fnc_playChangeFiremodeSound.sqf b/addons/weaponselect/functions/fnc_playChangeFiremodeSound.sqf index fc55b54b5f..641787a394 100644 --- a/addons/weaponselect/functions/fnc_playChangeFiremodeSound.sqf +++ b/addons/weaponselect/functions/fnc_playChangeFiremodeSound.sqf @@ -35,3 +35,5 @@ if !(toLowerANSI (_filename select [count _filename - 4]) in [".wav", ".ogg", ". }; playSound3D [_filename, objNull, false, _position, _volume, _soundPitch, _distance]; + +nil // return diff --git a/addons/weaponselect/functions/fnc_selectWeaponMode.sqf b/addons/weaponselect/functions/fnc_selectWeaponMode.sqf index f2810bb512..fd22bd4462 100644 --- a/addons/weaponselect/functions/fnc_selectWeaponMode.sqf +++ b/addons/weaponselect/functions/fnc_selectWeaponMode.sqf @@ -18,35 +18,23 @@ params ["_unit", "_weapon"]; -if (_weapon == "") exitWith {}; +if (_weapon == "" || {!(_unit hasWeapon _weapon)}) exitWith {}; + +private _currentWeaponMode = (_unit weaponState _weapon) select 2; +private _muzzle = (_weapon call EFUNC(common,getWeaponMuzzles)) select 0; if (currentWeapon _unit != _weapon) exitWith { - _unit selectWeapon _weapon; + _unit selectWeapon [_weapon, _muzzle, _currentWeaponMode]; }; -// unlock safety +// Unlock safety if (_weapon in (_unit getVariable [QEGVAR(safemode,safedWeapons), []])) exitWith { [_unit, _weapon, _weapon] call EFUNC(safemode,unlockSafety); }; -private _muzzles = [_weapon] call EFUNC(common,getWeaponMuzzles); -private _modes = [_weapon] call EFUNC(common,getWeaponModes); +private _modes = _weapon call EFUNC(common,getWeaponModes); -private _index = (_modes find currentWeaponMode _unit) + 1; +_unit selectWeapon [_weapon, _muzzle, _modes select (((_modes find _currentWeaponMode) + 1) % (count _modes))]; -if (_index > count _modes - 1) then {_index = 0}; - -private _muzzle = _muzzles select 0; -private _mode = _modes select _index; - -_index = 0; - -while { - _index < 299 && {currentMuzzle _unit != _muzzle || {currentWeaponMode _unit != _mode}} -} do { - _unit action ["SwitchWeapon", _unit, _unit, _index]; - _index = _index + 1; -}; - -// play fire mode selector sound +// Play fire mode selector sound [_unit, _weapon] call FUNC(playChangeFiremodeSound); diff --git a/addons/weaponselect/functions/fnc_selectWeaponMuzzle.sqf b/addons/weaponselect/functions/fnc_selectWeaponMuzzle.sqf index 9a27a515ad..3882253573 100644 --- a/addons/weaponselect/functions/fnc_selectWeaponMuzzle.sqf +++ b/addons/weaponselect/functions/fnc_selectWeaponMuzzle.sqf @@ -18,32 +18,22 @@ params ["_unit", "_weapon"]; -if (_weapon == "") exitWith {}; +if (_weapon == "" || {!(_unit hasWeapon _weapon)}) exitWith {}; private _muzzles = _weapon call EFUNC(common,getWeaponMuzzles); -if (currentWeapon _unit != _weapon) exitWith { - if (count _muzzles > 1) then { +if (count _muzzles <= 1) exitWith {}; - // unlock safety - /*if (_weapon in (_unit getVariable [QEGVAR(safemode,safedWeapons), []])) exitWith { - [_unit, _weapon, _muzzles select 1] call EFUNC(safemode,unlockSafety); - };*/ +private _muzzle = (_unit weaponState _weapon) select 1; - _unit selectWeapon (_muzzles select 1); - }; +private _index = if (currentWeapon _unit == _weapon) then { + (((_muzzles find currentMuzzle _unit) + 1) % (count _muzzles)) max 1 +} else { + 1 }; -private _index = (_muzzles find currentMuzzle _unit) + 1; - -if (_index > count _muzzles - 1) then {_index = 1}; - private _muzzle = _muzzles select _index; -_index = 0; -while { - _index < 299 && {currentMuzzle _unit != _muzzle} -} do { - _unit action ["SwitchWeapon", _unit, _unit, _index]; - _index = _index + 1; -}; +_unit selectWeapon [_weapon, _muzzle, ([_weapon, _muzzle] call EFUNC(common,getWeaponModes)) select 0]; + +nil // return diff --git a/docs/wiki/class-names.md b/docs/wiki/class-names.md index d8537f0645..4a4f9b032f 100644 --- a/docs/wiki/class-names.md +++ b/docs/wiki/class-names.md @@ -240,6 +240,7 @@ ACE_plasmaIV_250 | Plasma IV (250ml) | ACE_ItemCore | ACE_salineIV | Saline IV (1000ml) | ACE_ItemCore | ACE_salineIV_500 | Saline IV (500ml) | ACE_ItemCore | ACE_salineIV_250 | Saline IV (250ml) | ACE_ItemCore | +ACE_suture | Suture | ACE_ItemCore | ACE_surgicalKit | Surgical Kit | ACE_ItemCore | ACE_tourniquet | Tourniquet (CAT) | ACE_ItemCore | ACE_medicalSupplyCrate | Simple ACE Medical Supply Crate | ammo box | diff --git a/docs/wiki/framework/medical-framework.md b/docs/wiki/framework/medical-framework.md index 00d9133b00..c0e94b5f9e 100644 --- a/docs/wiki/framework/medical-framework.md +++ b/docs/wiki/framework/medical-framework.md @@ -241,3 +241,10 @@ The damage elements are sorted in descending order according to how much damage Some of ACE Medical's underlying behavior, primarily related to damage handling and the vitals loop, can be fine-tuned by editing `ace_medical_const_` variables, found in [script_macros_medical.hpp](https://github.com/acemod/ACE3/blob/master/addons/medical_engine/script_macros_medical.hpp). Modification of those values should be done by advanced users only. Values and variable names are subject to change without prior warning. Modifying values mid-mission may lead to undefined behavior. Expect minimal support. + +### 5.1 Disable seat locking for unconscious +ACE will lock the seat of an unconscious or dead unit to prevent automatic unloading. This can be disabled by setting: +```sqf +ace_medical_engine_disableSeatLocking = true; // disable on everything +ace_medical_engine_disableSeatLocking = ["ship"]; // disable just on boats +``` diff --git a/docs/wiki/framework/sitting-framework.md b/docs/wiki/framework/sitting-framework.md index 09f59a9df4..b8f8ff37b0 100644 --- a/docs/wiki/framework/sitting-framework.md +++ b/docs/wiki/framework/sitting-framework.md @@ -29,6 +29,7 @@ class CfgVehicles { acex_sitting_sitDirection = 180; // Direction relative to object acex_sitting_sitPosition[] = {0, -0.1, -0.45}; // Position relative to object (may behave weird with certain objects) acex_sitting_interactPosition[] = {0, -0.1, -0.45}; + ace_sitting_animations[] = {"ace_sitting_HubSittingChairA_idle1"}; // Overwrite random animation pool XEH_ENABLED; // Enable XEH (only necessary if XEH is not yet enabled for this class or the one this inherits from) }; };