diff --git a/addons/missile_aim9/$PBOPREFIX$ b/addons/missile_aim9/$PBOPREFIX$ new file mode 100644 index 00000000000..c47abf3aae6 --- /dev/null +++ b/addons/missile_aim9/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\missile_aim9 \ No newline at end of file diff --git a/addons/missile_aim9/CfgAmmo.hpp b/addons/missile_aim9/CfgAmmo.hpp new file mode 100644 index 00000000000..dae888c3561 --- /dev/null +++ b/addons/missile_aim9/CfgAmmo.hpp @@ -0,0 +1,91 @@ +class EGVAR(missileguidance,type_Sidewinder); +class EGVAR(missileguidance,type_ASRAAM); +class EGVAR(missileguidance,type_R73); +class EGVAR(missileguidance,type_R74); +class CfgAmmo { + class Missile_AA_04_F; + class GVAR(m): Missile_AA_04_F { + missileLockCone = 3; // caged lock + missileKeepLockedCone = 45; + missileLockMaxDistance = 5000; + missileLockMinDistance = 250; + + author = "Dani (TCVM)"; + maneuvrability = 0; + + class ace_missileguidance: EGVAR(missileguidance,type_Sidewinder) { + enabled = 1; + }; + }; + + class ammo_Missile_BIM9X; + class GVAR(x): ammo_Missile_BIM9X { + missileLockCone = 3; // caged lock + missileKeepLockedCone = 120; + missileLockMaxDistance = 5000; + missileLockMinDistance = 250; + + author = "Dani (TCVM)"; + maneuvrability = 0; + + class ace_missileguidance: EGVAR(missileguidance,type_Sidewinder) { + enabled = 1; + pitchRate = 90; + yawRate = 90; + flareDistanceFilter = 50; + flareAngleFilter = 0.8; // can filter out flares that are >= flareAngleFilter to known target velocity + defaultNavigationType = "ZeroEffortMiss"; + navigationTypes[] = { "ZeroEffortMiss" }; + seekerAngle = 120; + seekerAccuracy = 0.95; + }; + }; + + // AIM-132 + class M_Air_AA; + class GVAR(aim132): M_Air_AA { + missileLockCone = 3; // caged lock + missileKeepLockedCone = 120; + missileLockMaxDistance = 8000; + missileLockMinDistance = 250; + + author = "Dani (TCVM)"; + maneuvrability = 0; + + class ace_missileguidance: EGVAR(missileguidance,type_ASRAAM) { + enabled = 1; + }; + }; + + // R-73 + class ammo_Missile_AA_R73; + class GVAR(r73): ammo_Missile_AA_R73 { + missileLockCone = 3; // caged lock + missileKeepLockedCone = 40; + missileLockMaxDistance = 5000; + missileLockMinDistance = 250; + + author = "Dani (TCVM)"; + maneuvrability = 0; + + class ace_missileguidance: EGVAR(missileguidance,type_Sidewinder) { + enabled = 1; + }; + }; + + class Missile_AA_03_F; + class GVAR(r74): Missile_AA_03_F { + missileLockCone = 3; // caged lock + missileKeepLockedCone = 75; + missileLockMaxDistance = 8000; + missileLockMinDistance = 250; + + author = "Dani (TCVM)"; + maneuvrability = 0; + + class ace_missileguidance: EGVAR(missileguidance,type_R74) { + enabled = 1; + }; + }; +}; + diff --git a/addons/missile_aim9/CfgMagazines.hpp b/addons/missile_aim9/CfgMagazines.hpp new file mode 100644 index 00000000000..5fc12fcf106 --- /dev/null +++ b/addons/missile_aim9/CfgMagazines.hpp @@ -0,0 +1,153 @@ +class CfgMagazines { + class 2Rnd_Missile_AA_04_F; + class PylonRack_1Rnd_Missile_AA_04_F; + class PylonMissile_1Rnd_Missile_AA_04_F; + + // AIM-9 + class GVAR(2Rnd_Missile_9m): 2Rnd_Missile_AA_04_F { + author = "Dani (TCVM)"; + displayName = CSTRING(m_2x); + ammo = QGVAR(m); + }; + + class GVAR(PylonRack_1Rnd_Missile_9m): PylonRack_1Rnd_Missile_AA_04_F { + author = "Dani (TCVM)"; + displayName = CSTRING(m_1x); + ammo = QGVAR(m); + pylonWeapon = QGVAR(m); + }; + + class GVAR(PylonMissile_1Rnd_Missile_9m): PylonMissile_1Rnd_Missile_AA_04_F { + author = "Dani (TCVM)"; + displayName = CSTRING(m_1x); + ammo = QGVAR(m); + pylonWeapon = QGVAR(m); + }; + + class magazine_Missile_BIM9X_x1; + class PylonMissile_Missile_BIM9X_x1; + class PylonRack_Missile_BIM9X_x1; + class PylonRack_Missile_BIM9X_x2; + + class GVAR(magazine_Missile_9x): magazine_Missile_BIM9X_x1 { + author = "Dani (TCVM)"; + displayName = CSTRING(x_1x); + ammo = QGVAR(x); + }; + + class GVAR(PylonMissile_Missile_9x): PylonMissile_Missile_BIM9X_x1 { + author = "Dani (TCVM)"; + displayName = CSTRING(x_1x); + ammo = QGVAR(x); + pylonWeapon = QGVAR(x); + }; + + class GVAR(PylonRack_Missile_9x): PylonRack_Missile_BIM9X_x1 { + author = "Dani (TCVM)"; + displayName = CSTRING(x_1x); + ammo = QGVAR(x); + pylonWeapon = QGVAR(x); + }; + + class GVAR(PylonRack_Missile_9x_2): PylonRack_Missile_BIM9X_x2 { + author = "Dani (TCVM)"; + displayName = CSTRING(x_2x); + ammo = QGVAR(x); + pylonWeapon = QGVAR(x); + }; + + // AIM-132 + class 2Rnd_AAA_missiles; + class 2Rnd_AAA_missiles_MI02; + class 2Rnd_AAA_missiles_MI06; + class 4Rnd_AAA_missiles; + class 4Rnd_AAA_missiles_MI02; + class PylonRack_1Rnd_AAA_missiles; + class PylonMissile_1Rnd_AAA_missiles; + + class GVAR(aim132_2Rnd): 2Rnd_AAA_missiles { + author = "Dani (TCVM)"; + displayName = CSTRING(aim132_2x); + ammo = QGVAR(aim132); + }; + + class GVAR(aim132_2Rnd_MI02): 2Rnd_AAA_missiles_MI02 { + author = "Dani (TCVM)"; + displayName = CSTRING(aim132_2x); + ammo = QGVAR(aim132); + }; + + class GVAR(aim132_2Rnd_MI06): 2Rnd_AAA_missiles_MI06 { + author = "Dani (TCVM)"; + displayName = CSTRING(aim132_2x); + ammo = QGVAR(aim132); + }; + + class GVAR(aim132_4Rnd): 4Rnd_AAA_missiles { + author = "Dani (TCVM)"; + displayName = CSTRING(aim132_4x); + ammo = QGVAR(aim132); + }; + + class GVAR(aim132_4Rnd_MI02): 4Rnd_AAA_missiles_MI02 { + author = "Dani (TCVM)"; + displayName = CSTRING(aim132_4x); + ammo = QGVAR(aim132); + }; + + class GVAR(PylonRack_1Rnd_aim132): PylonRack_1Rnd_AAA_missiles { + author = "Dani (TCVM)"; + displayName = CSTRING(aim132_1x); + ammo = QGVAR(aim132); + pylonWeapon = QGVAR(aim132); + }; + + class GVAR(PylonMissile_1Rnd_aim132): PylonMissile_1Rnd_AAA_missiles { + author = "Dani (TCVM)"; + displayName = CSTRING(aim132_1x); + ammo = QGVAR(aim132); + pylonWeapon = QGVAR(aim132); + }; + + // R-73 + class PylonMissile_Missile_AA_R73_x1; + class magazine_Missile_AA_R73_x1; + class 2Rnd_Missile_AA_03_F; + class PylonRack_1Rnd_Missile_AA_03_F; + class PylonMissile_1Rnd_Missile_AA_03_F; + + class GVAR(r73): magazine_Missile_AA_R73_x1 { + author = "Dani (TCVM)"; + displayName = CSTRING(r73_1x); + ammo = QGVAR(r73); + }; + + class GVAR(PylonMissile_Missile_R73_x1): PylonMissile_Missile_AA_R73_x1 { + author = "Dani (TCVM)"; + displayName = CSTRING(r73_1x); + ammo = QGVAR(r73); + pylonWeapon = QGVAR(r73); + }; + + class GVAR(2Rnd_Missile_R74): 2Rnd_Missile_AA_03_F { + author = "Dani (TCVM)"; + displayName = CSTRING(r74_2x); + ammo = QGVAR(r74); + }; + + // R-74 -- improved R-73, same missile in the way that an AIM-9X is the same as an AIM-9M + class GVAR(PylonRack_1Rnd_Missile_R74): PylonRack_1Rnd_Missile_AA_03_F { + author = "Dani (TCVM)"; + displayName = CSTRING(r74_1x); + ammo = QGVAR(r74); + pylonWeapon = QGVAR(r74); + }; + + class GVAR(PylonMissile_1Rnd_Missile_R74): PylonMissile_1Rnd_Missile_AA_03_F { + author = "Dani (TCVM)"; + displayName = CSTRING(r74_1x); + ammo = QGVAR(r74); + pylonWeapon = QGVAR(r74); + }; +}; + diff --git a/addons/missile_aim9/CfgWeapons.hpp b/addons/missile_aim9/CfgWeapons.hpp new file mode 100644 index 00000000000..cf69f9179c6 --- /dev/null +++ b/addons/missile_aim9/CfgWeapons.hpp @@ -0,0 +1,72 @@ +class CfgWeapons { + // AIM-9 + class Missile_AA_04_Plane_CAS_01_F; + class GVAR(m): Missile_AA_04_Plane_CAS_01_F { + lockAcquire = 1; // auto lock + + author = "Dani (TCVM)"; + displayName = CSTRING(m); + weaponLockDelay = 0.5; + magazines[] = {QGVAR(2Rnd_Missile_9m), QGVAR(PylonRack_1Rnd_Missile_9m), QGVAR(PylonMissile_1Rnd_Missile_9m)}; + }; + + class weapon_BIM9xLauncher; + class GVAR(x): weapon_BIM9xLauncher { + lockAcquire = 1; // auto lock + + author = "Dani (TCVM)"; + displayName = CSTRING(x); + weaponLockDelay = 0.5; + magazines[] = { QGVAR(magazine_Missile_9x), QGVAR(PylonMissile_Missile_9x), QGVAR(PylonRack_Missile_9x), QGVAR(PylonRack_Missile_9x_2) }; + }; + + // ASRAAM + class missiles_ASRAAM; + class GVAR(aim132): missiles_ASRAAM { + lockAcquire = 1; // auto lock + + author = "Dani (TCVM)"; + displayName = CSTRING(aim132); + weaponLockDelay = 0.5; + magazines[] = { + QGVAR(aim132_2Rnd), + QGVAR(aim132_2Rnd_MI02), + QGVAR(aim132_2Rnd_MI06), + QGVAR(aim132_4Rnd), + QGVAR(aim132_4Rnd_MI02), + QGVAR(PylonRack_1Rnd_aim132), + QGVAR(PylonMissile_1Rnd_aim132) + }; + }; + + // R-73 + class weapon_R73Launcher; + class GVAR(r73): weapon_R73Launcher { + lockAcquire = 1; // auto lock + + author = "Dani (TCVM)"; + displayName = CSTRING(r73); + weaponLockDelay = 0.5; + + magazines[] = { + QGVAR(r73), + QGVAR(PylonMissile_Missile_R73_x1) + }; + }; + + class Missile_AA_03_Plane_CAS_02_F; + class GVAR(r74): Missile_AA_03_Plane_CAS_02_F { + lockAcquire = 1; // auto lock + + author = "Dani (TCVM)"; + displayName = CSTRING(r74); + weaponLockDelay = 0.5; + + magazines[] = { + QGVAR(2Rnd_Missile_R74), + QGVAR(PylonRack_1Rnd_Missile_R74), + QGVAR(PylonMissile_1Rnd_Missile_R74) + }; + }; +}; + diff --git a/addons/missile_aim9/README.md b/addons/missile_aim9/README.md new file mode 100644 index 00000000000..245c08a727a --- /dev/null +++ b/addons/missile_aim9/README.md @@ -0,0 +1,12 @@ +ace_missile_aim9 +=================== + +Adds AIM-9 and R-73 AHR missiles + + +## Maintainers + +The people responsible for merging changes to this component or answering potential questions. + +- [Dani-TCVM](https://github.com/TheCandianVendingMachine) + diff --git a/addons/missile_aim9/config.cpp b/addons/missile_aim9/config.cpp new file mode 100644 index 00000000000..6b84b38bb70 --- /dev/null +++ b/addons/missile_aim9/config.cpp @@ -0,0 +1,20 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_common","ace_missileguidance"}; + author = ECSTRING(common,ACETeam); + authors[] = {"Dani (TCVM)"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgAmmo.hpp" +#include "CfgMagazines.hpp" +#include "CfgWeapons.hpp" + diff --git a/addons/missile_aim9/script_component.hpp b/addons/missile_aim9/script_component.hpp new file mode 100644 index 00000000000..20bf611ad62 --- /dev/null +++ b/addons/missile_aim9/script_component.hpp @@ -0,0 +1,18 @@ +#define COMPONENT missile_aim9 +#define COMPONENT_BEAUTIFIED AIM-9 +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_MISSILE_AIM9 + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_MISSILE_AIM9 + #define DEBUG_SETTINGS DEBUG_SETTINGS_MISSILE_AIM9 +#endif + +#include "\z\ace\addons\main\script_macros.hpp" + diff --git a/addons/missile_aim9/stringtable.xml b/addons/missile_aim9/stringtable.xml new file mode 100644 index 00000000000..5261674153d --- /dev/null +++ b/addons/missile_aim9/stringtable.xml @@ -0,0 +1,50 @@ + + + + + AIM-9M [ACE] + + + AIM-9X [ACE] + + + AIM-132 [ACE] + + + R-73 [ACE] + + + R-74 [ACE] + + + 1x AIM-9M [ACE] + + + 2x AIM-9M [ACE] + + + 1x AIM-9X [ACE] + + + 2x AIM-9X [ACE] + + + 1x AIM-132 [ACE] + + + 2x AIM-132 [ACE] + + + 4x AIM-132 [ACE] + + + 1x R-73 [ACE] + + + 1x R-74 [ACE] + + + 2x R-74 [ACE] + + + diff --git a/addons/missileguidance/ACE_GuidanceConfig.hpp b/addons/missileguidance/ACE_GuidanceConfig.hpp index 0475da204eb..58c650307dd 100644 --- a/addons/missileguidance/ACE_GuidanceConfig.hpp +++ b/addons/missileguidance/ACE_GuidanceConfig.hpp @@ -88,6 +88,14 @@ class GVAR(SeekerTypes) { functionName = QFUNC(seekerType_MWR); onFired = QFUNC(mwr_onFired); }; + class IR { + name = ""; + visualName = ""; + description = ""; + + functionName = QFUNC(seekerType_IR); + onFired = QFUNC(IR_onFired); + }; class DopplerRadar { name = ""; visualName = ""; diff --git a/addons/missileguidance/CfgMissileTypesNato.hpp b/addons/missileguidance/CfgMissileTypesNato.hpp index 87730b5ed0c..7dcbd8e22c0 100644 --- a/addons/missileguidance/CfgMissileTypesNato.hpp +++ b/addons/missileguidance/CfgMissileTypesNato.hpp @@ -612,8 +612,8 @@ class GVAR(type_Redeye) { class GVAR(type_Sidewinder) { enabled = 0; - pitchRate = 25; // Minium flap deflection for guidance - yawRate = 25; // Maximum flap deflection for guidance + 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 diff --git a/addons/missileguidance/XEH_PREP.hpp b/addons/missileguidance/XEH_PREP.hpp index c59389992ff..afdaba260a0 100644 --- a/addons/missileguidance/XEH_PREP.hpp +++ b/addons/missileguidance/XEH_PREP.hpp @@ -48,6 +48,7 @@ PREP(seekerType_Optic); PREP(seekerType_SACLOS); PREP(seekerType_Doppler); PREP(seekerType_MWR); +PREP(seekerType_IR); // Attack Profiles OnFired PREP(wire_onFired); @@ -56,6 +57,7 @@ PREP(wire_onFired); PREP(doppler_onFired); PREP(SACLOS_onFired); PREP(mwr_onFired); +PREP(IR_onFired); // Navigation OnFired PREP(proNav_onFired); diff --git a/addons/missileguidance/functions/fnc_IR_onFired.sqf b/addons/missileguidance/functions/fnc_IR_onFired.sqf new file mode 100644 index 00000000000..14dfe45f18c --- /dev/null +++ b/addons/missileguidance/functions/fnc_IR_onFired.sqf @@ -0,0 +1,29 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Sets up IR state arrays (called from missileGuidance's onFired). + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * None + * + * Example: + * [] call ace_missileguidance_fnc_IR_onFired + * + * Public: No + */ +params ["_firedEH", "_launchParams", "", "", "_stateParams"]; +_firedEH params ["_shooter","_weapon","","","","","_projectile"]; +_stateParams params ["", "_seekerStateParams"]; +_launchParams params ["", "_targetLaunchParams"]; +_targetLaunchParams params ["_target"]; + +private _flareDistanceFilter = getNumber (configOf _projectile >> QUOTE(ADDON) >> "flareDistanceFilter"); +private _flareAngleFilter = getNumber (configOf _projectile >> QUOTE(ADDON) >> "flareAngleFilter"); + +_seekerStateParams set [0, _flareDistanceFilter]; +_seekerStateParams set [1, _flareAngleFilter]; +_seekerStateParams set [2, _target]; + diff --git a/addons/missileguidance/functions/fnc_seekerType_IR.sqf b/addons/missileguidance/functions/fnc_seekerType_IR.sqf new file mode 100644 index 00000000000..066a0cc98aa --- /dev/null +++ b/addons/missileguidance/functions/fnc_seekerType_IR.sqf @@ -0,0 +1,143 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Infrared seeker. Checks if flares are popped + * + * Arguments: + * 1: Guidance Arg Array + * 2: Seeker State + * + * Return Value: + * Position of wanted missile pos relative to the camera direction + * + * Example: + * [] call ace_missileguidance_fnc_seekerType_IR + * + * Public: No + */ +#ifdef DEBUG_MODE_FULL +#define TRACK_ON_PAUSE true +#else +#define TRACK_ON_PAUSE false +#endif + +_args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams", "_targetData"]; +_firedEH params ["_shooter","","","","_ammo","","_projectile"]; +_launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo","_navigationType"]; +_targetLaunchParams params ["_target", "", "_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"]; + +_seekerStateParams params ["_flareDistanceFilter", "_flareAngleFilter", "_trackingTarget"]; + +private _distanceFromLaunch = _launchPos distanceSqr getPosASLVisual _projectile; +if (_distanceFromLaunch <= _seekerMinRange * _seekerMinRange) exitWith { + private _dir = _launchPos vectorFromTo getPosASLVisual _projectile; + _dir vectorAdd getPosASLVisual _projectile +}; + +private _withinView = [_projectile, getPosASLVisual _trackingTarget, _seekerAngle] call FUNC(checkSeekerAngle); +private _canSee = [_projectile, _trackingTarget, false] call FUNC(checkLos); +if (_trackingTarget isNotEqualTo objNull && ({ !_withinView || !_canSee })) then { + _trackingTarget = objNull; +}; +if (isNull _trackingTarget) then { + // find any target within seeker range + private _potentialTargets = _projectile nearEntities ["Air", _seekerMaxRange]; + private _bestAngle = 90; + { + private _withinView = [_projectile, getPosASLVisual _x, _seekerAngle] call FUNC(checkSeekerAngle); + private _canSee = [_projectile, _x, false] call FUNC(checkLos); + + if (_withinView && _canSee) then { + private _los = (getPosASLVisual _projectile) vectorFromTo (getPosASLVisual _x); + private _losAngle = (_los#2 atan2 _los#0); + if (_losAngle < _bestAngle) then { + _trackingTarget = _x; + _bestAngle = _losAngle; + }; + }; + } forEach _potentialTargets; +}; + +if (accTime > 0 && !isGamePaused) then { + // If there are flares nearby, check if they will confuse missile + private _nearby = _trackingTarget nearObjects _flareDistanceFilter; + _nearby = _nearby select { + // 2 = IR blocking + (([getNumber (configOf _x >> "weaponLockSystem"), 4] call EFUNC(common,binarizeNumber)) select 1) && // Check if chaff can break radar lock + {[_projectile, getPosASLVisual _x, _seekerAngle] call FUNC(checkSeekerAngle)} && // Check if within view + {[_projectile, _x, false] call FUNC(checkLos)} // Check if can be seen + }; + + private _frontAspectMultiplier = 1; + if (_trackingTarget isKindOf "Air") then { + private _targetVelocity = velocity _trackingTarget; + + private _directionToTarget = (getPosASLVisual _projectile) vectorFromTo getPosASLVisual _trackingTarget; + private _angle = acos (_directionToTarget vectorCos _targetVelocity); + + _frontAspectMultiplier = (((_angle / 60) min 1) max 0.3); + }; + + private _relativeTargetVelocity = _projectile vectorWorldToModelVisual velocity _trackingTarget; + _relativeTargetVelocity set [1, 0]; + private _foundDecoy = false; + { + if (_trackingTarget isNotEqualTo _x) then { + private _considering = false; + + private _flareRelativeVelocity = _projectile vectorWorldToModelVisual velocity _x; + _flareRelativeVelocity set [1, 0]; + private _angleBetweenVelocities = acos (_relativeTargetVelocity vectorCos _flareRelativeVelocity); + // further away targets are filtered out by assumption that target cant move instantenously + private _chanceToDecoy = 1 - (_trackingTarget distance _x) / (_flareDistanceFilter * _frontAspectMultiplier); + if !(_foundDecoy) then { + if (_angleBetweenVelocities <= _flareAngleFilter) then { + _considering = true; + if (_seekerAccuracy <= random _chanceToDecoy) then { + _trackingTarget = _x; + _foundDecoy = true; + }; + }; + }; + + if (GVAR(debug_drawGuidanceInfo)) then { + private _flarePos = ASLToAGL getPosASLVisual _x; + private _colour = [1, 0, 0, 1]; + if (_considering) then { + _colour = [0, 1, 0, 1]; + }; + if (_trackingTarget isEqualTo _x) then { + _colour = [0, 0, 1, 1]; + }; + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", _colour, _flarePos, 0.75, 0.75, 0, format ["F %1 C %2", _angleBetweenVelocities, _chanceToDecoy], 1, 0.025, "TahomaB"]; + }; + }; + } forEach _nearby; + + _seekerStateParams set [2, _trackingTarget]; + +}; + +private _targetPosition = _trackingTarget modelToWorldVisualWorld getCenterOfMass _trackingTarget; + +if (GVAR(debug_drawGuidanceInfo) && { _targetPosition isNotEqualTo [0, 0, 0] }) then { + if (!isGamePaused && accTime > 0) then { + private _ps = "#particlesource" createVehicleLocal (ASLToAGL _targetPosition); + _PS setParticleParams [["\A3\Data_f\cl_basic", 8, 3, 1], "", "Billboard", 1, 3.0141, [0, 0, 0], [0, 0, 0], 1, 1.275, 1, 0, [1, 1], [[0, 0, 1, 1], [0, 0, 1, 1], [0, 0, 1, 1]], [1], 1, 0, "", "", nil]; + _PS setDropInterval 1.0; + }; +}; + +_targetData set [0, (getPosASL _projectile) vectorFromTo _targetPosition]; +_targetData set [2, 0]; +_targetData set [3, velocity _trackingTarget]; + +if (_targetPosition isEqualTo [0, 0, 0]) then { + _targetPosition = (velocity _projectile) vectorAdd getPosASLVisual _projectile +}; + +_targetPosition