diff --git a/addons/compat_rhs_afrf3/XEH_preInit.sqf b/addons/compat_rhs_afrf3/XEH_preInit.sqf index b47cf6628d..2ca4338e90 100644 --- a/addons/compat_rhs_afrf3/XEH_preInit.sqf +++ b/addons/compat_rhs_afrf3/XEH_preInit.sqf @@ -6,4 +6,12 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +// Disable RHS' wheel replacement mechanic +if (["ace_repair"] call EFUNC(common,isModLoaded)) then { + RHS_Retread_Enabled = false; + rhs_btr70_EnableRetread = false; + rhs_TypeTirePressure = 1; + RHS_BTR_Effects_Init = true; +}; + ADDON = true; diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_repair/CfgVehicles.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_repair/CfgVehicles.hpp new file mode 100644 index 0000000000..1acd977b99 --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_repair/CfgVehicles.hpp @@ -0,0 +1,123 @@ +class CfgVehicles { + class Wheeled_APC_F; + class rhs_btr_base: Wheeled_APC_F { + class EGVAR(interaction,anims) { + class wheel_1_unhide { + positions[] = {{-0.8, -1.7, 0}}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + class wheel_2_unhide { + positions[] = {{0.35, -2.9, -0.1}}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + class rhs_btr70_vmf: rhs_btr_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class wheel_1_unhide: wheel_1_unhide { + positions[] = {{-1.2, -2.6, 0.2}}; + }; + class wheel_2_unhide: wheel_2_unhide { + positions[] = {{-0.3, -3.8, 0}}; + }; + }; + }; + + class rhs_btr70_msv: rhs_btr70_vmf {}; + class rhs_btr80_msv: rhs_btr70_msv { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class wheel_1_unhide: wheel_1_unhide { + positions[] = {{-1, -2.5, 0.6}}; + }; + class wheel_2_unhide: wheel_2_unhide { + enabled = 0; + }; + }; + }; + + class Truck_F; + class rhs_truck: Truck_F { + class EGVAR(interaction,anims) { + class spare_hide { + selections[] = {"spare"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class RHS_Ural_BaseTurret: Truck_F { + class EGVAR(interaction,anims) { + class spare_hide { + selections[] = {"spare"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class rhs_zil131_base: Truck_F { + class EGVAR(interaction,anims) { + class spare_hide { + selections[] = {"spare"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class rhs_kraz255_base; + class rhs_kraz255b1_base: rhs_kraz255_base { + class EGVAR(interaction,anims) { + class spare_hide { + selections[] = {"spare"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class O_Truck_02_covered_F; + class rhs_kamaz5350: O_Truck_02_covered_F { + class EGVAR(interaction,anims) { + class spare_hide { + selections[] = {"spare"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class MRAP_02_base_F; + class rhs_tigr_base: MRAP_02_base_F { + class EGVAR(interaction,anims) { + class spare_hide { + selections[] = {"spare"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class Offroad_01_base_f; + class RHS_UAZ_Base: Offroad_01_base_f { + class EGVAR(interaction,anims) { + class spare_hide { + selections[] = {"spare"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; +}; diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_repair/config.cpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_repair/config.cpp new file mode 100644 index 0000000000..d6d4fab107 --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_repair/config.cpp @@ -0,0 +1,21 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhs_main_loadorder", + "ace_repair" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Dystopian", "johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_repair/script_component.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_repair/script_component.hpp new file mode 100644 index 0000000000..1af928486c --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_repair/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT repair +#define SUBCOMPONENT_BEAUTIFIED Repair +#include "..\script_component.hpp" diff --git a/addons/compat_rhs_usf3/CfgVehicles.hpp b/addons/compat_rhs_usf3/CfgVehicles.hpp index 0593c5a868..3933e543ec 100644 --- a/addons/compat_rhs_usf3/CfgVehicles.hpp +++ b/addons/compat_rhs_usf3/CfgVehicles.hpp @@ -43,8 +43,7 @@ class CfgVehicles { EGVAR(refuel,fuelCapacity) = 302; }; - class Truck_F; - class Truck_01_base_F: Truck_F {}; + class Truck_01_base_F; class rhsusf_fmtv_base: Truck_01_base_F { EGVAR(refuel,fuelCapacity) = 219; }; @@ -55,8 +54,7 @@ class CfgVehicles { EGVAR(refuel,fuelCargo) = 900; // 45 jerrycans }; - class rhsusf_HEMTT_A4_base: Truck_01_base_F {}; - class rhsusf_M977A4_usarmy_wd: rhsusf_HEMTT_A4_base {}; + class rhsusf_M977A4_usarmy_wd; class rhsusf_M977A4_AMMO_usarmy_wd: rhsusf_M977A4_usarmy_wd { EGVAR(rearm,defaultSupply) = 1200; }; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/CfgVehicles.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/CfgVehicles.hpp new file mode 100644 index 0000000000..445cab8226 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/CfgVehicles.hpp @@ -0,0 +1,52 @@ +class CfgVehicles { + class rhsusf_stryker_base; + class rhsusf_stryker_m1126_base: rhsusf_stryker_base { + class EGVAR(interaction,anims) { + class Hide_FCans { + positions[] = {{-0.7, -3, -0.4}}; + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + class rhsusf_stryker_m1127_base: rhsusf_stryker_m1126_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class Hide_FCans: Hide_FCans { + positions[] = {{-0.5, -3, -0.4}}; + }; + }; + }; + + class rhsusf_stryker_m1126_m2_base: rhsusf_stryker_m1126_base {}; + class rhsusf_stryker_m1132_m2_base: rhsusf_stryker_m1126_m2_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class Hide_FCans: Hide_FCans { + positions[] = {{-1, -4, -0.4}}; + }; + }; + }; + class rhsusf_stryker_m1134_base: rhsusf_stryker_m1132_m2_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class Hide_FCans: Hide_FCans { + positions[] = {{-0.7, -3, -0.7}}; + }; + }; + }; + + class rhsusf_m1a2tank_base; + class rhsusf_m1a2sep2_base: rhsusf_m1a2tank_base { + class EGVAR(interaction,anims) { + class fuelcans_hide { + // Rotate interactions with turret rotation + positions[] = { + "[0.23, -0.6, 0] vectorAdd ([[1.1, -3.6, 0.6], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D)", + "[0.23, -0.6, 0] vectorAdd ([[-1.1, -3.6, 0.6], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D)" + }; + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; +}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/config.cpp b/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/config.cpp index bf600d5d5a..391e22d95e 100644 --- a/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/config.cpp +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/config.cpp @@ -21,3 +21,4 @@ class CfgPatches { }; #include "CfgEventHandlers.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_repair/CfgVehicles.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_repair/CfgVehicles.hpp new file mode 100644 index 0000000000..26341db1da --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_repair/CfgVehicles.hpp @@ -0,0 +1,126 @@ +class CfgVehicles { + class Truck_01_base_F; + class rhsusf_fmtv_base: Truck_01_base_F { + class EGVAR(interaction,anims) { + class hide_spare { + positions[] = {{1, 1.4, 0}}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + class rhsusf_M1078A1P2_fmtv_usarmy: rhsusf_fmtv_base {}; + class rhsusf_M1078A1P2_B_fmtv_usarmy: rhsusf_M1078A1P2_fmtv_usarmy {}; + class rhsusf_M1078A1P2_B_M2_fmtv_usarmy: rhsusf_M1078A1P2_B_fmtv_usarmy { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare: hide_spare { + positions[] = {{1, 1.4, -0.5}}; + }; + }; + }; + class rhsusf_M1078A1R_SOV_M2_D_fmtv_socom: rhsusf_M1078A1P2_B_M2_fmtv_usarmy { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare: hide_spare { + positions[] = {{1, 1, -0.5}}; + }; + }; + }; + class rhsusf_M1083A1P2_fmtv_usarmy: rhsusf_M1078A1P2_fmtv_usarmy {}; + class rhsusf_M1083A1P2_B_fmtv_usarmy: rhsusf_M1083A1P2_fmtv_usarmy {}; + class rhsusf_M1083A1P2_B_M2_fmtv_usarmy: rhsusf_M1083A1P2_B_fmtv_usarmy { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare: hide_spare { + positions[] = {{1, 1.4, -0.5}}; + }; + }; + }; + class rhsusf_M1084A1P2_fmtv_usarmy: rhsusf_M1083A1P2_fmtv_usarmy { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare: hide_spare { + positions[] = {{1, 1.8, 0}}; + }; + }; + }; + class rhsusf_M1084A1P2_B_M2_fmtv_usarmy: rhsusf_M1083A1P2_B_M2_fmtv_usarmy { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare: hide_spare { + positions[] = {{1, 1.8, -0.5}}; + }; + }; + }; + class rhsusf_M1085A1P2_B_Medical_fmtv_usarmy: rhsusf_M1083A1P2_B_fmtv_usarmy { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare: hide_spare { + positions[] = {{1, 6.1, 0}}; + }; + }; + }; + + class rhsusf_HEMTT_A4_base: Truck_01_base_F { + class EGVAR(interaction,anims) { + class hide_spare { + positions[] = {"_target selectionPosition 'sparewheel' vectorAdd [0.6, 0.6, -0.4]"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class MRAP_01_base_F; + class rhsusf_m1151_base: MRAP_01_base_F { + class EGVAR(interaction,anims) { + class hide_spare { + positions[] = {"_target selectionPosition 'sparewheel' vectorAdd [-0.465, 0, 0]"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + // Don't inherit, as it's easier for the trenches compat + class rhsusf_M1165A1_GMV_SAG2_base: rhsusf_m1151_base { + class EGVAR(interaction,anims) { + class hide_spare { + positions[] = {"_target selectionPosition 'sparewheel_gmv' vectorAdd [0, -0.44, 0]"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class rhsusf_rg33_base: MRAP_01_base_F { + class EGVAR(interaction,anims) { + class hide_spare { + selections[] = {"sparewheel"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class rhsusf_M1239_base: MRAP_01_base_F { + class EGVAR(interaction,anims) { + class hide_spare { + selections[] = {"sparewheel"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class rhsusf_MATV_base: MRAP_01_base_F { + class EGVAR(interaction,anims) { + class hide_spare { + selections[] = {"sparewheel"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; +}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_repair/config.cpp b/addons/compat_rhs_usf3/compat_rhs_usf3_repair/config.cpp new file mode 100644 index 0000000000..b204f64166 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_repair/config.cpp @@ -0,0 +1,23 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhsusf_main_loadorder", + "ace_repair" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_repair/script_component.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_repair/script_component.hpp new file mode 100644 index 0000000000..1af928486c --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_repair/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT repair +#define SUBCOMPONENT_BEAUTIFIED Repair +#include "..\script_component.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_trenches/CfgVehicles.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_trenches/CfgVehicles.hpp new file mode 100644 index 0000000000..ba4dd16cd7 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_trenches/CfgVehicles.hpp @@ -0,0 +1,48 @@ +class CfgVehicles { + class rhsusf_stryker_base; + class rhsusf_stryker_m1126_base: rhsusf_stryker_base { + class EGVAR(interaction,anims) { + class Hide_PioKit { + positions[] = {{-1, -2.2, -0.5}}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + class rhsusf_stryker_m1127_base: rhsusf_stryker_m1126_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class Hide_PioKit: Hide_PioKit { + positions[] = {{-0.8, -2.2, -0.5}}; + }; + }; + }; + + class rhsusf_stryker_m1126_m2_base: rhsusf_stryker_m1126_base {}; + class rhsusf_stryker_m1132_m2_base: rhsusf_stryker_m1126_m2_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class Hide_PioKit: Hide_PioKit { + positions[] = {{-1.3, -3.3, -0.5}}; + }; + }; + }; + class rhsusf_stryker_m1134_base: rhsusf_stryker_m1132_m2_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class Hide_PioKit: Hide_PioKit { + positions[] = {{-1, -2.2, -0.8}}; + }; + }; + }; + + class rhsusf_m1151_base; + class rhsusf_M1165A1_GMV_SAG2_base: rhsusf_m1151_base { + class EGVAR(interaction,anims) { + class tools_hide { + positions[] = {{0.365, 1.5, -0.4}}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; +}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_trenches/config.cpp b/addons/compat_rhs_usf3/compat_rhs_usf3_trenches/config.cpp new file mode 100644 index 0000000000..aea4c9daeb --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_trenches/config.cpp @@ -0,0 +1,23 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhsusf_main_loadorder", + "ace_trenches" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_trenches/script_component.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_trenches/script_component.hpp new file mode 100644 index 0000000000..10b90eb71e --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_trenches/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT trenches +#define SUBCOMPONENT_BEAUTIFIED Trenches +#include "..\script_component.hpp" diff --git a/addons/interaction/CfgVehicles.hpp b/addons/interaction/CfgVehicles.hpp index 6ae0d4a982..b3a0c1d37e 100644 --- a/addons/interaction/CfgVehicles.hpp +++ b/addons/interaction/CfgVehicles.hpp @@ -372,6 +372,16 @@ class CfgVehicles { }; class Car_F: Car {}; + class Offroad_01_base_F: Car_F { + class GVAR(anims) { + class HideBackpacks { + positions[] = {{-1.15, -1.15, -0.2}, {1.1, -1.15, -0.2}, {1.1, -2.5, -0.2}}; + items[] = {"B_TacticalPack_blk", "B_TacticalPack_blk", "B_Carryall_khk", "B_Carryall_khk"}; + name = "$STR_a3_cfgvehicleclasses_backpacks0"; + text = "$STR_a3_cfgvehicleclasses_backpacks0"; + }; + }; + }; class Quadbike_01_base_F: Car_F { class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { @@ -405,6 +415,49 @@ class CfgVehicles { }; }; + class Wheeled_APC_F; + class APC_Wheeled_01_base_F: Wheeled_APC_F { + class GVAR(anims) { + class showBags { + phase = 0; + // Rotate interactions with turret rotation + positions[] = { + "[0, -1.6, 0] vectorAdd ([[1, -1, 0.1], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D)", + "[0, -1.6, 0] vectorAdd ([[-1, -1, 0.1], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D)" + }; + selections[] = {"vhc_bags"}; + items[] = {"B_Carryall_cbr", "B_Carryall_cbr"}; + name = "$STR_a3_cfgvehicleclasses_backpacks0"; + text = "$STR_a3_cfgvehicleclasses_backpacks0"; + }; + }; + }; + class APC_Wheeled_02_base_F: Wheeled_APC_F { + class GVAR(anims); + }; + class APC_Wheeled_02_base_v2_F: APC_Wheeled_02_base_F { + class GVAR(anims): GVAR(anims) { + class showBags { + phase = 0; + selections[] = {"vhc_bags"}; + items[] = {"B_Carryall_cbr"}; + name = "$STR_BACKPACK_CONTAINER_NAME"; + text = "$STR_BACKPACK_CONTAINER_NAME"; + }; + }; + }; + class APC_Wheeled_03_base_F: Wheeled_APC_F { + class GVAR(anims) { + class showBags { + phase = 0; + selections[] = {"vhc_bags"}; + items[] = {"B_Carryall_cbr", "B_Carryall_cbr"}; + name = "$STR_a3_cfgvehicleclasses_backpacks0"; + text = "$STR_a3_cfgvehicleclasses_backpacks0"; + }; + }; + }; + class Tank: LandVehicle { class ACE_Actions { class ACE_MainActions { @@ -432,6 +485,88 @@ class CfgVehicles { }; }; }; + class Tank_F; + class LT_01_base_F: Tank_F { + class GVAR(anims) { + class showBags { + phase = 0; + selections[] = {"vhc_bags"}; + items[] = {"B_Carryall_cbr"}; + name = "$STR_BACKPACK_CONTAINER_NAME"; + text = "$STR_BACKPACK_CONTAINER_NAME"; + }; + class showBags2: showBags { + selections[] = {"vhc_bags2"}; + }; + }; + }; + + class APC_Tracked_01_base_F: Tank_F { + class GVAR(anims); + }; + class B_APC_Tracked_01_base_F: APC_Tracked_01_base_F { + class GVAR(anims): GVAR(anims) { + class showBags { + phase = 0; + selections[] = {"vhc_bags"}; + positions[] = {"private _pos = _target selectionPosition 'vhc_bags'; _pos set [0, -(_pos select 0)]; _pos"}; // Mirror position to other side of vehicle + items[] = {"B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr"}; + name = "$STR_a3_cfgvehicleclasses_backpacks0"; + text = "$STR_a3_cfgvehicleclasses_backpacks0"; + }; + }; + }; + class B_APC_Tracked_01_CRV_F: B_APC_Tracked_01_base_F { + class GVAR(anims): GVAR(anims) { + class showBags: showBags { + items[] = {"B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr"}; + }; + }; + }; + + class APC_Tracked_02_base_F: Tank_F { + class GVAR(anims); + }; + class O_APC_Tracked_02_base_F: APC_Tracked_02_base_F {}; + class O_APC_Tracked_02_cannon_F: O_APC_Tracked_02_base_F { + class GVAR(anims): GVAR(anims) { + class showBags { + phase = 0; + selections[] = {"vhc_bags"}; + items[] = {"B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr"}; + name = "$STR_a3_cfgvehicleclasses_backpacks0"; + text = "$STR_a3_cfgvehicleclasses_backpacks0"; + }; + }; + }; + + class APC_Tracked_03_base_F: Tank_F { + class GVAR(anims) { + class showBags { + phase = 0; + selections[] = {"vhc_bags"}; + items[] = {"B_Carryall_cbr", "B_Carryall_cbr"}; + name = "$STR_a3_cfgvehicleclasses_backpacks0"; + text = "$STR_a3_cfgvehicleclasses_backpacks0"; + }; + }; + }; + + class MBT_01_base_F: Tank_F { + class GVAR(anims); + }; + class B_MBT_01_base_F: MBT_01_base_F {}; + class B_MBT_01_cannon_F: B_MBT_01_base_F { + class GVAR(anims): GVAR(anims) { + class showBags { + phase = 0; + selections[] = {"vhc_bags"}; + items[] = {"B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr"}; + name = "$STR_a3_cfgvehicleclasses_backpacks0"; + text = "$STR_a3_cfgvehicleclasses_backpacks0"; + }; + }; + }; class Motorcycle: LandVehicle { class ACE_Actions { diff --git a/addons/interaction/XEH_PREP.hpp b/addons/interaction/XEH_PREP.hpp index 554f903704..26d4cf4d00 100644 --- a/addons/interaction/XEH_PREP.hpp +++ b/addons/interaction/XEH_PREP.hpp @@ -54,4 +54,5 @@ PREP(push); // misc PREP(canFlip); +PREP(initAnimActions); PREP(replaceTerrainObject); diff --git a/addons/interaction/XEH_postInit.sqf b/addons/interaction/XEH_postInit.sqf index f461e2a770..dc1c167d7c 100644 --- a/addons/interaction/XEH_postInit.sqf +++ b/addons/interaction/XEH_postInit.sqf @@ -149,11 +149,20 @@ GVAR(isOpeningDoor) = false; ["isNotOnLadder", {getNumber (configFile >> "CfgMovesMaleSdr" >> "States" >> animationState (_this select 0) >> "ACE_isLadder") != 1}] call EFUNC(common,addCanInteractWithCondition); ["CBA_settingsInitialized", { + TRACE_2("settingsInitialized",GVAR(disableNegativeRating),GVAR(enableAnimActions)); + if (GVAR(disableNegativeRating)) then { player addEventHandler ["HandleRating", { (_this select 1) max 0 }]; }; + + if (!GVAR(enableAnimActions)) exitWith {}; + + // Don't add inherited anim actions (but actions are added to child classes) + { + [_x, "InitPost", LINKFUNC(initAnimActions), true, [], true] call CBA_fnc_addClassEventHandler; + } forEach (keys (uiNamespace getVariable QGVAR(animActionsClasses))); }] call CBA_fnc_addEventHandler; { @@ -162,7 +171,6 @@ GVAR(isOpeningDoor) = false; }] call CBA_fnc_addPlayerEventHandler; } forEach ["loadout", "weapon"]; - // add "Take _weapon_" action to dropped weapons private _action = [ // action display name will be overwritten in modifier function diff --git a/addons/interaction/XEH_preInit.sqf b/addons/interaction/XEH_preInit.sqf index c5873bcfc9..ec73b62b1b 100644 --- a/addons/interaction/XEH_preInit.sqf +++ b/addons/interaction/XEH_preInit.sqf @@ -16,6 +16,7 @@ DFUNC(repair_Statement) = { // moved from config because of build problems }; if (hasInterface) then { + GVAR(initializedAnimClasses) = []; GVAR(replaceTerrainModels) = createHashMapFromArray call (uiNamespace getVariable QGVAR(cacheReplaceTerrainModels)); }; diff --git a/addons/interaction/XEH_preStart.sqf b/addons/interaction/XEH_preStart.sqf index 331b5c6d36..39da54b3b5 100644 --- a/addons/interaction/XEH_preStart.sqf +++ b/addons/interaction/XEH_preStart.sqf @@ -23,3 +23,13 @@ private _cacheReplaceTerrainModels = createHashMap; } forEach _replaceTerrainClasses; uiNamespace setVariable [QGVAR(cacheReplaceTerrainModels), compileFinal str _cacheReplaceTerrainModels]; + + +// Cache classes with anim actions +private _animActionsClasses = (QUOTE(isClass (_x >> QQGVAR(anims)) && {!isClass (inheritsFrom _x >> QQGVAR(anims))}) configClasses (configFile >> "CfgVehicles")); +_animActionsClasses = _animActionsClasses apply { configName _x }; +_animActionsClasses = _animActionsClasses select { + private _class = _x; + (_animActionsClasses findIf {(_class != _x) && {_class isKindOf _x}}) == -1 // filter classes that already have a parent in the list +}; +uiNamespace setVariable [QGVAR(animActionsClasses), compileFinal (_animActionsClasses createHashMapFromArray [])]; diff --git a/addons/interaction/functions/fnc_initAnimActions.sqf b/addons/interaction/functions/fnc_initAnimActions.sqf new file mode 100644 index 0000000000..673946a2e1 --- /dev/null +++ b/addons/interaction/functions/fnc_initAnimActions.sqf @@ -0,0 +1,194 @@ +#include "..\script_component.hpp" +/* + * Author: Dystopian + * Initializes object interactions based on animations. + * + * Arguments: + * 0: Target + * + * Return Value: + * None + * + * Example: + * cursorObject call ace_interaction_fnc_initAnimActions + * + * Public: No + */ + +params ["_object"]; + +private _class = typeOf _object; + +if (_class in GVAR(initializedAnimClasses)) exitWith {}; + +GVAR(initializedAnimClasses) pushBack _class; + +private _statement = { + params ["_target", "_player", "_params"]; + _params params ["_anim", "_phase", "_duration", "_text"]; + TRACE_5("statement",_target,_player,_anim,_phase,_duration); + + [ + _duration, + [_target, _player, _anim, _phase], + { + (_this select 0) params ["_target", "_player", "_anim", "_phase"]; + + private _items = _target getVariable [ + format [QGVAR(animsItems_%1), _anim], + getArray (configOf _target >> QGVAR(anims) >> _anim >> "items") + ]; + + // If 1 object was spawned in, consider it a success + private _success = false; + + if (_items isNotEqualTo []) then { + if (_items isEqualType "") then { + _items = [_items]; + }; + + private _weaponHolder = objNull; + + { + private _type = (_x call EFUNC(common,getItemType)) select 0; + + if (_type == "") then { + private _emptyPosAGL = []; + + // This covers testing vehicle stability and finding a safe position + for "_i" from 1 to 3 do { + _emptyPosAGL = [_target, _x, _player] call EFUNC(common,findUnloadPosition); + + if (_emptyPosAGL isNotEqualTo []) exitWith {}; + }; + + // If still no valid position, try the next item + if (_emptyPosAGL isEqualTo []) then { + [LELSTRING(common,NoRoomToUnload)] call EFUNC(common,displayTextStructured); + + continue; + }; + + private _object = createVehicle [_x, _emptyPosAGL, [], 0, "CAN_COLLIDE"]; + + if (!isNull _object) then { + // Prevent items from taking damage when unloaded + [_object, "blockDamage", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); + [EFUNC(common,statusEffect_set), [_object, "blockDamage", QUOTE(ADDON), false], 2] call CBA_fnc_waitAndExecute; + + _success = true; + } else { + WARNING_1("Failed to create object of type '%1'",_x); + }; + + continue; + }; + + // Functions/code below are guaranteed to spawn in objects + _success = true; + + // getItemType considers backpacks as weapons, so handle them first + if (getNumber (configFile >> "CfgVehicles" >> _x >> "isBackpack") == 1) then { + if (backpack _player == "") then { + _player addBackpackGlobal _x; + } else { + if (isNull _weaponHolder) then { + _weaponHolder = nearestObject [_player, "WeaponHolder"]; + + if (isNull _weaponHolder || {_player distance _weaponHolder > 2}) then { + _weaponHolder = createVehicle ["GroundWeaponHolder", [0, 0, 0], [], 0, "NONE"]; + _weaponHolder setPosASL getPosASL _player; + }; + }; + + _weaponHolder addBackpackCargoGlobal [_x, 1]; + }; + + continue; + }; + + switch (_type) do { + case "weapon": { + [_player, _x, true] call CBA_fnc_addWeapon; + }; + case "item": { + [_player, _x, true] call CBA_fnc_addItem; + }; + case "magazine": { + [_player, _x, -1, true] call CBA_fnc_addMagazine; + }; + }; + } forEach _items; + }; + + if (!_success) exitWith {}; + + _target animate [_anim, _phase, true]; + }, + {}, + _text, + { + (_this select 0) params ["_target", "", "_anim", "_phase"]; + + _target animationPhase _anim != _phase + }, + ["isNotSwimming"] + ] call EFUNC(common,progressBar); +}; + +private _condition = { + params ["_target", "_player", "_params"]; + _params params ["_anim", "_phase"]; + + _target animationPhase _anim != _phase + && {[_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)} +}; + +private _config = configOf _object; + +{ + private _animConfig = _x; + private _anim = configName _animConfig; + + private _animationSourcesConfig = _config >> "AnimationSources" >> _anim; + + if !( + isClass _animationSourcesConfig // anim exist + && {0 != [_animationSourcesConfig >> "scope", "NUMBER", 1] call CBA_fnc_getConfigEntry} // anim not hidden + && {isNumber (_animationSourcesConfig >> "initPhase")} // anim correct (some CUP anims are inherited and cleared) + && {0 != [_animConfig >> "enabled", "NUMBER", 1] call CBA_fnc_getConfigEntry} // anim enabled + ) then {continue}; + + private _positions = []; + { + if (_x isEqualType "") then { + _positions pushBack compile _x; + } else { + _positions pushBack _x; + }; + } forEach getArray (_animConfig >> "positions"); + + _positions append getArray (_animConfig >> "selections"); + + if (_positions isEqualTo []) then { + ERROR_2("No action position for _class %1 anim %2",_class,_anim); + continue; + }; + + private _phase = [_animConfig >> "phase", "NUMBER", 1] call CBA_fnc_getConfigEntry; + private _name = [_animConfig >> "name", "TEXT", localize "str_a3_cfgactions_unmountitem0"] call CBA_fnc_getConfigEntry; + private _icon = [_animConfig >> "icon", "TEXT", "\A3\ui_f\data\igui\cfg\actions\take_ca.paa"] call CBA_fnc_getConfigEntry; + private _duration = [_animConfig >> "duration", "NUMBER", 10] call CBA_fnc_getConfigEntry; + private _text = getText (_animConfig >> "text"); + + { + private _action = [ + format [QGVAR(anim_%1_%2), _anim, _forEachIndex], + _name, _icon, _statement, _condition, {}, + [_anim, _phase, _duration, _text], + _x + ] call EFUNC(interact_menu,createAction); + [_class, 0, [], _action] call EFUNC(interact_menu,addActionToClass); + TRACE_3("add anim",_class,_anim,_x); + } forEach _positions; +} forEach configProperties [_config >> QGVAR(anims), "isClass _x"]; diff --git a/addons/interaction/initSettings.inc.sqf b/addons/interaction/initSettings.inc.sqf index 2cefb162a7..4adc5a6daf 100644 --- a/addons/interaction/initSettings.inc.sqf +++ b/addons/interaction/initSettings.inc.sqf @@ -38,6 +38,16 @@ true ] call CBA_fnc_addSetting; +[ + QGVAR(enableAnimActions), "CHECKBOX", + LSTRING(SettingAnimActionsName), + format ["ACE %1", LLSTRING(DisplayName)], + true, + true, + {[QGVAR(enableAnimActions), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + [ QGVAR(interactWithTerrainObjects), "CHECKBOX", ["str_a3_modules_moduleomquest_defend_f_attributes_useterrainobject0", LSTRING(interactWithTerrainObjects_Description)], diff --git a/addons/interaction/stringtable.xml b/addons/interaction/stringtable.xml index 5b79a69e69..3d1daf9c3c 100644 --- a/addons/interaction/stringtable.xml +++ b/addons/interaction/stringtable.xml @@ -1324,5 +1324,9 @@ Advertencia: puede provocar que algunos objetos choquen con otros. Aviso: pode causar que alguns objetos colidam com outros. + + Interaction with animations + Взаимодействие с анимациями + diff --git a/addons/refuel/CfgVehicles.hpp b/addons/refuel/CfgVehicles.hpp index 44575a141d..dbbcaf04d1 100644 --- a/addons/refuel/CfgVehicles.hpp +++ b/addons/refuel/CfgVehicles.hpp @@ -238,6 +238,20 @@ class CfgVehicles { // Patria = LAV GVAR(fuelCapacity) = 269; }; + class APC_Wheeled_02_base_F: Wheeled_APC_F { + class EGVAR(interaction,anims); + }; + class APC_Wheeled_02_base_v2_F: APC_Wheeled_02_base_F { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class showCanisters { + phase = 0; + positions[] = {{-1.188, -3.87, -0.769}, {1.638, -3.87, -0.769}}; + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = CSTRING(TakeFuelCanister); + text = CSTRING(TakeFuelCanisterAction); + }; + }; + }; class Truck_F: Car_F { GVAR(fuelCapacity) = 400; @@ -308,12 +322,14 @@ class CfgVehicles { class MBT_01_base_F: Tank_F { // Merkava IV GVAR(fuelCapacity) = 1400; + class EGVAR(interaction,anims); }; class MBT_02_base_F: Tank_F { // T100 Black Eagle // Assuming T80 GVAR(fuelCapacity) = 1100; + class EGVAR(interaction,anims); }; class MBT_03_base_F: Tank_F { @@ -324,11 +340,37 @@ class CfgVehicles { class MBT_01_arty_base_F: MBT_01_base_F { // Assuming similar 2S3 GVAR(fuelCapacity) = 830; + + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class showCanisters { + phase = 0; + // Rotate interactions with turret rotation + positions[] = { + "[0, -2.5, 0] vectorAdd ([[1.6, -2.4, -0.3], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D)", + "[0, -2.5, 0] vectorAdd ([[1.8, 0.55, -0.7], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D)", + "[0, -2.5, 0] vectorAdd ([[-1.8, 0.55, -0.7], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D)" + }; + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = CSTRING(TakeFuelCanister); + text = CSTRING(TakeFuelCanisterAction); + }; + }; }; class MBT_02_arty_base_F: MBT_02_base_F { // Assuming similar 2S3 GVAR(fuelCapacity) = 830; + + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class showCanisters { + phase = 0; + // Rotate interactions with turret rotation + positions[] = {"[0, -2.1, 0] vectorAdd ([[1.6, -2.65, -0.3], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D)"}; + items[] = {"Land_CanisterFuel_F"}; + name = CSTRING(TakeFuelCanister); + text = CSTRING(TakeFuelCanisterAction); + }; + }; }; class Heli_Light_02_base_F: Helicopter_Base_H { diff --git a/addons/repair/CfgVehicles.hpp b/addons/repair/CfgVehicles.hpp index ce74737b76..6172b72679 100644 --- a/addons/repair/CfgVehicles.hpp +++ b/addons/repair/CfgVehicles.hpp @@ -429,9 +429,33 @@ class CfgVehicles { GVAR(hitpointPositions)[] = {{"HitTurret", {0,-2,0}}}; }; + class Tank_F; + class APC_Tracked_02_base_F: Tank_F { + class EGVAR(interaction,anims) { + class showTracks { + phase = 0; + positions[] = {{-1.7, -3.875, -0.7}, {1.7, -3.875, -0.7}}; + items[] = {"ACE_Track", "ACE_Track", "ACE_Track"}; + name = CSTRING(RemoveTrack); + text = CSTRING(RemovingTrack); + }; + }; + }; + class Car_F: Car { class HitPoints; }; + class Offroad_02_base_F: Car_F { + class EGVAR(interaction,anims) { + class hideSpareWheel { + selections[] = {"spare_wheel"}; + items[] = {"ACE_Wheel"}; + name = CSTRING(RemoveWheel); + text = CSTRING(RemovingWheel); + }; + }; + }; + class Truck_F: Car_F { class HitPoints: HitPoints { class HitLBWheel; @@ -449,10 +473,43 @@ class CfgVehicles { }; }; + class Truck_01_viv_base_F; + class Truck_01_cargo_base_F: Truck_01_viv_base_F { + class EGVAR(interaction,anims) { + class Tyre1_hide { + selections[] = {"tyre1_hide"}; + items[] = {"ACE_Wheel"}; + name = CSTRING(RemoveWheel); + text = CSTRING(RemovingWheel); + }; + }; + }; + class Truck_01_flatbed_base_F: Truck_01_viv_base_F { + class EGVAR(interaction,anims) { + class Tyre1_hide { + selections[] = {"tyre1_hide"}; + items[] = {"ACE_Wheel"}; + name = CSTRING(RemoveWheel); + text = CSTRING(RemovingWheel); + }; + }; + }; + class Quadbike_01_base_F: Car_F { GVAR(hitpointPositions)[] = { {"HitEngine", {0, 0.5, -0.7}}, {"HitFuel", {0, 0, -0.5}} }; }; class Hatchback_01_base_F: Car_F { GVAR(hitpointPositions)[] = {{"HitBody", {0, 0.7, -0.5}}, {"HitFuel", {0, -1.75, -0.75}}}; }; + + class Van_02_base_F: Truck_F { + class EGVAR(interaction,anims) { + class spare_tyre_hide { + positions[] = {"[[-1.2, -3.7, -0.4], [-0.45, -3.5, -0.4]] select (_target animationPhase 'Door_4_source' == 0)"}; + items[] = {"ACE_Wheel"}; + name = CSTRING(RemoveWheel); + text = CSTRING(RemovingWheel); + }; + }; + }; }; diff --git a/addons/trenches/CfgVehicles.hpp b/addons/trenches/CfgVehicles.hpp index bec66e2e64..554a75149b 100644 --- a/addons/trenches/CfgVehicles.hpp +++ b/addons/trenches/CfgVehicles.hpp @@ -106,4 +106,44 @@ class CfgVehicles { MACRO_ADDITEM(ACE_EntrenchingTool,50); }; }; + + class Wheeled_APC_F; + class APC_Wheeled_02_base_F: Wheeled_APC_F { + class EGVAR(interaction,anims); + }; + class APC_Wheeled_02_base_v2_F: APC_Wheeled_02_base_F { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class showTools { + phase = 0; + positions[] = {{-1.108, -1.47, -0.769}}; + items[] = {"ACE_EntrenchingTool"}; + name = CSTRING(EntrenchingToolName); + text = CSTRING(EntrenchingToolName); + }; + }; + }; + class APC_Wheeled_03_base_F: Wheeled_APC_F { + class EGVAR(interaction,anims) { + class showTools { + phase = 0; + positions[] = {{-0.9, -3, -0.5}}; + items[] = {"ACE_EntrenchingTool"}; + name = CSTRING(EntrenchingToolName); + text = CSTRING(EntrenchingToolName); + }; + }; + }; + + class Tank_F; + class LT_01_base_F: Tank_F { + class EGVAR(interaction,anims) { + class showTools { + phase = 0; + positions[] = {{0.6, 0, -0.3}}; + items[] = {"ACE_EntrenchingTool"}; + name = CSTRING(EntrenchingToolName); + text = CSTRING(EntrenchingToolName); + }; + }; + }; };