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