diff --git a/addons/missileguidance/ACE_GuidanceConfig.hpp b/addons/missileguidance/ACE_GuidanceConfig.hpp index 0475da204e..131beee339 100644 --- a/addons/missileguidance/ACE_GuidanceConfig.hpp +++ b/addons/missileguidance/ACE_GuidanceConfig.hpp @@ -88,14 +88,6 @@ class GVAR(SeekerTypes) { functionName = QFUNC(seekerType_MWR); onFired = QFUNC(mwr_onFired); }; - class DopplerRadar { - name = ""; - visualName = ""; - description = ""; - - functionName = QFUNC(seekerType_Doppler); - onFired = QFUNC(doppler_onFired); - }; }; class GVAR(NavigationTypes) { diff --git a/addons/missileguidance/XEH_PREP.hpp b/addons/missileguidance/XEH_PREP.hpp index 2d6b1874be..471886b156 100644 --- a/addons/missileguidance/XEH_PREP.hpp +++ b/addons/missileguidance/XEH_PREP.hpp @@ -51,7 +51,6 @@ PREP(wire_onFired); // Seeker OnFired PREP(SACLOS_onFired); -PREP(doppler_onFired); PREP(mwr_onFired); // Navigation OnFired diff --git a/addons/missileguidance/functions/fnc_doppler_onFired.sqf b/addons/missileguidance/functions/fnc_doppler_onFired.sqf deleted file mode 100644 index 1fce581b79..0000000000 --- a/addons/missileguidance/functions/fnc_doppler_onFired.sqf +++ /dev/null @@ -1,83 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: tcvm - * Sets up doppler radar state arrays (called from missileGuidance's onFired). - * - * Arguments: - * Guidance Arg Array - * - * Return Value: - * None - * - * Example: - * [] call ace_missileguidance_fnc_mwr_onFired - * - * Public: No - */ -params ["_firedEH", "_launchParams", "", "", "_stateParams"]; -_firedEH params ["_shooter","","","","","","_projectile"]; -_stateParams params ["", "_seekerStateParams"]; -_launchParams params ["","_targetLaunchParams"]; -_targetLaunchParams params ["_target"]; - -if (isNull _target && isVehicleRadarOn vehicle _shooter) then { - _target = cursorTarget; -}; -// always allow tracking of projectiles -if !(_target isKindOf "AllVehicles" || { (typeOf _target) isKindOf ["Default", configFile >> "CfgAmmo"] }) then { - _target = nil; -}; -_launchParams set [0, _target]; -_projectile setMissileTarget objNull; // to emulate a no launch warning - -private _projectileConfig = configOf _projectile; -private _config = _projectileConfig >> "ace_missileguidance"; - -private _isActive = false; -private _activeRadarDistance = [_config >> "activeRadarEngageDistance", "NUMBER", 500] call CBA_fnc_getConfigEntry; -private _projectileThrust = [_projectileConfig >> "thrust", "NUMBER", 0] call CBA_fnc_getConfigEntry; -private _projectileThrustTime = [_projectileConfig >> "thrustTime", "NUMBER", 0] call CBA_fnc_getConfigEntry; - -private _lockTypes = [_config >> "lockableTypes", "ARRAY", ["Air", "LandVehicle", "Ship"]] call CBA_fnc_getConfigEntry; - -private _minimumFilterSpeed = [_config >> "minimumSpeedFilter", "NUMBER", 30] call CBA_fnc_getConfigEntry; -private _minimumFilterTime = [_config >> "minimumTimeFilter", "NUMBER", 1e-4] call CBA_fnc_getConfigEntry; -private _maxTerrainCheck = [_config >> "maxTerrainCheck", "NUMBER", 16000] call CBA_fnc_getConfigEntry; - -private _velocityAtImpact = _projectileThrust * _projectileThrustTime; -private _timeToActive = 0; -if (!isNil "_target" && _velocityAtImpact > 0) then { - private _distanceUntilActive = (((getPosASL _shooter) vectorDistance (getPosASL _target)) - _activeRadarDistance); - _timeToActive = 0 max (_distanceUntilActive / _velocityAtImpact); -}; - -if (isNil "_target") then { - _timeToActive = 0; - _isActive = true; - _target = objNull; -}; - -private _shooterHasActiveRadar = { - if ("ActiveRadarSensorComponent" in _x) exitWith { true }; - false -} forEach listVehicleSensors vehicle _shooter; - -if !(isVehicleRadarOn vehicle _shooter) then { - _isActive = true; -}; - -_seekerStateParams set [0, _isActive]; -_seekerStateParams set [1, _activeRadarDistance]; -_seekerStateParams set [2, CBA_missionTime + _timeToActive]; -_seekerStateParams set [3, getPosASL _target]; -_seekerStateParams set [4, CBA_missionTime]; -_seekerStateParams set [5, _shooterHasActiveRadar]; -_seekerStateParams set [6, false]; -_seekerStateParams set [7, [0, 0, 0]]; -_seekerStateParams set [8, CBA_missionTime]; -_seekerStateParams set [9, isNull _target]; -_seekerStateParams set [10, _lockTypes]; -_seekerStateParams set [11, _minimumFilterSpeed]; -_seekerStateParams set [12, _minimumFilterTime]; -_seekerStateParams set [13, _maxTerrainCheck]; - diff --git a/addons/missileguidance/functions/fnc_seekerType_Doppler.sqf b/addons/missileguidance/functions/fnc_seekerType_Doppler.sqf deleted file mode 100644 index 7b5ec2e3da..0000000000 --- a/addons/missileguidance/functions/fnc_seekerType_Doppler.sqf +++ /dev/null @@ -1,163 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: tcvm - * doppler radar seeker - * - * Arguments: - * 1: Guidance Arg Array - * 2: Seeker State - * - * Return Value: - * Seeker Pos - * - * Example: - * [] call call ace_missileguidance_fnc_seekerType_MWR; - * - * Public: No - */ -params ["", "_args", "_seekerStateParams", "", "_timestep"]; -_args params ["_firedEH", "_launchParams", "", "_seekerParams", "_stateParams", "_targetData"]; -_firedEH params ["_shooter","","","","","","_projectile"]; -_launchParams params ["_target","","","",""]; -_seekerParams params ["_seekerAngle", "", "_seekerMaxRange"]; -_seekerStateParams params ["_isActive", "_activeRadarEngageDistance", "_timeWhenActive", "_expectedTargetPos", "_lastTargetPollTime", "_shooterHasRadar", "_wasActive", "_lastKnownVelocity", "_lastTimeSeen", "_doesntHaveTarget", "_lockTypes", "_minimumFilterSpeed", "_minimumFilterTime", "_maxTerrainCheck"]; - -if (_isActive || { CBA_missionTime >= _timeWhenActive }) then { - if !(_isActive) then { - _seekerStateParams set [0, true]; - }; - if !(_wasActive) then { - _seekerStateParams set [6, true]; - TRACE_1("Missile Pitbull",_seekerStateParams); - }; - - // if we are tracking a projectile, don't bother with radar crap just fly to it - if (!isNil "_target" || { !((typeOf _target) isKindOf ["Default", configFile >> "CfgAmmo"]) }) then { - // Internal radar homing - // For performance reasons only poll for target every so often instead of each frame - if ((_lastTargetPollTime + ACTIVE_RADAR_POLL_FREQUENCY) - CBA_missionTime < 0) then { - private _searchPos = _expectedTargetPos; - if (_searchPos isEqualTo [0, 0, 0] || { _doesntHaveTarget }) then { - _seekerStateParams set [9, true]; - // no target pos - shot without lock. Have the missile's radar search infront of it on the ground - _searchPos = (getPosASL _projectile) vectorAdd (_projectile vectorModelToWorld [0, _seekerMaxRange, -((getPos _projectile)#2)]); - }; - - _target = objNull; - _lastTargetPollTime = CBA_missionTime; - _seekerStateParams set [4, _lastTargetPollTime]; - private _distanceToExpectedTarget = _seekerMaxRange min ((getPosASL _projectile) vectorDistance _searchPos); - - // Simulate how much the seeker can see at the ground - private _projDir = vectorDir _projectile; - private _projYaw = getDir _projectile; - private _rotatedYaw = (+(_projDir select 0) * sin _projYaw) + (+(_projDir select 1) * cos _projYaw); - if (_rotatedYaw isEqualTo 0) then { _rotatedYaw = 0.001 }; - private _projPitch = atan ((_projDir select 2) / _rotatedYaw); - private _a1 = abs _projPitch; - private _a2 = 180 - ((_seekerAngle / 2) + _a1); - private _seekerBaseRadiusAtGround = ACTIVE_RADAR_MINIMUM_SCAN_AREA max (_distanceToExpectedTarget / sin(_a2) * sin(_seekerAngle / 2)); - - private _lastKnownSpeed = if (_lastKnownVelocity isEqualTo [0, 0, 0]) then { - 0 - } else { - vectorMagnitude _lastKnownVelocity; - }; - private _seekerBaseRadiusAdjusted = linearConversion [0, _seekerBaseRadiusAtGround, (CBA_missionTime - _lastTimeSeen) * vectorMagnitude _lastKnownVelocity, ACTIVE_RADAR_MINIMUM_SCAN_AREA, _seekerBaseRadiusAtGround, false]; - if (_doesntHaveTarget) then { - _seekerBaseRadiusAdjusted = _seekerBaseRadiusAtGround; - }; - // Look in front of seeker for any targets - private _nearestObjects = nearestObjects [ASLtoAGL _searchPos, _lockTypes, _seekerBaseRadiusAdjusted, false]; - _nearestObjects = _nearestObjects apply { - // I check both Line of Sight versions to make sure that a single bush doesnt make the target lock dissapear but at the same time ensure that this can see through smoke. Should work 80% of the time - if ([_projectile, getPosASL _x, _seekerAngle] call FUNC(checkSeekerAngle) && { ([_projectile, _x, true] call FUNC(checkLOS)) || { ([_projectile, _x, false] call FUNC(checkLOS)) } }) then { - - if !([_x, _projectile, _minimumFilterSpeed, _minimumFilterTime, _maxTerrainCheck, _seekerAngle] call FUNC(shouldFilterRadarHit)) exitWith { - _x - }; - objNull; - } else { - objNull - }; - }; - _nearestObjects = _nearestObjects select { !isNull _x }; - // Select closest object to the expected position to be the current radar target - if ((count _nearestObjects) <= 0) exitWith { - _projectile setMissileTarget objNull; - _seekerStateParams set [3, _searchPos]; - _searchPos - }; - private _closestDistance = _seekerBaseRadiusAtGround; - { - if ((_x distance2d _searchPos) < _closestDistance) then { - _closestDistance = _x distance2d _searchPos; - _target = _x; - }; - } forEach _nearestObjects; - - _expectedTargetPos = _searchPos; - }; - }; -} else { - if (GVAR(debug_drawGuidanceInfo)) then { - _seekerTypeName = "DOPPLER - EXT"; - }; - // External radar homing - // if the target is in the remote targets for the side, whoever the donor is will "datalink" the target for the hellfire. - private _remoteTargets = listRemoteTargets side _shooter; - if ((_remoteTargets findIf { (_target in _x) && (_x#1 > 0) }) < 0) then { - // I check both Line of Sight versions to make sure that a single bush doesnt make the target lock dissapear but at the same time ensure that this can see through smoke. Should work 80% of the time - if (!_shooterHasRadar || { !isVehicleRadarOn vehicle _shooter } || { !alive vehicle _shooter } || { !([vehicle _shooter, _target, true] call FUNC(checkLOS)) && { !([vehicle _shooter, _target, false] call FUNC(checkLOS)) } }) then { - _seekerStateParams set [0, true]; - _target = objNull; // set up state for active guidance - }; - }; -}; - -if (GVAR(debug_drawGuidanceInfo)) then { - drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,1], ASLtoAGL _expectedTargetPos, 0.75, 0.75, 0, "expected target pos", 1, 0.025, "TahomaB"]; -}; - -if !(isNull _target) then { - // we check if the target is moving away from us or perpendicular to see if we maintain lock - private _centerOfObject = getCenterOfMass _target; - private _targetAdjustedPos = _target modelToWorldVisualWorld _centerOfObject; - _expectedTargetPos = _targetAdjustedPos; - - private _filterTarget = [_target, _projectile, _minimumFilterSpeed, _minimumFilterTime, _maxTerrainCheck, _seekerAngle] call FUNC(shouldFilterRadarHit); - if (_filterTarget) then { - // filter out target - _target = objNull; - _seekerStateParams set [9, true]; - } else { - private _lineOfSight = vectorDirVisual _projectile; - private _realTargetVelocity = velocity _target; - private _projectedTargetVelocity = _lineOfSight vectorMultiply (_realTargetVelocity vectorDotProduct _lineOfSight); - private _relativeTargetVelocity = _realTargetVelocity vectorDiff _projectedTargetVelocity; - - _seekerStateParams set [7, _relativeTargetVelocity]; - _seekerStateParams set [8, CBA_missionTime]; - _seekerStateParams set [9, false]; - - _targetData set [2, _projectile distance _target]; - _targetData set [3, _relativeTargetVelocity]; - - if (_timestep != 0) then { - private _acceleration = (_relativeTargetVelocity vectorDiff _lastKnownVelocity) vectorMultiply (1 / _timestep); - _targetData set [4, _acceleration]; - }; - }; - _projectile setMissileTarget _target; -}; - -if (_expectedTargetPos isEqualTo [0, 0, 0]) then { - _expectedTargetPos = (getPosASLVisual _projectile) vectorAdd velocity _projectile; -}; - -_targetData set [0, (getPosASLVisual _projectile) vectorFromTo _expectedTargetPos]; - -_seekerStateParams set [3, _expectedTargetPos]; -_launchParams set [0, _target]; -_expectedTargetPos - diff --git a/addons/missileguidance/functions/fnc_shouldFilterRadarHit.sqf b/addons/missileguidance/functions/fnc_shouldFilterRadarHit.sqf deleted file mode 100644 index d2cd090f6c..0000000000 --- a/addons/missileguidance/functions/fnc_shouldFilterRadarHit.sqf +++ /dev/null @@ -1,133 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: tcvm - * Whether or not we should filter out this target due to masking. Useful for only doppler radar types - * - * Arguments: - * 0: Target - * 1: Projectile - * 2: Minimum speed for doppler return to filter out - * 3: Minimum time for doppler return to filter out - * 4: Maximum distance to check for terrain - * 5: Radar seeker angle - * - * Return Value: - * Whether or not to filter out this target - * - * Example: - * [] call call ace_missileguidance_fnc_shouldFilterRadarHit; - * - * Public: Yes - */ -// as defined by lineIntersectsSurfaces -#define MAX_LINE_DISTANCE 5000 - -params ["_target", "_projectile", "_minimumSpeed", "_minimumTime", "_maximumTerrainCheck", "_seekerAngle"]; -TRACE_5("should filter target",_projectile,_target,_minimumSpeed,_minimumTime,_maximumTerrainCheck); -// Theory developed from doppler radar visuals at https://www.mudspike.com/dcs-f-15c-combat-guide-for-beginners/ - -// helicopter blades will always produce a doppler shift due to their nature. Don't filter -if (_target isKindOf "Helicopter" && isEngineOn _target) exitWith { - TRACE_2("dont filter helicopters",_target isKindOf "Helicopter",isEngineOn _target); - false -}; - -private _lineOfSight = (getPosASLVisual _projectile) vectorFromTo (getPosASLVisual _target); -private _realTargetVelocity = velocity _target; -private _closingVelocity = _lineOfSight vectorMultiply (_realTargetVelocity vectorDotProduct _lineOfSight); -private _closingSpeed = vectorMagnitude _closingVelocity; - -// if relative target velocity is greather than threshold, we can easily see it. Don't filter -if (_closingSpeed > _minimumSpeed) exitWith { - TRACE_2("dont filter fast objects approaching",_closingSpeed,_minimumSpeed); - false -}; - -private _projectilePos = getPosASLVisual _projectile; - -private _stepDistance = _lineOfSight vectorMultiply (MAX_LINE_DISTANCE min _maximumTerrainCheck); - -private _checkPos = _projectilePos; -private _maskedByGround = false; - -// Check for all surfaces until we reach our max range -for "_i" from 0 to _maximumTerrainCheck step MAX_LINE_DISTANCE do { - // determine if target is masked by ground - private _endPos = _checkPos vectorAdd _stepDistance; - private _groundHit = lineIntersectsSurfaces [_checkPos, _endPos, _projectile, _target]; - - _maskedByGround = _groundHit isNotEqualTo []; - - _checkPos = _endPos; - - if (_maskedByGround || (_checkPos select 2) <= 0) then { - // for ease assume that we can't check underwater - if ((_checkPos select 2) < 0) then { - _checkPos set [2, 0]; - }; - break - }; -}; - -// looking at sky, target is clear as day. Check for chaff before filtering -if !(_maskedByGround) exitWith { - TRACE_1("dont filter stuff in the sky",_maskedByGround); - - // If there is chaff nearby, check if they will confuse missile - private _nearby = _target nearObjects 50; - _nearby = _nearby select { - // 8 = radar blocking - private _blocking = configOf _x >> "weaponLockSystem"; - private _isChaff = false; - if (isNumber _blocking) then { - _isChaff = (8 == getNumber _blocking); - }; - - if (isText _blocking) then { - _isChaff = ("8" in getText _blocking); - }; - - private _withinView = [_projectile, getPosASLVisual _x, _seekerAngle] call FUNC(checkSeekerAngle); - private _canSee = [_projectile, _x, false] call FUNC(checkLos); - - (_withinView && _canSee && _isChaff) - }; - - private _foundDecoy = false; - { - private _considering = false; - if !(_foundDecoy) then { - _considering = true; - if (0.95 <= random 1) then { - _foundDecoy = true; - }; - }; - - if (GVAR(debug_drawGuidanceInfo)) then { - private _chaffPos = ASLToAGL getPosASLVisual _x; - private _colour = [1, 0, 0, 1]; - if (_considering) then { - _colour = [0, 1, 0, 1]; - }; - if (_foundDecoy) then { - _colour = [0, 0, 1, 1]; - }; - drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", _colour, _chaffPos, 0.75, 0.75, 0, "C", 1, 0.025, "TahomaB"]; - }; - } forEach _nearby; - - _foundDecoy -}; - -private _distanceToTerrain = _checkPos vectorDistance _projectilePos; -private _checkTime = _distanceToTerrain / 3e8; - -// Time to ground is large enough to know if we are looking at a target, don't filter -if (_checkTime > _minimumTime) exitWith { - TRACE_2("dont filter targets that we can see in ground clutter",_checkTime,_minimumTime); - false -}; - -// filter out the target since we can't reasonably see it -true -