Skip to content

Commit

Permalink
Merge branch 'master' into missile_aim120
Browse files Browse the repository at this point in the history
  • Loading branch information
PabstMirror committed Aug 23, 2024
2 parents 2537493 + 7279b94 commit 052cd2a
Show file tree
Hide file tree
Showing 32 changed files with 621 additions and 99 deletions.
11 changes: 8 additions & 3 deletions addons/dragon/CfgAmmo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,8 @@ class CfgAmmo {
EGVAR(vehicle_damage,incendiary) = 1.0;

class ace_missileguidance {
minDeflection = 0;
maxDeflection = 0;
incDeflection = 0;
pitchRate = 0;
yawRate = 0;

canVanillaLock = 0;

Expand All @@ -51,6 +50,9 @@ class CfgAmmo {
defaultSeekerLockMode = "LOAL";
seekerLockModes[] = { "LOAL", "LOBL" };

defaultNavigationType = "LineOfSight";
navigationTypes[] = { "LineOfSight" };

seekLastTargetPos = 0;
seekerAngle = 30;
seekerAccuracy = 1;
Expand Down Expand Up @@ -82,6 +84,9 @@ class CfgAmmo {
class ace_missileguidance {
enabled = 1;

pitchRate = 0;
yawRate = 0;

// Guidance type for munitions
defaultSeekerType = "SACLOS";
seekerTypes[] = { "SACLOS" };
Expand Down
25 changes: 20 additions & 5 deletions addons/hellfire/CfgAmmo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ class CfgAmmo {
class ace_missileguidance {
enabled = 1;

minDeflection = 0.0005; // Minium flap deflection for guidance
maxDeflection = 0.01; // Maximum flap deflection for guidance
incDeflection = 0.0005; // The incrmeent in which deflection adjusts.
pitchRate = 30; // degrees per second
yawRate = 30;

canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode

Expand All @@ -39,6 +38,9 @@ class CfgAmmo {
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
Expand All @@ -49,6 +51,19 @@ class CfgAmmo {
// 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 {
Expand All @@ -75,8 +90,8 @@ class CfgAmmo {
canVanillaLock = 1;
enabled = 1; // Missile Guidance must be explicitly enabled
seekLastTargetPos = 0;
defaultSeekerType = "ARH";
seekerTypes[] = { "ARH" };
defaultSeekerType = "MillimeterWaveRadar";
seekerTypes[] = { "MillimeterWaveRadar" };
defaultSeekerLockMode = "LOBL";
seekerLockModes[] = { "LOBL" };

Expand Down
1 change: 1 addition & 0 deletions addons/hellfire/XEH_PREP.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ LOG("prep");
PREP(attackProfile);
PREP(getAttackProfileSettings);
PREP(setupVehicle);
PREP(midCourseTransition);
81 changes: 50 additions & 31 deletions addons/hellfire/functions/fnc_attackProfile.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -18,80 +18,99 @@
*/

params ["_seekerTargetPos", "_args", "_attackProfileStateParams"];
_args params ["_firedEH", "_launchParams", "", "", "_stateParams"];
_args params ["_firedEH", "_launchParams", "_flightParams", "", "_stateParams"];
_stateParams params ["", "_seekerStateParams"];
_launchParams params ["","_targetLaunchParams","_seekerType"];

_targetLaunchParams params ["", "", "_launchPos"];
_targetLaunchParams params ["", "", "_launchPos", "_launchDir"];
_firedEH params ["","","","","","","_projectile"];

// Get state params:
if (_attackProfileStateParams isEqualTo []) then {
_this call FUNC(getAttackProfileSettings);
};
_attackProfileStateParams params ["_attackStage", "_configLaunchHeightClear"];

_attackProfileStateParams params ["_attackStage", "_configLaunchHeightClear", "_missileStateData"];

private _projectilePos = getPosASL _projectile;
private _distanceFromLaunch2d = _launchPos distance2d _projectilePos;
private _heightAboveLaunch = (_projectilePos select 2) - (_launchPos select 2);

// Add height depending on distance for compensate
private _returnTargetPos = nil;
private _returnTargetPos = _seekerTargetPos;
if (_returnTargetPos isEqualTo [0, 0, 0]) then {
private _initialDistanceToTarget = 8000;
_returnTargetPos = _launchPos vectorAdd (_launchDir vectorMultiply _initialDistanceToTarget);
};

private _closingRate = vectorMagnitude velocity _projectile;
// subtract 500 meters to account for the fact that we don't want to be at the perfect pitch exactly when we cross the target
// 500 seemed good in testing
private _timeToGo = ((_projectilePos distance2d _seekerTargetPos) - 500) / _closingRate;

// we could do stuff like desired attack angle, but I'm not going that far today
private _los = _projectilePos vectorFromTo _seekerTargetPos;

_flightParams params ["_pitchRate", "_yawRate"];

private _angleToTarget = acos ((vectorDir _projectile) vectorCos _los);
private _atMinRotationAngle = _angleToTarget >= (_pitchRate * _timeToGo);

switch (_attackStage) do {
case STAGE_LAUNCH: { // Gain height quickly to pass terrain mask
_returnTargetPos = _projectilePos getPos [100, getDir _projectile];
_returnTargetPos set [2, (_projectilePos select 2) + 36.4]; // 100 and 36.4 gives a 20 deg angle
_missileStateData params ["_heightBeforeStateSwitch", "_initialDistanceToTarget"];

_returnTargetPos set [2, _heightBeforeStateSwitch + (_initialDistanceToTarget * sin 20)]; // 100 and 36.4 gives a 20 deg angle

if (_heightAboveLaunch > _configLaunchHeightClear) then {
_attackProfileStateParams set [0, STAGE_SEEK_CRUISE];

_attackProfileStateParams set [2, [_projectilePos select 2, _seekerTargetPos distance2d _projectilePos]];
TRACE_2("New Stage: STAGE_SEEK_CRUISE",_distanceFromLaunch2d,_heightAboveLaunch);
};

if (_atMinRotationAngle) then {
_attackProfileStateParams set [0, STAGE_ATTACK_TERMINAL];

_attackProfileStateParams set [2, [_projectilePos select 2, _seekerTargetPos distance2d _projectilePos]];
TRACE_2("New Stage: STAGE_ATTACK_TERMINAL",_distanceToTarget2d,_currentHeightOverTarget);
};
};
case STAGE_SEEK_CRUISE: { // Slowly gain altitude while searching for target
_missileStateData params ["_heightBeforeStateSwitch", "_initialDistanceToTarget"];

// Before 4000 cruise at 5.7 degrees up, then level out
private _cruiseHeight = linearConversion [3000, 5000, _distanceFromLaunch2d, 10, 0, true];

_returnTargetPos = _projectilePos getPos [100, getDir _projectile];
_returnTargetPos set [2, (_projectilePos select 2) + _cruiseHeight];

_returnTargetPos set [2, _heightBeforeStateSwitch + (_initialDistanceToTarget * sin 5.7)];

if (_seekerTargetPos isNotEqualTo [0,0,0]) then {
_attackProfileStateParams set [0, STAGE_ATTACK_CRUISE];

_attackProfileStateParams set [2, [_projectilePos select 2, _seekerTargetPos distance2d _projectilePos]];
TRACE_1("New Stage: STAGE_ATTACK_CRUISE",_distanceFromLaunch2d);
};
};
case STAGE_ATTACK_CRUISE: {
_missileStateData params ["_heightBeforeStateSwitch", "_initialDistanceToTarget"];

private _currentHeightOverTarget = (_projectilePos select 2) - (_seekerTargetPos select 2);
private _distanceToTarget2d = _seekerTargetPos distance2d _projectilePos;
private _distToGoRatio = _distanceToTarget2d / (_launchPos distance2d _seekerTargetPos);

// arcing up at 7 degrees to start until 50% left, then smooth curve to a downward attack
private _gainSlope = linearConversion [0.5, 0.1, _distToGoRatio, 7, -7, true];
_returnTargetPos = +_seekerTargetPos;
_returnTargetPos set [2, ((_projectilePos select 2) + (_distanceToTarget2d * sin _gainSlope)) max (_seekerTargetPos select 2)];
_returnTargetPos set [2, _heightBeforeStateSwitch + (_initialDistanceToTarget * sin 7)];

if ((_distanceToTarget2d < 500) || {(_currentHeightOverTarget atan2 _distanceToTarget2d) > 15}) then { // Wait until we can come down at a sharp angle
// if we are at the rotation limit, rotate to target
if (_atMinRotationAngle || {(_currentHeightOverTarget atan2 _distanceToTarget2d) > 15}) then { // Wait until we can come down at a sharp angle
_attackProfileStateParams set [0, STAGE_ATTACK_TERMINAL];

_attackProfileStateParams set [2, [_projectilePos select 2, _seekerTargetPos distance2d _projectilePos]];
TRACE_2("New Stage: STAGE_ATTACK_TERMINAL",_distanceToTarget2d,_currentHeightOverTarget);
};
};
case STAGE_ATTACK_TERMINAL: {
private _distanceToTarget2d = _seekerTargetPos distance2d _projectilePos;
_returnTargetPos = _seekerTargetPos vectorAdd [0, 0, _distanceToTarget2d * 0.02];
};
};

// Special radar case. Adjust target position such that we are leading it
if (_attackStage >= 3 && { _seekerType isEqualTo "ARH" }) then {
_seekerStateParams params ["", "", "", "", "", "", "", "_lastKnownVelocity"];
private _projectileVelocity = velocity _projectile;
if (_projectileVelocity#2 < 0) then {
private _projectileSpeed = vectorMagnitude _projectileVelocity; // this gives a precise impact time versus using speed _projectile. Dont change
private _timeUntilImpact = (_seekerTargetPos distance _projectilePos) / _projectileSpeed;
_returnTargetPos = _returnTargetPos vectorAdd (_lastKnownVelocity vectorMultiply _timeUntilImpact);
};
};
// missile guidance defines this variable in doAttackProfile
//IGNORE_PRIVATE_WARNING ["_attackProfileName"];
_attackProfileName = ["na", "hellfire - LAUNCH", "hellfire - SEEK CRUISE", "hellfire - ATTACK CRUISE", "hellfire - TERMINAL"] select _attackStage;

// TRACE_1("Adjusted target position",_returnTargetPos);
TRACE_1("Adjusted target position",_returnTargetPos);
_returnTargetPos;
6 changes: 6 additions & 0 deletions addons/hellfire/functions/fnc_getAttackProfileSettings.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ private _attackConfig = configFile >> QEGVAR(missileguidance,AttackProfiles) >>
// Launch (clearing terrain mask for LO/HI):
private _configLaunchHeightClear = getNumber (_attackConfig >> QGVAR(launchHeightClear));

private _projectilePos = getPosASL _projectile;

// Get starting stage
private _startingStage = if (_configLaunchHeightClear > 0) then {
STAGE_LAUNCH; // LOAL-HI / LO
Expand All @@ -40,5 +42,9 @@ private _startingStage = if (_configLaunchHeightClear > 0) then {
// Set data in param array
_attackProfileStateParams set [0, _startingStage];
_attackProfileStateParams set [1, _configLaunchHeightClear];
_attackProfileStateParams set [2, [
_projectilePos select 2,
_seekerTargetPos distance2d _projectilePos
]];

TRACE_1("new shot settings",_attackProfileStateParams);
29 changes: 29 additions & 0 deletions addons/hellfire/functions/fnc_midCourseTransition.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include "..\script_component.hpp"
/*
* Author: tcvm
* Condition to switch to next navigation profile
*
* Arguments:
* Guidance Arg Array <ARRAY>
*
* Return Value:
* None
*
* Example:
* [] call ace_hellfire_fnc_midCourseTransition
*
* Public: No
*/

_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"];

_attackProfileStateParams params ["_state"];
_state isEqualTo STAGE_ATTACK_TERMINAL;

16 changes: 12 additions & 4 deletions addons/hot/CfgAmmo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,27 +58,35 @@ class CfgAmmo {
class ace_missileguidance {
enabled = 1;

minDeflection = 0; // Minium flap deflection for guidance
maxDeflection = 0.0030; // Maximum flap deflection for guidance
incDeflection = 0.0005; // The incrmeent in which deflection adjusts.
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

correctionDistance = 8; // distance from center of crosshair where missile slows down
offsetFromCrosshair[] = { 0, 0, 0.5 }; // where the missile wants to stay in relation to the center of the crosshair.

// Attack profile type selection
Expand Down
11 changes: 11 additions & 0 deletions addons/hot/CfgVehicles.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,22 @@ class CfgVehicles {
class Turrets;
};
class LT_01_base_F: Tank_F {
class AnimationSources;
class Turrets: Turrets {
class MainTurret;
};
};
class LT_01_AT_base_F: LT_01_base_F {
class AnimationSources: AnimationSources {
class Missiles_revolving {
source = "revolving";
weapon = QGVAR(generic_launcher);
};
class Missiles_reloadMagazine {
source = "reloadMagazine";
weapon = QGVAR(generic_launcher);
};
};
class Turrets: Turrets {
class MainTurret: MainTurret {
weapons[] = {"SmokeLauncher","HMG_127",QGVAR(generic_launcher)};
Expand Down
2 changes: 1 addition & 1 deletion addons/maverick/ACE_GuidanceConfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ class EGVAR(missileguidance,AttackProfiles) {
class maverick {
name = "LOAL-DIR";
nameLocked = "LOBL-DIR";
functionName = QEFUNC(missileguidance,attackProfile_DIR);
functionName = QEFUNC(missileguidance,attackProfile_LIN);
};
};
Loading

0 comments on commit 052cd2a

Please sign in to comment.