From 00178ceb0b5868797ec2848f7057903c51420e75 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Thu, 5 Sep 2024 07:59:24 +0200 Subject: [PATCH 01/24] Explosives - Remove unnecessary info from RPT (#10291) --- addons/explosives/functions/fnc_openTimerUI.sqf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/explosives/functions/fnc_openTimerUI.sqf b/addons/explosives/functions/fnc_openTimerUI.sqf index c8d3707ed19..391c71b3b24 100644 --- a/addons/explosives/functions/fnc_openTimerUI.sqf +++ b/addons/explosives/functions/fnc_openTimerUI.sqf @@ -64,14 +64,14 @@ _display displayAddEventHandler ["MouseZChanged", { [{ params ["_display", "_pfhID"]; - // Make sure explosive still exists and is near player - if ((!isNull _display) && {!alive ACE_player} || {!alive GVAR(explosive)} || {(ACE_player distance GVAR(explosive)) > 5}) exitWith { - INFO_2("%1's explosive %2 became invalid",ACE_player,GVAR(explosive)); - closeDialog 0; + if (isNull _display || {!alive ACE_player}) exitWith { _pfhID call CBA_fnc_removePerFrameHandler; }; - if (isNull _display) exitWith { + // Make sure explosive still exists and is near player + if (!alive GVAR(explosive) || {(ACE_player distance GVAR(explosive)) > 5}) exitWith { + INFO_2("%1's explosive %2 became invalid",ACE_player,GVAR(explosive)); + closeDialog 0; _pfhID call CBA_fnc_removePerFrameHandler; }; From 2f72c77c0c10f1030a85ba6b46c743df31994d30 Mon Sep 17 00:00:00 2001 From: Dart <59131299+DartRuffian@users.noreply.github.com> Date: Thu, 5 Sep 2024 01:01:31 -0500 Subject: [PATCH 02/24] Fortify - Add item/weapon/backpack fortify tool property (#10290) Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/fortify/CfgWeapons.hpp | 1 + addons/fortify/XEH_preInit.sqf | 2 ++ addons/fortify/XEH_preStart.sqf | 6 ++++++ addons/fortify/functions/fnc_canFortify.sqf | 6 +++++- docs/wiki/framework/fortify-framework.md | 16 ++++++++++++++-- 5 files changed, 28 insertions(+), 3 deletions(-) diff --git a/addons/fortify/CfgWeapons.hpp b/addons/fortify/CfgWeapons.hpp index 66ff7f52d88..82396288721 100644 --- a/addons/fortify/CfgWeapons.hpp +++ b/addons/fortify/CfgWeapons.hpp @@ -10,6 +10,7 @@ class CfgWeapons { picture = QPATHTOF(UI\hammer_ca.paa); scope = 2; ACE_isTool = 1; + GVAR(fortifyTool) = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 0; }; diff --git a/addons/fortify/XEH_preInit.sqf b/addons/fortify/XEH_preInit.sqf index 382fc805660..50f641f9cf7 100644 --- a/addons/fortify/XEH_preInit.sqf +++ b/addons/fortify/XEH_preInit.sqf @@ -13,6 +13,8 @@ GVAR(locations) = []; // Custom deploy handlers GVAR(deployHandlers) = []; +GVAR(fortifyTools) = keys (uiNamespace getVariable QGVAR(fortifyTools)); + #include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/fortify/XEH_preStart.sqf b/addons/fortify/XEH_preStart.sqf index 022888575ed..4da9eeb40da 100644 --- a/addons/fortify/XEH_preStart.sqf +++ b/addons/fortify/XEH_preStart.sqf @@ -1,3 +1,9 @@ #include "script_component.hpp" #include "XEH_PREP.hpp" + +private _fortifyTools = (QUOTE(getNumber (_x >> QQGVAR(fortifyTool)) > 0) configClasses (configFile >> "CfgWeapons") apply {configName _x}); +_fortifyTools append (QUOTE(getNumber (_x >> QQGVAR(fortifyTool)) > 0) configClasses (configFile >> "CfgVehicles") apply {configName _x}); +TRACE_1("",_fortifyTools); + +uiNamespace setVariable [QGVAR(fortifyTools), compileFinal (_fortifyTools createHashMapFromArray [])]; diff --git a/addons/fortify/functions/fnc_canFortify.sqf b/addons/fortify/functions/fnc_canFortify.sqf index 3a382bc98c9..ad676a91031 100644 --- a/addons/fortify/functions/fnc_canFortify.sqf +++ b/addons/fortify/functions/fnc_canFortify.sqf @@ -19,8 +19,12 @@ params ["_player", ["_cost", 0]]; (missionNamespace getVariable [QGVAR(fortifyAllowed), true]) && -{"ACE_Fortify" in (_player call EFUNC(common,uniqueItems))} && { + private _items = _player call EFUNC(common,uniqueItems); + _items append weapons _player; + _items pushBack backpack _player; + GVAR(fortifyTools) findAny _items != -1 +} && { private _budget = [side group _player] call FUNC(getBudget); ((_budget == -1) || {_budget >= _cost}) } && { diff --git a/docs/wiki/framework/fortify-framework.md b/docs/wiki/framework/fortify-framework.md index 9de0fab35b3..19cdf45e6b9 100644 --- a/docs/wiki/framework/fortify-framework.md +++ b/docs/wiki/framework/fortify-framework.md @@ -109,10 +109,22 @@ The Fortify budget can be updated for any side using the function. * [west, -250, false] call ace_fortify_fnc_updateBudget ``` +## 2. Config Values -## 2. Events +### 2.1 Enabling fortify tools on an item or backpack +```cpp +class CfgWeapons { // same config also works on backpacks (CfgVehicles) + class yourBaseClass; + class yourFortifyToolClass: yourBaseClass { + ace_fortify_fortifyTool = 1; + }; +}; +``` + + +## 3. Events -### 2.1 Listenable +### 3.1 Listenable | Event Name | Passed Parameter(s) | Locality | Description | | ---------- | ----------- | ------------------- | -------- | From 391a81c0b8dd33bf54d981dd7abaf056f17f7162 Mon Sep 17 00:00:00 2001 From: Bailey Danyluk Date: Thu, 5 Sep 2024 00:02:31 -0600 Subject: [PATCH 03/24] Missileguidance - Fix Javelin flight profile (#10269) Co-authored-by: Grim <69561145+LinkIsGrim@users.noreply.github.com> Co-authored-by: PabstMirror --- .../compat_cup_weapons_javelin/CfgAmmo.hpp | 49 +++++++++++++++---- .../compat_rhs_usf3_javelin/CfgAmmo.hpp | 25 ++++++++-- .../functions/fnc_midCourseTransition.sqf | 1 + addons/missileguidance/CfgAmmo.hpp | 4 +- .../functions/fnc_attackProfile_JAV_DIR.sqf | 22 ++++++--- .../functions/fnc_attackProfile_JAV_TOP.sqf | 44 +++++++++++------ .../functions/fnc_guidancePFH.sqf | 2 +- .../fnc_javelin_midCourseTransition.sqf | 19 ++++++- .../functions/fnc_navigationType_direct.sqf | 21 ++++++-- 9 files changed, 145 insertions(+), 42 deletions(-) diff --git a/addons/compat_cup_weapons/compat_cup_weapons_javelin/CfgAmmo.hpp b/addons/compat_cup_weapons/compat_cup_weapons_javelin/CfgAmmo.hpp index 2632a43e61e..220af016575 100644 --- a/addons/compat_cup_weapons/compat_cup_weapons_javelin/CfgAmmo.hpp +++ b/addons/compat_cup_weapons/compat_cup_weapons_javelin/CfgAmmo.hpp @@ -7,20 +7,51 @@ class CfgAmmo { class ace_missileguidance { enabled = 1; - minDeflection = 0.00005; - maxDeflection = 0.025; - incDeflection = 0.00005; + + pitchRate = 120; // degrees per second + yawRate = 120; + stabilityCoefficient = 0.2; + bangBangGuidance = 0; + canVanillaLock = 0; + + // Guidance type for munitions defaultSeekerType = "Optic"; - seekerTypes[] = {"Optic"}; + seekerTypes[] = { "Optic" }; + defaultSeekerLockMode = "LOBL"; - seekerLockModes[] = {"LOBL"}; - seekerAngle = 180; - seekerAccuracy = 1; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "Direct"; + navigationTypes[] = { "Direct", "ZeroEffortMiss" }; + + navigationGain = 3; + + seekerAngle = 180; // Angle in front of the missile which can be searched + seekerAccuracy = 1; // seeker accuracy multiplier + seekerMinRange = 0; - seekerMaxRange = 2500; + seekerMaxRange = 2500; // Range from the missile which the seeker can visually search + + seekLastTargetPos = 1; // seek last target position [if seeker loses LOS of target, continue to last known pos] + + // Attack profile type selection defaultAttackProfile = "JAV_TOP"; - attackProfiles[] = {"JAV_TOP", "JAV_DIR"}; + attackProfiles[] = { "JAV_TOP", "JAV_DIR" }; + useModeForAttackProfile = 1; + + class navigationStates { + class initial { + transitionCondition = QEFUNC(missileguidance,javelin_midCourseTransition); + navigationType = "Direct"; + }; + class terminal { + transitionCondition = ""; + navigationType = "ZeroEffortMiss"; + }; + // transitions from initial -> termimal + states[] = {"initial", "terminal"}; + }; }; }; }; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_javelin/CfgAmmo.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_javelin/CfgAmmo.hpp index 65ca880587f..b0df767e3a0 100644 --- a/addons/compat_rhs_usf3/compat_rhs_usf3_javelin/CfgAmmo.hpp +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_javelin/CfgAmmo.hpp @@ -9,9 +9,10 @@ class CfgAmmo { class ace_missileguidance { enabled = 1; - minDeflection = 0.00005; // Minium flap deflection for guidance - maxDeflection = 0.025; // Maximum flap deflection for guidance - incDeflection = 0.00005; // The incrmeent in which deflection adjusts. + pitchRate = 120; // degrees per second + yawRate = 120; + stabilityCoefficient = 0.2; + bangBangGuidance = 0; canVanillaLock = 0; @@ -22,6 +23,11 @@ class CfgAmmo { defaultSeekerLockMode = "LOBL"; seekerLockModes[] = { "LOBL" }; + defaultNavigationType = "Direct"; + navigationTypes[] = { "Direct", "ZeroEffortMiss" }; + + navigationGain = 3; + seekerAngle = 180; // Angle in front of the missile which can be searched seekerAccuracy = 1; // seeker accuracy multiplier @@ -34,6 +40,19 @@ class CfgAmmo { defaultAttackProfile = "JAV_TOP"; attackProfiles[] = { "JAV_TOP", "JAV_DIR" }; useModeForAttackProfile = 1; + + class navigationStates { + class initial { + transitionCondition = QEFUNC(missileguidance,javelin_midCourseTransition); + navigationType = "Direct"; + }; + class terminal { + transitionCondition = ""; + navigationType = "ZeroEffortMiss"; + }; + // transitions from initial -> termimal + states[] = {"initial", "terminal"}; + }; }; }; }; diff --git a/addons/hellfire/functions/fnc_midCourseTransition.sqf b/addons/hellfire/functions/fnc_midCourseTransition.sqf index ee567734103..034bd25d61a 100644 --- a/addons/hellfire/functions/fnc_midCourseTransition.sqf +++ b/addons/hellfire/functions/fnc_midCourseTransition.sqf @@ -15,6 +15,7 @@ * Public: No */ +params ["_args", "_timestep"]; _args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams", "_targetData", "_navigationStateData"]; _firedEH params ["_shooter","","","","_ammo","","_projectile"]; _launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo","_navigationType"]; diff --git a/addons/missileguidance/CfgAmmo.hpp b/addons/missileguidance/CfgAmmo.hpp index d9813fdf772..8f913e99656 100644 --- a/addons/missileguidance/CfgAmmo.hpp +++ b/addons/missileguidance/CfgAmmo.hpp @@ -71,8 +71,8 @@ class CfgAmmo { class ADDON { enabled = 1; - pitchRate = 100; // degrees per second - yawRate = 100; + pitchRate = 120; // degrees per second + yawRate = 120; stabilityCoefficient = 0.2; bangBangGuidance = 0; diff --git a/addons/missileguidance/functions/fnc_attackProfile_JAV_DIR.sqf b/addons/missileguidance/functions/fnc_attackProfile_JAV_DIR.sqf index 6b06c0dd915..64895a3e54a 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_JAV_DIR.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_JAV_DIR.sqf @@ -22,6 +22,9 @@ #define STAGE_COAST 3 #define STAGE_TERMINAL 4 +#define CLIMB_ANGLE 12 +#define ATTACK_ANGLE 2 + params ["_seekerTargetPos", "_args", "_attackProfileStateParams"]; _args params ["_firedEH"]; _firedEH params ["_shooter","","","","","","_projectile"]; @@ -30,6 +33,7 @@ if (_seekerTargetPos isEqualTo [0,0,0]) exitWith {_seekerTargetPos}; if (_attackProfileStateParams isEqualTo []) then { _attackProfileStateParams set [0, STAGE_LAUNCH]; + _attackProfileStateParams set [1, 0]; }; private _shooterPos = getPosASL _shooter; @@ -44,24 +48,28 @@ TRACE_2("",_distanceToTarget,_distanceToShooter); // Add height depending on distance for compensate private _returnTargetPos = _seekerTargetPos; +private _attackDirection = _seekerTargetPos vectorDiff _projectilePos; +private _horizon = velocity _projectile; +_horizon set [2, 0]; +_horizon = vectorNormalized _horizon; +private _attackAngle = acos (_horizon vectorCos _attackDirection); + switch (_attackProfileStateParams select 0) do { case STAGE_LAUNCH: { TRACE_1("STAGE_LAUNCH",""); if (_distanceToShooter < 6) then { - _returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget*2]; + _returnTargetPos = _seekerTargetPos vectorAdd [0,0,5]; } else { _attackProfileStateParams set [0, STAGE_CLIMB]; }; }; case STAGE_CLIMB: { TRACE_1("STAGE_CLIMB",""); - // 65 is min range - private _cruisAlt = 60 * ((0 max (_distanceShooterToTarget - 65))/2000); - - if ( ((ASLToAGL _projectilePos) select 2) - ((ASLToAGL _seekerTargetPos) select 2) >= _cruisAlt) then { + if (_attackAngle >= ATTACK_ANGLE) then { _attackProfileStateParams set [0, STAGE_TERMINAL]; } else { - _returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget*1.5]; + private _height = _distanceShooterToTarget * tan CLIMB_ANGLE; + _returnTargetPos = _seekerTargetPos vectorAdd [0,0,_height]; }; }; case STAGE_TERMINAL: { @@ -70,5 +78,7 @@ switch (_attackProfileStateParams select 0) do { }; }; +_attackProfileStateParams set [2, _returnTargetPos]; + TRACE_1("Adjusted target position",_returnTargetPos); _returnTargetPos; diff --git a/addons/missileguidance/functions/fnc_attackProfile_JAV_TOP.sqf b/addons/missileguidance/functions/fnc_attackProfile_JAV_TOP.sqf index 347d1449140..a3ae233eba0 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_JAV_TOP.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_JAV_TOP.sqf @@ -22,6 +22,10 @@ #define STAGE_COAST 3 #define STAGE_TERMINAL 4 +#define CRUISE_ALT 160 +#define CLIMB_ANGLE 22 +#define ATTACK_ANGLE 12 + params ["_seekerTargetPos", "_args", "_attackProfileStateParams"]; _args params ["_firedEH"]; _firedEH params ["_shooter","","","","","","_projectile"]; @@ -30,6 +34,7 @@ if (_seekerTargetPos isEqualTo [0,0,0]) exitWith {_seekerTargetPos}; if (_attackProfileStateParams isEqualTo []) then { _attackProfileStateParams set [0, STAGE_LAUNCH]; + _attackProfileStateParams set [1, 0]; }; private _shooterPos = getPosASL _shooter; @@ -44,39 +49,44 @@ TRACE_2("",_distanceToTarget,_distanceToShooter); // Add height depending on distance for compensate private _returnTargetPos = _seekerTargetPos; +private _attackDirection = _seekerTargetPos vectorDiff _projectilePos; +private _horizon = velocity _projectile; +_horizon set [2, 0]; +_horizon = vectorNormalized _horizon; +private _attackAngle = acos (_horizon vectorCos _attackDirection); + switch( (_attackProfileStateParams select 0) ) do { case STAGE_LAUNCH: { TRACE_1("STAGE_LAUNCH",""); if (_distanceToShooter < 10) then { - _returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget*2]; + _returnTargetPos = _seekerTargetPos vectorAdd [0,0,5]; } else { _attackProfileStateParams set [0, STAGE_CLIMB]; }; }; case STAGE_CLIMB: { TRACE_1("STAGE_CLIMB",""); - private _cruisAlt = 140; - if (_distanceShooterToTarget < 1250) then { - _cruisAlt = 140 * ((0 max (_distanceShooterToTarget - 150))/1250); - TRACE_1("_cruisAlt",_cruisAlt); - }; - if ( ((ASLToAGL _projectilePos) select 2) - ((ASLToAGL _seekerTargetPos) select 2) >= _cruisAlt) then { - if (_cruisAlt < 140) then { - _attackProfileStateParams set [0, STAGE_TERMINAL]; - } else { + private _altitude = (ASLToAGL _projectilePos) select 2; + switch (true) do { + case (_altitude >= CRUISE_ALT): { _attackProfileStateParams set [0, STAGE_COAST]; }; - } else { - _returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget*1.5]; - }; + case (_attackAngle >= ATTACK_ANGLE): { + _attackProfileStateParams set [0, STAGE_TERMINAL]; + }; + default { + private _height = _distanceShooterToTarget * tan CLIMB_ANGLE; + _returnTargetPos = _seekerTargetPos vectorAdd [0,0,_height]; + } + } }; case STAGE_COAST: { TRACE_1("STAGE_COAST",""); - TRACE_1("",((ASLToAGL _projectilePos) select 2) - (( ASLToAGL _seekerTargetPos) select 2)); - if (_distanceToTarget < ( ((ASLToAGL _projectilePos) select 2) - (( ASLToAGL _seekerTargetPos) select 2) ) * 2) then { + TRACE_1("",_attackAngle); + if (_attackAngle >= ATTACK_ANGLE) then { _attackProfileStateParams set [0, STAGE_TERMINAL]; } else { - _returnTargetPos = _seekerTargetPos vectorAdd [0,0,(_projectilePos select 2)]; + _returnTargetPos = _seekerTargetPos vectorAdd [0,0,(_projectilePos select 2) min CRUISE_ALT]; }; }; case STAGE_TERMINAL: { @@ -86,5 +96,7 @@ switch( (_attackProfileStateParams select 0) ) do { }; }; +_attackProfileStateParams set [2, _returnTargetPos]; + TRACE_1("Adjusted target position",_returnTargetPos); _returnTargetPos; diff --git a/addons/missileguidance/functions/fnc_guidancePFH.sqf b/addons/missileguidance/functions/fnc_guidancePFH.sqf index 2615d9061a7..8b8df3d5114 100644 --- a/addons/missileguidance/functions/fnc_guidancePFH.sqf +++ b/addons/missileguidance/functions/fnc_guidancePFH.sqf @@ -54,7 +54,7 @@ if ((_pitchRate != 0 || {_yawRate != 0})) then { private _navigationFunction = getText (configFile >> QGVAR(NavigationTypes) >> _navigationType >> "functionName"); if (_navigationStateData isNotEqualTo []) then { (_navigationStateData select _currentState) params ["_transitionCondition"]; - private _transition = (_args call (missionNamespace getVariable [_transitionCondition, { false }])); + private _transition = ([_args, _timestep] call (missionNamespace getVariable [_transitionCondition, { false }])); if (_transition) then { _currentState = _currentState + 1; _navigationStateParams set [0, _currentState]; diff --git a/addons/missileguidance/functions/fnc_javelin_midCourseTransition.sqf b/addons/missileguidance/functions/fnc_javelin_midCourseTransition.sqf index ad0eca65cba..58995dee31d 100644 --- a/addons/missileguidance/functions/fnc_javelin_midCourseTransition.sqf +++ b/addons/missileguidance/functions/fnc_javelin_midCourseTransition.sqf @@ -19,6 +19,10 @@ #define STAGE_COAST 3 #define STAGE_TERMINAL 4 +#define REQUIRED_STABLE_TIME 0.2 +#define REQUIRED_ANGLE 1 + +params ["_args", "_timestep"]; _args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams", "_targetData", "_navigationStateData"]; _firedEH params ["_shooter","","","","_ammo","","_projectile"]; _launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo","_navigationType"]; @@ -28,6 +32,17 @@ _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateP _seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange", "_seekerMinRange"]; _targetData params ["_targetDirection", "_attackProfileDirection", "_targetRange", "_targetVelocity", "_targetAcceleration"]; -_attackProfileStateParams params ["_state"]; -_state isEqualTo STAGE_TERMINAL +_attackProfileStateParams params ["_state", "_stableTime", "_target"]; +private _projectileDirection = vectorNormalized velocity _projectile; +private _targetDistance = _target vectorDistance getPosASLVisual _projectile; +private _targetDirection = (getPosASLVisual _projectile) vectorFromTo _target; +private _angle = _projectileDirection vectorCos _targetDirection; +if (_angle > cos REQUIRED_ANGLE) then { + _stableTime = _stableTime + _timestep; +} else { + _stableTime = 0; +}; + +_attackProfileStateParams set [1, _stableTime]; +_state isEqualTo STAGE_TERMINAL && _stableTime > REQUIRED_STABLE_TIME diff --git a/addons/missileguidance/functions/fnc_navigationType_direct.sqf b/addons/missileguidance/functions/fnc_navigationType_direct.sqf index 7b4763b44ef..5681c85b9ae 100644 --- a/addons/missileguidance/functions/fnc_navigationType_direct.sqf +++ b/addons/missileguidance/functions/fnc_navigationType_direct.sqf @@ -14,8 +14,23 @@ * * Public: No */ -params ["_args", "", "", "_profileAdjustedTargetPos"]; -_args params ["_firedEH"]; +params ["_args", "_timestep", "", "_profileAdjustedTargetPos"]; +_args params ["_firedEH", "", "_flightParams"]; +_flightParams params ["_pitchRate", "_yawRate"]; _firedEH params ["","","","","","","_projectile"]; -_profileAdjustedTargetPos vectorDiff getPosASLVisual _projectile +private _projectilePos = getPosASLVisual _projectile; + +private _targetDirection = _projectilePos vectorFromTo _profileAdjustedTargetPos; +private _projectileDirection = vectorNormalized velocity _projectile; + +private _deltaDirection = _targetDirection vectorDiff _projectileDirection; +_deltaDirection = _projectile vectorWorldToModelVisual _deltaDirection; +_deltaDirection = _deltaDirection vectorMultiply [_yawRate, 0, _pitchRate]; +_deltaDirection = _projectile vectorModelToWorldVisual _deltaDirection; + +private _iTimestep = 0; +if (_timestep != 0) then { + _iTimestep = 1 / _timestep; +}; +_deltaDirection vectorMultiply _iTimestep // return From e23a26da1c0ca940b5e4c03aa9661cf3868b91c0 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Thu, 5 Sep 2024 20:07:39 +0200 Subject: [PATCH 04/24] General - Use `findAny` where possible (#10292) Use `findAny` --- addons/medical_treatment/functions/fnc_hasItem.sqf | 2 +- addons/trenches/functions/fnc_hasEntrenchingTool.sqf | 2 +- addons/vehiclelock/functions/fnc_hasKeyForVehicle.sqf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/medical_treatment/functions/fnc_hasItem.sqf b/addons/medical_treatment/functions/fnc_hasItem.sqf index e0ef4c8a4fe..8faea65652f 100644 --- a/addons/medical_treatment/functions/fnc_hasItem.sqf +++ b/addons/medical_treatment/functions/fnc_hasItem.sqf @@ -31,7 +31,7 @@ private _fnc_checkItems = { _unitItems append (itemCargo _unitVehicle); _unitItems append (magazineCargo _unitVehicle); }; - _items findIf {_x in _unitItems} != -1 + _items findAny _unitItems != -1 }; _medic call _fnc_checkItems || {GVAR(allowSharedEquipment) != 2 && {_patient call _fnc_checkItems}} diff --git a/addons/trenches/functions/fnc_hasEntrenchingTool.sqf b/addons/trenches/functions/fnc_hasEntrenchingTool.sqf index 5a1127d0072..1568801fdb8 100644 --- a/addons/trenches/functions/fnc_hasEntrenchingTool.sqf +++ b/addons/trenches/functions/fnc_hasEntrenchingTool.sqf @@ -23,4 +23,4 @@ private _uniqueItems = _unit call EFUNC(common,uniqueItems); _uniqueItems append weapons _unit; _uniqueItems pushBack backpack _unit; -GVAR(entrenchingTools) findIf {_x in _uniqueItems} != -1 // return +GVAR(entrenchingTools) findAny _uniqueItems != -1 // return diff --git a/addons/vehiclelock/functions/fnc_hasKeyForVehicle.sqf b/addons/vehiclelock/functions/fnc_hasKeyForVehicle.sqf index c5f7e0e35a0..ec58a6fa2c5 100644 --- a/addons/vehiclelock/functions/fnc_hasKeyForVehicle.sqf +++ b/addons/vehiclelock/functions/fnc_hasKeyForVehicle.sqf @@ -34,4 +34,4 @@ if (_sideKeyName in _items) exitWith {true}; private _customKeys = _veh getVariable [QGVAR(customKeys), []]; private _magazines = magazinesDetail _unit; -(_customKeys findIf {_x in _magazines}) != -1 +_customKeys findAny _magazines != -1 From e4d09689e3339c9671498c7d0a46975378a1205e Mon Sep 17 00:00:00 2001 From: Timi007 Date: Sat, 7 Sep 2024 05:42:50 +0200 Subject: [PATCH 05/24] CI - Fix HEMTT CI artifacts not uploaded (#10294) * Fix HEMTT CI annotations not shown * Fix HEMTT artifacts not uploaded * Revert "Fix HEMTT CI annotations not shown" This reverts commit 278ddba68e7ebd3fe017132491e8d55ba592ee5c. * Bump up actions/upload-artifact to v4 --- .github/workflows/arma.yml | 1 + .github/workflows/extensions.yml | 2 +- .github/workflows/hemtt.yml | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/arma.yml b/.github/workflows/arma.yml index 3ddfefd63fa..1af2e7e0602 100644 --- a/.github/workflows/arma.yml +++ b/.github/workflows/arma.yml @@ -43,3 +43,4 @@ jobs: with: name: ace3-${{ github.sha }}-nobin path: .hemttout/@* + include-hidden-files: true # Because .hemttout is a hidden directory diff --git a/.github/workflows/extensions.yml b/.github/workflows/extensions.yml index 8cafd847e26..ce475e5a006 100644 --- a/.github/workflows/extensions.yml +++ b/.github/workflows/extensions.yml @@ -57,7 +57,7 @@ jobs: - name: Build run: cargo build --verbose - name: Upload - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: ${{ matrix.arrays.os.target }} path: target/debug/ace.dll diff --git a/.github/workflows/hemtt.yml b/.github/workflows/hemtt.yml index 23fad275602..79286fc45c3 100644 --- a/.github/workflows/hemtt.yml +++ b/.github/workflows/hemtt.yml @@ -44,3 +44,4 @@ jobs: with: name: ace3-${{ github.sha }} path: .hemttout/@* + include-hidden-files: true # Because .hemttout is a hidden directory From e560036e2cc4a324715ef011e0ba54c729b3a565 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Sat, 7 Sep 2024 13:49:44 -0500 Subject: [PATCH 06/24] Reload - Change "Check Ammo" anim to not block movement (#10293) --- addons/reload/functions/fnc_checkAmmo.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/reload/functions/fnc_checkAmmo.sqf b/addons/reload/functions/fnc_checkAmmo.sqf index f558d917699..8039c9527ca 100644 --- a/addons/reload/functions/fnc_checkAmmo.sqf +++ b/addons/reload/functions/fnc_checkAmmo.sqf @@ -23,7 +23,7 @@ if (_unit == _target) then { _target = vehicle _target; }; - [_unit, "Gear", 1] call EFUNC(common,doGesture); + [_unit, "reloadMagazine", 0] call EFUNC(common,doGesture); }; [FUNC(displayAmmo), _target, 1] call CBA_fnc_waitAndExecute; From e2335c9333e47cc39b1c98cd7dab6098440abc0e Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Sat, 7 Sep 2024 20:54:21 +0200 Subject: [PATCH 07/24] Dragging - Corpse carrying and dragging - continued (#9273) Co-authored-by: Dystopian Co-authored-by: Grim <69561145+LinkIsGrim@users.noreply.github.com> Co-authored-by: Joko Co-authored-by: PabstMirror Co-authored-by: BaerMitUmlaut Co-authored-by: LinkIsGrim --- addons/dragging/CfgVehicles.hpp | 3 + addons/dragging/XEH_PREP.hpp | 2 + addons/dragging/XEH_postInit.sqf | 66 ++++++++++++ addons/dragging/functions/fnc_canCarry.sqf | 20 ++-- addons/dragging/functions/fnc_canDrag.sqf | 20 ++-- addons/dragging/functions/fnc_createClone.sqf | 101 ++++++++++++++++++ addons/dragging/functions/fnc_deleteClone.sqf | 80 ++++++++++++++ .../dragging/functions/fnc_dragObjectPFH.sqf | 5 + addons/dragging/functions/fnc_dropObject.sqf | 8 +- .../functions/fnc_dropObject_carry.sqf | 9 +- .../functions/fnc_handleAnimChanged.sqf | 2 +- addons/dragging/functions/fnc_startCarry.sqf | 1 + .../functions/fnc_startCarryLocal.sqf | 5 + addons/dragging/functions/fnc_startDrag.sqf | 1 + .../dragging/functions/fnc_startDragLocal.sqf | 5 + .../fnc_displayPatientInformation.sqf | 1 + addons/medical_gui/functions/fnc_menuPFH.sqf | 2 + .../functions/fnc_addInventoryActions.sqf | 1 + docs/wiki/feature/dragging.md | 4 +- docs/wiki/framework/dragging-framework.md | 24 +++++ docs/wiki/framework/events-framework.md | 9 +- 21 files changed, 348 insertions(+), 21 deletions(-) create mode 100644 addons/dragging/functions/fnc_createClone.sqf create mode 100644 addons/dragging/functions/fnc_deleteClone.sqf diff --git a/addons/dragging/CfgVehicles.hpp b/addons/dragging/CfgVehicles.hpp index 395133e9464..bd9758447bf 100644 --- a/addons/dragging/CfgVehicles.hpp +++ b/addons/dragging/CfgVehicles.hpp @@ -3,6 +3,9 @@ class CBA_Extended_EventHandlers; class CfgVehicles { + class C_man_1; + class GVAR(clone): C_man_1 {}; + // Static weapons class LandVehicle; class StaticWeapon: LandVehicle { diff --git a/addons/dragging/XEH_PREP.hpp b/addons/dragging/XEH_PREP.hpp index 0861c9533d2..aeba3135ab5 100644 --- a/addons/dragging/XEH_PREP.hpp +++ b/addons/dragging/XEH_PREP.hpp @@ -5,6 +5,8 @@ PREP(canDrop_carry); PREP(canRun_carry); PREP(carryObject); PREP(carryObjectPFH); +PREP(createClone); +PREP(deleteClone); PREP(dragObject); PREP(dragObjectPFH); PREP(dropObject); diff --git a/addons/dragging/XEH_postInit.sqf b/addons/dragging/XEH_postInit.sqf index 5c66fe692c8..48655c5833a 100644 --- a/addons/dragging/XEH_postInit.sqf +++ b/addons/dragging/XEH_postInit.sqf @@ -1,9 +1,62 @@ // by PabstMirror, commy2 #include "script_component.hpp" +[QGVAR(moveCorpse), { + params ["_corpse", "_dir", "_posATL"]; + + if (isNull _corpse) exitWith {}; + + // Check if the corpse is already close to the target + // If so, don't teleport + if ((getPosATL _corpse) distance _posATL > 0.25) then { + // Set direction before position + _corpse setDir _dir; + + // Bring corpse back to clone's position + _corpse setPosATL _posATL; + }; + + // Sync the corpse with its position + [{ + _this awake true; + + [{ + _this awake false; + }, _this] call CBA_fnc_execNextFrame; + }, _corpse] call CBA_fnc_execNextFrame; + + // Allow the corpse to be synced for JIP players + if (isServer) exitWith { + GVAR(movedCorpses) pushBackUnique _corpse; + }; +}] call CBA_fnc_addEventHandler; + if (isServer) then { // Release object on disconnection. Function is identical to killed addMissionEventHandler ["HandleDisconnect", LINKFUNC(handleKilled)]; + + GVAR(movedCorpses) = []; + + ["CAManBase", "Deleted", { + GVAR(movedCorpses) deleteAt (GVAR(movedCorpses) find (_this select 0)); + }, true, [], true] call CBA_fnc_addClassEventHandler; + + [QGVAR(disableSyncMovedCorpseOnJIP), { + params ["_corpse"]; + + GVAR(movedCorpses) deleteAt (GVAR(movedCorpses) find _corpse); + }] call CBA_fnc_addEventHandler; + + // Sync position of dead corpse for JIP unit (prevents weird invisible hitboxes on corpses) + [QGVAR(requestSyncMovedCorpsesJIP), { + params ["_clientOwner"]; + + { + [QGVAR(moveCorpse), [_x, getDir _x, getPosATL _x], _clientOwner] call CBA_fnc_ownerEvent; + } forEach GVAR(movedCorpses); + }] call CBA_fnc_addEventHandler; +} else { + [QGVAR(requestSyncMovedCorpsesJIP), clientOwner] call CBA_fnc_serverEvent; }; if (!hasInterface) exitWith {}; @@ -20,6 +73,11 @@ if (isNil QGVAR(maxWeightCarryRun)) then { GVAR(maxWeightCarryRun) = 50; }; +// Extended EH doesn't fire for dead units, so add interactions manually +{ + _x call FUNC(initPerson); +} forEach allDeadMen; + ["isNotDragging", {!((_this select 0) getVariable [QGVAR(isDragging), false])}] call EFUNC(common,addCanInteractWithCondition); ["isNotCarrying", {!((_this select 0) getVariable [QGVAR(isCarrying), false])}] call EFUNC(common,addCanInteractWithCondition); @@ -57,6 +115,14 @@ if (isNil QGVAR(maxWeightCarryRun)) then { // Display event handler ["MouseZChanged", {(_this select 1) call FUNC(handleScrollWheel)}] call CBA_fnc_addDisplayHandler; +// Handle local effect commands for clones +[QGVAR(setCloneFace), { + params ["_clone", "_corpse"]; + + _clone setFace face _corpse; + _clone setMimic "unconscious"; +}] call CBA_fnc_addEventHandler; + // Handle surrendering and handcuffing ["ace_captiveStatusChanged", { params ["_unit", "_state"]; diff --git a/addons/dragging/functions/fnc_canCarry.sqf b/addons/dragging/functions/fnc_canCarry.sqf index be3015868b5..a38f37a02ee 100644 --- a/addons/dragging/functions/fnc_canCarry.sqf +++ b/addons/dragging/functions/fnc_canCarry.sqf @@ -18,7 +18,10 @@ params ["_unit", "_target"]; -if !(alive _target && {_target getVariable [QGVAR(canCarry), false]} && {isNull objectParent _target}) exitWith {false}; +private _alive = alive _target; +private _isPerson = _target isKindOf "CAManBase"; + +if !((_alive || _isPerson) && {_target getVariable [QGVAR(canCarry), false]} && {isNull objectParent _target}) exitWith {false}; if !([_unit, _target, []] call EFUNC(common,canInteractWith)) exitWith {false}; @@ -26,18 +29,19 @@ if !([_unit, _target, []] call EFUNC(common,canInteractWith)) exitWith {false}; // The fireman carry animation does not slow down for injured legs, so you could carry and run if ((_unit getHitPointDamage "HitLegs") >= 0.5) exitWith {false}; +// Units need to be unconscious or limping; Units also need to not be in ragdoll if alive, as that causes desync issues +if (_isPerson) exitWith { + ((!_alive) && {missionNamespace getVariable [QGVAR(canMoveDead), true]}) || + {(isAwake _target) && // not ragdolled if alive + {!(_target call EFUNC(common,isAwake)) || + {_target getHitPointDamage "HitLegs" >= 0.5}}} +}; + // Static weapons need to be empty for carrying (ignore UAV AI) if (_target isKindOf "StaticWeapon") exitWith { (crew _target) findIf {!unitIsUAV _x} == -1 }; -// Units need to be unconscious or limping; Units also need to not be in ragdoll, as that causes desync issues -if (_target isKindOf "CAManBase") exitWith { - isAwake _target && // not ragdolled - {lifeState _target == "INCAPACITATED" || - {_target getHitPointDamage "HitLegs" >= 0.5}} -}; - // Check max items for WeaponHolders if (["WeaponHolder", "WeaponHolderSimulated"] findIf {_target isKindOf _x} != -1) exitWith { (count (weaponCargo _target + magazineCargo _target + itemCargo _target)) <= MAX_DRAGGED_ITEMS diff --git a/addons/dragging/functions/fnc_canDrag.sqf b/addons/dragging/functions/fnc_canDrag.sqf index 586e23feaf8..2616d6d1447 100644 --- a/addons/dragging/functions/fnc_canDrag.sqf +++ b/addons/dragging/functions/fnc_canDrag.sqf @@ -18,22 +18,26 @@ params ["_unit", "_target"]; -if !(alive _target && {_target getVariable [QGVAR(canDrag), false]} && {isNull objectParent _target}) exitWith {false}; +private _alive = alive _target; +private _isPerson = _target isKindOf "CAManBase"; + +if !((_alive || _isPerson) && {_target getVariable [QGVAR(canDrag), false]} && {isNull objectParent _target}) exitWith {false}; if !([_unit, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; +// Units need to be unconscious or limping; Units also need to not be in ragdoll if alive, as that causes desync issues +if (_isPerson) exitWith { + ((!_alive) && {missionNamespace getVariable [QGVAR(canMoveDead), true]}) || + {(isAwake _target) && // not ragdolled if alive + {!(_target call EFUNC(common,isAwake)) || + {_target getHitPointDamage "HitLegs" >= 0.5}}} +}; + // Static weapons need to be empty for dragging (ignore UAV AI) if (_target isKindOf "StaticWeapon") exitWith { (crew _target) findIf {!unitIsUAV _x} == -1 }; -// Units need to be unconscious or limping; Units also need to not be in ragdoll, as that causes desync issues -if (_target isKindOf "CAManBase") exitWith { - isAwake _target && // not ragdolled - {lifeState _target == "INCAPACITATED" || - {_target getHitPointDamage "HitLegs" >= 0.5}} -}; - // Check max items for WeaponHolders if (["WeaponHolder", "WeaponHolderSimulated"] findIf {_target isKindOf _x} != -1) exitWith { (count (weaponCargo _target + magazineCargo _target + itemCargo _target)) <= MAX_DRAGGED_ITEMS diff --git a/addons/dragging/functions/fnc_createClone.sqf b/addons/dragging/functions/fnc_createClone.sqf new file mode 100644 index 00000000000..6cb4aa0ec69 --- /dev/null +++ b/addons/dragging/functions/fnc_createClone.sqf @@ -0,0 +1,101 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut, johnb43 + * Creates a draggable / carryable clone of a dead unit. + * + * Arguments: + * 0: Unit dragging/carrying + * 1: Dead unit + * + * Return Value: + * Cloned unit + * + * Example: + * [player, cursorObject] call ace_dragging_fnc_createClone; + * + * Public: No + */ + +params ["_unit", "_target"]; + +// Don't sync corpse when a player joins in progress until the corpse is in its proper position +[QGVAR(disableSyncMovedCorpseOnJIP), _target] call CBA_fnc_serverEvent; + +private _posATL = getPosATL _target; + +// Create clone +private _clone = createVehicle [[configOf _target >> QGVAR(cloneClass), "TEXT", QGVAR(clone)] call CBA_fnc_getConfigEntry, _posATL, [], 0, "CAN_COLLIDE"]; + +// Claim the clone +[_unit, _clone] call EFUNC(common,claim); + +// Move unit -10 m below terrain in order to hide it and remove its inventory access +_posATL set [2, -10]; + +// Corpse is desynced, but it doesn't matter here +_target setPosATL _posATL; + +// Hide unit until it can be moved below terrain +private _isObjectHidden = isObjectHidden _target; + +if (!_isObjectHidden) then { + [QEGVAR(common,hideObjectGlobal), [_target, true]] call CBA_fnc_serverEvent; +}; + +// Prevents unit from falling when below terrain +private _simulationEnabled = simulationEnabled _target; + +if (_simulationEnabled) then { + [QEGVAR(common,enableSimulationGlobal), [_target, false]] call CBA_fnc_serverEvent; +}; + +private _isInRemainsCollector = isInRemainsCollector _target; + +// Make sure corpse isn't deleted by engine's garbage collector +if (_isInRemainsCollector) then { + removeFromRemainsCollector [_target]; +}; + +// Make sure clone has the same wound textures as the corpse +_clone setDamage ((damage _target) min 0.99); // Don't kill the clone + +{ + _clone setHitPointDamage [_x, (_target getHitPointDamage _x) min 0.99]; +} forEach ["HitHead", "HitBody", "HitHands", "HitLegs"]; // Relevant hitpoints + +// Disable all damage +_clone allowDamage false; +_clone setVariable [QGVAR(original), [_target, _isInRemainsCollector, _isObjectHidden, _simulationEnabled], true]; + +[_clone, _target call CBA_fnc_getLoadout] call CBA_fnc_setLoadout; + +// Sets the facial expression +[[QGVAR(setCloneFace), [_clone, _target]] call CBA_fnc_globalEventJIP, _clone] call CBA_fnc_removeGlobalEventJIP; + +// API +[QGVAR(cloneCreated), [_clone, _target]] call CBA_fnc_localEvent; + +[{ + params ["_clone", "_target"]; + + // Remove clone from all zeuses + if (["ace_zeus"] call EFUNC(common,isModLoaded)) then { + [QEGVAR(zeus,removeObjects), [[_clone]]] call CBA_fnc_serverEvent; + }; + + // Release claim on corpse + [objNull, _target] call EFUNC(common,claim); +}, [_clone, _target], 0.25] call CBA_fnc_waitAndExecute; + +// Save which curators had this object as editable +if (["ace_zeus"] call EFUNC(common,isModLoaded)) then { + private _objectCurators = objectCurators _target; + + _target setVariable [QGVAR(objectCurators), _objectCurators, true]; + + if (_objectCurators isEqualTo []) exitWith {}; + + [QEGVAR(zeus,removeObjects), [[_target], _objectCurators]] call CBA_fnc_serverEvent; +}; + +_clone diff --git a/addons/dragging/functions/fnc_deleteClone.sqf b/addons/dragging/functions/fnc_deleteClone.sqf new file mode 100644 index 00000000000..148b88a3a31 --- /dev/null +++ b/addons/dragging/functions/fnc_deleteClone.sqf @@ -0,0 +1,80 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut, johnb43 + * Drops a draggable / carryable clone of a dead unit. + * + * Arguments: + * 0: Unit dragging / carrying + * 1: Clone + * 2: If unit is in building + * + * Return Value: + * Original unit + * + * Example: + * [player, cursorObject, false] call ace_dragging_fnc_deleteClone; + * + * Public: No + */ + +params ["_unit", "_clone", "_inBuilding"]; + +(_clone getVariable [QGVAR(original), []]) params [ + ["_target", objNull], + ["_isInRemainsCollector", true], + ["_isObjectHidden", false], + ["_simulationEnabled", true] +]; + +// API +[QGVAR(cloneDeleted), [_clone, _target]] call CBA_fnc_localEvent; + +// Check if unit was deleted +if (!isNull _target) then { + private _posATL = getPosATL _clone; + + if (_inBuilding) then { + _posATL = _posATL vectorAdd [0, 0, 0.05]; + }; + + // Make sure position isn't underground + if (_posATL select 2 < 0.05) then { + _posATL set [2, 0.05]; + }; + + // Move the unit globally (important, as it desyncs the corpse position otherwise) + [QGVAR(moveCorpse), [_target, getDir _unit + 180, _posATL]] call CBA_fnc_globalEvent; + + // Unhide unit + if (!_isObjectHidden) then { + [QEGVAR(common,hideObjectGlobal), [_target, false]] call CBA_fnc_serverEvent; + }; + + // Enable simulation again + if (_simulationEnabled) then { + [QEGVAR(common,enableSimulationGlobal), [_target, true]] call CBA_fnc_serverEvent; + }; + + // Detach first to prevent objNull in attachedObjects + detach _clone; + deleteVehicle _clone; + + // Get which curators had this object as editable + if (["ace_zeus"] call EFUNC(common,isModLoaded)) then { + private _objectCurators = _target getVariable [QGVAR(objectCurators), []]; + + if (_objectCurators isEqualTo []) exitWith {}; + + [QEGVAR(zeus,addObjects), [[_target], _objectCurators]] call CBA_fnc_serverEvent; + }; + + if (_isInRemainsCollector) then { + addToRemainsCollector [_target]; + }; +} else { + // Detach first to prevent objNull in attachedObjects + detach _clone; + deleteVehicle _clone; +}; + +_target diff --git a/addons/dragging/functions/fnc_dragObjectPFH.sqf b/addons/dragging/functions/fnc_dragObjectPFH.sqf index 249f3866bb5..13400aa349f 100644 --- a/addons/dragging/functions/fnc_dragObjectPFH.sqf +++ b/addons/dragging/functions/fnc_dragObjectPFH.sqf @@ -62,3 +62,8 @@ if (_target isKindOf "StaticWeapon" && {((crew _target) - (_target getVariable [ _idPFH call CBA_fnc_removePerFrameHandler; }; + +// Clones can die of drowning if oxygen is under 0.5, so refill their oxygen from time to time +if (_target isKindOf QGVAR(clone) && {getOxygenRemaining _target < 0.8}) then { + _target setOxygenRemaining 1; +}; diff --git a/addons/dragging/functions/fnc_dropObject.sqf b/addons/dragging/functions/fnc_dropObject.sqf index 119eaf415af..965e3b9efa3 100644 --- a/addons/dragging/functions/fnc_dropObject.sqf +++ b/addons/dragging/functions/fnc_dropObject.sqf @@ -31,6 +31,12 @@ if (!GVAR(dragAndFire)) then { }; private _inBuilding = _unit call FUNC(isObjectOnObject); +private _isClone = _target isKindOf QGVAR(clone); + +// Drop cloned dead units +if (_isClone) then { + _target = [_unit, _target, _inBuilding] call FUNC(deleteClone); +}; // Play release animation if (_unit call EFUNC(common,isAwake)) then { @@ -57,7 +63,7 @@ _unit removeWeapon "ACE_FakePrimaryWeapon"; [_unit, "blockThrow", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); // Prevent object from flipping inside buildings -if (_inBuilding) then { +if (_inBuilding && {!_isClone}) then { _target setPosASL (getPosASL _target vectorAdd [0, 0, 0.05]); TRACE_2("setPos",getPosASL _unit,getPosASL _target); }; diff --git a/addons/dragging/functions/fnc_dropObject_carry.sqf b/addons/dragging/functions/fnc_dropObject_carry.sqf index d244d93a2ee..ba8cbd09f12 100644 --- a/addons/dragging/functions/fnc_dropObject_carry.sqf +++ b/addons/dragging/functions/fnc_dropObject_carry.sqf @@ -25,6 +25,12 @@ TRACE_1("params",_this); _unit setVariable [QGVAR(releaseActionID), nil]; private _inBuilding = _unit call FUNC(isObjectOnObject); +private _isClone = _target isKindOf QGVAR(clone); + +// Drop cloned dead units +if (_isClone) then { + _target = [_unit, _target, _inBuilding] call FUNC(deleteClone); +}; // Prevent collision damage [QEGVAR(common,fixCollision), _unit] call CBA_fnc_localEvent; @@ -72,8 +78,9 @@ if (!isNil "_previousWeaponState") then { [_unit, "blockThrow", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); // Prevent object from flipping inside buildings -if (_inBuilding) then { +if (_inBuilding && {!_isClone}) then { _target setPosASL (getPosASL _target vectorAdd [0, 0, 0.05]); + TRACE_2("setPos",getPosASL _unit,getPosASL _target); }; _unit setVariable [QGVAR(isCarrying), false, true]; diff --git a/addons/dragging/functions/fnc_handleAnimChanged.sqf b/addons/dragging/functions/fnc_handleAnimChanged.sqf index 24b8f582057..f89790d2e61 100644 --- a/addons/dragging/functions/fnc_handleAnimChanged.sqf +++ b/addons/dragging/functions/fnc_handleAnimChanged.sqf @@ -5,7 +5,7 @@ * * Arguments: * 0: Unit - * 1: Animaion + * 1: Animation * * Return Value: * None diff --git a/addons/dragging/functions/fnc_startCarry.sqf b/addons/dragging/functions/fnc_startCarry.sqf index 3e2cc17efde..99652fc263d 100644 --- a/addons/dragging/functions/fnc_startCarry.sqf +++ b/addons/dragging/functions/fnc_startCarry.sqf @@ -15,6 +15,7 @@ * * Public: No */ + params ["_unit", "_target"]; // Try to claim the object diff --git a/addons/dragging/functions/fnc_startCarryLocal.sqf b/addons/dragging/functions/fnc_startCarryLocal.sqf index 0f679f2d499..e7d102825aa 100644 --- a/addons/dragging/functions/fnc_startCarryLocal.sqf +++ b/addons/dragging/functions/fnc_startCarryLocal.sqf @@ -41,6 +41,11 @@ private _timer = CBA_missionTime + 5; // Handle objects vs. persons if (_target isKindOf "CAManBase") then { + // Create clone for dead units + if (!alive _target) then { + _target = [_unit, _target] call FUNC(createClone); + }; + private _primaryWeapon = primaryWeapon _unit; // Add a primary weapon if the unit has none diff --git a/addons/dragging/functions/fnc_startDrag.sqf b/addons/dragging/functions/fnc_startDrag.sqf index 8dd6db6dee5..d65f218acd7 100644 --- a/addons/dragging/functions/fnc_startDrag.sqf +++ b/addons/dragging/functions/fnc_startDrag.sqf @@ -15,6 +15,7 @@ * * Public: No */ + params ["_unit", "_target"]; // Try to claim the object diff --git a/addons/dragging/functions/fnc_startDragLocal.sqf b/addons/dragging/functions/fnc_startDragLocal.sqf index 20d5e007dbe..3abcef44305 100644 --- a/addons/dragging/functions/fnc_startDragLocal.sqf +++ b/addons/dragging/functions/fnc_startDragLocal.sqf @@ -90,6 +90,11 @@ if !(_unit call EFUNC(common,isSwimming)) then { // Move a bit closer and adjust direction when trying to pick up a person if (_target isKindOf "CAManBase") then { + // Create clone for dead units + if (!alive _target) then { + _target = [_unit, _target] call FUNC(createClone); + }; + [QEGVAR(common,setDir), [_target, getDir _unit + 180], _target] call CBA_fnc_targetEvent; _target setPosASL (getPosASL _unit vectorAdd (vectorDir _unit vectorMultiply 1.5)); diff --git a/addons/medical_gui/functions/fnc_displayPatientInformation.sqf b/addons/medical_gui/functions/fnc_displayPatientInformation.sqf index 65660eec798..abea0ec07bb 100644 --- a/addons/medical_gui/functions/fnc_displayPatientInformation.sqf +++ b/addons/medical_gui/functions/fnc_displayPatientInformation.sqf @@ -40,6 +40,7 @@ if (isNull _display) then { if (ACE_player distance _target > MAX_DISTANCE && {vehicle _target != vehicle ACE_player}) exitWith { [_pfhID] call CBA_fnc_removePerFrameHandler; QGVAR(RscPatientInfo) cutFadeOut 0.3; + if (((getPosATL _target) # 2) < -9) exitWith {}; // handle dragging corpse/clone [[ELSTRING(medical,DistanceToFar), _target call EFUNC(common,getName)], 2] call EFUNC(common,displayTextStructured); }; diff --git a/addons/medical_gui/functions/fnc_menuPFH.sqf b/addons/medical_gui/functions/fnc_menuPFH.sqf index b3d51c2dc9c..0e213eaf5ec 100644 --- a/addons/medical_gui/functions/fnc_menuPFH.sqf +++ b/addons/medical_gui/functions/fnc_menuPFH.sqf @@ -23,6 +23,8 @@ if !( closeDialog 0; // Show hint if distance condition failed if ((ACE_player distance GVAR(target) > GVAR(maxDistance)) && {vehicle ACE_player != vehicle GVAR(target)}) then { + if (((getPosATL GVAR(target)) # 2) < -9) exitWith {}; // handle dragging corpse/clone + [[ELSTRING(medical,DistanceToFar), GVAR(target) call EFUNC(common,getName)], 2] call EFUNC(common,displayTextStructured); }; }; diff --git a/addons/medical_status/functions/fnc_addInventoryActions.sqf b/addons/medical_status/functions/fnc_addInventoryActions.sqf index 8041eb06135..e4e65a31649 100644 --- a/addons/medical_status/functions/fnc_addInventoryActions.sqf +++ b/addons/medical_status/functions/fnc_addInventoryActions.sqf @@ -46,5 +46,6 @@ _unit addAction ["OpenBag", { {!lockedInventory _backpackContainer} && {maxLoad _backpackContainer > 0} && {getNumber (_backpackConfig >> "disableInventory") != 1} && + {!(_target isKindOf QEGVAR(dragging,clone))} && {_target setUserActionText [_actionId, format [localize "STR_ACTION_OPEN_BAG", getText (_backpackConfig >> "displayName")]]; true} }, 2]; diff --git a/docs/wiki/feature/dragging.md b/docs/wiki/feature/dragging.md index 0d42240a238..aa462d2e64d 100644 --- a/docs/wiki/feature/dragging.md +++ b/docs/wiki/feature/dragging.md @@ -20,7 +20,9 @@ This adds the option to drag or carry units or objects. ## 2. Usage ### 2.1 Dragging / Carrying units and objects -- You can only drag or carry an unconscious unit. +- You can drag or carry dead or unconscious units. These units can't be in a ragdoll state. +- You can drag or carry units whose legs are broken. +- You can't carry if you have broken legs. - Interact with the unit or object ⊞ Win (ACE3 default key bind `Interact Key`). - Select `Drag` or `Carry`. - To release, use the mouse wheel and select `Release` or use Self Interaction Ctrl+⊞ Win and select `Release`. diff --git a/docs/wiki/framework/dragging-framework.md b/docs/wiki/framework/dragging-framework.md index 56bfba2801a..256d41570d4 100644 --- a/docs/wiki/framework/dragging-framework.md +++ b/docs/wiki/framework/dragging-framework.md @@ -98,3 +98,27 @@ You will **not** be able to carry / drag objects that are too heavy, the mass is | 1 | `true`| Carrying is enabled | | 2 | `[0,2,0]` | 0 meters sideways, 3 meters forward, 1 meter upwards | | 3 | `10` | Rotated by 10° | + +## 3. Corpse moving +Added in 3.18.0, ACE allows you to drag and carry corpses. + +### 3.1 Config Values + +```cpp +class CfgVehicles { + class MyUnit { + ace_dragging_cloneClass = "MyClone"; // Allows you to define what type of clone is used for moving the corpse (default: "ace_dragging_clone") + }; + + class ace_dragging_clone; + class MyClone: ace_dragging_clone {}; // Custom clones must inherit from ace_dragging_clone +}; +``` + +### 3.2 Enabling / disabling corpse moving + +By default, corpse moving is enabled. If you wish to disable it, you can set the variable below to `false`: + +```sqf +ace_dragging_canMoveDead = false; +``` diff --git a/docs/wiki/framework/events-framework.md b/docs/wiki/framework/events-framework.md index 4aad8f16741..c0aa43a5739 100644 --- a/docs/wiki/framework/events-framework.md +++ b/docs/wiki/framework/events-framework.md @@ -167,7 +167,14 @@ MenuType: 0 = Interaction, 1 = Self Interaction | `ace_headless_groupTransferPre` | [_group, _HC (OBJECT), _previousOwner, _idHC] | Target | Listen | Called just before a group is transferred from any machine to a HC. Called where group currently is local and on the HC, where group is going to be local. | `ace_headless_groupTransferPost` | [_group, _HC (OBJECT), _previousOwner, _idHC, _transferredSuccessfully] | Target | Listen | Called just after a group is transferred from a machine to a HC. Called where group was local and on the HC, where group is now local. `_transferredSuccessfully` is passed so mods can actually check if the locality was properly transferred, as ownership transfer is not guaranteed. -### 2.18 HuntIR (`ace_huntir`) +### 2.18 Dragging (`ace_dragging`) + +| Event Key | Parameters | Locality | Type | Description | +|---------- |------------|----------|------|-------------| +| `ace_dragging_cloneCreated` | [_clone, _corpse] | Local | Listen | Called when a clone used for dragging/carrying corpses is created +| `ace_dragging_cloneDeleted` | [_clone, _corpse] | Local | Listen | Called when a clone used for dragging/carrying corpses is deleted + +### 2.19 HuntIR (`ace_huntir`) | Event Key | Parameters | Locality | Type | Description | |---------- |------------|----------|------|-------------| From d4ffdd7d89182c36f584b01cf79e2d474950737b Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Sat, 7 Sep 2024 18:04:37 -0500 Subject: [PATCH 08/24] Common - Add `ace_common_fnc_addExplosionEventHandler` (#10243) * Common - Add `ace_common_fnc_addExplosionEventHandler` * Update addons/hearing/XEH_postInit.sqf Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> * make non-public, use netID directly * Update addons/common/functions/fnc_addExplosionEventHandler.sqf Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> * Update fnc_addExplosionEventHandler.sqf * Update addons/hearing/XEH_postInit.sqf Co-authored-by: Grim <69561145+LinkIsGrim@users.noreply.github.com> --------- Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> Co-authored-by: Grim <69561145+LinkIsGrim@users.noreply.github.com> --- addons/common/XEH_PREP.hpp | 1 + .../fnc_addExplosionEventHandler.sqf | 48 +++++++++++++++++++ addons/hearing/XEH_postInit.sqf | 23 +++++---- addons/hearing/functions/fnc_explosion.sqf | 3 +- 4 files changed, 63 insertions(+), 12 deletions(-) create mode 100644 addons/common/functions/fnc_addExplosionEventHandler.sqf diff --git a/addons/common/XEH_PREP.hpp b/addons/common/XEH_PREP.hpp index 36147753459..529da07da2b 100644 --- a/addons/common/XEH_PREP.hpp +++ b/addons/common/XEH_PREP.hpp @@ -269,6 +269,7 @@ PREP(_handleRequestAllSyncedEvents); // other eventhandlers PREP(addActionEventHandler); PREP(addActionMenuEventHandler); +PREP(addExplosionEventHandler); PREP(addMapMarkerCreatedEventHandler); PREP(addPlayerEH); diff --git a/addons/common/functions/fnc_addExplosionEventHandler.sqf b/addons/common/functions/fnc_addExplosionEventHandler.sqf new file mode 100644 index 00000000000..9fb5ef80f24 --- /dev/null +++ b/addons/common/functions/fnc_addExplosionEventHandler.sqf @@ -0,0 +1,48 @@ +#include "..\script_component.hpp" +/* + * Author: johnb432, PabstMirror + * Adds event hander for explosions (for local projectiles) + * Warning: For shots that are tracers and explosive the event will trigger on all machines in range + * This function may be changed after 2.18! + * + * Arguments: + * 0: Code to execute + * + * Return Value: + * The CBA Event Handler Index + * + * Example: + * [{systemChat "boom"}] call ace_common_fnc_addExplosionEventHandler + * + * Public: No (maybe after 2.18) + */ + +params [["_code", {}, [{}]]]; + +if !(missionNamespace getVariable [QGVAR(addExplosionEventHandlerActive), false]) then { + GVAR(addExplosionEventHandlerActive) = true; + + // Add EH to existing projectiles and mines + { + TRACE_2("existing",typeOf _x,local _x); + // Rockets only explode on local clients + _x addEventHandler ["Explode", { + TRACE_1("exp (existing)",_this); + [QGVAR(explosion), _this] call CBA_fnc_localEvent; + }]; + } forEach ((8 allObjects 2) select {local _x}); + + addMissionEventHandler ["ProjectileCreated", { + params ["_projectile"]; + TRACE_2("pc",typeOf _projectile,local _projectile); + + if (!local _projectile) exitWith {}; // Rockets only explode on local clients + + _projectile addEventHandler ["Explode", { + TRACE_1("exp",_this); + [QGVAR(explosion), _this] call CBA_fnc_localEvent; + }]; + }]; +}; + +[QGVAR(explosion), _code] call CBA_fnc_addEventHandler diff --git a/addons/hearing/XEH_postInit.sqf b/addons/hearing/XEH_postInit.sqf index 93a86f73497..f9fb2043334 100644 --- a/addons/hearing/XEH_postInit.sqf +++ b/addons/hearing/XEH_postInit.sqf @@ -16,16 +16,19 @@ if (isServer) then { // Only install event handler if combat deafness is enabled if (!GVAR(enableCombatDeafness)) exitWith {}; - addMissionEventHandler ["ProjectileCreated", { - params ["_projectile"]; - - if (!local _projectile) exitWith {}; - - // Rockets only explode on local clients - _projectile addEventHandler ["Explode", { - [QGVAR(explosion), _this] call CBA_fnc_globalEvent; - }]; - }]; + [{ // Convert ace_common's local explosion to a hearing global explosion event + params ["_projectile", "_pos"]; + TRACE_1("Explode",_this); + + // If projectile is local only, don't raise event globally + // TODO: netId always returns valid after 2.18 + // use _projectile getShotInfo 5 (https://community.bistudio.com/wiki/getShotInfo) + if (isMultiplayer && {(netId _projectile) == "0:0"}) then { + [QGVAR(explosion), [_projectile, _pos]] call CBA_fnc_localEvent; + } else { + [QGVAR(explosion), [_projectile, _pos]] call CBA_fnc_globalEvent; + }; + }] call EFUNC(common,addExplosionEventHandler); }] call CBA_fnc_addEventHandler; if (!hasInterface) exitWith {}; diff --git a/addons/hearing/functions/fnc_explosion.sqf b/addons/hearing/functions/fnc_explosion.sqf index 159f6660114..b5a6f14a69c 100644 --- a/addons/hearing/functions/fnc_explosion.sqf +++ b/addons/hearing/functions/fnc_explosion.sqf @@ -6,13 +6,12 @@ * Arguments: * 0: Projectile * 1: Explosion position ASL - * 2: Velocity (unused) * * Return Value: * None * * Example: - * [_projectile, [0, 0, 0], [0, 0, 0]] call ace_hearing_fnc_explosion + * [_projectile, [0, 0, 0]] call ace_hearing_fnc_explosion * * Public: No */ From e77861a7973cf94f6250bd57857bdeb0cabdeb17 Mon Sep 17 00:00:00 2001 From: Bailey Danyluk Date: Sat, 7 Sep 2024 17:07:04 -0600 Subject: [PATCH 09/24] Missileguidance - Add common configs for many missiles (#10275) * Add base classes for a bunch of misisles * change all default missiles to use types * update presets --- addons/dragon/CfgAmmo.hpp | 64 +- addons/hellfire/CfgAmmo.hpp | 42 +- addons/hot/CfgAmmo.hpp | 39 +- addons/maverick/CfgAmmo.hpp | 63 +- addons/metis/CfgAmmo.hpp | 71 +- addons/missileguidance/CfgAmmo.hpp | 78 +- .../missileguidance/CfgMissileTypesNato.hpp | 716 ++++++++++++++ .../missileguidance/CfgMissileTypesWarsaw.hpp | 901 ++++++++++++++++++ addons/missileguidance/config.cpp | 2 + addons/nlaw/CfgAmmo.hpp | 34 +- 10 files changed, 1642 insertions(+), 368 deletions(-) create mode 100644 addons/missileguidance/CfgMissileTypesNato.hpp create mode 100644 addons/missileguidance/CfgMissileTypesWarsaw.hpp diff --git a/addons/dragon/CfgAmmo.hpp b/addons/dragon/CfgAmmo.hpp index 22630e03b00..3a5a4a1ed6d 100644 --- a/addons/dragon/CfgAmmo.hpp +++ b/addons/dragon/CfgAmmo.hpp @@ -1,3 +1,4 @@ +class ace_missileguidance_type_Dragon; class CfgAmmo { class ammo_Penetrator_Base; class M_Scalpel_AT; @@ -37,41 +38,7 @@ class CfgAmmo { EGVAR(vehicle_damage,incendiary) = 1.0; - class ace_missileguidance { - pitchRate = 0; - yawRate = 0; - - canVanillaLock = 0; - - // Guidance type for munitions - defaultSeekerType = "SACLOS"; - seekerTypes[] = { "SACLOS" }; - - defaultSeekerLockMode = "LOAL"; - seekerLockModes[] = { "LOAL", "LOBL" }; - - defaultNavigationType = "LineOfSight"; - navigationTypes[] = { "LineOfSight" }; - - seekLastTargetPos = 0; - seekerAngle = 30; - seekerAccuracy = 1; - - seekerMinRange = 65; - seekerMaxRange = 1000; - - correctionDistance = 30; - missileLeadDistance = 0; - offsetFromCrosshair[] = { 0, 0, 0 }; - - serviceInterval = 0.33; // how many seconds between pops - serviceCharges = 32; // how many charges are in this missile - serviceChargeAcceleration = 6.5; - dragonSpeed = 100; // meters per second - - defaultAttackProfile = "DRAGON"; - attackProfiles[] = {"DRAGON"}; - }; + class ace_missileguidance: ace_missileguidance_type_Dragon {}; }; class GVAR(super): GVAR(dragonBase) { @@ -81,36 +48,11 @@ class CfgAmmo { submunitionParentSpeedCoef = 0; submunitionInitialOffset[] = { 0, 0, -0.2 }; - class ace_missileguidance { + class ace_missileguidance: ace_missileguidance { enabled = 1; - - pitchRate = 0; - yawRate = 0; - - // Guidance type for munitions - defaultSeekerType = "SACLOS"; - seekerTypes[] = { "SACLOS" }; - - defaultSeekerLockMode = "LOAL"; - seekerLockModes[] = { "LOAL", "LOBL" }; - - seekLastTargetPos = 0; - seekerAngle = 30; - seekerAccuracy = 1; - seekerMinRange = 30; seekerMaxRange = 1500; - - correctionDistance = 30; - missileLeadDistance = 0; - - serviceInterval = 0.33; // how many seconds between pops serviceCharges = 60; // how many charges are in this missile - serviceChargeAcceleration = 6.5; - dragonSpeed = 100; // meters per second - - defaultAttackProfile = "DRAGON"; - attackProfiles[] = {"DRAGON"}; }; }; diff --git a/addons/hellfire/CfgAmmo.hpp b/addons/hellfire/CfgAmmo.hpp index 02346deac3d..8789be711ce 100644 --- a/addons/hellfire/CfgAmmo.hpp +++ b/addons/hellfire/CfgAmmo.hpp @@ -1,3 +1,4 @@ +class ace_missileguidance_type_Hellfire; class CfgAmmo { class M_Scalpel_AT; @@ -23,47 +24,8 @@ class CfgAmmo { EGVAR(rearm,caliber) = 178; - class ace_missileguidance { + class ace_missileguidance: ace_missileguidance_type_Hellfire { enabled = 1; - - pitchRate = 30; // degrees per second - yawRate = 30; - - canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode - - // Guidance type for munitions - defaultSeekerType = "SALH"; - seekerTypes[] = { "SALH", "LIDAR", "SARH", "Optic", "Thermal", "GPS", "SACLOS", "MCLOS" }; - - defaultSeekerLockMode = "LOAL"; - seekerLockModes[] = { "LOAL", "LOBL" }; - - defaultNavigationType = "Direct"; - navigationTypes[] = { "Direct", "ZeroEffortMiss" }; - - seekLastTargetPos = 1; // seek last target position [if seeker loses LOS of target, continue to last known pos] - seekerAngle = 70; // Angle in front of the missile which can be searched - seekerAccuracy = 1; // seeker accuracy multiplier - - seekerMinRange = 1; - seekerMaxRange = 8000; // Range from the missile which the seeker can visually search - - // Attack profile type selection - defaultAttackProfile = "hellfire"; - attackProfiles[] = {"hellfire", "hellfire_hi", "hellfire_lo"}; - - class navigationStates { - class initial { - transitionCondition = QFUNC(midCourseTransition); - navigationType = "Direct"; - }; - class terminal { - transitionCondition = ""; - navigationType = "ZeroEffortMiss"; - }; - // transitions from initial -> termimal - states[] = {"initial", "terminal"}; - }; }; }; class ACE_Hellfire_AGM114N: ACE_Hellfire_AGM114K { diff --git a/addons/hot/CfgAmmo.hpp b/addons/hot/CfgAmmo.hpp index c5978b6d923..6f91d241fb9 100644 --- a/addons/hot/CfgAmmo.hpp +++ b/addons/hot/CfgAmmo.hpp @@ -1,3 +1,4 @@ +class ace_missileguidance_type_Hot; class CfgAmmo { class M_Scalpel_AT; class ammo_Penetrator_Base; @@ -55,43 +56,8 @@ class CfgAmmo { EGVAR(rearm,caliber) = 178; EGVAR(vehicle_damage,incendiary) = 1.0; - class ace_missileguidance { + class ace_missileguidance: ace_missileguidance_type_Hot { enabled = 1; - - pitchRate = 45; // Minium flap deflection for guidance - yawRate = 45; // Maximum flap deflection for guidance - - canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode - - showTrail = 1; - - // Guidance type for munitions - defaultSeekerType = "SACLOS"; - seekerTypes[] = { "SACLOS" }; - - defaultSeekerLockMode = "LOAL"; - seekerLockModes[] = { "LOAL", "LOBL" }; - - defaultNavigationType = "Line"; - navigationTypes[] = { "Line" }; - - lineGainP = 7; - lineGainD = 6; - - initialPitch = 2; - - seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] - seekerAngle = 30; // Angle from the shooter's view that can track the missile - seekerAccuracy = 1; // seeker accuracy multiplier - - seekerMinRange = 75; - seekerMaxRange = 4000; // Range from the missile which the seeker can visually search - - offsetFromCrosshair[] = { 0, 0, 0.5 }; // where the missile wants to stay in relation to the center of the crosshair. - - // Attack profile type selection - defaultAttackProfile = "WIRE"; - attackProfiles[] = {"WIRE"}; }; }; @@ -143,6 +109,7 @@ class CfgAmmo { class ace_missileguidance: ace_missileguidance { enabled = 1; seekerMaxRange = 4300; + offsetFromCrosshair[] = { 0, 0, 0.5 }; // where the missile wants to stay in relation to the center of the crosshair. }; }; }; diff --git a/addons/maverick/CfgAmmo.hpp b/addons/maverick/CfgAmmo.hpp index 7e66e2edee0..dbf847b10d6 100644 --- a/addons/maverick/CfgAmmo.hpp +++ b/addons/maverick/CfgAmmo.hpp @@ -1,3 +1,4 @@ +class ace_missileguidance_type_Maverick; class CfgAmmo { class MissileCore; class MissileBase: MissileCore { @@ -9,32 +10,8 @@ class CfgAmmo { author = "Dani (TCVM)"; missileLockMaxDistance = 14000; maneuvrability = 0; - class ace_missileguidance { + class ace_missileguidance: ace_missileguidance_type_Maverick { enabled = 1; - - pitchRate = 15; - yawRate = 15; - - canVanillaLock = 1; - - defaultSeekerType = "Optic"; - seekerTypes[] = {"Optic"}; - - defaultSeekerLockMode = "LOBL"; - seekerLockModes[] = {"LOBL"}; - - defaultNavigationType = "AugmentedProportionalNavigation"; - navigationTypes[] = { "AugmentedProportionalNavigation" }; - - seekLastTargetPos = 1; - seekerAngle = 60; - seekerAccuracy = 1; - - seekerMinRange = 1; - seekerMaxRange = 14000; - - defaultAttackProfile = "maverick"; - attackProfiles[] = {"maverick"}; }; }; @@ -52,32 +29,15 @@ class CfgAmmo { manualControl = 0; missileLockMaxDistance = 16000; weaponLockSystem = 4; - class ace_missileguidance { + class ace_missileguidance: ace_missileguidance_type_Maverick { enabled = 1; - - pitchRate = 15; - yawRate = 15; - - canVanillaLock = 0; - defaultSeekerType = "SALH"; seekerTypes[] = {"SALH"}; defaultSeekerLockMode = "LOAL"; - seekerLockModes[] = {"LOAL","LOBL"}; - - defaultNavigationType = "AugmentedProportionalNavigation"; - navigationTypes[] = { "AugmentedProportionalNavigation" }; - - seekLastTargetPos = 1; - seekerAngle = 60; - seekerAccuracy = 1; + seekerLockModes[] = {"LOAL"}; - seekerMinRange = 1; seekerMaxRange = 16000; - - defaultAttackProfile = "maverick"; - attackProfiles[] = {"maverick"}; }; }; @@ -87,32 +47,19 @@ class CfgAmmo { irLock = 0; missileLockMaxDistance = 10000; weaponLockSystem = 4; - class ace_missileguidance { + class ace_missileguidance: ace_missileguidance_type_Maverick { enabled = 1; - pitchRate = 20; yawRate = 20; - canVanillaLock = 0; - defaultSeekerType = "SALH"; seekerTypes[] = {"SALH"}; defaultSeekerLockMode = "LOAL"; seekerLockModes[] = {"LOAL"}; - defaultNavigationType = "AugmentedProportionalNavigation"; - navigationTypes[] = { "AugmentedProportionalNavigation" }; - - seekLastTargetPos = 1; seekerAngle = 40; - seekerAccuracy = 1; - - seekerMinRange = 1; seekerMaxRange = 10000; - - defaultAttackProfile = "maverick"; - attackProfiles[] = {"maverick"}; }; }; }; diff --git a/addons/metis/CfgAmmo.hpp b/addons/metis/CfgAmmo.hpp index c070343253a..4a6fe513d23 100644 --- a/addons/metis/CfgAmmo.hpp +++ b/addons/metis/CfgAmmo.hpp @@ -1,3 +1,4 @@ +class ace_missileguidance_type_Metis; class CfgAmmo { class M_Vorona_HEAT; class GVAR(HEAT): M_Vorona_HEAT { @@ -7,42 +8,8 @@ class CfgAmmo { airLock = 0; lockType = 0; - class ace_missileguidance { + class ace_missileguidance: ace_missileguidance_type_Metis { enabled = 1; - - pitchRate = 50; // Minium flap deflection for guidance - yawRate = 50; // Maximum flap deflection for guidance - initialPitch = 2; - - canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode - - showTrail = 1; - - // Guidance type for munitions - defaultSeekerType = "SACLOS"; - seekerTypes[] = { "SACLOS" }; - - defaultSeekerLockMode = "LOAL"; - seekerLockModes[] = { "LOAL", "LOBL" }; - - defaultNavigationType = "Line"; - navigationTypes[] = { "Line" }; - - lineGainP = 10; - lineGainD = 9; - - seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] - seekerAngle = 15; // Angle from the shooter's view that can track the missile - seekerAccuracy = 1; // seeker accuracy multiplier - - seekerMinRange = 80; - seekerMaxRange = 2000; // Range from the missile which the seeker can visually search - - offsetFromCrosshair[] = { 0, 0, 0 }; // where the missile wants to stay in relation to the center of the crosshair. - - // Attack profile type selection - defaultAttackProfile = "WIRE"; - attackProfiles[] = {"WIRE"}; }; }; @@ -54,40 +21,8 @@ class CfgAmmo { airLock = 0; lockType = 0; - class ace_missileguidance { + class ace_missileguidance: ace_missileguidance_type_Metis { enabled = 1; - - pitchRate = 25; // Minium flap deflection for guidance - yawRate = 25; // Maximum flap deflection for guidance - - canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode - - // Guidance type for munitions - defaultSeekerType = "SACLOS"; - seekerTypes[] = { "SACLOS" }; - - defaultSeekerLockMode = "LOAL"; - seekerLockModes[] = { "LOAL", "LOBL" }; - - defaultNavigationType = "Line"; - navigationTypes[] = { "Line" }; - - lineGainP = 21; - lineGainD = 18; - - seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] - seekerAngle = 15; // Angle from the shooter's view that can track the missile - seekerAccuracy = 1; // seeker accuracy multiplier - - seekerMinRange = 80; - seekerMaxRange = 2000; // Range from the missile which the seeker can visually search - - correctionDistance = 1; // distance from center of crosshair where missile slows down - offsetFromCrosshair[] = { 0, 0, 0 }; // where the missile wants to stay in relation to the center of the crosshair. - - // Attack profile type selection - defaultAttackProfile = "WIRE"; - attackProfiles[] = {"WIRE"}; }; }; }; diff --git a/addons/missileguidance/CfgAmmo.hpp b/addons/missileguidance/CfgAmmo.hpp index 8f913e99656..44e35d40811 100644 --- a/addons/missileguidance/CfgAmmo.hpp +++ b/addons/missileguidance/CfgAmmo.hpp @@ -17,33 +17,8 @@ class CfgAmmo { EGVAR(rearm,caliber) = 70; - class ADDON { + class ADDON: GVAR(type_Dagr) { enabled = 1; - - pitchRate = 40; // degrees per second - yawRate = 40; - - canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode - - // Guidance type for munitions - defaultSeekerType = "SALH"; - seekerTypes[] = { "SALH" }; - - defaultSeekerLockMode = "LOAL"; - seekerLockModes[] = { "LOAL", "LOBL" }; - - defaultNavigationType = "AugmentedProportionalNavigation"; - navigationTypes[] = { "AugmentedProportionalNavigation" }; - - seekerAngle = 90; // Angle in front of the missile which can be searched - seekerAccuracy = 1; // seeker accuracy multiplier - - seekerMinRange = 1; - seekerMaxRange = 2500; // Range from the missile which the seeker can visually search - - // Attack profile type selection - defaultAttackProfile = "LIN"; - attackProfiles[] = { "LIN", "DIR", "MID", "HI" }; }; }; @@ -68,53 +43,8 @@ class CfgAmmo { initTime = 0.5; // Begin ACE guidance Configs - class ADDON { + class ADDON: GVAR(type_Javelin) { enabled = 1; - - pitchRate = 120; // degrees per second - yawRate = 120; - stabilityCoefficient = 0.2; - bangBangGuidance = 0; - - canVanillaLock = 0; - - // Guidance type for munitions - defaultSeekerType = "Optic"; - seekerTypes[] = { "Optic" }; - - defaultSeekerLockMode = "LOBL"; - seekerLockModes[] = { "LOBL" }; - - defaultNavigationType = "Direct"; - navigationTypes[] = { "Direct", "ZeroEffortMiss" }; - - navigationGain = 3; - - seekerAngle = 180; // Angle in front of the missile which can be searched - seekerAccuracy = 1; // seeker accuracy multiplier - - seekerMinRange = 0; - seekerMaxRange = 2500; // Range from the missile which the seeker can visually search - - seekLastTargetPos = 1; // seek last target position [if seeker loses LOS of target, continue to last known pos] - - // Attack profile type selection - defaultAttackProfile = "JAV_TOP"; - attackProfiles[] = { "JAV_TOP", "JAV_DIR" }; - useModeForAttackProfile = 1; - - class navigationStates { - class initial { - transitionCondition = QFUNC(javelin_midCourseTransition); - navigationType = "Direct"; - }; - class terminal { - transitionCondition = ""; - navigationType = "ZeroEffortMiss"; - }; - // transitions from initial -> termimal - states[] = {"initial", "terminal"}; - }; }; }; class ACE_Javelin_FGM148_static: ACE_Javelin_FGM148 { @@ -123,6 +53,8 @@ class CfgAmmo { effectsMissileInit = "RocketBackEffectsStaticRPG"; //Explicity add guidance config - class ADDON: ADDON {}; + class ADDON: ADDON { + enabled = 1; + }; }; }; diff --git a/addons/missileguidance/CfgMissileTypesNato.hpp b/addons/missileguidance/CfgMissileTypesNato.hpp new file mode 100644 index 00000000000..ee4c76890e9 --- /dev/null +++ b/addons/missileguidance/CfgMissileTypesNato.hpp @@ -0,0 +1,716 @@ +class GVAR(type_AMRAAM) { + enabled = 0; + + pitchRate = 30; // Minium flap deflection for guidance + yawRate = 30; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "DopplerRadar"; + seekerTypes[] = { "DopplerRadar" }; + lockableTypes[] = {"Air"}; + + minimumSpeedFilter = 25; // filter out targets that have a closing velocity less than this + minimumTimeFilter = 0.0001; // filter out targets that are this close to the ground (speed of light) + maxTerrainCheck = 16000; // How far we should check for terrain + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "ZeroEffortMiss"; + navigationTypes[] = { "ZeroEffortMiss" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 50; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 2500; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR", "LOFT"}; + useModeForAttackProfile = 1; +}; + +class GVAR(type_ASRAAM) { + enabled = 0; + + pitchRate = 100; // Minium flap deflection for guidance + yawRate = 100; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "IR"; + seekerTypes[] = { "IR" }; + + flareDistanceFilter = 50; + flareAngleFilter = 0.8; // can filter out flares that are >= flareAngleFilter to known target velocity + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "ZeroEffortMiss"; + navigationTypes[] = { "ZeroEffortMiss" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 120; // Angle from the shooter's view that can track the missile + seekerAccuracy = 0.98; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 8000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_Dagr) { + enabled = 0; + + pitchRate = 40; // degrees per second + yawRate = 40; + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "SALH"; + seekerTypes[] = { "SALH" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "AugmentedProportionalNavigation"; + navigationTypes[] = { "AugmentedProportionalNavigation" }; + + seekerAngle = 90; // Angle in front of the missile which can be searched + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 1; + seekerMaxRange = 2500; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "LIN"; + attackProfiles[] = { "LIN", "DIR", "MID", "HI" }; +}; + +class GVAR(type_Dragon) { + enabled = 0; + + pitchRate = 0; + yawRate = 0; + + canVanillaLock = 0; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "LineOfSight"; + navigationTypes[] = { "LineOfSight" }; + + seekLastTargetPos = 0; + seekerAngle = 30; + seekerAccuracy = 1; + + seekerMinRange = 65; + seekerMaxRange = 1000; + + correctionDistance = 30; + missileLeadDistance = 0; + offsetFromCrosshair[] = { 0, 0, 0 }; + + serviceInterval = 0.33; // how many seconds between pops + serviceCharges = 32; // how many charges are in this missile + serviceChargeAcceleration = 6.5; + dragonSpeed = 100; // meters per second + + defaultAttackProfile = "DRAGON"; + attackProfiles[] = {"DRAGON"}; +}; + +class GVAR(type_ESSM) { + enabled = 0; + + pitchRate = 15; // Minium flap deflection for guidance + yawRate = 15; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "DopplerRadar"; + seekerTypes[] = { "DopplerRadar" }; + lockableTypes[] = {"Air"}; + + minimumSpeedFilter = 20; // filter out targets that have a closing velocity less than this + minimumTimeFilter = 0.00001; // filter out targets that are this close to the ground (speed of light) + maxTerrainCheck = 16000; // How far we should check for terrain + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "ZeroEffortMiss"; + navigationTypes[] = { "ZeroEffortMiss" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 50; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 2500; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_Hellfire) { + enabled = 0; + + pitchRate = 30; // degrees per second + yawRate = 30; + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "SALH"; + seekerTypes[] = { "SALH" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Direct"; + navigationTypes[] = { "Direct", "ZeroEffortMiss" }; + + seekLastTargetPos = 1; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 70; // Angle in front of the missile which can be searched + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 1; + seekerMaxRange = 8000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "hellfire"; + attackProfiles[] = {"hellfire", "hellfire_hi", "hellfire_lo"}; + + class navigationStates { + class initial { + transitionCondition = QEFUNC(hellfire,midCourseTransition); + navigationType = "Direct"; + }; + class terminal { + transitionCondition = ""; + navigationType = "ZeroEffortMiss"; + }; + // transitions from initial -> termimal + states[] = {"initial", "terminal"}; + }; +}; + +class GVAR(type_Hot) { + enabled = 0; + + pitchRate = 45; // Minium flap deflection for guidance + yawRate = 45; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 7; + lineGainD = 6; + + initialPitch = 2; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 4000; // Range from the missile which the seeker can visually search + + offsetFromCrosshair[] = { 0, 0, 0 }; // where the missile wants to stay in relation to the center of the crosshair. + + // Attack profile type selection + defaultAttackProfile = "WIRE"; + attackProfiles[] = {"WIRE"}; +}; + +class GVAR(type_Javelin) { + enabled = 0; + + pitchRate = 120; // degrees per second + yawRate = 120; + stabilityCoefficient = 0.2; + bangBangGuidance = 0; + + canVanillaLock = 0; + + // Guidance type for munitions + defaultSeekerType = "Optic"; + seekerTypes[] = { "Optic" }; + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "Direct"; + navigationTypes[] = { "Direct", "ZeroEffortMiss" }; + + navigationGain = 3; + + seekerAngle = 180; // Angle in front of the missile which can be searched + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 0; + seekerMaxRange = 2500; // Range from the missile which the seeker can visually search + + seekLastTargetPos = 1; // seek last target position [if seeker loses LOS of target, continue to last known pos] + + // Attack profile type selection + defaultAttackProfile = "JAV_TOP"; + attackProfiles[] = { "JAV_TOP", "JAV_DIR" }; + useModeForAttackProfile = 1; + + class navigationStates { + class initial { + transitionCondition = QFUNC(javelin_midCourseTransition); + navigationType = "Direct"; + }; + class terminal { + transitionCondition = ""; + navigationType = "ZeroEffortMiss"; + }; + // transitions from initial -> termimal + states[] = {"initial", "terminal"}; + }; +}; + +class GVAR(type_Jdam) { + enabled = 0; + + pitchRate = 15; + yawRate = 20; + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "GPS"; + seekerTypes[] = { "GPS" }; + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "LINE"; + navigationTypes[] = { "LINE" }; + + lineGainP = 50; + lineGainD = 0; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 60; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 5; + seekerMaxRange = 4000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "JDAM"; + attackProfiles[] = {"JDAM"}; +}; + +class GVAR(type_Maverick) { + enabled = 0; + + pitchRate = 15; + yawRate = 15; + + canVanillaLock = 1; + + defaultSeekerType = "Optic"; + seekerTypes[] = {"Optic"}; + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = {"LOBL"}; + + defaultNavigationType = "AugmentedProportionalNavigation"; + navigationTypes[] = { "AugmentedProportionalNavigation" }; + + seekLastTargetPos = 1; + seekerAngle = 60; + seekerAccuracy = 1; + + seekerMinRange = 1; + seekerMaxRange = 14000; + + defaultAttackProfile = "maverick"; + attackProfiles[] = {"maverick"}; +}; + +class GVAR(type_Milan) { + enabled = 0; + + pitchRate = 60; // Minium flap deflection for guidance + yawRate = 60; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 0; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 25; + lineGainD = 12; + + initialPitch = -0.4; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 5; // Angle from the shooter's view that can track the missile, implemented + seekerAccuracy = 1; // seeker accuracy multiplier, not implemented? + + seekerMinRange = 100; + seekerMaxRange = 2000; // Range from the missile which the seeker can visually search + + offsetFromCrosshair[] = { 0, 0, 0 }; // where the missile wants to stay in relation to the center of the crosshair. + + // Attack profile type selection + defaultAttackProfile = "WIRE"; + attackProfiles[] = {"WIRE"}; +}; + +class GVAR(type_Nlaw) { + enabled = 0; + + pitchRate = 5; // Minium flap deflection for guidance + yawRate = 10; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = QEGVAR(nlaw,seeker); + seekerTypes[] = {QEGVAR(nlaw,seeker)}; + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = {"LOBL"}; + + defaultNavigationType = QEGVAR(nlaw,PLOS); + navigationTypes[] = { QEGVAR(nlaw,PLOS) }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 45; // Angle in front of the missile which can be searched + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 0; + seekerMaxRange = 10; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = QEGVAR(nlaw,directAttack); + attackProfiles[] = {QEGVAR(nlaw,directAttack), QEGVAR(nlaw,overflyTopAttack)}; + useModeForAttackProfile = 1; + showHintOnCycle = 1; + + // Run once at fired event + onFired = QEFUNC(nlaw,onFired); +}; + +class GVAR(type_Patriot) { + enabled = 0; + + pitchRate = 30; // Minium flap deflection for guidance + yawRate = 30; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "DopplerRadar"; + seekerTypes[] = { "DopplerRadar" }; + lockableTypes[] = {"Air"}; + + minimumSpeedFilter = 10; // filter out targets that have a closing velocity less than this + minimumTimeFilter = 0.00001; // filter out targets that are this close to the ground (speed of light) + maxTerrainCheck = 16000; // How far we should check for terrain + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "ZeroEffortMiss"; + navigationTypes[] = { "ZeroEffortMiss" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 50; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 2500; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_Paveway) { + enabled = 0; + + pitchRate = 5; + yawRate = 5; + + bangBangGuidance = 1; + stabilityCoefficient = 0.4; // how much this projectile likes to "weathervane" (keep direction toward velocity) + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "SALH"; + seekerTypes[] = { "SALH" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL" }; + + defaultNavigationType = "ProportionalNavigation"; + navigationTypes[] = { "ProportionalNavigation" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 60; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 5; + seekerMaxRange = 4000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_RAM) { + enabled = 0; + + pitchRate = 50; // Minium flap deflection for guidance + yawRate = 50; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "IR"; + seekerTypes[] = { "IR" }; + + flareDistanceFilter = 100; + flareAngleFilter = 0.5; // can filter out flares that are >= flareAngleFilter to known target velocity + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "ZeroEffortMiss"; + navigationTypes[] = { "ZeroEffortMiss" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 45; // Angle from the shooter's view that can track the missile + seekerAccuracy = 0.8; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 5000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_RBS70) { + enabled = 0; + + pitchRate = 45; // Minium flap deflection for guidance + yawRate = 45; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 20; + lineGainD = 16; + + initialPitch = 2; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 5000; // Range from the missile which the seeker can visually search + + correctionDistance = 30; // distance from center of crosshair where missile slows down + offsetFromCrosshair[] = { 0, 0, 0 }; // where the missile wants to stay in relation to the center of the crosshair. + + // Attack profile type selection + defaultAttackProfile = "BEAM"; + attackProfiles[] = {"BEAM"}; +}; + +class GVAR(type_Redeye) { + enabled = 0; + + pitchRate = 27; // Minium flap deflection for guidance + yawRate = 27; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "IR"; + seekerTypes[] = { "IR" }; + + flareDistanceFilter = 100; + flareAngleFilter = 2.0; // can filter out flares that are >= flareAngleFilter to known target velocity + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "ProportionalNavigation"; + navigationTypes[] = { "ProportionalNavigation" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 45; // Angle from the shooter's view that can track the missile + seekerAccuracy = 0.4; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 4500; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_Sidewinder) { + enabled = 0; + + pitchRate = 25; // Minium flap deflection for guidance + yawRate = 25; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "IR"; + seekerTypes[] = { "IR" }; + + flareDistanceFilter = 100; + flareAngleFilter = 1.6; // can filter out flares that are >= flareAngleFilter to known target velocity + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "AugmentedProportionalNavigation"; + navigationTypes[] = { "AugmentedProportionalNavigation" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 45; // Angle from the shooter's view that can track the missile + seekerAccuracy = 0.8; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 5000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_Stinger) { + enabled = 0; + + pitchRate = 42; // Minium flap deflection for guidance + yawRate = 42; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "IR"; + seekerTypes[] = { "IR" }; + + flareDistanceFilter = 100; + flareAngleFilter = 1.3; // can filter out flares that are >= flareAngleFilter to known target velocity + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "AugmentedProportionalNavigation"; + navigationTypes[] = { "AugmentedProportionalNavigation" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 45; // Angle from the shooter's view that can track the missile + seekerAccuracy = 0.8; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 5000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_TOW) { + enabled = 0; + + pitchRate = 45; // Minium flap deflection for guidance + yawRate = 45; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 20; + lineGainD = 7; + + initialPitch = 2; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 65; + seekerMaxRange = 3750; // Range from the missile which the seeker can visually search + + correctionDistance = 30; // distance from center of crosshair where missile slows down + offsetFromCrosshair[] = { 0, 0, 0 }; // where the missile wants to stay in relation to the center of the crosshair. + + // Attack profile type selection + defaultAttackProfile = "WIRE"; + attackProfiles[] = {"WIRE"}; +}; \ No newline at end of file diff --git a/addons/missileguidance/CfgMissileTypesWarsaw.hpp b/addons/missileguidance/CfgMissileTypesWarsaw.hpp new file mode 100644 index 00000000000..4dbe81bbbf5 --- /dev/null +++ b/addons/missileguidance/CfgMissileTypesWarsaw.hpp @@ -0,0 +1,901 @@ +class GVAR(type_Ataka) { + enabled = 0; + + pitchRate = 45; // Minium flap deflection for guidance + yawRate = 45; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 16; + lineGainD = 10.44; + + initialPitch = 2; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 6000; // Range from the missile which the seeker can visually search + + offsetFromCrosshair[] = { 0, 0, 0 }; // where the missile wants to stay in relation to the center of the crosshair. + + // Attack profile type selection + defaultAttackProfile = "BEAM"; + attackProfiles[] = {"BEAM"}; +}; + +class GVAR(type_Bastion) { + enabled = 0; + + pitchRate = 45; // Minium flap deflection for guidance + yawRate = 45; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 16; + lineGainD = 10.44; + + initialPitch = 2; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 6000; // Range from the missile which the seeker can visually search + + offsetFromCrosshair[] = { 0, 0, 0 }; // where the missile wants to stay in relation to the center of the crosshair. + + // Attack profile type selection + defaultAttackProfile = "BEAM"; + attackProfiles[] = {"BEAM"}; +}; + +class GVAR(type_Drakon) { + enabled = 0; + + pitchRate = 25; // Minium flap deflection for guidance + yawRate = 25; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 16; + lineGainD = 9.5; + + initialPitch = 2; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 3300; // Range from the missile which the seeker can visually search + + correctionDistance = 30; // distance from center of crosshair where missile slows down + offsetFromCrosshair[] = { 0, 0, 0 }; // where the missile wants to stay in relation to the center of the crosshair. + + // Attack profile type selection + defaultAttackProfile = "BEAM"; + attackProfiles[] = {"BEAM"}; +}; + +class GVAR(type_Fagot) { + enabled = 0; + + pitchRate = 45; // Minium flap deflection for guidance + yawRate = 45; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 16; + lineGainD = 10.44; + + initialPitch = 2; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 2000; // Range from the missile which the seeker can visually search + + correctionDistance = 30; // distance from center of crosshair where missile slows down + offsetFromCrosshair[] = { 0, 0, 0 }; // where the missile wants to stay in relation to the center of the crosshair. + + // Attack profile type selection + defaultAttackProfile = "BEAM"; + attackProfiles[] = {"BEAM"}; +}; + +class GVAR(type_Falanga) { + enabled = 0; + + pitchRate = 15; // Minium flap deflection for guidance + yawRate = 15; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "MCLOS"; + seekerTypes[] = { "MCLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 5; + lineGainD = 0; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 0; + seekerMaxRange = 2500; // Range from the missile which the seeker can visually search + + correctionDistance = 0; // distance from center of crosshair where missile slows down + offsetFromCrosshair[] = { 0, 0, 0 }; // where the missile wants to stay in relation to the center of the crosshair. + + // Attack profile type selection + defaultAttackProfile = "WIRE"; + attackProfiles[] = {"WIRE"}; +}; + +class GVAR(type_Fleyta) { + enabled = 0; + + pitchRate = 15; // Minium flap deflection for guidance + yawRate = 15; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "MCLOS"; + seekerTypes[] = { "MCLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 5; + lineGainD = 0; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 0; + seekerMaxRange = 3000; // Range from the missile which the seeker can visually search + + correctionDistance = 0; // distance from center of crosshair where missile slows down + offsetFromCrosshair[] = { 0, 0, 0 }; // where the missile wants to stay in relation to the center of the crosshair. + + // Attack profile type selection + defaultAttackProfile = "WIRE"; + attackProfiles[] = {"WIRE"}; +}; + +class GVAR(type_Igla) { + enabled = 0; + + pitchRate = 30; // Minium flap deflection for guidance + yawRate = 43; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "IR"; + seekerTypes[] = { "IR" }; + + flareDistanceFilter = 100; + flareAngleFilter = 1.1; // can filter out flares that are >= flareAngleFilter to known target velocity + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "AugmentedProportionalNavigation"; + navigationTypes[] = { "AugmentedProportionalNavigation" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 45; // Angle from the shooter's view that can track the missile + seekerAccuracy = 0.76; // seeker accuracy multiplier + + seekerMinRange = 5; + seekerMaxRange = 5200; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_KAB) { + enabled = 0; + + pitchRate = 8; + yawRate = 8; + + bangBangGuidance = 1; + stabilityCoefficient = 0.4; // how much this projectile likes to "weathervane" (keep direction toward velocity) + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "SALH"; + seekerTypes[] = { "SALH" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL" }; + + defaultNavigationType = "ProportionalNavigation"; + navigationTypes[] = { "ProportionalNavigation" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 60; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 5; + seekerMaxRange = 4000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_KH25) { + enabled = 0; + + pitchRate = 20; + yawRate = 20; + + canVanillaLock = 0; + + defaultSeekerType = "SALH"; + seekerTypes[] = {"SALH"}; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = {"LOAL"}; + + defaultNavigationType = "AugmentedProportionalNavigation"; + navigationTypes[] = { "AugmentedProportionalNavigation" }; + + seekLastTargetPos = 1; + seekerAngle = 40; + seekerAccuracy = 1; + + seekerMinRange = 1; + seekerMaxRange = 10000; + + defaultAttackProfile = "maverick"; + attackProfiles[] = {"maverick"}; +}; + +class GVAR(type_KH29) { + enabled = 0; + + pitchRate = 20; + yawRate = 20; + + canVanillaLock = 0; + + defaultSeekerType = "SALH"; + seekerTypes[] = {"SALH"}; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = {"LOAL"}; + + defaultNavigationType = "AugmentedProportionalNavigation"; + navigationTypes[] = { "AugmentedProportionalNavigation" }; + + seekLastTargetPos = 1; + seekerAngle = 40; + seekerAccuracy = 1; + + seekerMinRange = 1; + seekerMaxRange = 10000; + + defaultAttackProfile = "maverick"; + attackProfiles[] = {"maverick"}; +}; + +class GVAR(type_Kobra) { + enabled = 0; + + pitchRate = 45; // Minium flap deflection for guidance + yawRate = 45; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 16; + lineGainD = 9.5; + + initialPitch = 2; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 5000; // Range from the missile which the seeker can visually search + + correctionDistance = 30; // distance from center of crosshair where missile slows down + offsetFromCrosshair[] = { 0, 0, 0 }; // where the missile wants to stay in relation to the center of the crosshair. + + // Attack profile type selection + defaultAttackProfile = "BEAM"; + attackProfiles[] = {"BEAM"}; +}; + +class GVAR(type_Konkurs) { + enabled = 0; + + pitchRate = 45; // Minium flap deflection for guidance + yawRate = 45; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 10; + lineGainD = 8.5; + + initialPitch = 2; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 4000; // Range from the missile which the seeker can visually search + + offsetFromCrosshair[] = { 0, 0, 0 }; // where the missile wants to stay in relation to the center of the crosshair. + + // Attack profile type selection + defaultAttackProfile = "WIRE"; + attackProfiles[] = {"WIRE"}; +}; + +class GVAR(type_Kornet) { + enabled = 0; + + pitchRate = 45; // Minium flap deflection for guidance + yawRate = 45; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 16; + lineGainD = 10.44; + + initialPitch = 2; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 5000; // Range from the missile which the seeker can visually search + + correctionDistance = 30; // distance from center of crosshair where missile slows down + offsetFromCrosshair[] = { 0, 0, 0 }; // where the missile wants to stay in relation to the center of the crosshair. + + // Attack profile type selection + defaultAttackProfile = "BEAM"; + attackProfiles[] = {"BEAM"}; +}; + +class GVAR(type_Malyutka) { + enabled = 0; + + pitchRate = 15; // Minium flap deflection for guidance + yawRate = 15; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "MCLOS"; + seekerTypes[] = { "MCLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 5; + lineGainD = 0; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 0; + seekerMaxRange = 2500; // Range from the missile which the seeker can visually search + + correctionDistance = 0; // distance from center of crosshair where missile slows down + offsetFromCrosshair[] = { 0, 0, 0 }; // where the missile wants to stay in relation to the center of the crosshair. + + // Attack profile type selection + defaultAttackProfile = "WIRE"; + attackProfiles[] = {"WIRE"}; +}; + +class GVAR(type_Metis) { + enabled = 0; + + pitchRate = 50; // Minium flap deflection for guidance + yawRate = 50; // Maximum flap deflection for guidance + initialPitch = 2; + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 16; + lineGainD = 10.44; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 15; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 80; + seekerMaxRange = 1000; // Range from the missile which the seeker can visually search + + correctionDistance = 3; // distance from center of crosshair where missile slows down + offsetFromCrosshair[] = { 0, 0, 0 }; // where the missile wants to stay in relation to the center of the crosshair. + + // Attack profile type selection + defaultAttackProfile = "WIRE"; + attackProfiles[] = {"WIRE"}; +}; + +class GVAR(type_Molniya) { + enabled = 0; + + pitchRate = 45; // Minium flap deflection for guidance + yawRate = 45; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "IR"; + seekerTypes[] = { "IR" }; + + flareDistanceFilter = 50; + flareAngleFilter = 0.8; // can filter out flares that are >= flareAngleFilter to known target velocity + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "AugmentedProportionalNavigation"; + navigationTypes[] = { "AugmentedProportionalNavigation" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 40; // Angle from the shooter's view that can track the missile + seekerAccuracy = 0.85; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 5000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_R73) { + enabled = 0; + + pitchRate = 35; // Minium flap deflection for guidance + yawRate = 35; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "IR"; + seekerTypes[] = { "IR" }; + + flareDistanceFilter = 50; + flareAngleFilter = 0.8; // can filter out flares that are >= flareAngleFilter to known target velocity + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "AugmentedProportionalNavigation"; + navigationTypes[] = { "AugmentedProportionalNavigation" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 40; // Angle from the shooter's view that can track the missile + seekerAccuracy = 0.85; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 5000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_R74) { + enabled = 1; + + pitchRate = 50; // Minium flap deflection for guidance + yawRate = 50; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "IR"; + seekerTypes[] = { "IR" }; + + flareDistanceFilter = 50; + flareAngleFilter = 0.8; // can filter out flares that are >= flareAngleFilter to known target velocity + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "AugmentedProportionalNavigation"; + navigationTypes[] = { "AugmentedProportionalNavigation" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 75; // Angle from the shooter's view that can track the missile + seekerAccuracy = 0.95; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 8000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_R77) { + enabled = 0; + + pitchRate = 40; // Minium flap deflection for guidance + yawRate = 40; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "DopplerRadar"; + seekerTypes[] = { "DopplerRadar" }; + lockableTypes[] = {"Air"}; + + minimumSpeedFilter = 15; // filter out targets that have a closing velocity less than this + minimumTimeFilter = 0.00005; // filter out targets that are this close to the ground (speed of light) + maxTerrainCheck = 16000; // How far we should check for terrain + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "ZeroEffortMiss"; + navigationTypes[] = { "ZeroEffortMiss" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 50; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 2500; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR", "LOFT"}; + useModeForAttackProfile = 1; +}; + +class GVAR(type_Refleks) { + enabled = 0; + + pitchRate = 45; // Minium flap deflection for guidance + yawRate = 45; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 16; + lineGainD = 10.44; + + initialPitch = 2; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 5000; // Range from the missile which the seeker can visually search + + correctionDistance = 30; // distance from center of crosshair where missile slows down + offsetFromCrosshair[] = { 0, 0, 0 }; // where the missile wants to stay in relation to the center of the crosshair. + + // Attack profile type selection + defaultAttackProfile = "BEAM"; + attackProfiles[] = {"BEAM"}; +}; + +class GVAR(type_S400) { + enabled = 0; + + pitchRate = 25; // Minium flap deflection for guidance + yawRate = 25; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "DopplerRadar"; + seekerTypes[] = { "DopplerRadar" }; + lockableTypes[] = {"Air"}; + + minimumSpeedFilter = 5; // filter out targets that have a closing velocity less than this + minimumTimeFilter = 0.000001; // filter out targets that are this close to the ground (speed of light) + maxTerrainCheck = 16000; // How far we should check for terrain + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "ZeroEffortMiss"; + navigationTypes[] = { "ZeroEffortMiss" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 50; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 2500; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_Shturm) { + enabled = 0; + + pitchRate = 45; // Minium flap deflection for guidance + yawRate = 45; // Maximum flap deflection for guidance + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + showTrail = 1; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 16; + lineGainD = 10.44; + + initialPitch = 2; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 30; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 4000; // Range from the missile which the seeker can visually search + + offsetFromCrosshair[] = { 0, 0, 0 }; // where the missile wants to stay in relation to the center of the crosshair. + + // Attack profile type selection + defaultAttackProfile = "BEAM"; + attackProfiles[] = {"BEAM"}; +}; + +class GVAR(type_Strela) { + enabled = 0; + + pitchRate = 30; // Minium flap deflection for guidance + yawRate = 30; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "IR"; + seekerTypes[] = { "IR" }; + + flareDistanceFilter = 100; + flareAngleFilter = 1.6; // can filter out flares that are >= flareAngleFilter to known target velocity + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "ProportionalNavigation"; + navigationTypes[] = { "ProportionalNavigation" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 45; // Angle from the shooter's view that can track the missile + seekerAccuracy = 0.6; // seeker accuracy multiplier + + seekerMinRange = 10; + seekerMaxRange = 3700; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; + +class GVAR(type_Vikhr) { + enabled = 0; + showTrail = 1; + + pitchRate = 60; // Minium flap deflection for guidance + yawRate = 60; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "Line"; + navigationTypes[] = { "Line" }; + + lineGainP = 20; + lineGainD = 16; + correctionDistance = 5; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 15; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 30; + seekerMaxRange = 12000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "BEAM"; + attackProfiles[] = {"BEAM"}; +}; + +class GVAR(type_Vympel) { + enabled = 0; + + pitchRate = 35; // Minium flap deflection for guidance + yawRate = 35; // Maximum flap deflection for guidance + + canVanillaLock = 1; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "IR"; + seekerTypes[] = { "IR" }; + + flareDistanceFilter = 50; + flareAngleFilter = 0.8; // can filter out flares that are >= flareAngleFilter to known target velocity + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + defaultNavigationType = "AugmentedProportionalNavigation"; + navigationTypes[] = { "AugmentedProportionalNavigation" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 40; // Angle from the shooter's view that can track the missile + seekerAccuracy = 0.85; // seeker accuracy multiplier + + seekerMinRange = 75; + seekerMaxRange = 5000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "DIR"; + attackProfiles[] = {"DIR"}; +}; \ No newline at end of file diff --git a/addons/missileguidance/config.cpp b/addons/missileguidance/config.cpp index e98d99ebcbb..4e1f2e3e1f1 100644 --- a/addons/missileguidance/config.cpp +++ b/addons/missileguidance/config.cpp @@ -15,6 +15,8 @@ class CfgPatches { #include "ACE_GuidanceConfig.hpp" +#include "CfgMissileTypesNato.hpp" +#include "CfgMissileTypesWarsaw.hpp" #include "CfgEventhandlers.hpp" #include "CfgAmmo.hpp" #include "CfgMagazines.hpp" diff --git a/addons/nlaw/CfgAmmo.hpp b/addons/nlaw/CfgAmmo.hpp index f572678d20b..650fa148873 100644 --- a/addons/nlaw/CfgAmmo.hpp +++ b/addons/nlaw/CfgAmmo.hpp @@ -1,41 +1,11 @@ +class ace_missileguidance_type_Nlaw; class CfgAmmo { class M_NLAW_AT_F; class ACE_NLAW: M_NLAW_AT_F { hit = 400; // Default was 500 indirectHit = 20; // Default was 15 - class ace_missileguidance { + class ace_missileguidance: ace_missileguidance_type_Nlaw { enabled = 1; - - pitchRate = 5; // Minium flap deflection for guidance - yawRate = 10; // Maximum flap deflection for guidance - - canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode - - // Guidance type for munitions - defaultSeekerType = QGVAR(seeker); - seekerTypes[] = {QGVAR(seeker)}; - - defaultSeekerLockMode = "LOBL"; - seekerLockModes[] = {"LOBL"}; - - defaultNavigationType = QGVAR(PLOS); - navigationTypes[] = { QGVAR(PLOS) }; - - seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] - seekerAngle = 45; // Angle in front of the missile which can be searched - seekerAccuracy = 1; // seeker accuracy multiplier - - seekerMinRange = 0; - seekerMaxRange = 10; // Range from the missile which the seeker can visually search - - // Attack profile type selection - defaultAttackProfile = QGVAR(directAttack); - attackProfiles[] = {QGVAR(directAttack), QGVAR(overflyTopAttack)}; - useModeForAttackProfile = 1; - showHintOnCycle = 1; - - // Run once at fired event - onFired = QFUNC(onFired); }; }; From 6bc3277c542f5300e90ee017346d70a61beeffe3 Mon Sep 17 00:00:00 2001 From: Dart <59131299+DartRuffian@users.noreply.github.com> Date: Sat, 7 Sep 2024 18:07:37 -0500 Subject: [PATCH 10/24] Trenches - Make entrenching tool cache use hashMap (#10298) Save entrenching tools to hashmap instead of code --- addons/trenches/XEH_preInit.sqf | 2 +- addons/trenches/XEH_preStart.sqf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/trenches/XEH_preInit.sqf b/addons/trenches/XEH_preInit.sqf index 94decd550af..c8c9a3451f9 100644 --- a/addons/trenches/XEH_preInit.sqf +++ b/addons/trenches/XEH_preInit.sqf @@ -8,6 +8,6 @@ PREP_RECOMPILE_END; #include "initSettings.inc.sqf" -GVAR(entrenchingTools) = call (uiNamespace getVariable QGVAR(entrenchingTools)); +GVAR(entrenchingTools) = keys (uiNamespace getVariable QGVAR(entrenchingTools)); ADDON = true; diff --git a/addons/trenches/XEH_preStart.sqf b/addons/trenches/XEH_preStart.sqf index c966b2c9b6d..05065910397 100644 --- a/addons/trenches/XEH_preStart.sqf +++ b/addons/trenches/XEH_preStart.sqf @@ -6,4 +6,4 @@ private _entrenchingTools = (QUOTE(getNumber (_x >> QQGVAR(entrenchingTool)) > 0 _entrenchingTools append (QUOTE(getNumber (_x >> QQGVAR(entrenchingTool)) > 0) configClasses (configFile >> "CfgVehicles") apply {configName _x}); TRACE_1("",_entrenchingTools); -uiNamespace setVariable [QGVAR(entrenchingTools), compileFinal str _entrenchingTools]; +uiNamespace setVariable [QGVAR(entrenchingTools), compileFinal (_entrenchingTools createHashMapFromArray [])]; From 067f5f8cf2801c93c8cc58be6b1a4c64a1d178b2 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Sun, 8 Sep 2024 09:15:50 +0200 Subject: [PATCH 11/24] CSW - Add primary weapon support (#10284) * Add primary weapon support for CSW * Update addons/csw/functions/fnc_assemble_deployWeapon.sqf Co-authored-by: PabstMirror * Update crew-served-weapons-framework.md --------- Co-authored-by: PabstMirror --- .../fnc_assemble_canDeployWeapon.sqf | 5 ++++- .../functions/fnc_assemble_deployWeapon.sqf | 21 ++++++++++++------- .../fnc_assemble_deployWeaponModifier.sqf | 13 ++++++++---- .../functions/fnc_assemble_pickupWeapon.sqf | 17 +++++++++++++-- .../fnc_reload_getVehicleMagazine.sqf | 2 +- .../crew-served-weapons-framework.md | 1 + 6 files changed, 43 insertions(+), 16 deletions(-) diff --git a/addons/csw/functions/fnc_assemble_canDeployWeapon.sqf b/addons/csw/functions/fnc_assemble_canDeployWeapon.sqf index 6dd58fe4fba..12d00ca44e9 100644 --- a/addons/csw/functions/fnc_assemble_canDeployWeapon.sqf +++ b/addons/csw/functions/fnc_assemble_canDeployWeapon.sqf @@ -20,4 +20,7 @@ params ["_target", "_player"]; // If the current launcher has a config-value that defines the tripod, it is a CSW (alive _target) && -{(getText (configFile >> "CfgWeapons" >> secondaryWeapon _player >> QUOTE(ADDON) >> "assembleTo" >> typeOf _target)) != ""} +{ + (getText (configFile >> "CfgWeapons" >> secondaryWeapon _player >> QUOTE(ADDON) >> "assembleTo" >> typeOf _target)) != "" || + {(getText (configFile >> "CfgWeapons" >> primaryWeapon _player >> QUOTE(ADDON) >> "assembleTo" >> typeOf _target)) != ""} +} diff --git a/addons/csw/functions/fnc_assemble_deployWeapon.sqf b/addons/csw/functions/fnc_assemble_deployWeapon.sqf index ee0b3156eae..f852a1954af 100644 --- a/addons/csw/functions/fnc_assemble_deployWeapon.sqf +++ b/addons/csw/functions/fnc_assemble_deployWeapon.sqf @@ -21,8 +21,19 @@ [{ params ["_tripod", "_player"]; + private _tripodClassname = typeOf _tripod; + private _assembledClassname = getText (configFile >> "CfgWeapons" >> secondaryWeapon _player >> QUOTE(ADDON) >> "assembleTo" >> _tripodClassname); + private _index = 1; + + if (_assembledClassname == "") then { + _assembledClassname = getText (configFile >> "CfgWeapons" >> primaryWeapon _player >> QUOTE(ADDON) >> "assembleTo" >> _tripodClassname); + _index = 0; + }; + + if (!isClass (configFile >> "CfgVehicles" >> _assembledClassname)) exitWith {ERROR_1("bad static classname [%1]",_assembledClassname);}; + // Save magazines and attachments (handle loaded launchers which can become csw like CUP Metis) - private _carryWeaponInfo = (getUnitLoadout _player) select 1; + private _carryWeaponInfo = (getUnitLoadout _player) select _index; private _carryWeaponClassname = _carryWeaponInfo deleteAt 0; // Remove empty entries @@ -30,15 +41,9 @@ TRACE_3("assemble_deployWeapon_carryWeaponClassname",_tripod,_player,_carryWeaponClassname); - private _tripodClassname = typeOf _tripod; - private _weaponConfig = configFile >> "CfgWeapons" >> _carryWeaponClassname >> QUOTE(ADDON); - private _assembledClassname = getText (_weaponConfig >> "assembleTo" >> _tripodClassname); - - if (!isClass (configFile >> "CfgVehicles" >> _assembledClassname)) exitWith {ERROR_1("bad static classname [%1]",_assembledClassname);}; - _player removeWeaponGlobal _carryWeaponClassname; - private _deployTime = getNumber (_weaponConfig >> "deployTime"); + private _deployTime = getNumber (configFile >> "CfgWeapons" >> _carryWeaponClassname >> QUOTE(ADDON) >> "deployTime"); TRACE_4("",_carryWeaponClassname,_tripodClassname,_assembledClassname,_deployTime); diff --git a/addons/csw/functions/fnc_assemble_deployWeaponModifier.sqf b/addons/csw/functions/fnc_assemble_deployWeaponModifier.sqf index f98978195d9..f3f1fd7bfcb 100644 --- a/addons/csw/functions/fnc_assemble_deployWeaponModifier.sqf +++ b/addons/csw/functions/fnc_assemble_deployWeaponModifier.sqf @@ -20,9 +20,14 @@ params ["_target", "_player", "", "_actionData"]; -private _carryWeaponClassname = secondaryWeapon _player; -private _assembleTo = getText (configFile >> "CfgWeapons" >> _carryWeaponClassname >> QUOTE(ADDON) >> "assembleTo" >> typeOf _target); -private _icon = getText (configFile >> "CfgVehicles" >> _assembleTo >> "picture"); -TRACE_2("",_assembleTo,_icon); +private _tripodClassname = typeOf _target; +private _assembledClassname = getText (configFile >> "CfgWeapons" >> secondaryWeapon _player >> QUOTE(ADDON) >> "assembleTo" >> _tripodClassname); + +if (_assembledClassname == "") then { + _assembledClassname = getText (configFile >> "CfgWeapons" >> primaryWeapon _player >> QUOTE(ADDON) >> "assembleTo" >> _tripodClassname); +}; + +private _icon = getText (configFile >> "CfgVehicles" >> _assembledClassname >> "picture"); +TRACE_2("",_assembledClassname,_icon); _actionData set [2, _icon]; diff --git a/addons/csw/functions/fnc_assemble_pickupWeapon.sqf b/addons/csw/functions/fnc_assemble_pickupWeapon.sqf index 65dc5fa7403..867c151d278 100644 --- a/addons/csw/functions/fnc_assemble_pickupWeapon.sqf +++ b/addons/csw/functions/fnc_assemble_pickupWeapon.sqf @@ -58,7 +58,9 @@ if (_carryWeaponMag isEqualTo [] && {_carryMag in _carryWeaponMags}) then { TRACE_3("Adding mag to secondary weapon",_xMag,_xAmmo,_carryMag); _carryWeaponMag = [_carryMag, _xAmmo]; - DEC(_xAmmo); + + // Do not return this magazine, as it will be put into the weapon + continue; }; if ((_xAmmo > 0) && {_carryMag != ""}) then { TRACE_2("Removing ammo",_xMag,_carryMag); @@ -82,8 +84,19 @@ [{ params ["_player", "_weaponPos", "_carryWeaponClassname", "_carryWeaponMag", "_turretClassname"]; + private _carryWeaponType = _carryWeaponClassname call EFUNC(common,getWeaponType); + + if !(_carryWeaponType in [1, 2]) exitWith { + ERROR_1("bad carry weapon type [%1]",_carryWeaponClassname); + + if (_carryWeaponMag isEqualTo []) exitWith {}; + + // Return the ammo, so it doesn't vanish + [_player, _carryWeaponMag select 0, _carryWeaponMag select 1] call FUNC(reload_handleReturnAmmo); + }; + // Give the weapon to the player if possible - if ((alive _player) && {(secondaryWeapon _player) == ""}) exitWith { + if ((alive _player) && {([primaryWeapon _player, secondaryWeapon _player] select (_carryWeaponType - 1)) == ""}) exitWith { [_player, _carryWeaponClassname] call CBA_fnc_addWeaponWithoutItems; if (_carryWeaponMag isNotEqualTo []) then { diff --git a/addons/csw/functions/fnc_reload_getVehicleMagazine.sqf b/addons/csw/functions/fnc_reload_getVehicleMagazine.sqf index 3682651aac6..24d21534ee2 100644 --- a/addons/csw/functions/fnc_reload_getVehicleMagazine.sqf +++ b/addons/csw/functions/fnc_reload_getVehicleMagazine.sqf @@ -37,7 +37,7 @@ private _bestMagCount = -1; _bestMagCount = _xAmmo; }; }; - } forEach (getArray (configFile >> "CfgWeapons" >> _weapon >> "magazines")); + } forEach (compatibleMagazines _weapon); } forEach (_vehicle weaponsTurret _turret); TRACE_3("best fit",_desiredAmmo,_bestMag,_bestMagCount); diff --git a/docs/wiki/framework/crew-served-weapons-framework.md b/docs/wiki/framework/crew-served-weapons-framework.md index 9b3ef28d4fb..a2f8e74ae65 100644 --- a/docs/wiki/framework/crew-served-weapons-framework.md +++ b/docs/wiki/framework/crew-served-weapons-framework.md @@ -39,6 +39,7 @@ class CfgWeapons { ### 1.2 Carryable Weapon Carried CSW weapons are technically rocket launchers. This allows the player to carry both a CSW weapon and a backpack with magazines for the CSW. +ACE 3.18.0 added support for primary weapons to be used as CSW weapons, but not tripods. ```cpp class CfgWeapons { From 36b9835e1916c59c7e8f64b5764bd0ae136cc117 Mon Sep 17 00:00:00 2001 From: OverlordZorn <56258612+OverlordZorn@users.noreply.github.com> Date: Mon, 9 Sep 2024 01:07:18 +0200 Subject: [PATCH 12/24] Compat RF - Field Rations - Watersource Offsets (#10282) * Update config.cpp * Create CfgVehicles.hpp * Update CfgVehicles.hpp * Update CfgVehicles.hpp * remove empty line2 * macro'fied * Update config.cpp * Update addons/compat_rf/CfgVehicles.hpp Co-authored-by: PabstMirror * Update addons/compat_rf/CfgVehicles.hpp Co-authored-by: PabstMirror * Update addons/compat_rf/CfgVehicles.hpp Co-authored-by: PabstMirror * Update addons/compat_rf/CfgVehicles.hpp Co-authored-by: PabstMirror * Update addons/compat_rf/CfgVehicles.hpp Co-authored-by: Mike-MF * Update addons/compat_rf/CfgVehicles.hpp Co-authored-by: Mike-MF * Update addons/compat_rf/CfgVehicles.hpp Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> * Update addons/compat_rf/CfgVehicles.hpp Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> * Update addons/compat_rf/CfgVehicles.hpp Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --------- Co-authored-by: PabstMirror Co-authored-by: Mike-MF Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/compat_rf/CfgVehicles.hpp | 25 +++++++++++++++++++++++++ addons/compat_rf/config.cpp | 3 ++- 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 addons/compat_rf/CfgVehicles.hpp diff --git a/addons/compat_rf/CfgVehicles.hpp b/addons/compat_rf/CfgVehicles.hpp new file mode 100644 index 00000000000..fa0343908a9 --- /dev/null +++ b/addons/compat_rf/CfgVehicles.hpp @@ -0,0 +1,25 @@ +class CfgVehicles { + // Applies the offset to all RF Offroads which can have the optional tank in the back + class Offroad_01_unarmed_base_F; + class Pickup_01_base_rf: Offroad_01_unarmed_base_F { + EXGVAR(field_rations,offset)[] = {-0.04, -2.45, -0.9}; + }; + + // Enable Water Source by Default + class C_IDAP_Pickup_rf; + class C_IDAP_Pickup_water_rf: C_IDAP_Pickup_rf { + EXGVAR(field_rations,waterSupply) = 500; + }; + + class O_Truck_03_fuel_F; + class C_Truck_03_water_rf: O_Truck_03_fuel_F { + EXGVAR(field_rations,waterSupply) = 10000; + EXGVAR(field_rations,offset)[] = {0, -5.05, -0.3}; + }; + + class B_Truck_01_fuel_F; + class C_Truck_01_water_rf: B_Truck_01_fuel_F { + EXGVAR(field_rations,waterSupply) = 10000; + EXGVAR(field_rations,offset)[] = {-0.41, -5.15, -0.3}; + }; +}; diff --git a/addons/compat_rf/config.cpp b/addons/compat_rf/config.cpp index ab6fb942751..52ef83c1b74 100644 --- a/addons/compat_rf/config.cpp +++ b/addons/compat_rf/config.cpp @@ -9,10 +9,11 @@ class CfgPatches { requiredAddons[] = {"RF_Data_Loadorder"}; skipWhenMissingDependencies = 1; author = ECSTRING(common,ACETeam); - authors[] = {"Mike"}; + authors[] = {"Mike", "OverlordZorn[CVO]"}; url = ECSTRING(main,URL); VERSION_CONFIG; }; }; #include "CfgWeapons.hpp" +#include "CfgVehicles.hpp" From 8c582f1fe0b9929ee883da8859255df96902e99d Mon Sep 17 00:00:00 2001 From: Dart <59131299+DartRuffian@users.noreply.github.com> Date: Sun, 8 Sep 2024 19:12:43 -0500 Subject: [PATCH 13/24] Arsenal Stats - Add support for multiline text (#9856) Co-authored-by: Grim <69561145+LinkIsGrim@users.noreply.github.com> Co-authored-by: Walthzer <19926813+Walthzer@users.noreply.github.com> --- addons/arsenal/defines.hpp | 2 + addons/arsenal/functions/fnc_handleStats.sqf | 54 +++++++++++++++++--- addons/arsenal/ui/RscAttributes.hpp | 14 ++--- docs/wiki/framework/arsenal-framework.md | 2 +- 4 files changed, 57 insertions(+), 15 deletions(-) diff --git a/addons/arsenal/defines.hpp b/addons/arsenal/defines.hpp index 6967c3f0401..ecd50f7a479 100644 --- a/addons/arsenal/defines.hpp +++ b/addons/arsenal/defines.hpp @@ -154,6 +154,8 @@ #define IDC_statsPreviousPage 52 #define IDC_statsNextPage 53 #define IDC_statsCurrentPage 54 +#define IDC_statsBoxTitleBackground 55 +#define IDC_statsBoxBackground 56 #define IDC_actionsBox 90 #define IDC_actionsBackground1 90010 #define IDC_actionsBackground2 90011 diff --git a/addons/arsenal/functions/fnc_handleStats.sqf b/addons/arsenal/functions/fnc_handleStats.sqf index 3fd92d64f0f..0511c05a25a 100644 --- a/addons/arsenal/functions/fnc_handleStats.sqf +++ b/addons/arsenal/functions/fnc_handleStats.sqf @@ -19,6 +19,8 @@ params ["_display", "_control", "_curSel", ["_itemCfg", configNull]]; private _statsBoxCtrl = _display displayCtrl IDC_statsBox; +private _statsBoxTitleBackgroundCtrl = _display displayCtrl IDC_statsBoxTitleBackground; +private _statsBoxBackgroundCtrl = _display displayCtrl IDC_statsBoxBackground; private _statsPreviousPageCtrl = _display displayCtrl IDC_statsPreviousPage; private _statsNextPageCtrl = _display displayCtrl IDC_statsNextPage; private _statsCurrentPageCtrl = _display displayCtrl IDC_statsCurrentPage; @@ -111,6 +113,7 @@ private _fnc_handleStats = { private _statsBarCtrl = controlNull; private _statsTextCtrl = controlNull; private _textStatementResult = ""; + private _lastCtrl = _statsBoxTitleBackgroundCtrl; { _x params ["", "_configEntry", "_title", "_bools", "_statements"]; @@ -127,6 +130,17 @@ private _fnc_handleStats = { _statsTitleCtrl ctrlSetText _title; _statsTitleCtrl ctrlSetFade 0; + // Vertical Position + ctrlPosition _lastCtrl params ["", "_lastPosY", "", "_lastPosH"]; + _statsTitleCtrl ctrlSetPositionY (_lastPosY + _lastPosH + GRID_H); + { + _x ctrlSetPositionY (_lastPosY + _lastPosH + GRID_H + (5 * GRID_H)); + } forEach [ + _statsBackgroundCtrl, + _statsBarCtrl, + _statsTextCtrl + ]; + // Handle bars if (_showBar) then { _statsBarCtrl progressSetPosition ([_configEntry, _itemCfg] call _barStatement); @@ -140,18 +154,39 @@ private _fnc_handleStats = { // Handle text entries if (_showText) then { _textStatementResult = [_configEntry, _itemCfg] call _textStatement; - - if !(_textStatementResult isEqualType "") then { - _textStatementResult = str _textStatementResult; + if (_textStatementResult isEqualType []) then { + _textStatementResult = _textStatementResult joinString endl; + } else { + if !(_textStatementResult isEqualType "") then { + _textStatementResult = str _textStatementResult; + }; }; _statsTextCtrl ctrlSetText _textStatementResult; _statsTextCtrl ctrlSetTextColor ([[1, 1, 1, 1], [0, 0, 0, 1]] select (_showBar)); + + //Height based on Text lines + { + _x ctrlSetPositionH (ctrlTextHeight _statsTextCtrl); + } forEach [ + _statsBackgroundCtrl, + _statsBarCtrl, + _statsTextCtrl + ]; + _statsTextCtrl ctrlSetFade 0; } else { _statsTextCtrl ctrlSetFade 1; + //Ensure default height + { + _x ctrlSetPositionH (5 * GRID_H); + } forEach [ + _statsBackgroundCtrl, + _statsBarCtrl, + _statsTextCtrl + ]; }; - + { _x ctrlCommit 0; } forEach [ @@ -160,24 +195,29 @@ private _fnc_handleStats = { _statsBarCtrl, _statsTextCtrl ]; + + _lastCtrl = _statsTextCtrl; + } forEach _statsToDisplay; // Resize the window (5 - _statsCount) call _fnc_hideUnused; - private _height = 10 * _statsCount + 5; + ctrlPosition _lastCtrl params ["", "_lastPosY", "", "_lastPosH"]; _statsBoxCtrl ctrlSetPosition [ (0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP, safeZoneY + 1.8 * GRID_H, 47 * GRID_W, - _height * GRID_H + _lastPosY + _lastPosH + GRID_H ]; + _statsBoxBackgroundCtrl ctrlSetPositionH (_lastPosY + _lastPosH + GRID_H); + _statsBoxBackgroundCtrl ctrlCommit 0; _statsBoxCtrl ctrlCommit 0; // Move the actions box private _ctrl = _display displayCtrl IDC_actionsBox; private _pos = ctrlPosition _ctrl; - _pos set [1, safeZoneY + (_height + 3.6) * GRID_H]; + _pos set [1, safeZoneY + (_lastPosY + _lastPosH + GRID_H + (3.6 * GRID_H))]; _ctrl ctrlSetPosition _pos; _ctrl ctrlCommit 0; diff --git a/addons/arsenal/ui/RscAttributes.hpp b/addons/arsenal/ui/RscAttributes.hpp index 6ec69223355..b487cffd617 100644 --- a/addons/arsenal/ui/RscAttributes.hpp +++ b/addons/arsenal/ui/RscAttributes.hpp @@ -283,7 +283,7 @@ class GVAR(display) { h = QUOTE(55 * GRID_H); class controls { class statsStaticBackground1: ctrlStaticBackground { - idc = -1; + idc = IDC_statsBoxBackground; x = QUOTE(0); y = QUOTE(0); w = QUOTE(47 * GRID_W); @@ -291,7 +291,7 @@ class GVAR(display) { colorBackground[] = {0.1,0.1,0.1,0.5}; }; class statsStaticBackground2: ctrlStaticBackground { - idc = -1; + idc = IDC_statsBoxTitleBackground; x = QUOTE(0); y = QUOTE(0); w = QUOTE(47 * GRID_W); @@ -316,7 +316,7 @@ class GVAR(display) { x = QUOTE(1 * GRID_W); y = QUOTE(10 * GRID_H); w = QUOTE(45 * GRID_W); - h = QUOTE(4 * GRID_H); + h = QUOTE(5 * GRID_H); colorBackground[] = {1,1,1,0.15}; }; class statsBar1: ctrlProgress { @@ -329,9 +329,9 @@ class GVAR(display) { x = QUOTE(1 * GRID_W); y = QUOTE(10 * GRID_H); w = QUOTE(45 * GRID_W); - h = QUOTE(4 * GRID_H); + h = QUOTE(5 * GRID_H); }; - class statsText1: RscText { + class statsText1: RscTextMulti { idc = IDC_statsText1; shadow = 0; fade = 1; @@ -340,7 +340,7 @@ class GVAR(display) { x = QUOTE(0 * GRID_W); y = QUOTE(10 * GRID_H); w = QUOTE(45 * GRID_W); - h = QUOTE(4 * GRID_H); + h = QUOTE(5 * GRID_H); sizeEx = QUOTE(5 * GRID_H); text = ""; }; @@ -482,7 +482,7 @@ class GVAR(display) { x = QUOTE(1 * GRID_W); y = QUOTE(6 * GRID_H); w = QUOTE(45 * GRID_W); - h = QUOTE(4 * GRID_H); + h = QUOTE(5 * GRID_H); }; class actionsText2: actionsText1 { idc = IDC_actionsText2; diff --git a/docs/wiki/framework/arsenal-framework.md b/docs/wiki/framework/arsenal-framework.md index a02dcdf646a..330e7fa99b1 100644 --- a/docs/wiki/framework/arsenal-framework.md +++ b/docs/wiki/framework/arsenal-framework.md @@ -214,7 +214,7 @@ class ace_arsenal_stats { showBar = 1; // 0 disabled; 1 enabled; showText = 1; // 0 disabled; 1 enabled; barStatement = "1"; // Statement evaluated to set the bar progress, needs to return a NUMBER. - textStatement = "test entry"; // statement evaluated to set the text entry, can return anything. + textStatement = "test entry"; // statement evaluated to set the text entry, can return anything. Arrays will have a linebreak added after each element. condition = "true"; // Condition for the stats to be displayed, default is true if not defined, needs to return a BOOL. tabs[] = { {0,1,2}, { } }; // Arrays of tabs, left array is left tabs, right array is right tabs. }; From 4092dddcbe9543ad689484740ed84be226bff2ea Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Tue, 10 Sep 2024 09:25:36 +0200 Subject: [PATCH 14/24] SPE Compat - Make 50Rnd M1919 & M2 100Rnd belts linkable (#10301) Tweaked SPE belts --- addons/compat_spe/CfgMagazines/csw.hpp | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/addons/compat_spe/CfgMagazines/csw.hpp b/addons/compat_spe/CfgMagazines/csw.hpp index 404156bd8f8..9fa46140899 100644 --- a/addons/compat_spe/CfgMagazines/csw.hpp +++ b/addons/compat_spe/CfgMagazines/csw.hpp @@ -2,43 +2,29 @@ class CA_Magazine; // M1919A4/A6 class SPE_50Rnd_762x63: CA_Magazine { - ACE_isBelt = 0; -}; - -class SPE_100Rnd_762x63: SPE_50Rnd_762x63 { ACE_isBelt = 1; }; -class SPE_100Rnd_762x63_M1: SPE_100Rnd_762x63 { +// M2 +class VehicleMagazine; +class SPE_100Rnd_127x99_M2: VehicleMagazine { ACE_isBelt = 1; }; -class SPE_100Rnd_762x63_M2_AP: SPE_100Rnd_762x63 { - ACE_isBelt = 1; -}; - -//MG34/42 - +// MG34/42 class SPE_50Rnd_792x57: CA_Magazine { ACE_isBelt = 0; }; - -class SPE_50Rnd_792x57_sS: SPE_50Rnd_792x57 { - ACE_isBelt = 0; -}; - -class SPE_50Rnd_792x57_SMK: SPE_50Rnd_792x57_sS { - ACE_isBelt = 0; -}; - class SPE_100Rnd_792x57: SPE_50Rnd_792x57 { ACE_isBelt = 1; }; +class SPE_50Rnd_792x57_sS; class SPE_100Rnd_792x57_sS: SPE_50Rnd_792x57_sS { ACE_isBelt = 1; }; +class SPE_50Rnd_792x57_SMK; class SPE_100Rnd_792x57_SMK: SPE_50Rnd_792x57_SMK { ACE_isBelt = 1; }; From 4abae0fcb53b2a48c8794faeaca20e0e7d6b45f1 Mon Sep 17 00:00:00 2001 From: OverlordZorn <56258612+OverlordZorn@users.noreply.github.com> Date: Wed, 11 Sep 2024 23:43:20 +0200 Subject: [PATCH 15/24] Nightvision - Fixes Exploit with FogScaling (#10299) Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/nightvision/functions/fnc_pfeh.sqf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/addons/nightvision/functions/fnc_pfeh.sqf b/addons/nightvision/functions/fnc_pfeh.sqf index dbd101631cd..9d5f6e93bb8 100644 --- a/addons/nightvision/functions/fnc_pfeh.sqf +++ b/addons/nightvision/functions/fnc_pfeh.sqf @@ -163,7 +163,9 @@ if (CBA_missionTime < GVAR(nextEffectsUpdate)) then { }; _fogApply = linearConversion [0, 1, GVAR(priorFog) select 0, (GVAR(fogScaling) * _fogApply), 1]; // mix in old fog if present - GVAR(nvgFog) = [_fogApply, 0, 0]; + GVAR(nvgFog) = fogParams; + GVAR(nvgFog) set [0, _fogApply]; + 0 setFog GVAR(nvgFog) }; From 5d4f1cd1c7f172d0bfab4abfa748930cdc46d375 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Wed, 11 Sep 2024 16:43:31 -0500 Subject: [PATCH 16/24] General - Optimize some if statements (#10302) --- addons/common/functions/fnc_claim.sqf | 6 +++--- addons/common/functions/fnc_getDeathAnim.sqf | 6 +++--- .../functions/fnc_getActionOffset.sqf | 8 ++++---- .../functions/fnc_getRemainingWater.sqf | 8 ++++---- .../functions/fnc_applyRotorWashEffect.sqf | 10 +++++----- addons/interact_menu/functions/fnc_keyDown.sqf | 14 +++++++------- .../functions/fnc_renderActionPoints.sqf | 15 ++++++++------- addons/laser/XEH_postInit.sqf | 6 +++--- .../medical_engine/functions/fnc_handleDamage.sqf | 10 +++++----- .../functions/fnc_showApplicationPage.sqf | 2 +- addons/missileguidance/functions/fnc_checkLos.sqf | 6 +++--- .../functions/fnc_seekerType_SACLOS.sqf | 8 ++++---- addons/nametags/functions/fnc_drawNameTagIcon.sqf | 6 +++--- addons/nametags/functions/fnc_onDraw3d.sqf | 6 +++--- .../functions/fnc_addFreeSeatsActions.sqf | 8 ++++---- .../fnc_calculateZeroAngleCorrection.sqf | 6 +++--- addons/spectator/functions/fnc_cam_tick.sqf | 6 +++--- .../functions/fnc_handleVehicleDamage.sqf | 6 +++--- addons/volume/XEH_postInitClient.sqf | 6 +++--- 19 files changed, 72 insertions(+), 71 deletions(-) diff --git a/addons/common/functions/fnc_claim.sqf b/addons/common/functions/fnc_claim.sqf index 997d54f33b8..170c2c6a8f3 100644 --- a/addons/common/functions/fnc_claim.sqf +++ b/addons/common/functions/fnc_claim.sqf @@ -30,10 +30,10 @@ _target setVariable [QGVAR(owner), _unit, true]; // lock target object if (_lockTarget) then { - if (!isNull _unit) then { - [QGVAR(lockVehicle), _target, _target] call CBA_fnc_targetEvent; - } else { + if (isNull _unit) then { [QGVAR(unlockVehicle), _target, _target] call CBA_fnc_targetEvent; + } else { + [QGVAR(lockVehicle), _target, _target] call CBA_fnc_targetEvent; }; }; diff --git a/addons/common/functions/fnc_getDeathAnim.sqf b/addons/common/functions/fnc_getDeathAnim.sqf index 18c6c93c074..4e0b0578729 100644 --- a/addons/common/functions/fnc_getDeathAnim.sqf +++ b/addons/common/functions/fnc_getDeathAnim.sqf @@ -29,7 +29,9 @@ private _unitActionsCfg = configFile >> "CfgMovesBasic" >> "Actions" >> getText TRACE_2("Animation/Action",configName _unitAnimationCfg,configName _unitActionsCfg); -if (!isNull objectParent _unit) then { +if (isNull objectParent _unit) then { + _returnAnimation = getText (_unitActionsCfg >> "die"); +} else { private _interpolateArray = getArray (_unitAnimationCfg >> "interpolateTo"); for "_index" from 0 to (count _interpolateArray - 1) step 2 do { @@ -42,8 +44,6 @@ if (!isNull objectParent _unit) then { _returnAnimation = _indexAnimation; }; }; -} else { - _returnAnimation = getText (_unitActionsCfg >> "die"); }; //Fallback if nothing valid found: diff --git a/addons/field_rations/functions/fnc_getActionOffset.sqf b/addons/field_rations/functions/fnc_getActionOffset.sqf index dd7658dfda1..763654c6559 100644 --- a/addons/field_rations/functions/fnc_getActionOffset.sqf +++ b/addons/field_rations/functions/fnc_getActionOffset.sqf @@ -18,11 +18,11 @@ params ["_object"]; private _configOf = configOf _object; -if !(isNull _configOf) then { +if (isNull _configOf) then { + // Check for offset corresponding to p3d list + GVAR(waterSourceOffsets) param [GVAR(waterSourceP3ds) find (getModelInfo _object select 0), [0, 0, 0], [[]]]; +} else { // Check for offset in config since we have valid typeOf private _offset = getArray (_configOf >> QXGVAR(offset)); if (_offset isEqualTo []) then {[0, 0, 0]} else {_offset}; -} else { - // Check for offset corresponding to p3d list - GVAR(waterSourceOffsets) param [GVAR(waterSourceP3ds) find (getModelInfo _object select 0), [0, 0, 0], [[]]]; }; diff --git a/addons/field_rations/functions/fnc_getRemainingWater.sqf b/addons/field_rations/functions/fnc_getRemainingWater.sqf index 253fd62285d..1011136e0ce 100644 --- a/addons/field_rations/functions/fnc_getRemainingWater.sqf +++ b/addons/field_rations/functions/fnc_getRemainingWater.sqf @@ -23,7 +23,10 @@ private _water = _source getVariable QGVAR(currentWaterSupply); if (isNil "_water") then { private _configOf = configOf _source; - if !(isNull _configOf) then { + if (isNull _configOf) then { + // Check the p3d name against list + _water = if ((getModelInfo _source select 0) in GVAR(waterSourceP3ds)) then {REFILL_WATER_INFINITE} else {REFILL_WATER_DISABLED}; + } else { // Check for waterSupply entry since we have valid typeOf _water = getNumber (_configOf >> QXGVAR(waterSupply)); if (_water == 0) then {_water = REFILL_WATER_DISABLED}; @@ -35,9 +38,6 @@ if (isNil "_water") then { _source setVariable [QGVAR(currentWaterSupply), _water, true]; }; }; - } else { - // Check the p3d name against list - _water = if ((getModelInfo _source select 0) in GVAR(waterSourceP3ds)) then {REFILL_WATER_INFINITE} else {REFILL_WATER_DISABLED}; }; }; diff --git a/addons/goggles/functions/fnc_applyRotorWashEffect.sqf b/addons/goggles/functions/fnc_applyRotorWashEffect.sqf index 341adcecdde..5a77a16ce91 100644 --- a/addons/goggles/functions/fnc_applyRotorWashEffect.sqf +++ b/addons/goggles/functions/fnc_applyRotorWashEffect.sqf @@ -64,14 +64,14 @@ if !(_safe) then { if !([_unit] call FUNC(isGogglesVisible)) exitWith {}; if (GETDUSTT(DAMOUNT) < 2) then { - if !(GETDUSTT(DACTIVE)) then { - SETDUST(DACTIVE,true); - - call FUNC(applyDustEffect); - } else { + if (GETDUSTT(DACTIVE)) then { if (_rotorWash select 1 > 0.5) then { call FUNC(applyDustEffect); }; + } else { + SETDUST(DACTIVE,true); + + call FUNC(applyDustEffect); }; }; diff --git a/addons/interact_menu/functions/fnc_keyDown.sqf b/addons/interact_menu/functions/fnc_keyDown.sqf index 2d15715b953..d87f6cfa3ba 100644 --- a/addons/interact_menu/functions/fnc_keyDown.sqf +++ b/addons/interact_menu/functions/fnc_keyDown.sqf @@ -116,13 +116,7 @@ GVAR(selfMenuOffset) = (AGLToASL (positionCameraToWorld [0, 0, 2])) vectorDiff ( //Auto expand the first level when self, mounted vehicle or zeus (skips the first animation as there is only one choice) if (GVAR(openedMenuType) == 0) then { if (isNull curatorCamera) then { - if !(isNull (ACE_controlledUAV select 0)) then { - GVAR(menuDepthPath) = [["ACE_SelfActions", (ACE_controlledUAV select 0)]]; - GVAR(expanded) = true; - GVAR(expandedTime) = diag_tickTime; - GVAR(lastPath) = +GVAR(menuDepthPath); - GVAR(startHoverTime) = -1000; - } else { + if (isNull (ACE_controlledUAV select 0)) then { if (vehicle ACE_player != ACE_player) then { GVAR(menuDepthPath) = [["ACE_SelfActions", (vehicle ACE_player)]]; GVAR(expanded) = true; @@ -130,6 +124,12 @@ if (GVAR(openedMenuType) == 0) then { GVAR(lastPath) = +GVAR(menuDepthPath); GVAR(startHoverTime) = -1000; }; + } else { + GVAR(menuDepthPath) = [["ACE_SelfActions", (ACE_controlledUAV select 0)]]; + GVAR(expanded) = true; + GVAR(expandedTime) = diag_tickTime; + GVAR(lastPath) = +GVAR(menuDepthPath); + GVAR(startHoverTime) = -1000; }; } else { GVAR(menuDepthPath) = [["ACE_ZeusActions", (getAssignedCuratorLogic player)]]; diff --git a/addons/interact_menu/functions/fnc_renderActionPoints.sqf b/addons/interact_menu/functions/fnc_renderActionPoints.sqf index 492f8b73c9a..502e4de6f94 100644 --- a/addons/interact_menu/functions/fnc_renderActionPoints.sqf +++ b/addons/interact_menu/functions/fnc_renderActionPoints.sqf @@ -97,11 +97,11 @@ private _fnc_renderSelfActions = { // Iterate through base level class actions and render them if appropiate private _classActions = GVAR(ActSelfNamespace) get typeOf _target; - private _pos = if !(GVAR(useCursorMenu)) then { + private _pos = if (GVAR(useCursorMenu)) then { + [0.5, 0.5] + } else { //Convert to ASL, add offset and then convert back to AGL (handles waves when over water) ASLToAGL ((AGLToASL (positionCameraToWorld [0, 0, 0])) vectorAdd GVAR(selfMenuOffset)); - } else { - [0.5, 0.5] }; { @@ -123,10 +123,7 @@ GVAR(collectedActionPoints) resize 0; // Render nearby actions, unit self actions or vehicle self actions as appropiate if (GVAR(openedMenuType) == 0) then { if (isNull curatorCamera) then { - if !(isNull (ACE_controlledUAV select 0)) then { - // Render UAV self actions when in control of UAV AI - (ACE_controlledUAV select 0) call _fnc_renderSelfActions; - } else { + if (isNull (ACE_controlledUAV select 0)) then { if (vehicle ACE_player == ACE_player) then { if (diag_tickTime > GVAR(lastTimeSearchedActions) + 0.20) then { // Once every 0.2 secs, collect nearby objects active and visible action points and render them @@ -139,6 +136,10 @@ if (GVAR(openedMenuType) == 0) then { // Render vehicle self actions when in vehicle (vehicle ACE_player) call _fnc_renderSelfActions; }; + } else { + // Render UAV self actions when in control of UAV AI + (ACE_controlledUAV select 0) call _fnc_renderSelfActions; + }; } else { // Render zeus actions when zeus open diff --git a/addons/laser/XEH_postInit.sqf b/addons/laser/XEH_postInit.sqf index 768752bee2e..eb4cb247ed7 100644 --- a/addons/laser/XEH_postInit.sqf +++ b/addons/laser/XEH_postInit.sqf @@ -21,10 +21,10 @@ if (hasInterface) then { ["ACE_controlledUAV", { params ["_UAV", "_seatAI", "_turret", "_position"]; TRACE_4("ACE_controlledUAV EH",_UAV,_seatAI,_turret,_position); - if (!isNull _seatAI) then { - [_seatAI] call FUNC(showVehicleHud); - } else { + if (isNull _seatAI) then { [ace_player] call FUNC(showVehicleHud); + } else { + [_seatAI] call FUNC(showVehicleHud); }; }] call CBA_fnc_addEventHandler; }] call CBA_fnc_addEventHandler; diff --git a/addons/medical_engine/functions/fnc_handleDamage.sqf b/addons/medical_engine/functions/fnc_handleDamage.sqf index 95e48fcc3e4..591e68e2533 100644 --- a/addons/medical_engine/functions/fnc_handleDamage.sqf +++ b/addons/medical_engine/functions/fnc_handleDamage.sqf @@ -165,7 +165,11 @@ if (_context == 2) then { if (_environmentDamage) then { // Any collision with terrain/vehicle/object has a shooter // Check this first because burning can happen at any velocity - if !(isNull _shooter) then { + if (isNull _shooter) then { + // Anything else is almost guaranteed to be fire damage + _ammo = "fire"; + TRACE_5("Fire Damage",_unit,_shooter,_instigator,_damage,_allDamages); + } else { /* If shooter != unit then they hit unit, otherwise it could be: - Unit hitting anything at speed @@ -180,10 +184,6 @@ if (_context == 2) then { _ammo = "collision"; TRACE_5("Collision",_unit,_shooter,_instigator,_damage,_allDamages); }; - } else { - // Anything else is almost guaranteed to be fire damage - _ammo = "fire"; - TRACE_5("Fire Damage",_unit,_shooter,_instigator,_damage,_allDamages); }; }; diff --git a/addons/microdagr/functions/fnc_showApplicationPage.sqf b/addons/microdagr/functions/fnc_showApplicationPage.sqf index 75f817ad3f3..e150bf2261a 100644 --- a/addons/microdagr/functions/fnc_showApplicationPage.sqf +++ b/addons/microdagr/functions/fnc_showApplicationPage.sqf @@ -57,7 +57,7 @@ if (GVAR(currentApplicationPage) == APP_MODE_INFODISPLAY) then { (_display displayCtrl IDC_MAPDETAILS) ctrlShow ((GVAR(currentApplicationPage) == APP_MODE_MAP) && {GVAR(mapShowTexture)}); if (GVAR(currentApplicationPage) == APP_MODE_MAP) then { - _theMap = if (!GVAR(mapShowTexture)) then {_display displayCtrl IDC_MAPPLAIN} else {_display displayCtrl IDC_MAPDETAILS}; + _theMap = if (GVAR(mapShowTexture)) then {_display displayCtrl IDC_MAPDETAILS} else {_display displayCtrl IDC_MAPPLAIN}; _mapSize = (ctrlPosition _theMap) select 3; _theMap ctrlMapAnimAdd [0, (GVAR(mapZoom) / _mapSize), GVAR(mapPosition)]; ctrlMapAnimCommit _theMap; diff --git a/addons/missileguidance/functions/fnc_checkLos.sqf b/addons/missileguidance/functions/fnc_checkLos.sqf index 242b595ab8f..152c7c24074 100644 --- a/addons/missileguidance/functions/fnc_checkLos.sqf +++ b/addons/missileguidance/functions/fnc_checkLos.sqf @@ -34,12 +34,12 @@ private _targetAimPos = aimPos _target; private _seekerPos = getPosASL _seeker; private _return = true; -if (!((terrainIntersectASL [_seekerPos, _targetPos]) && {terrainIntersectASL [_seekerPos, _targetAimPos]})) then { +if ((terrainIntersectASL [_seekerPos, _targetPos]) && {terrainIntersectASL [_seekerPos, _targetAimPos]}) then { + _return = false; +} else { if (lineIntersects [_seekerPos, _targetPos, _seeker, _target]) then { _return = false; }; -} else { - _return = false; }; _return diff --git a/addons/missileguidance/functions/fnc_seekerType_SACLOS.sqf b/addons/missileguidance/functions/fnc_seekerType_SACLOS.sqf index 1641ff4a7df..d9fd444043f 100644 --- a/addons/missileguidance/functions/fnc_seekerType_SACLOS.sqf +++ b/addons/missileguidance/functions/fnc_seekerType_SACLOS.sqf @@ -25,7 +25,10 @@ _seekerStateParams params ["_memoryPointGunnerOptics", "_animationSourceBody", " private _shooterPos = AGLToASL (_shooter modelToWorldVisual (_shooter selectionPosition _memoryPointGunnerOptics)); private _projPos = getPosASL _projectile; -private _lookDirection = if !(_shooter isKindOf "CAManBase" || {_shooter isKindOf "StaticWeapon"}) then { +private _lookDirection = if (_shooter isKindOf "CAManBase" || {_shooter isKindOf "StaticWeapon"}) then { + _shooterPos = eyePos _shooter; + _shooter weaponDirection _weapon +} else { private _finalLookDirection = if (_usePilotCamera) then { _shooterPos = _shooter modelToWorldVisualWorld getPilotCameraPosition _shooter; private _trackingTarget = getPilotCameraTarget _shooter; @@ -43,9 +46,6 @@ private _lookDirection = if !(_shooter isKindOf "CAManBase" || {_shooter isKindO _shooter vectorModelToWorldVisual ([1, _gBody, _gGun] call CBA_fnc_polar2vect); }; _finalLookDirection -} else { - _shooterPos = eyePos _shooter; - _shooter weaponDirection _weapon }; private _distanceToProj = _shooterPos vectorDistance _projPos; diff --git a/addons/nametags/functions/fnc_drawNameTagIcon.sqf b/addons/nametags/functions/fnc_drawNameTagIcon.sqf index efe0c6bf157..26ef2584ead 100644 --- a/addons/nametags/functions/fnc_drawNameTagIcon.sqf +++ b/addons/nametags/functions/fnc_drawNameTagIcon.sqf @@ -44,11 +44,11 @@ _fnc_parameters = { private _targetFaction = _target getVariable [QGVAR(faction), faction _target]; private _customRankIcons = GVAR(factionRanks) get _targetFaction; - if (!isNil "_customRankIcons") then { - _customRankIcons param [ALL_RANKS find rank _target, ""] // return - } else { + if (isNil "_customRankIcons") then { // default rank icons format ["\A3\Ui_f\data\GUI\Cfg\Ranks\%1_gs.paa", rank _target] // return + } else { + _customRankIcons param [ALL_RANKS find rank _target, ""] // return }; }; }; diff --git a/addons/nametags/functions/fnc_onDraw3d.sqf b/addons/nametags/functions/fnc_onDraw3d.sqf index 4fbbc7ee1c7..e169eb72692 100644 --- a/addons/nametags/functions/fnc_onDraw3d.sqf +++ b/addons/nametags/functions/fnc_onDraw3d.sqf @@ -44,10 +44,10 @@ if (_enabledTagsCursor) then { private _target = cursorTarget; if !(_target isKindOf "CAManBase") then { // When cursorTarget is on a vehicle show the nametag for the commander. - if !(_target in allUnitsUAV) then { - _target = effectiveCommander _target; - } else { + if (_target in allUnitsUAV) then { _target = objNull; + } else { + _target = effectiveCommander _target; }; }; if (isNull _target) exitWith {}; diff --git a/addons/quickmount/functions/fnc_addFreeSeatsActions.sqf b/addons/quickmount/functions/fnc_addFreeSeatsActions.sqf index 0a3a7a2dc1a..efb40d2ac1a 100644 --- a/addons/quickmount/functions/fnc_addFreeSeatsActions.sqf +++ b/addons/quickmount/functions/fnc_addFreeSeatsActions.sqf @@ -202,15 +202,15 @@ private _cargoNumber = -1; if (_vehicle lockedTurret _turretPath) then {breakTo "crewLoop"}; if (_role == "gunner" && {unitIsUAV _vehicle}) then {breakTo "crewLoop"}; private _turretConfig = [_vehicleConfig, _turretPath] call CBA_fnc_getTurret; - if (!_isInVehicle) then { - _params = ["GetInTurret", _vehicle, _turretPath]; - _statement = {_player action (_this select 2)}; - } else { + if (_isInVehicle) then { private _gunnerCompartments = (_turretConfig >> "gunnerCompartments") call BIS_fnc_getCfgData; TO_COMPARTMENT_STRING(_gunnerCompartments); if (_compartment != _gunnerCompartments) then {breakTo "crewLoop"}; _params = [{MOVE_IN_CODE(moveInTurret)}, [_vehicle, _turretPath], _currentTurret, _moveBackCode, _moveBackParams]; _statement = _fnc_move; + } else { + _params = ["GetInTurret", _vehicle, _turretPath]; + _statement = {_player action (_this select 2)}; }; _name = getText (_turretConfig >> "gunnerName"); _icon = switch true do { diff --git a/addons/scopes/functions/fnc_calculateZeroAngleCorrection.sqf b/addons/scopes/functions/fnc_calculateZeroAngleCorrection.sqf index ed1222e3bbc..670a119f839 100644 --- a/addons/scopes/functions/fnc_calculateZeroAngleCorrection.sqf +++ b/addons/scopes/functions/fnc_calculateZeroAngleCorrection.sqf @@ -42,9 +42,7 @@ private _vanillaZero = parseNumber (("ace" callExtension ["ballistics:replicate_ _vanillaZero = 0; #endif -private _trueZero = if (!_advancedBallistics) then { - parseNumber (("ace" callExtension ["ballistics:zero_vanilla", [_newZeroRange, _initSpeed, _airFriction, _boreHeight]]) select 0) -} else { +private _trueZero = if (_advancedBallistics) then { // Get Weapon and Ammo Configurations private _AmmoCacheEntry = uiNamespace getVariable format[QEGVAR(advanced_ballistics,%1), _ammo]; if (isNil "_AmmoCacheEntry") then { @@ -81,6 +79,8 @@ private _trueZero = if (!_advancedBallistics) then { _atmosphereModel ]]) select 0 ) +} else { + parseNumber (("ace" callExtension ["ballistics:zero_vanilla", [_newZeroRange, _initSpeed, _airFriction, _boreHeight]]) select 0) }; private _zeroAngleCorrection = _trueZero - _vanillaZero; diff --git a/addons/spectator/functions/fnc_cam_tick.sqf b/addons/spectator/functions/fnc_cam_tick.sqf index 1e7e1b99137..11f257b7d5a 100644 --- a/addons/spectator/functions/fnc_cam_tick.sqf +++ b/addons/spectator/functions/fnc_cam_tick.sqf @@ -58,7 +58,9 @@ if (_cameraMode != MODE_FREE) then { _camTarget = GVAR(camFocus); // Focus get in / out of vehicle state -if !(isNull _camTarget) then { +if (isNull _camTarget) then { + GVAR(camTargetInVehicle) = false; +} else { private _targetInVeh = GVAR(camTargetInVehicle); if (GVAR(camHasTarget)) then { @@ -72,8 +74,6 @@ if !(isNull _camTarget) then { GVAR(camTargetInVehicle) = false; }; }; -} else { - GVAR(camTargetInVehicle) = false; }; // Camera lights diff --git a/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf b/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf index 4654b616d06..b0540de484f 100644 --- a/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf +++ b/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf @@ -75,14 +75,14 @@ if (isNil "_multHit") then { _ignoreHit = true; } else { // If the hitpoint isnt in the old array then that means that the time expired and a new array should be generated - if (!_hitPointInOldArray) then { + if (_hitPointInOldArray) then { + _vehicle setVariable [QGVAR(hitTime), [CBA_missionTime, _source, [_hitPoint]]]; + } else { private _oldHitPoints = _multHit select 2; _oldHitPoints pushBack _hitPoint; _vehicle setVariable [QGVAR(hitTime), [CBA_missionTime, _source, _oldHitPoints]]; _ignoreBailCheck = true; - } else { - _vehicle setVariable [QGVAR(hitTime), [CBA_missionTime, _source, [_hitPoint]]]; }; }; }; diff --git a/addons/volume/XEH_postInitClient.sqf b/addons/volume/XEH_postInitClient.sqf index 896bb718f8d..ae774f2f51d 100644 --- a/addons/volume/XEH_postInitClient.sqf +++ b/addons/volume/XEH_postInitClient.sqf @@ -23,10 +23,10 @@ if (!hasInterface) exitWith {}; if (!XGVAR(lowerInVehicles)) exitWith {}; - if (!isNull objectParent _unit) then { - call FUNC(lowerVolume); - } else { + if (isNull objectParent _unit) then { call FUNC(restoreVolume); + } else { + call FUNC(lowerVolume); }; }] call CBA_fnc_addPlayerEventHandler; From 07f10b976a73bd23b52e7c87229bf28d70f18f5f Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Wed, 11 Sep 2024 23:43:50 +0200 Subject: [PATCH 17/24] Medical Engine - Fix limping not applying with open wounds (#10307) --- addons/medical_engine/functions/fnc_updateDamageEffects.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/medical_engine/functions/fnc_updateDamageEffects.sqf b/addons/medical_engine/functions/fnc_updateDamageEffects.sqf index 7dc73e04f47..f4a18094a60 100644 --- a/addons/medical_engine/functions/fnc_updateDamageEffects.sqf +++ b/addons/medical_engine/functions/fnc_updateDamageEffects.sqf @@ -67,7 +67,7 @@ if (!_isLimping && {EGVAR(medical,limping) > 0}) then { (_xAmountOf > 0) && {_xDamage > LIMPING_DAMAGE_THRESHOLD} // select _causeLimping from woundDetails - && {(EGVAR(medical_damage,woundDetails) get (_xClassID / 10)) select 3} + && {(EGVAR(medical_damage,woundDetails) get (floor (_xClassID / 10))) select 3} ) exitWith { TRACE_1("limping because of wound",_x); _isLimping = true; From 39ad959ad545c4098a2060eb1a3e39f3c1195815 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Wed, 11 Sep 2024 23:46:07 +0200 Subject: [PATCH 18/24] CSW - Take individual components into account for disassembly (#10300) --- addons/csw/functions/fnc_assemble_deployWeapon.sqf | 11 ++++++----- addons/csw/functions/fnc_assemble_pickupWeapon.sqf | 10 +++++++--- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/addons/csw/functions/fnc_assemble_deployWeapon.sqf b/addons/csw/functions/fnc_assemble_deployWeapon.sqf index f852a1954af..a0cdc102ca8 100644 --- a/addons/csw/functions/fnc_assemble_deployWeapon.sqf +++ b/addons/csw/functions/fnc_assemble_deployWeapon.sqf @@ -49,7 +49,7 @@ private _onFinish = { params ["_args"]; - _args params ["_tripod", "_player", "_assembledClassname", "", "_carryWeaponInfo"]; + _args params ["_tripod", "_player", "_assembledClassname", "_tripodClassname", "_carryWeaponClassname", "_carryWeaponInfo"]; TRACE_3("deployWeapon finish",_tripod,_player,_assembledClassname); private _secondaryWeaponMagazines = _tripod getVariable [QGVAR(secondaryWeaponMagazines), []]; @@ -61,10 +61,11 @@ _tripodPos set [2, (_tripodPos select 2) + 0.1]; // Delay a frame so tripod has a chance to be deleted [{ - params ["_assembledClassname", "_tripodDir", "_tripodPos", "_player", "_carryWeaponInfo", "_secondaryWeaponMagazines"]; + params ["_assembledClassname", "_componentClasses", "_tripodDir", "_tripodPos", "_player", "_carryWeaponInfo", "_secondaryWeaponMagazines"]; private _csw = createVehicle [_assembledClassname, [0, 0, 0], [], 0, "NONE"]; // Assembly mode: [0=disabled, 1=enabled, 2=enabled&unload, 3=default] _csw setVariable [QGVAR(assemblyMode), 2, true]; // Explicitly set advanced assembly mode + unload, and broadcast + _csw setVariable [QGVAR(componentClasses), _componentClasses, true]; { // Magazines @@ -91,12 +92,12 @@ }; [QGVAR(deployWeaponSucceeded), [_csw]] call CBA_fnc_localEvent; TRACE_2("csw placed",_csw,_assembledClassname); - }, [_assembledClassname, _tripodDir, _tripodPos, _player, _carryWeaponInfo, _secondaryWeaponMagazines]] call CBA_fnc_execNextFrame; + }, [_assembledClassname, [_tripodClassname, _carryWeaponClassname], _tripodDir, _tripodPos, _player, _carryWeaponInfo, _secondaryWeaponMagazines]] call CBA_fnc_execNextFrame; }; private _onFailure = { params ["_args"]; - _args params ["", "_player", "", "_carryWeaponClassname", "_carryWeaponInfo"]; + _args params ["", "_player", "", "", "_carryWeaponClassname", "_carryWeaponInfo"]; TRACE_2("deployWeapon failure",_player,_carryWeaponClassname); // Add weapon back @@ -115,5 +116,5 @@ alive _tripod }; - [TIME_PROGRESSBAR(_deployTime), [_tripod, _player, _assembledClassname, _carryWeaponClassname, _carryWeaponInfo], _onFinish, _onFailure, LLSTRING(AssembleCSW_progressBar), _condition] call EFUNC(common,progressBar); + [TIME_PROGRESSBAR(_deployTime), [_tripod, _player, _assembledClassname, _tripodClassname, _carryWeaponClassname, _carryWeaponInfo], _onFinish, _onFailure, LLSTRING(AssembleCSW_progressBar), _condition] call EFUNC(common,progressBar); }, _this] call CBA_fnc_execNextFrame; diff --git a/addons/csw/functions/fnc_assemble_pickupWeapon.sqf b/addons/csw/functions/fnc_assemble_pickupWeapon.sqf index 867c151d278..023143710b6 100644 --- a/addons/csw/functions/fnc_assemble_pickupWeapon.sqf +++ b/addons/csw/functions/fnc_assemble_pickupWeapon.sqf @@ -21,14 +21,18 @@ TRACE_2("assemble_pickupWeapon",_vehicle,_player); private _weaponConfig = configOf _vehicle >> QUOTE(ADDON); - private _carryWeaponClassname = getText (_weaponConfig >> "disassembleWeapon"); + private _componentClasses = _vehicle getVariable QGVAR(componentClasses); + + (if (!isNil "_componentClasses") then { + _componentClasses + } else { + [getText (_weaponConfig >> "disassembleTurret"), getText (_weaponConfig >> "disassembleWeapon")] + }) params ["_turretClassname", "_carryWeaponClassname"]; if (!isClass (configFile >> "CfgWeapons" >> _carryWeaponClassname)) exitWith { ERROR_1("bad weapon classname [%1]",_carryWeaponClassname); }; - private _turretClassname = getText (_weaponConfig >> "disassembleTurret"); - // Turret classname can equal nothing if the deploy bag is the "whole" weapon. e.g Kornet, Metis, other ATGMs if ((_turretClassname != "") && {!isClass (configFile >> "CfgVehicles" >> _turretClassname)}) exitWith { ERROR_1("bad turret classname [%1]",_turretClassname); From 0f756dc18a2c161e08de5445156a8deffe191fbf Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Wed, 11 Sep 2024 23:46:37 +0200 Subject: [PATCH 19/24] SPE Compat - Make all German belts linkable (#10305) --- addons/compat_spe/CfgMagazines/csw.hpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/addons/compat_spe/CfgMagazines/csw.hpp b/addons/compat_spe/CfgMagazines/csw.hpp index 9fa46140899..6b4c385a42a 100644 --- a/addons/compat_spe/CfgMagazines/csw.hpp +++ b/addons/compat_spe/CfgMagazines/csw.hpp @@ -13,18 +13,5 @@ class SPE_100Rnd_127x99_M2: VehicleMagazine { // MG34/42 class SPE_50Rnd_792x57: CA_Magazine { - ACE_isBelt = 0; -}; -class SPE_100Rnd_792x57: SPE_50Rnd_792x57 { - ACE_isBelt = 1; -}; - -class SPE_50Rnd_792x57_sS; -class SPE_100Rnd_792x57_sS: SPE_50Rnd_792x57_sS { - ACE_isBelt = 1; -}; - -class SPE_50Rnd_792x57_SMK; -class SPE_100Rnd_792x57_SMK: SPE_50Rnd_792x57_SMK { ACE_isBelt = 1; }; From c5935dc843d04718e94b975f699f53afe9210bdb Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Wed, 11 Sep 2024 23:49:22 +0200 Subject: [PATCH 20/24] CSW - Rework settings (#9901) --- addons/csw/XEH_postInit.sqf | 24 +++++++++--- addons/csw/functions/fnc_ai_handleFired.sqf | 2 + addons/csw/functions/fnc_ai_handleGetIn.sqf | 2 + addons/csw/functions/fnc_initVehicle.sqf | 12 +++++- addons/csw/initSettings.inc.sqf | 43 ++++++++++----------- 5 files changed, 53 insertions(+), 30 deletions(-) diff --git a/addons/csw/XEH_postInit.sqf b/addons/csw/XEH_postInit.sqf index 87196f33772..419e7013809 100644 --- a/addons/csw/XEH_postInit.sqf +++ b/addons/csw/XEH_postInit.sqf @@ -8,18 +8,32 @@ GVAR(vehicleMagCache) = createHashMap; // needs a small delay for network syncing, or we end up with duplicate mags with ammo handling [LINKFUNC(initVehicle), _this, 1] call CBA_fnc_waitAndExecute; }, true, [], true] call CBA_fnc_addClassEventHandler; - - GVAR(quickmountEnabled) = ( - missionNamespace getVariable [QEGVAR(quickmount,enabled), false] && - {(missionNamespace getVariable [QEGVAR(quickmount,enableMenu), -1]) in [1,3]} - ); }] call CBA_fnc_addEventHandler; +// Also triggered at mission start ["CBA_SettingChanged", { GVAR(quickmountEnabled) = ( missionNamespace getVariable [QEGVAR(quickmount,enabled), false] && {(missionNamespace getVariable [QEGVAR(quickmount,enableMenu), -1]) in [1,3]} ); + + // Do not allow no ammo handling when advanced assembly is enabled + // Reason: When using advanced assembly, the amount of ammo is not stored anywhere, so when you reassemble a static, it will spawn full ammo + if (GVAR(defaultAssemblyMode) && GVAR(ammoHandling) == 0) then { + if (isServer) then { + [QGVAR(ammoHandling), 2, 2, "server"] call CBA_settings_fnc_set; + }; + + // Notify everyone about change + [QEGVAR(common,displayTextStructured), [composeText [ + lineBreak, + parseText format [ + "%1", format ["%1 requires %2 to be set higher than 0.", QGVAR(defaultAssemblyMode), QGVAR(ammoHandling)] + ], + lineBreak, + parseText format ["%1", "No mission restart is required."] + ], 4]] call CBA_fnc_localEvent; + }; }] call CBA_fnc_addEventHandler; // Event handlers: diff --git a/addons/csw/functions/fnc_ai_handleFired.sqf b/addons/csw/functions/fnc_ai_handleFired.sqf index 6f7a6452579..4a6615f4043 100644 --- a/addons/csw/functions/fnc_ai_handleFired.sqf +++ b/addons/csw/functions/fnc_ai_handleFired.sqf @@ -12,6 +12,8 @@ * Public: No */ +if (GVAR(ammoHandling) != 2) exitWith {}; + params ["_vehicle", "_weapon", "", "", "", "_magazine", "", "_gunner"]; TRACE_4("firedEH:",_vehicle,_weapon,_magazine,_gunner); diff --git a/addons/csw/functions/fnc_ai_handleGetIn.sqf b/addons/csw/functions/fnc_ai_handleGetIn.sqf index 14b4453f530..bbbddaf537f 100644 --- a/addons/csw/functions/fnc_ai_handleGetIn.sqf +++ b/addons/csw/functions/fnc_ai_handleGetIn.sqf @@ -12,6 +12,8 @@ * Public: No */ +if (GVAR(ammoHandling) != 2) exitWith {}; + params ["_vehicle", "", "_gunner"]; TRACE_2("getInEH:",_vehicle,_gunner); diff --git a/addons/csw/functions/fnc_initVehicle.sqf b/addons/csw/functions/fnc_initVehicle.sqf index bde31b41d06..f9cd10dbb1c 100644 --- a/addons/csw/functions/fnc_initVehicle.sqf +++ b/addons/csw/functions/fnc_initVehicle.sqf @@ -97,9 +97,17 @@ if (hasInterface && {!(_typeOf in GVAR(initializedStaticTypes))}) then { }; if (["ace_reload"] call EFUNC(common,isModLoaded)) then { - // move reload's check ammo action to the ammo handling point (remove and re-add) [_typeOf, 0, ["ACE_MainActions", QEGVAR(reload,CheckAmmo)]] call EFUNC(interact_menu,removeActionFromClass); - private _checkAmmoAction = [QGVAR(checkAmmo), LELSTRING(reload,checkAmmo), "", EFUNC(reload,checkAmmo), EFUNC(reload,canCheckAmmo)] call EFUNC(interact_menu,createAction); + + // Replace existing check ammo interaction with one that takes into account if the magazine actions are available + private _checkAmmoAction = [QEGVAR(reload,CheckAmmo), LELSTRING(reload,checkAmmo), "", EFUNC(reload,checkAmmo), { + if !((GVAR(ammoHandling) == 0) && {!([false, true, true, GVAR(defaultAssemblyMode)] select (_target getVariable [QGVAR(assemblyMode), 3]))}) exitWith { false }; + _this call EFUNC(reload,canCheckAmmo) + }] call ace_interact_menu_fnc_createAction; + [_typeOf, 0, ["ACE_MainActions"], _checkAmmoAction] call EFUNC(interact_menu,addActionToClass); + + // Add another check ammo action to the ammo handling point + _checkAmmoAction = [QGVAR(checkAmmo), LELSTRING(reload,checkAmmo), "", EFUNC(reload,checkAmmo), EFUNC(reload,canCheckAmmo)] call EFUNC(interact_menu,createAction); [_typeOf, 0, _ammoActionPath, _checkAmmoAction] call EFUNC(interact_menu,addActionToClass); }; }; diff --git a/addons/csw/initSettings.inc.sqf b/addons/csw/initSettings.inc.sqf index bc157e1164b..4a58ed80b03 100644 --- a/addons/csw/initSettings.inc.sqf +++ b/addons/csw/initSettings.inc.sqf @@ -1,56 +1,53 @@ -private _categoryArray = [format ["ACE %1", localize LSTRING(DisplayName)]]; +private _categoryArray = [format ["ACE %1", LLSTRING(DisplayName)]]; [ - QGVAR(defaultAssemblyMode), "CHECKBOX", + QGVAR(defaultAssemblyMode), + "CHECKBOX", [LSTRING(defaultAssemblyMode_displayName), LSTRING(defaultAssemblyMode_description)], _categoryArray, false, // default value - true, // isGlobal - {[QGVAR(defaultAssemblyMode), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + 1 // isGlobal ] call CBA_fnc_addSetting; [ - QGVAR(handleExtraMagazines), "CHECKBOX", + QGVAR(handleExtraMagazines), + "CHECKBOX", [LSTRING(handleExtraMagazines_displayName), LSTRING(handleExtraMagazines_description)], _categoryArray, true, // default value - true, // isGlobal - {[QGVAR(handleExtraMagazines), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + 1 // isGlobal ] call CBA_fnc_addSetting; [ - QGVAR(handleExtraMagazinesType), "LIST", + QGVAR(handleExtraMagazinesType), + "LIST", [LSTRING(handleExtraMagazinesType_displayName), LSTRING(handleExtraMagazinesType_description)], _categoryArray, [[0, 1], [LSTRING(handleExtraMagazinesType_weaponHolder), LSTRING(handleExtraMagazinesType_ammoBox)], 0], - true, // isGlobal - {[QGVAR(handleExtraMagazinesType), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + 1 // isGlobal ] call CBA_fnc_addSetting; [ - QGVAR(ammoHandling), "LIST", + QGVAR(ammoHandling), + "LIST", [LSTRING(ammoHandling_displayName), LSTRING(ammoHandling_description)], _categoryArray, [[0, 1, 2], [LELSTRING(common,Disabled), LELSTRING(common,playerOnly), LELSTRING(common,playersAndAI)], 2], // [_values, _valueTitles, _defaultIndex] - true, // isGlobal - {[QGVAR(ammoHandling), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + 1 // isGlobal ] call CBA_fnc_addSetting; [ - QGVAR(progressBarTimeCoefficent), "SLIDER", + QGVAR(progressBarTimeCoefficent), + "SLIDER", [LSTRING(progressBarTimeCoefficent_displayName), LSTRING(progressBarTimeCoefficent_description)], _categoryArray, - [0,2,1,2], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true // isGlobal + [0, 2, 1, 2], // [min, max, default value, trailing decimals (-1 for whole numbers only)] + 1 // isGlobal ] call CBA_fnc_addSetting; [ - QGVAR(dragAfterDeploy), "CHECKBOX", + QGVAR(dragAfterDeploy), + "CHECKBOX", [LSTRING(dragAfterDeploy_displayName), LSTRING(dragAfterDeploy_description)], - _categoryArray, - false // default value + _categoryArray ] call CBA_fnc_addSetting; From d4d87a13cecfa666c11f80e5350b61c66fa91b35 Mon Sep 17 00:00:00 2001 From: Fabio Schick <58027418+mrschick@users.noreply.github.com> Date: Wed, 11 Sep 2024 23:57:14 +0200 Subject: [PATCH 21/24] Scopes - Setting to show Adjustment UI while sighted in (#10241) --- .../functions/fnc_applyScopeAdjustment.sqf | 4 ++++ addons/scopes/initSettings.inc.sqf | 16 ++++++++++++---- addons/scopes/stringtable.xml | 5 +++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/addons/scopes/functions/fnc_applyScopeAdjustment.sqf b/addons/scopes/functions/fnc_applyScopeAdjustment.sqf index b813dde9ef8..d356343099d 100644 --- a/addons/scopes/functions/fnc_applyScopeAdjustment.sqf +++ b/addons/scopes/functions/fnc_applyScopeAdjustment.sqf @@ -43,6 +43,10 @@ if (cameraView == "GUNNER") then { _yaw = _yaw + _windageDifference; [_unit, _pitch, _bank, _yaw] call EFUNC(common,setPitchBankYaw); }; + + if (GVAR(inScopeAdjustment)) then { + [] call FUNC(showZeroing); + }; } else { [] call FUNC(showZeroing); }; diff --git a/addons/scopes/initSettings.inc.sqf b/addons/scopes/initSettings.inc.sqf index 40ed62cbcc2..e74bcb4c073 100644 --- a/addons/scopes/initSettings.inc.sqf +++ b/addons/scopes/initSettings.inc.sqf @@ -76,18 +76,26 @@ private _category = format ["ACE %1", localize LSTRING(DisplayName)]; true // Needs mission restart ] call CBA_fnc_addSetting; +[ + QGVAR(simplifiedZeroing), "CHECKBOX", + [LSTRING(simplifiedZeroing_displayName), LSTRING(simplifiedZeroing_description)], + _category, + false, + 1 +] call CBA_fnc_addSetting; + [ QGVAR(useLegacyUI), "CHECKBOX", [LSTRING(useLegacyUI_displayName), LSTRING(useLegacyUI_description)], _category, false, - 0 + 2 ] call CBA_fnc_addSetting; [ - QGVAR(simplifiedZeroing), "CHECKBOX", - [LSTRING(simplifiedZeroing_displayName), LSTRING(simplifiedZeroing_description)], + QGVAR(inScopeAdjustment), "CHECKBOX", + LSTRING(inScopeAdjustment_displayName), _category, false, - 1 + 0 ] call CBA_fnc_addSetting; diff --git a/addons/scopes/stringtable.xml b/addons/scopes/stringtable.xml index 9a47f657cc0..4174a91d02e 100644 --- a/addons/scopes/stringtable.xml +++ b/addons/scopes/stringtable.xml @@ -347,6 +347,11 @@ Replikuje systém naměřování puškohledů ze základní hry. Replica en los visores el sistema de homogeneizado de vanilla + + Show adjustment UI in scope + Zeige Absehenverstellungs-UI im Zielfernrohr + Mostra UI delle manopole nel mirino + Minor adjustment up Kleine Korrektur hoch From fdf3198855eab9387b5f525027d1412fbb1aeb57 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Wed, 11 Sep 2024 17:36:42 -0500 Subject: [PATCH 22/24] Advanced Fatigue - Fix stamina costs when not touching ground (#10297) --- .../advanced_fatigue/functions/fnc_mainLoop.sqf | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/addons/advanced_fatigue/functions/fnc_mainLoop.sqf b/addons/advanced_fatigue/functions/fnc_mainLoop.sqf index 16d355a424d..e6327a3fa56 100644 --- a/addons/advanced_fatigue/functions/fnc_mainLoop.sqf +++ b/addons/advanced_fatigue/functions/fnc_mainLoop.sqf @@ -27,9 +27,18 @@ if (!alive ACE_player) exitWith { private _velocity = velocity ACE_player; private _normal = surfaceNormal (getPosWorld ACE_player); private _movementVector = vectorNormalized _velocity; -private _sideVector = vectorNormalized (_movementVector vectorCrossProduct _normal); private _fwdAngle = asin (_movementVector select 2); -private _sideAngle = asin (_sideVector select 2); +private _sideAngle = if ((getPosATL ACE_player) select 2 > 0.01) then { + 0 // ignore terrain normal if not touching it +} else { + private _sideVector = vectorNormalized (_movementVector vectorCrossProduct _normal); + asin (_sideVector select 2); +}; +if (GVAR(isSwimming)) then { // ignore when floating + _fwdAngle = 0; + _sideAngle = 0; +}; + private _currentWork = REE; private _currentSpeed = (vectorMagnitude _velocity) min 6; @@ -62,7 +71,7 @@ if (isNull objectParent ACE_player && {_currentSpeed > 0.1} && {isTouchingGround }; // Used to simulate the unevenness/roughness of the terrain - if ((getPosATL ACE_player) select 2 < 0.01) then { + if (_sideAngle != 0) then { private _sideGradient = abs (_sideAngle / 45) min 1; _terrainFactor = 1 + _sideGradient ^ 4; From 33f2143019588d54c17d671fa45d9257866f3769 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Thu, 12 Sep 2024 00:54:19 +0200 Subject: [PATCH 23/24] Docs - Update CSW proxy weapon information (#10309) --- docs/wiki/framework/crew-served-weapons-framework.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/wiki/framework/crew-served-weapons-framework.md b/docs/wiki/framework/crew-served-weapons-framework.md index a2f8e74ae65..0213e42a5e9 100644 --- a/docs/wiki/framework/crew-served-weapons-framework.md +++ b/docs/wiki/framework/crew-served-weapons-framework.md @@ -16,7 +16,7 @@ version: To convert a static weapon into a crew served weapon, you need to create the following: -- A proxy weapon +- A proxy weapon (optional) - A carryable weapon that can be mounted on a tripod - Carryable weapon magazines - The CSW config in the static weapon @@ -27,6 +27,8 @@ For the following examples, we are going to assume you are modifying your existi Because the magazine loading time is already handled by the ACE interaction, a proxy weapon with a very low loading time is used. It automatically replaces the default weapon of the turret when CSW is enabled. +A proxy weapon isn't required for a CSW to work. If a CSW uses the default weapons, the reload times will just be longer. + ```cpp class CfgWeapons { class prefix_hmg_weapon; @@ -136,7 +138,7 @@ class CfgVehicles { class prefix_hmg: StaticMGWeapon { class ACE_CSW { enabled = 1; // Enables ACE CSW for this weapon - proxyWeapon = "prefix_hmg_weapon_proxy"; // The proxy weapon created above + proxyWeapon = "prefix_hmg_weapon_proxy"; // The proxy weapon created above. This can also be a function name that returns a proxy weapon - passed [_vehicle, _turret, _currentWeapon, _needed, _emptyWeapon] magazineLocation = "_target selectionPosition 'magazine'"; // Ammo handling interaction point location disassembleWeapon = "prefix_hmg_carry"; // Carryable weapon created above disassembleTurret = "ace_csw_m3Tripod"; // Which static tripod will appear when weapon is disassembled From fef34a82dc51d640ba3df82ccfcb228647998cb4 Mon Sep 17 00:00:00 2001 From: some-evil-kitty <106408180+some-evil-kitty@users.noreply.github.com> Date: Wed, 11 Sep 2024 19:54:51 -0400 Subject: [PATCH 24/24] Carrying - Add hookable events to dropping objects (#10304) Co-authored-by: PabstMirror Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/dragging/functions/fnc_carryObject.sqf | 3 +++ addons/dragging/functions/fnc_dragObject.sqf | 3 +++ addons/dragging/functions/fnc_dropObject.sqf | 3 +++ addons/dragging/functions/fnc_dropObject_carry.sqf | 6 ++++++ addons/dragging/functions/fnc_startCarryLocal.sqf | 3 +++ addons/dragging/functions/fnc_startDragLocal.sqf | 3 +++ docs/wiki/framework/events-framework.md | 6 ++++++ 7 files changed, 27 insertions(+) diff --git a/addons/dragging/functions/fnc_carryObject.sqf b/addons/dragging/functions/fnc_carryObject.sqf index 7b2b4faa6b0..d765020f96e 100644 --- a/addons/dragging/functions/fnc_carryObject.sqf +++ b/addons/dragging/functions/fnc_carryObject.sqf @@ -71,3 +71,6 @@ if (_UAVCrew isNotEqualTo []) then { // Check everything [LINKFUNC(carryObjectPFH), 0.5, [_unit, _target, CBA_missionTime]] call CBA_fnc_addPerFrameHandler; + +// API +[QGVAR(startedCarry), [_unit, _target]] call CBA_fnc_localEvent; diff --git a/addons/dragging/functions/fnc_dragObject.sqf b/addons/dragging/functions/fnc_dragObject.sqf index a8053b8dfee..3169db26795 100644 --- a/addons/dragging/functions/fnc_dragObject.sqf +++ b/addons/dragging/functions/fnc_dragObject.sqf @@ -87,3 +87,6 @@ if (_UAVCrew isNotEqualTo []) then { // Fixes not being able to move when in combat pace [_unit, "forceWalk", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); + +// API +[QGVAR(startedDrag), [_unit, _target]] call CBA_fnc_localEvent; diff --git a/addons/dragging/functions/fnc_dropObject.sqf b/addons/dragging/functions/fnc_dropObject.sqf index 965e3b9efa3..049f8228168 100644 --- a/addons/dragging/functions/fnc_dropObject.sqf +++ b/addons/dragging/functions/fnc_dropObject.sqf @@ -107,3 +107,6 @@ private _mass = _target getVariable [QGVAR(originalMass), 0]; if (_mass != 0) then { [QEGVAR(common,setMass), [_target, _mass]] call CBA_fnc_globalEvent; // Force global sync }; + +// API +[QGVAR(stoppedDrag), [_unit, _target]] call CBA_fnc_localEvent; diff --git a/addons/dragging/functions/fnc_dropObject_carry.sqf b/addons/dragging/functions/fnc_dropObject_carry.sqf index ba8cbd09f12..525a150bcff 100644 --- a/addons/dragging/functions/fnc_dropObject_carry.sqf +++ b/addons/dragging/functions/fnc_dropObject_carry.sqf @@ -129,6 +129,12 @@ if (_loadCargo) then { } else { [_unit, _target, _cursorObject] call EFUNC(common,loadPerson); }; + + // Repurpose variable for flag used in event below + _loadCargo = true; }; }; }; + +// API +[QGVAR(stoppedCarry), [_unit, _target, _loadCargo]] call CBA_fnc_localEvent; diff --git a/addons/dragging/functions/fnc_startCarryLocal.sqf b/addons/dragging/functions/fnc_startCarryLocal.sqf index e7d102825aa..cf17dfb311d 100644 --- a/addons/dragging/functions/fnc_startCarryLocal.sqf +++ b/addons/dragging/functions/fnc_startCarryLocal.sqf @@ -99,3 +99,6 @@ if (_mass > 1) then { _target setVariable [QGVAR(originalMass), _mass, true]; [QEGVAR(common,setMass), [_target, 1e-12]] call CBA_fnc_globalEvent; // Force global sync }; + +// API +[QGVAR(setupCarry), [_unit, _target]] call CBA_fnc_localEvent; diff --git a/addons/dragging/functions/fnc_startDragLocal.sqf b/addons/dragging/functions/fnc_startDragLocal.sqf index 3abcef44305..f0468f133ba 100644 --- a/addons/dragging/functions/fnc_startDragLocal.sqf +++ b/addons/dragging/functions/fnc_startDragLocal.sqf @@ -116,3 +116,6 @@ if (_mass > 1) then { _target setVariable [QGVAR(originalMass), _mass, true]; [QEGVAR(common,setMass), [_target, 1e-12]] call CBA_fnc_globalEvent; // Force global sync }; + +// API +[QGVAR(setupDrag), [_unit, _target]] call CBA_fnc_localEvent; diff --git a/docs/wiki/framework/events-framework.md b/docs/wiki/framework/events-framework.md index c0aa43a5739..b531387ee79 100644 --- a/docs/wiki/framework/events-framework.md +++ b/docs/wiki/framework/events-framework.md @@ -173,6 +173,12 @@ MenuType: 0 = Interaction, 1 = Self Interaction |---------- |------------|----------|------|-------------| | `ace_dragging_cloneCreated` | [_clone, _corpse] | Local | Listen | Called when a clone used for dragging/carrying corpses is created | `ace_dragging_cloneDeleted` | [_clone, _corpse] | Local | Listen | Called when a clone used for dragging/carrying corpses is deleted +| `ace_dragging_setupCarry` | [_unit, _target] | Local | Listen | Called when the unit starts the carrying animation for the target +| `ace_dragging_startedCarry` | [_unit, _target] | Local | Listen | Called when the unit starts successfully carrying the target. This event is called after `ace_dragging_setupCarry`. +| `ace_dragging_stoppedCarry` | [_unit, _target, _loadCargo] | Local | Listen | Called when the unit stops carrying the target. `_loadCargo` says if the target is being loaded as cargo/person or not. +| `ace_dragging_setupDrag` | [_unit, _target] | Local | Listen | Called when the unit starts the dragging animation for the target +| `ace_dragging_startedDrag` | [_unit, _target] | Local | Listen | Called when the unit starts successfully dragging the target. This event is called after `ace_dragging_setupDrag`. +| `ace_dragging_stoppedDrag` | [_unit, _target] | Local | Listen | Called when the unit stops dragging the target ### 2.19 HuntIR (`ace_huntir`)