From c3531004db578ebe99a39e881e0d155e924e349c Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Sat, 28 Sep 2024 01:16:29 -0500 Subject: [PATCH] Update for mg changes --- addons/clgp/CfgAmmo.hpp | 9 +- addons/clgp/GUI.hpp | 6 +- addons/clgp/dev/quickTesting.sqf | 6 +- .../functions/fnc_submunition_ammoFired.sqf | 2 +- .../fnc_submunition_submunitionCreated.sqf | 6 - addons/clgp/stringtable.xml | 3 - addons/missileguidance/XEH_PREP.hpp | 2 +- .../functions/fnc_doAttackProfile.sqf | 2 +- .../functions/fnc_guidancePFH.sqf | 2 +- .../missileguidance/functions/fnc_onFired.sqf | 211 +---------------- .../functions/fnc_onFiredDeferred.sqf | 137 ----------- .../functions/fnc_onFiredGetArgs.sqf | 220 ++++++++++++++++++ 12 files changed, 241 insertions(+), 365 deletions(-) delete mode 100644 addons/missileguidance/functions/fnc_onFiredDeferred.sqf create mode 100644 addons/missileguidance/functions/fnc_onFiredGetArgs.sqf diff --git a/addons/clgp/CfgAmmo.hpp b/addons/clgp/CfgAmmo.hpp index 9d48a150bf9..5be9aa432b2 100644 --- a/addons/clgp/CfgAmmo.hpp +++ b/addons/clgp/CfgAmmo.hpp @@ -115,6 +115,7 @@ class CfgAmmo { thrustTime = 14; initTime = 0; airFriction = 0.1; + sideAirFriction = 0.1; hit = 120; indirectHit = 10; @@ -146,9 +147,8 @@ class CfgAmmo { class ace_missileguidance { enabled = 2; - minDeflection = 0.0005; // Minium flap deflection for guidance - maxDeflection = 0.0025; // Maximum flap deflection for guidance - incDeflection = 0.0005; // The incrmeent in which deflection adjusts. + pitchRate = 15; + yawRate = 20; canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode @@ -159,6 +159,9 @@ class CfgAmmo { defaultSeekerLockMode = "LOAL"; seekerLockModes[] = {"LOAL"}; + defaultNavigationType = "Direct"; + navigationTypes[] = { "Direct" }; + seekerAngle = 90; // Angle in front of the missile which can be searched seekerAccuracy = 1; // seeker accuracy multiplier diff --git a/addons/clgp/GUI.hpp b/addons/clgp/GUI.hpp index c9d1625c46c..1257bb899e4 100644 --- a/addons/clgp/GUI.hpp +++ b/addons/clgp/GUI.hpp @@ -64,7 +64,7 @@ class GVAR(copperhead_dialog) { class Controls { class ButtonDial: GVAR(copperhead_dialButton) { idc = 113; - tooltip = CSTRING(copperhead_dial_LaserCode); + tooltip = ECSTRING(laser,laserCode); }; }; }; @@ -73,7 +73,7 @@ class GVAR(copperhead_dialog) { class Controls { class ButtonDial: GVAR(copperhead_dialButton) { idc = 114; - tooltip = CSTRING(copperhead_dial_LaserCode); + tooltip = ECSTRING(laser,laserCode); }; }; }; @@ -82,7 +82,7 @@ class GVAR(copperhead_dialog) { class Controls { class ButtonDial: GVAR(copperhead_dialButton) { idc = 115; - tooltip = CSTRING(copperhead_dial_LaserCode); + tooltip = ECSTRING(laser,laserCode); }; }; }; diff --git a/addons/clgp/dev/quickTesting.sqf b/addons/clgp/dev/quickTesting.sqf index 28c1c52e6bd..fe3b62c844e 100644 --- a/addons/clgp/dev/quickTesting.sqf +++ b/addons/clgp/dev/quickTesting.sqf @@ -23,10 +23,10 @@ DFUNC(dev_trackShell) = { if (_ammo isKindOf "SubmunitionBase") then { private _projectilePos = getPosASL _projectile; private _forwardPosition = _projectilePos vectorAdd ((vectorNormalized (velocity _projectile)) vectorMultiply 15); - drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,1], ASLtoAGL _projectilePos, 0.75, 0.75, 0, _ammo, 1, 0.025, "TahomaB"]; - drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0.5,0,1,1], ASLtoAGL _forwardPosition, 0.75, 0.75, 0, + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,1], ASLToAGL _projectilePos, 0.75, 0.75, 0, _ammo, 1, 0.025, "TahomaB"]; + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0.5,0,1,1], ASLToAGL _forwardPosition, 0.75, 0.75, 0, format ["V: %1 (%2)", round vectorMagnitude velocity _projectile, round ((velocity _projectile) # 2)], 1, 0.025, "TahomaB"]; - drawLine3D [ASLtoAGL _projectilePos, ASLtoAGL _forwardPosition, [0.5,0,1,1]]; + drawLine3D [ASLToAGL _projectilePos, ASLToAGL _forwardPosition, [0.5,0,1,1]]; }; private _deltaT = CBA_missionTime - _time; diff --git a/addons/clgp/functions/fnc_submunition_ammoFired.sqf b/addons/clgp/functions/fnc_submunition_ammoFired.sqf index d7ea236589c..8f3b0e35210 100644 --- a/addons/clgp/functions/fnc_submunition_ammoFired.sqf +++ b/addons/clgp/functions/fnc_submunition_ammoFired.sqf @@ -25,7 +25,7 @@ private _ammoCfg = configOf _projectile; private _firedEH = +_this; // Inject the submunition ammo into guidance args _firedEH set [4, getText (_ammoCfg >> "submunitionAmmo")]; -private _guidanceArgs = _firedEH call EFUNC(missileguidance,onFiredDeferred); +private _guidanceArgs = _firedEH call EFUNC(missileguidance,onFiredGetArgs); if (_guidanceArgs isEqualTo []) then { WARNING_1("no args %1",_projectile); }; _projectile setVariable [QGVAR(guidanceArgs), _guidanceArgs]; diff --git a/addons/clgp/functions/fnc_submunition_submunitionCreated.sqf b/addons/clgp/functions/fnc_submunition_submunitionCreated.sqf index 1550b669574..b0aaece6216 100644 --- a/addons/clgp/functions/fnc_submunition_submunitionCreated.sqf +++ b/addons/clgp/functions/fnc_submunition_submunitionCreated.sqf @@ -30,12 +30,6 @@ if (_guidanceArgs isNotEqualTo []) then { // Inject the submunition projectile a [EFUNC(missileguidance,guidancePFH), 0, _guidanceArgs] call CBA_fnc_addPerFrameHandler; }; -// NOTE: Probably need to remove after frag-rewrite -if (!isNil QEFUNC(frag,addPfhRound)) then { // todo make frag work for original and sub - TRACE_1("-Starting frag track",_submunitionProjectile); - [_firedEH # 0, _firedEH # 4, _submunitionProjectile] call EFUNC(frag,addPfhRound); -}; - private _deployArtilleryDragConfig = (configOf _projectile) >> QGVAR(artilleryDrag); if (isNumber _deployArtilleryDragConfig) then { private _deployArtilleryDrag = getNumber _deployArtilleryDragConfig; diff --git a/addons/clgp/stringtable.xml b/addons/clgp/stringtable.xml index e220015de3c..28b954bcea5 100644 --- a/addons/clgp/stringtable.xml +++ b/addons/clgp/stringtable.xml @@ -10,9 +10,6 @@ Guidance Delay - - Laser Code - 40mm Pike diff --git a/addons/missileguidance/XEH_PREP.hpp b/addons/missileguidance/XEH_PREP.hpp index 73018d4674d..01f65719090 100644 --- a/addons/missileguidance/XEH_PREP.hpp +++ b/addons/missileguidance/XEH_PREP.hpp @@ -9,7 +9,7 @@ PREP(checkLos); PREP(dev_ProjectileCamera); PREP(onFired); -PREP(onFiredDeferred); +PREP(onFiredGetArgs); PREP(onIncomingMissile); PREP(guidancePFH); diff --git a/addons/missileguidance/functions/fnc_doAttackProfile.sqf b/addons/missileguidance/functions/fnc_doAttackProfile.sqf index e33d2bfd9be..d6dde00f91b 100644 --- a/addons/missileguidance/functions/fnc_doAttackProfile.sqf +++ b/addons/missileguidance/functions/fnc_doAttackProfile.sqf @@ -25,7 +25,7 @@ private _attackProfileFunction = getText (configFile >> QGVAR(AttackProfiles) >> private _attackProfilePos = _this call (missionNamespace getVariable _attackProfileFunction); if ((isNil "_attackProfilePos") || {_attackProfilePos isEqualTo [0,0,0]}) exitWith { - ERROR_2("attack profile [%1] returned bad pos %2",_attackProfileName,_attackProfilePos); + // ERROR_2("attack profile [%1] returned bad pos %2",_attackProfileName,_attackProfilePos); [0,0,0] }; diff --git a/addons/missileguidance/functions/fnc_guidancePFH.sqf b/addons/missileguidance/functions/fnc_guidancePFH.sqf index 8b8df3d5114..82d3d57a35f 100644 --- a/addons/missileguidance/functions/fnc_guidancePFH.sqf +++ b/addons/missileguidance/functions/fnc_guidancePFH.sqf @@ -50,7 +50,7 @@ _targetData set [1, _projectilePos vectorFromTo _profileAdjustedTargetPos]; // If we have no seeker target, then do not change anything // If there is no deflection on the missile, this cannot change and therefore is redundant. Avoid calculations for missiles without any deflection -if ((_pitchRate != 0 || {_yawRate != 0})) then { +if ((_pitchRate != 0 || {_yawRate != 0}) && {_profileAdjustedTargetPos isNotEqualTo [0,0,0]}) then { private _navigationFunction = getText (configFile >> QGVAR(NavigationTypes) >> _navigationType >> "functionName"); if (_navigationStateData isNotEqualTo []) then { (_navigationStateData select _currentState) params ["_transitionCondition"]; diff --git a/addons/missileguidance/functions/fnc_onFired.sqf b/addons/missileguidance/functions/fnc_onFired.sqf index 9cc91f300a9..f4a1250087b 100644 --- a/addons/missileguidance/functions/fnc_onFired.sqf +++ b/addons/missileguidance/functions/fnc_onFired.sqf @@ -5,6 +5,8 @@ * * Arguments: * 0: Shooter (Man/Vehicle) + * 1: Weapon + * 3: Mode * 4: Ammo * 6: Projectile * @@ -30,214 +32,11 @@ if ( !isPlayer _shooter && { GVAR(enabled) < 2 } ) exitWith {}; // Verify ammo has explicity added guidance config (ignore inheritances) private _configs = configProperties [(configFile >> "CfgAmmo" >> _ammo), QUOTE(configName _x == QUOTE(QUOTE(ADDON))), false]; -if ((count _configs) < 1) exitWith {}; +if (_configs isEqualTo []) exitWith {}; -// MissileGuidance is enabled for this shot -TRACE_4("enabled",_shooter,_ammo,_projectile,typeOf _shooter); - -private _config = configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON); - -private _target = _shooter getVariable [QGVAR(target), nil]; -private _targetPos = _shooter getVariable [QGVAR(targetPosition), nil]; -private _seekerType = _shooter getVariable [QGVAR(seekerType), nil]; -private _attackProfile = _shooter getVariable [QGVAR(attackProfile), nil]; -private _navigationType = _shooter getVariable [QGVAR(navigationType), nil]; -if ((getNumber (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON) >> "useModeForAttackProfile")) == 1) then { - _attackProfile = getText (configFile >> "CfgWeapons" >> _weapon >> _mode >> QGVAR(attackProfile)) -}; -private _lockMode = _shooter getVariable [QGVAR(lockMode), nil]; - -private _laserCode = _shooter getVariable [QEGVAR(laser,code), ACE_DEFAULT_LASER_CODE]; -private _laserInfo = [_laserCode, ACE_DEFAULT_LASER_WAVELENGTH, ACE_DEFAULT_LASER_WAVELENGTH]; - -TRACE_7("getVars",_target,_targetPos,_seekerType,_attackProfile,_lockMode,_laserCode,_navigationType); - -private _launchPos = getPosASL (vehicle _shooter); - -if (isNil "_seekerType" || {!(_seekerType in (getArray (_config >> "seekerTypes")))}) then { - _seekerType = getText (_config >> "defaultSeekerType"); -}; -if (isNil "_attackProfile" || {!(_attackProfile in (getArray (_config >> "attackProfiles")))}) then { - _attackProfile = getText (_config >> "defaultAttackProfile"); -}; -if (isNil "_lockMode" || {!(_lockMode in (getArray (_config >> "seekerLockModes")))}) then { - _lockMode = getText (_config >> "defaultSeekerLockMode"); -}; -if (isNil "_navigationType" || {!(_navigationType in (getArray (_config >> "navigationTypes")))}) then { - _navigationType = getText (_config >> "defaultNavigationType"); -}; - -if (isNil "_navigationType" || _navigationType isEqualTo "") then { - // most missiles use ProNav by default - _navigationType = "ProportionalNavigation"; -}; - -// If we didn't get a target, try to fall back on tab locking -if (isNil "_target") then { - if (!isPlayer _shooter) then { - // This was an AI shot, lets still guide it on the AI target - _target = _shooter getVariable [QGVAR(vanilla_target), nil]; - TRACE_1("Detected AI Shooter!",_target); - } else { - private _canUseLock = getNumber (_config >> "canVanillaLock"); - // @TODO: Get vanilla target - if (_canUseLock > 0 || difficulty < 1) then { - private _vanillaTarget = missileTarget _projectile; - - TRACE_1("Using Vanilla Locking",_vanillaTarget); - if (!isNil "_vanillaTarget") then { - _target = _vanillaTarget; - }; - }; - }; -}; -_targetPos = getPosASLVisual _target; - -// Array for seek last target position -private _seekLastTargetPos = (getNumber ( _config >> "seekLastTargetPos")) == 1; -private _lastKnownPosState = [_seekLastTargetPos]; -if (_seekLastTargetPos && {!isNil "_target"}) then { - _lastKnownPosState set [1, (getPosASL _target)]; -} else { - _lastKnownPosState set [1, [0,0,0]]; -}; - -private _navigationParameters = [ - // set up in navigation type onFired function -]; - -// default config values to make sure there is backwards compat -private _pitchRate = 30; -private _yawRate = 30; -private _bangBang = false; -if (isNumber (_config >> "pitchRate")) then { - _pitchRate = getNumber ( _config >> "pitchRate" ); - _yawRate = getNumber ( _config >> "yawRate" ); - _bangBang = (1 == getNumber (_config >> "bangBangGuidance")); -}; - -// How much this projectile likes to stay toward current velocity -private _stabilityCoefficient = getNumber (_config >> "stabilityCoefficient"); - -// show a light trail in flight -private _showTrail = (1 == getNumber (_config >> "showTrail")); - -private _navigationStateSubclass = _config >> "navigationStates"; -private _states = getArray (_navigationStateSubclass >> "states"); - -private _navigationStateData = []; -private _initialState = ""; - -if (_states isNotEqualTo []) then { - _initialState = _states select 0; - { - private _stateClass = _navigationStateSubclass >> _x; - _navigationStateData pushBack [ - getText (_stateClass >> "transitionCondition"), - getText (_stateClass >> "navigationType"), - [] - ]; - } forEach _states; -}; - -private _initialRoll = getNumber (_config >> "initialRoll"); -private _initialYaw = getNumber (_config >> "initialYaw"); -private _initialPitch = getNumber (_config >> "initialPitch"); - -private _yawRollPitch = (vectorDir _projectile) call CBA_fnc_vect2Polar; - -TRACE_5("Beginning ACE guidance system",_target,_ammo,_seekerType,_attackProfile,_navigationType); -private _args = [_this, - [ _shooter, - [_target, _targetPos, _launchPos, vectorDirVisual vehicle _shooter, CBA_missionTime], - _seekerType, - _attackProfile, - _lockMode, - _laserInfo, - _navigationType - ], - [ - _pitchRate, - _yawRate, - _bangBang, - _stabilityCoefficient, - _showTrail - ], - [ - getNumber ( _config >> "seekerAngle" ), - getNumber ( _config >> "seekerAccuracy" ), - getNumber ( _config >> "seekerMaxRange" ), - getNumber ( _config >> "seekerMinRange" ) - ], - [ diag_tickTime, [], [], _lastKnownPosState, _navigationParameters, [_initialYaw + (_yawRollPitch select 1), _initialRoll, _initialPitch + (_yawRollPitch select 2)]], - [ - // target data from missile. Must be filled by seeker for navigation to work - [0, 0, 0], // direction to target - [0, 0, 0], // direction to attack profile - 0, // range to target - [0, 0, 0], // target velocity - [0, 0, 0] // target acceleration - ], - [0, _navigationStateData] - ]; - -private _onFiredFunc = getText (configFile >> QGVAR(SeekerTypes) >> _seekerType >> "onFired"); -TRACE_1("seeker on fired",_onFiredFunc); -if (_onFiredFunc != "") then { - _args call (missionNamespace getVariable _onFiredFunc); -}; - -_onFiredFunc = getText (configFile >> QGVAR(AttackProfiles) >> _attackProfile >> "onFired"); -TRACE_1("attack on fired",_onFiredFunc); -if (_onFiredFunc != "") then { - _args call (missionNamespace getVariable _onFiredFunc); -}; - -if (_states isEqualTo []) then { - _onFiredFunc = getText (configFile >> QGVAR(NavigationTypes) >> _navigationType >> "onFired"); - TRACE_1("navigation on fired",_onFiredFunc); - if (_onFiredFunc != "") then { - private _navState = (_args call (missionNamespace getVariable _onFiredFunc)); - (_args select 4) set [4, _navState]; - }; -} else { - { - _onFiredFunc = getText (configFile >> QGVAR(NavigationTypes) >> _x >> "onFired"); - TRACE_1("navigation on fired",_onFiredFunc); - if (_onFiredFunc != "") then { - private _navState = (_args call (missionNamespace getVariable _onFiredFunc)); - (_navigationStateData select _forEachIndex) set [2, _navState]; - }; - } forEach getArray (_config >> "navigationTypes"); -}; - -// Run the "onFired" function passing the full guidance args array -_onFiredFunc = getText (_config >> "onFired"); -TRACE_1("general on fired",_onFiredFunc); -if (_onFiredFunc != "") then { - _args call (missionNamespace getVariable _onFiredFunc); -}; - -// Reverse: -// _args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams", "_targetData", "_navigationStateData"]; -// _firedEH params ["_shooter","","","","_ammo","","_projectile"]; -// _launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo","_navigationType"]; -// _targetLaunchParams params ["_target", "_targetPos", "_launchPos", "_launchDir", "_launchTime"]; -// _flightParams params ["_pitchRate", "_yawRate", "_isBangBangGuidance"]; -// _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState", "_navigationParams", "_guidanceParameters"]; -// _seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange", "_seekerMinRange"]; -// _targetData params ["_targetDirection", "_attackProfileDirection", "_targetRange", "_targetVelocity", "_targetAcceleration"]; - -[LINKFUNC(guidancePFH),0, _args ] call CBA_fnc_addPerFrameHandler; +private _args = call FUNC(onFiredGetArgs); +[LINKFUNC(guidancePFH),0, _args] call CBA_fnc_addPerFrameHandler; if (GVAR(debug_enableMissileCamera)) then { [_projectile] call FUNC(dev_ProjectileCamera); }; - - -/* Clears locking settings -(vehicle _shooter) setVariable [QGVAR(target), nil]; -(vehicle _shooter) setVariable [QGVAR(seekerType), nil]; -(vehicle _shooter) setVariable [QGVAR(attackProfile), nil]; -(vehicle _shooter) setVariable [QGVAR(lockMode), nil]; - */ diff --git a/addons/missileguidance/functions/fnc_onFiredDeferred.sqf b/addons/missileguidance/functions/fnc_onFiredDeferred.sqf deleted file mode 100644 index 195967b74aa..00000000000 --- a/addons/missileguidance/functions/fnc_onFiredDeferred.sqf +++ /dev/null @@ -1,137 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: PabstMirror (mostly copy of onFired) - * Fired event handler for defered ammos (clgp), returns guidance args - * - * Arguments: - * 0: Shooter (Man/Vehicle) - * 1: Weapon - * 3: Mode - * 4: Ammo (in the future) - * 6: Projectile - * - * Return Value: - * - * - * Example: - * [player, "", "", "", "ACE_Javelin_FGM148", "", theMissile] call ace_missileguidance_fnc_onFiredDeferred; - * - * Public: No - */ - -params ["_shooter","_weapon","","_mode","_ammo","","_projectile"]; - -// Bail if guidance is disabled for this ammo -if ((getNumber (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON) >> "enabled")) != 2) exitWith { ERROR("not enabled=2"); [] }; - -// MissileGuidance is enabled for this shot -TRACE_4("enabled",_shooter,_ammo,_projectile,typeOf _shooter); - -private _config = configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON); - -private _target = _shooter getVariable [QGVAR(target), nil]; -private _targetPos = _shooter getVariable [QGVAR(targetPosition), nil]; -private _seekerType = _shooter getVariable [QGVAR(seekerType), nil]; -private _attackProfile = _shooter getVariable [QGVAR(attackProfile), nil]; -if ((getNumber (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON) >> "useModeForAttackProfile")) == 1) then { - _attackProfile = getText (configFile >> "CfgWeapons" >> _weapon >> _mode >> QGVAR(attackProfile)) -}; -private _lockMode = _shooter getVariable [QGVAR(lockMode), nil]; - -private _laserCode = _shooter getVariable [QEGVAR(laser,code), ACE_DEFAULT_LASER_CODE]; -private _laserInfo = [_laserCode, ACE_DEFAULT_LASER_WAVELENGTH, ACE_DEFAULT_LASER_WAVELENGTH]; - -TRACE_6("getVars",_target,_targetPos,_seekerType,_attackProfile,_lockMode,_laserCode); - -private _launchPos = getPosASL (vehicle _shooter); - -if (isNil "_seekerType" || {!(_seekerType in (getArray (_config >> "seekerTypes")))}) then { - _seekerType = getText (_config >> "defaultSeekerType"); -}; -if (isNil "_attackProfile" || {!(_attackProfile in (getArray (_config >> "attackProfiles")))}) then { - _attackProfile = getText (_config >> "defaultAttackProfile"); -}; -if (isNil "_lockMode" || {!(_lockMode in (getArray (_config >> "seekerLockModes")))}) then { - _lockMode = getText (_config >> "defaultSeekerLockMode"); -}; - -// If we didn't get a target, try to fall back on tab locking -if (isNil "_target") then { - if (!isPlayer _shooter) then { - // This was an AI shot, lets still guide it on the AI target - _target = _shooter getVariable [QGVAR(vanilla_target), nil]; - TRACE_1("Detected AI Shooter!",_target); - } else { - private _canUseLock = getNumber (_config >> "canVanillaLock"); - // @TODO: Get vanilla target - if (_canUseLock > 0 || difficulty < 1) then { - private _vanillaTarget = cursorTarget; - - TRACE_1("Using Vanilla Locking",_vanillaTarget); - if (!isNil "_vanillaTarget") then { - _target = _vanillaTarget; - }; - }; - }; -}; - -// Array for seek last target position -private _seekLastTargetPos = (getNumber ( _config >> "seekLastTargetPos")) == 1; -private _lastKnownPosState = [_seekLastTargetPos]; -if (_seekLastTargetPos && {!isNil "_target"}) then { - _lastKnownPosState set [1, (getPosASL _target)]; -} else { - _lastKnownPosState set [1, [0,0,0]]; -}; - -TRACE_4("Beginning ACE guidance system",_target,_ammo,_seekerType,_attackProfile); -private _args = [_this, - [ _shooter, - [_target, _targetPos, _launchPos], - _seekerType, - _attackProfile, - _lockMode, - _laserInfo - ], - [ - getNumber ( _config >> "minDeflection" ), - getNumber ( _config >> "maxDeflection" ), - getNumber ( _config >> "incDeflection" ) - ], - [ - getNumber ( _config >> "seekerAngle" ), - getNumber ( _config >> "seekerAccuracy" ), - getNumber ( _config >> "seekerMaxRange" ), - getNumber ( _config >> "seekerMinRange" ) - ], - [ diag_tickTime, [], [], _lastKnownPosState] - ]; - -private _onFiredFunc = getText (configFile >> QGVAR(SeekerTypes) >> _seekerType >> "onFired"); -TRACE_1("",_onFiredFunc); -if (_onFiredFunc != "") then { - _args call (missionNamespace getVariable _onFiredFunc); -}; - -_onFiredFunc = getText (configFile >> QGVAR(AttackProfiles) >> _attackProfile >> "onFired"); -TRACE_1("",_onFiredFunc); -if (_onFiredFunc != "") then { - _args call (missionNamespace getVariable _onFiredFunc); -}; - -// Run the "onFired" function passing the full guidance args array -_onFiredFunc = getText (_config >> "onFired"); -TRACE_1("",_onFiredFunc); -if (_onFiredFunc != "") then { - _args call (missionNamespace getVariable _onFiredFunc); -}; - -// Reverse: -// _args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams"]; -// _firedEH params ["_shooter","","","","_ammo","","_projectile"]; -// _launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo"]; -// _targetLaunchParams params ["_target", "_targetPos", "_launchPos"]; -// _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState"]; -// _seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange", "_seekerMinRange"]; - -_args diff --git a/addons/missileguidance/functions/fnc_onFiredGetArgs.sqf b/addons/missileguidance/functions/fnc_onFiredGetArgs.sqf new file mode 100644 index 00000000000..55a2e722807 --- /dev/null +++ b/addons/missileguidance/functions/fnc_onFiredGetArgs.sqf @@ -0,0 +1,220 @@ +#include "..\script_component.hpp" +/* + * Author: jaynus, nou, TCVM, PabstMirror + * Gets guidance args for a fired missile, running fired EHs and returning the full guidance arg array + * + * Arguments: + * 0: Shooter (Man/Vehicle) + * 1: Weapon + * 3: Mode + * 4: Ammo (in the future) + * 6: Projectile + * + * Return Value: + * + * + * Example: + * [player, "", "", "", "ACE_Javelin_FGM148", "", theMissile] call ace_missileguidance_fnc_onFiredGetArgs + * + * Public: No + */ + +params ["_shooter","_weapon","","_mode","_ammo","","_projectile"]; + +// MissileGuidance is enabled for this shot +TRACE_4("enabled",_shooter,_ammo,_projectile,typeOf _shooter); + +private _config = configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON); + +private _target = _shooter getVariable [QGVAR(target), nil]; +private _targetPos = _shooter getVariable [QGVAR(targetPosition), nil]; +private _seekerType = _shooter getVariable [QGVAR(seekerType), nil]; +private _attackProfile = _shooter getVariable [QGVAR(attackProfile), nil]; +private _navigationType = _shooter getVariable [QGVAR(navigationType), nil]; +if ((getNumber (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON) >> "useModeForAttackProfile")) == 1) then { + _attackProfile = getText (configFile >> "CfgWeapons" >> _weapon >> _mode >> QGVAR(attackProfile)) +}; +private _lockMode = _shooter getVariable [QGVAR(lockMode), nil]; + +private _laserCode = _shooter getVariable [QEGVAR(laser,code), ACE_DEFAULT_LASER_CODE]; +private _laserInfo = [_laserCode, ACE_DEFAULT_LASER_WAVELENGTH, ACE_DEFAULT_LASER_WAVELENGTH]; + +TRACE_7("onFiredGetArgs",_target,_targetPos,_seekerType,_attackProfile,_lockMode,_laserCode,_navigationType); + +private _launchPos = getPosASL (vehicle _shooter); + +if (isNil "_seekerType" || {!(_seekerType in (getArray (_config >> "seekerTypes")))}) then { + _seekerType = getText (_config >> "defaultSeekerType"); +}; +if (isNil "_attackProfile" || {!(_attackProfile in (getArray (_config >> "attackProfiles")))}) then { + _attackProfile = getText (_config >> "defaultAttackProfile"); +}; +if (isNil "_lockMode" || {!(_lockMode in (getArray (_config >> "seekerLockModes")))}) then { + _lockMode = getText (_config >> "defaultSeekerLockMode"); +}; +if (isNil "_navigationType" || {!(_navigationType in (getArray (_config >> "navigationTypes")))}) then { + _navigationType = getText (_config >> "defaultNavigationType"); +}; + +if (isNil "_navigationType" || _navigationType isEqualTo "") then { + // most missiles use ProNav by default + _navigationType = "ProportionalNavigation"; +}; + +// If we didn't get a target, try to fall back on tab locking +if (isNil "_target") then { + if (!isPlayer _shooter) then { + // This was an AI shot, lets still guide it on the AI target + _target = _shooter getVariable [QGVAR(vanilla_target), nil]; + TRACE_1("Detected AI Shooter!",_target); + } else { + private _canUseLock = getNumber (_config >> "canVanillaLock"); + // @TODO: Get vanilla target + if (_canUseLock > 0 || difficulty < 1) then { + private _vanillaTarget = missileTarget _projectile; + + TRACE_1("Using Vanilla Locking",_vanillaTarget); + if (!isNil "_vanillaTarget") then { + _target = _vanillaTarget; + }; + }; + }; +}; +_targetPos = getPosASLVisual _target; + +// Array for seek last target position +private _seekLastTargetPos = (getNumber ( _config >> "seekLastTargetPos")) == 1; +private _lastKnownPosState = [_seekLastTargetPos]; +if (_seekLastTargetPos && {!isNil "_target"}) then { + _lastKnownPosState set [1, (getPosASL _target)]; +} else { + _lastKnownPosState set [1, [0,0,0]]; +}; + +private _navigationParameters = [ + // set up in navigation type onFired function +]; + +// default config values to make sure there is backwards compat +private _pitchRate = 30; +private _yawRate = 30; +private _bangBang = false; +if (isNumber (_config >> "pitchRate")) then { + _pitchRate = getNumber ( _config >> "pitchRate" ); + _yawRate = getNumber ( _config >> "yawRate" ); + _bangBang = (1 == getNumber (_config >> "bangBangGuidance")); +}; + +// How much this projectile likes to stay toward current velocity +private _stabilityCoefficient = getNumber (_config >> "stabilityCoefficient"); + +// show a light trail in flight +private _showTrail = (1 == getNumber (_config >> "showTrail")); + +private _navigationStateSubclass = _config >> "navigationStates"; +private _states = getArray (_navigationStateSubclass >> "states"); + +private _navigationStateData = []; +private _initialState = ""; + +if (_states isNotEqualTo []) then { + _initialState = _states select 0; + { + private _stateClass = _navigationStateSubclass >> _x; + _navigationStateData pushBack [ + getText (_stateClass >> "transitionCondition"), + getText (_stateClass >> "navigationType"), + [] + ]; + } forEach _states; +}; + +private _initialRoll = getNumber (_config >> "initialRoll"); +private _initialYaw = getNumber (_config >> "initialYaw"); +private _initialPitch = getNumber (_config >> "initialPitch"); + +private _yawRollPitch = (vectorDir _projectile) call CBA_fnc_vect2Polar; + +TRACE_5("Beginning ACE guidance system",_target,_ammo,_seekerType,_attackProfile,_navigationType); +private _args = [_this, + [ _shooter, + [_target, _targetPos, _launchPos, vectorDirVisual vehicle _shooter, CBA_missionTime], + _seekerType, + _attackProfile, + _lockMode, + _laserInfo, + _navigationType + ], + [ + _pitchRate, + _yawRate, + _bangBang, + _stabilityCoefficient, + _showTrail + ], + [ + getNumber ( _config >> "seekerAngle" ), + getNumber ( _config >> "seekerAccuracy" ), + getNumber ( _config >> "seekerMaxRange" ), + getNumber ( _config >> "seekerMinRange" ) + ], + [ diag_tickTime, [], [], _lastKnownPosState, _navigationParameters, [_initialYaw + (_yawRollPitch select 1), _initialRoll, _initialPitch + (_yawRollPitch select 2)]], + [ + // target data from missile. Must be filled by seeker for navigation to work + [0, 0, 0], // direction to target + [0, 0, 0], // direction to attack profile + 0, // range to target + [0, 0, 0], // target velocity + [0, 0, 0] // target acceleration + ], + [0, _navigationStateData] + ]; + +private _onFiredFunc = getText (configFile >> QGVAR(SeekerTypes) >> _seekerType >> "onFired"); +TRACE_1("seeker on fired",_onFiredFunc); +if (_onFiredFunc != "") then { + _args call (missionNamespace getVariable _onFiredFunc); +}; + +_onFiredFunc = getText (configFile >> QGVAR(AttackProfiles) >> _attackProfile >> "onFired"); +TRACE_1("attack on fired",_onFiredFunc); +if (_onFiredFunc != "") then { + _args call (missionNamespace getVariable _onFiredFunc); +}; + +if (_states isEqualTo []) then { + _onFiredFunc = getText (configFile >> QGVAR(NavigationTypes) >> _navigationType >> "onFired"); + TRACE_1("navigation on fired",_onFiredFunc); + if (_onFiredFunc != "") then { + private _navState = (_args call (missionNamespace getVariable _onFiredFunc)); + (_args select 4) set [4, _navState]; + }; +} else { + { + _onFiredFunc = getText (configFile >> QGVAR(NavigationTypes) >> _x >> "onFired"); + TRACE_1("navigation on fired",_onFiredFunc); + if (_onFiredFunc != "") then { + private _navState = (_args call (missionNamespace getVariable _onFiredFunc)); + (_navigationStateData select _forEachIndex) set [2, _navState]; + }; + } forEach getArray (_config >> "navigationTypes"); +}; + +// Run the "onFired" function passing the full guidance args array +_onFiredFunc = getText (_config >> "onFired"); +TRACE_1("general on fired",_onFiredFunc); +if (_onFiredFunc != "") then { + _args call (missionNamespace getVariable _onFiredFunc); +}; + +// Reverse: +// _args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams", "_targetData", "_navigationStateData"]; +// _firedEH params ["_shooter","","","","_ammo","","_projectile"]; +// _launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo","_navigationType"]; +// _targetLaunchParams params ["_target", "_targetPos", "_launchPos", "_launchDir", "_launchTime"]; +// _flightParams params ["_pitchRate", "_yawRate", "_isBangBangGuidance"]; +// _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState", "_navigationParams", "_guidanceParameters"]; +// _seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange", "_seekerMinRange"]; +// _targetData params ["_targetDirection", "_attackProfileDirection", "_targetRange", "_targetVelocity", "_targetAcceleration"]; + +_args