IR seeker and AIM-9M

This commit is contained in:
Brandon Danyluk 2021-04-13 22:45:18 -06:00
parent 555f0c8921
commit e2c8ddfd3b
13 changed files with 298 additions and 4 deletions

1
addons/aim9/$PBOPREFIX$ Normal file
View File

@ -0,0 +1 @@
z\ace\addons\aim9

41
addons/aim9/CfgAmmo.hpp Normal file
View File

@ -0,0 +1,41 @@
class CfgAmmo {
class Missile_AA_04_F;
class GVAR(m): Missile_AA_04_F {
author = "Brandon (TCVM)";
maneuvrability = 0;
class ace_missileguidance {
enabled = 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 = "IR";
seekerTypes[] = { "IR" };
flareDistanceFilter = 15;
flareAngleFilter = 0.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 = 30; // Angle from the shooter's view that can track the missile
seekerAccuracy = 0.95; // 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"};
};
};
};

View File

@ -0,0 +1,26 @@
class CfgMagazines {
class 2Rnd_Missile_AA_04_F;
class PylonRack_1Rnd_Missile_AA_04_F;
class PylonMissile_1Rnd_Missile_AA_04_F;
class GVAR(2Rnd_Missile_9m): 2Rnd_Missile_AA_04_F {
author = "Brandon (TCVM)";
displayName = "2x AIM-9M [ACE]";
ammo = QGVAR(m);
};
class GVAR(PylonRack_1Rnd_Missile_9m): PylonRack_1Rnd_Missile_AA_04_F {
author = "Brandon (TCVM)";
displayName = "1x AIM-9M [ACE]";
ammo = QGVAR(m);
pylonWeapon = QGVAR(m);
};
class GVAR(PylonMissile_1Rnd_Missile_9m): PylonMissile_1Rnd_Missile_AA_04_F {
author = "Brandon (TCVM)";
displayName = "1x AIM-9M [ACE]";
ammo = QGVAR(m);
pylonWeapon = QGVAR(m);
};
};

View File

@ -0,0 +1,12 @@
class CfgWeapons {
class Missile_AA_04_Plane_CAS_01_F;
class GVAR(m): Missile_AA_04_Plane_CAS_01_F {
lockAcquire = 1; // auto lock
author = "Brandon (TCVM)";
displayName = "AIM-9M [ACE]";
weaponLockDelay = 0.5;
magazines[] = {QGVAR(2Rnd_Missile_9m), QGVAR(PylonRack_1Rnd_Missile_9m), QGVAR(PylonMissile_1Rnd_Missile_9m)};
};
};

12
addons/aim9/README.md Normal file
View File

@ -0,0 +1,12 @@
ace_aim9
===================
Adds AIM-9 and R-73 AHR missiles
## Maintainers
The people responsible for merging changes to this component or answering potential questions.
- [Brandon-TCVM](https://github.com/TheCandianVendingMachine)

20
addons/aim9/config.cpp Normal file
View File

@ -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[] = {"Brandon (TCVM)"};
url = ECSTRING(main,URL);
VERSION_CONFIG;
};
};
#include "CfgAmmo.hpp"
#include "CfgMagazines.hpp"
#include "CfgWeapons.hpp"

View File

@ -0,0 +1,18 @@
#define COMPONENT 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_AIM9
#define DEBUG_MODE_FULL
#endif
#ifdef DEBUG_SETTINGS_AIM9
#define DEBUG_SETTINGS DEBUG_SETTINGS_GBU
#endif
#include "\z\ace\addons\main\script_macros.hpp"

View File

@ -88,6 +88,14 @@ class GVAR(SeekerTypes) {
functionName = QFUNC(seekerType_ARH);
onFired = QFUNC(ahr_onFired);
};
class IR {
name = "";
visualName = "";
description = "";
functionName = QFUNC(seekerType_IR);
onFired = QFUNC(IR_onFired);
};
};
class GVAR(NavigationTypes) {

View File

@ -39,6 +39,7 @@ PREP(seekerType_SALH);
PREP(seekerType_Optic);
PREP(seekerType_SACLOS);
PREP(seekerType_ARH);
PREP(seekerType_IR);
// Attack Profiles OnFired
PREP(wire_onFired);
@ -46,6 +47,7 @@ PREP(wire_onFired);
// Seeker OnFired
PREP(SACLOS_onFired);
PREP(ahr_onFired);
PREP(IR_onFired);
// Navigation OnFired
PREP(proNav_onFired);

View File

@ -0,0 +1,27 @@
#include "script_component.hpp"
/*
* Author: Brandon (TCVM)
* Sets up IR state arrays (called from missileGuidance's onFired).
*
* Arguments:
* Guidance Arg Array <ARRAY>
*
* Return Value:
* None
*
* Example:
* [] call ace_missileguidance_fnc_IR_onFired
*
* Public: No
*/
params ["_firedEH", "", "", "", "_stateParams"];
_firedEH params ["_shooter","_weapon","","","","","_projectile"];
_stateParams params ["", "_seekerStateParams"];
private _flareDistanceFilter = getNumber (configOf _projectile >> "flareDistanceFilter");
private _flareAngleFilter = getNumber (configOf _projectile >> "flareAngleFilter");
_seekerStateParams set [0, _flareDistanceFilter];
_seekerStateParams set [1, _flareAngleFilter];
_seekerStateParams set [2, missileTarget _projectile];

View File

@ -119,7 +119,7 @@ if !(isNull _target) then {
_targetData set [2, _projectile distance _target];
_targetData set [3, velocity _target];
_targetData set [4, 0]; // todo: acceleration
_targetData set [4, [0, 0, 0]]; // todo: acceleration
};
_targetData set [0, (getPosASLVisual _projectile) vectorFromTo _expectedTargetPos];

View File

@ -0,0 +1,127 @@
#include "script_component.hpp"
/*
* Author: Brandon (TCVM)
* Infrared seeker. Checks if flares are popped
*
* Arguments:
* 1: Guidance Arg Array <ARRAY>
* 2: Seeker State <ARRAY>
*
* Return Value:
* Position of wanted missile pos relative to the camera direction <ARRAY>
*
* Example:
* [] call ace_missileguidance_fnc_seekerType_IR
*
* Public: No
*/
_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", "_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"];
_seekerStateParams params ["_flareDistanceFilter", "_flareAngleFilter", "_trackingTarget"];
_flareDistanceFilter = 15; //debug temp
_flareAngleFilter = 2.0; // debug temp
_seekerAccuracy = 0.95; // debug temp
private _projectileVelocity = velocity _projectile;
private _closingVelocity = _targetVelocity vectorDiff _projectileVelocity;
private _withinView = [_projectile, getPosASLVisual _trackingTarget, _seekerAngle] call FUNC(checkSeekerAngle);
private _canSee = [_projectile, _trackingTarget, false] call FUNC(checkLos);
if (!_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
private _blocking = configOf _x >> "weaponLockSystem";
private _isFlare = false;
if (isNumber _blocking) then {
_isFlare = (2 == getNumber _blocking);
};
if (isText _blocking) then {
_isFlare = ("2" in getText _blocking);
};
private _withinView = [_projectile, getPosASLVisual _x, _seekerAngle] call FUNC(checkSeekerAngle);
private _canSee = [_projectile, _x, false] call FUNC(checkLos);
(_x isEqualTo _target && _trackingTarget isNotEqualTo _target) || { (_withinView && _canSee && _isFlare) }
};
private _foundDecoy = false;
{
if (_trackingTarget isNotEqualTo _x) then {
private _considering = false;
private _distanceToFlare = _trackingTarget distanceSqr _x;
if (!_foundDecoy && _distanceToFlare <= _flareDistanceFilter * _flareDistanceFilter) then {
private _flareRelativeVelocity = (velocity _x) vectorDiff _projectileVelocity;
private _angleBetweenVelocities = acos (_closingVelocity vectorCos _flareRelativeVelocity);
if (_angleBetweenVelocities <= _flareAngleFilter) then {
systemChat str _angleBetweenVelocities;
_considering = true;
if (_seekerAccuracy <= random 1) then {
_trackingTarget = _x;
_foundDecoy = true;
};
};
};
#ifdef DRAW_GUIDANCE_INFO
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, "F", 1, 0.025, "TahomaB"];
#endif
};
} forEach _nearby;
_seekerStateParams set [2, _trackingTarget];
};
private _targetPosition = _trackingTarget modelToWorldVisualWorld getCenterOfMass _trackingTarget;
_targetData set [0, (getPosASL _projectile) vectorFromTo _targetPosition];
_targetData set [2, 0];
_targetData set [3, velocity _trackingTarget];
_targetPosition

View File

@ -14,7 +14,7 @@ Weapon Configs:
Vikhr - Beam Rider SACLOS
R-73 - Infrared
AIM-9 - Infrared
X AIM-9 - Infrared
AIM-132 - Infrared
R-77 - AHR
@ -31,7 +31,7 @@ Weapon Configs:
Seeker Types:
X Laser
Optical
Infrared
X Infrared
GPS/INS
Navigation Types:
@ -50,7 +50,7 @@ Navigation Types:
R-73 - APN
AGM-88 - APN
KH-58 - APN
AIM-9 - APN
X AIM-9 - APN
X Javelin - ZEM
X Hellfire - ZEM