From 316fbfe7b92c782e0fcc618721472c2019042402 Mon Sep 17 00:00:00 2001 From: Brandon Danyluk Date: Mon, 16 Dec 2019 19:01:30 -0700 Subject: [PATCH] Implement Metis SACLOS guidance (#6997) * abc * Revert "abc" This reverts commit bcb4214bd99bba3fec692efa4dca950323da582d. * Update to current commit * Begin transfer of SACLOS into Missile Guidance * Allow seeker and attack profiles to have their own "OnFired" functions * Fix bugs with SACLOS * Implement Metis wire guidance. Add "Beam" guidance * add missing parenthesis * Update how Wire/Beam guidance works. Add compatability for SACLOS planes. Move all base missile changes out of missileguidance and into their own files. * try to cleanup merge * minor stuff --- addons/hot/ACE_GuidanceConfig.hpp | 21 ----- addons/hot/CfgAmmo.hpp | 2 +- addons/hot/CfgEventHandlers.hpp | 12 --- addons/hot/XEH_PREP.hpp | 5 -- addons/hot/XEH_preInit.sqf | 10 --- addons/hot/XEH_preStart.sqf | 4 - addons/hot/config.cpp | 2 - addons/hot/functions/script_component.hpp | 2 - addons/hot/script_component.hpp | 10 --- addons/maverick/CfgAmmo.hpp | 2 +- addons/metis/$PBOPREFIX$ | 1 + addons/metis/CfgAmmo.hpp | 81 +++++++++++++++++++ addons/metis/CfgMagazines.hpp | 10 +++ addons/metis/README.md | 12 +++ addons/metis/config.cpp | 19 +++++ addons/metis/script_component.hpp | 18 +++++ addons/missileguidance/ACE_GuidanceConfig.hpp | 24 ++++++ addons/missileguidance/XEH_PREP.hpp | 11 ++- .../functions/fnc_SACLOS_onFired.sqf | 6 +- .../functions/fnc_attackProfile_BEAM.sqf | 47 +++++++++++ .../functions/fnc_attackProfile_WIRE.sqf | 19 +++-- .../missileguidance/functions/fnc_onFired.sqf | 8 +- .../functions/fnc_seekerType_SACLOS.sqf | 26 ++++-- .../functions/fnc_wire_onFired.sqf | 6 +- addons/missileguidance/script_component.hpp | 11 +++ 25 files changed, 275 insertions(+), 94 deletions(-) delete mode 100644 addons/hot/ACE_GuidanceConfig.hpp delete mode 100644 addons/hot/CfgEventHandlers.hpp delete mode 100644 addons/hot/XEH_PREP.hpp delete mode 100644 addons/hot/XEH_preInit.sqf delete mode 100644 addons/hot/XEH_preStart.sqf delete mode 100644 addons/hot/functions/script_component.hpp create mode 100644 addons/metis/$PBOPREFIX$ create mode 100644 addons/metis/CfgAmmo.hpp create mode 100644 addons/metis/CfgMagazines.hpp create mode 100644 addons/metis/README.md create mode 100644 addons/metis/config.cpp create mode 100644 addons/metis/script_component.hpp rename addons/{hot => missileguidance}/functions/fnc_SACLOS_onFired.sqf (76%) create mode 100644 addons/missileguidance/functions/fnc_attackProfile_BEAM.sqf rename addons/{hot => missileguidance}/functions/fnc_attackProfile_WIRE.sqf (74%) rename addons/{hot => missileguidance}/functions/fnc_seekerType_SACLOS.sqf (54%) rename addons/{hot => missileguidance}/functions/fnc_wire_onFired.sqf (83%) diff --git a/addons/hot/ACE_GuidanceConfig.hpp b/addons/hot/ACE_GuidanceConfig.hpp deleted file mode 100644 index f129a6b558..0000000000 --- a/addons/hot/ACE_GuidanceConfig.hpp +++ /dev/null @@ -1,21 +0,0 @@ -class EGVAR(missileguidance,AttackProfiles) { - class WIRE { - name = CSTRING(missileType); - visualName = CSTRING(missileType); - description = CSTRING(missileType_Description); - - functionName = QFUNC(attackProfile_WIRE); - onFired = QFUNC(wire_onFired); - }; -}; -class EGVAR(missileguidance,SeekerTypes) { - class SACLOS { - name = "SACLOS"; - visualName = "SACLOS"; - description = CSTRING(SACLOS_Description); - - functionName = QFUNC(seekerType_SACLOS); - onFired = QFUNC(SACLOS_onFired); - }; -}; - diff --git a/addons/hot/CfgAmmo.hpp b/addons/hot/CfgAmmo.hpp index e591d13aff..4ee29bec6d 100644 --- a/addons/hot/CfgAmmo.hpp +++ b/addons/hot/CfgAmmo.hpp @@ -77,7 +77,7 @@ class CfgAmmo { seekerMinRange = 75; seekerMaxRange = 4000; // Range from the missile which the seeker can visually search - correctionDistance = 15; // distance from center of crosshair where missile slows down + 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 diff --git a/addons/hot/CfgEventHandlers.hpp b/addons/hot/CfgEventHandlers.hpp deleted file mode 100644 index 755e0552c5..0000000000 --- a/addons/hot/CfgEventHandlers.hpp +++ /dev/null @@ -1,12 +0,0 @@ -class Extended_PreStart_EventHandlers { - class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); - }; -}; - -class Extended_PreInit_EventHandlers { - class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); - }; -}; - diff --git a/addons/hot/XEH_PREP.hpp b/addons/hot/XEH_PREP.hpp deleted file mode 100644 index ec59d0f41f..0000000000 --- a/addons/hot/XEH_PREP.hpp +++ /dev/null @@ -1,5 +0,0 @@ -PREP(seekerType_SACLOS); -PREP(attackProfile_WIRE); -PREP(wire_onFired); -PREP(SACLOS_onFired); - diff --git a/addons/hot/XEH_preInit.sqf b/addons/hot/XEH_preInit.sqf deleted file mode 100644 index 29cc0a7f24..0000000000 --- a/addons/hot/XEH_preInit.sqf +++ /dev/null @@ -1,10 +0,0 @@ -#include "script_component.hpp" - -ADDON = false; - -PREP_RECOMPILE_START; -#include "XEH_PREP.hpp" -PREP_RECOMPILE_END; - -ADDON = true; - diff --git a/addons/hot/XEH_preStart.sqf b/addons/hot/XEH_preStart.sqf deleted file mode 100644 index 76b104a5bc..0000000000 --- a/addons/hot/XEH_preStart.sqf +++ /dev/null @@ -1,4 +0,0 @@ -#include "script_component.hpp" - -#include "XEH_PREP.hpp" - diff --git a/addons/hot/config.cpp b/addons/hot/config.cpp index 52f9f5ef6e..c61886cd26 100644 --- a/addons/hot/config.cpp +++ b/addons/hot/config.cpp @@ -14,8 +14,6 @@ class CfgPatches { }; }; -#include "ACE_GuidanceConfig.hpp" -#include "CfgEventHandlers.hpp" #include "CfgAmmo.hpp" #include "CfgMagazines.hpp" #include "CfgWeapons.hpp" diff --git a/addons/hot/functions/script_component.hpp b/addons/hot/functions/script_component.hpp deleted file mode 100644 index fbebb0b9a3..0000000000 --- a/addons/hot/functions/script_component.hpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "\z\ace\addons\hot\script_component.hpp" - diff --git a/addons/hot/script_component.hpp b/addons/hot/script_component.hpp index fd5475f15f..54cf5ccea1 100644 --- a/addons/hot/script_component.hpp +++ b/addons/hot/script_component.hpp @@ -16,13 +16,3 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define RANDOM_VECTOR_3D (call {\ - private _z = random 2 - 1;\ - private _r = sqrt (1 - _z^2);\ - private _theta = random 360;\ - [_r * cos _theta, _r * sin _theta, _z]\ -}) - -#define DEFAULT_CORRECTION_DISTANCE 10 -#define DEFAULT_LEAD_DISTANCE 50 - diff --git a/addons/maverick/CfgAmmo.hpp b/addons/maverick/CfgAmmo.hpp index 2b48618e82..a741501540 100644 --- a/addons/maverick/CfgAmmo.hpp +++ b/addons/maverick/CfgAmmo.hpp @@ -4,7 +4,7 @@ class CfgAmmo { class Components; }; class Missile_AGM_02_F : MissileBase {}; - + class GVAR(L) : Missile_AGM_02_F { author = "xrufix"; autoSeekTarget = 0; diff --git a/addons/metis/$PBOPREFIX$ b/addons/metis/$PBOPREFIX$ new file mode 100644 index 0000000000..d37f3f7328 --- /dev/null +++ b/addons/metis/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\metis \ No newline at end of file diff --git a/addons/metis/CfgAmmo.hpp b/addons/metis/CfgAmmo.hpp new file mode 100644 index 0000000000..1f613a36b1 --- /dev/null +++ b/addons/metis/CfgAmmo.hpp @@ -0,0 +1,81 @@ +class CfgAmmo { + class M_Vorona_HEAT; + class GVAR(HEAT): M_Vorona_HEAT { + manualControl = 0; + irLock = 0; + laserLock = 0; + airLock = 0; + lockType = 0; + + class ace_missileguidance { + enabled = 1; + + minDeflection = 0; // Minium flap deflection for guidance + maxDeflection = 0.0027; // Maximum flap deflection for guidance + incDeflection = 0.0005; // The incrmeent in which deflection adjusts. + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 15; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 80; + seekerMaxRange = 2000; // Range from the missile which the seeker can visually search + + correctionDistance = 3; // distance from center of crosshair where missile slows down + offsetFromCrosshair[] = { 0, 0, 0 }; // where the missile wants to stay in relation to the center of the crosshair. + + // Attack profile type selection + defaultAttackProfile = "WIRE"; + attackProfiles[] = {"WIRE"}; + }; + }; + + class M_Vorona_HE; + class GVAR(HE): M_Vorona_HE { + manualControl = 0; + irLock = 0; + laserLock = 0; + airLock = 0; + lockType = 0; + + class ace_missileguidance { + enabled = 1; + + minDeflection = 0; // Minium flap deflection for guidance + maxDeflection = 0.0027; // Maximum flap deflection for guidance + incDeflection = 0.0005; // The incrmeent in which deflection adjusts. + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 15; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 80; + seekerMaxRange = 2000; // Range from the missile which the seeker can visually search + + correctionDistance = 3; // distance from center of crosshair where missile slows down + offsetFromCrosshair[] = { 0, 0, 0 }; // where the missile wants to stay in relation to the center of the crosshair. + + // Attack profile type selection + defaultAttackProfile = "WIRE"; + attackProfiles[] = {"WIRE"}; + }; + }; +}; diff --git a/addons/metis/CfgMagazines.hpp b/addons/metis/CfgMagazines.hpp new file mode 100644 index 0000000000..e1c26d844f --- /dev/null +++ b/addons/metis/CfgMagazines.hpp @@ -0,0 +1,10 @@ +class CfgMagazines { + class CA_LauncherMagazine; + class Vorona_HEAT : CA_LauncherMagazine { + ammo = QGVAR(HEAT); + }; + class Vorona_HE : Vorona_HEAT { + ammo = QGVAR(HE); + }; +}; + diff --git a/addons/metis/README.md b/addons/metis/README.md new file mode 100644 index 0000000000..c494b9f8f9 --- /dev/null +++ b/addons/metis/README.md @@ -0,0 +1,12 @@ +ace_metis +=================== + +Converts vanilla "Vorona" Missile Guidance into ACE SACLOS Guidance + + +## Maintainers + +The people responsible for merging changes to this component or answering potential questions. + +- [Brandon-TCVM](https://github.com/TheCandianVendingMachine) + diff --git a/addons/metis/config.cpp b/addons/metis/config.cpp new file mode 100644 index 0000000000..65e4474dd9 --- /dev/null +++ b/addons/metis/config.cpp @@ -0,0 +1,19 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_missileguidance"}; + author = ECSTRING(common,ACETeam); + authors[] = {"Brandon (TCVM)"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgAmmo.hpp" +#include "CfgMagazines.hpp" + diff --git a/addons/metis/script_component.hpp b/addons/metis/script_component.hpp new file mode 100644 index 0000000000..d812eba2a2 --- /dev/null +++ b/addons/metis/script_component.hpp @@ -0,0 +1,18 @@ +#define COMPONENT metis +#define COMPONENT_BEAUTIFIED Metis +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_METIS + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_METIS + #define DEBUG_SETTINGS DEBUG_SETTINGS_METIS +#endif + +#include "\z\ace\addons\main\script_macros.hpp" + diff --git a/addons/missileguidance/ACE_GuidanceConfig.hpp b/addons/missileguidance/ACE_GuidanceConfig.hpp index f202e7d161..d3c9a8a999 100644 --- a/addons/missileguidance/ACE_GuidanceConfig.hpp +++ b/addons/missileguidance/ACE_GuidanceConfig.hpp @@ -41,6 +41,22 @@ class GVAR(AttackProfiles) { functionName = QFUNC(attackProfile_JAV_TOP); }; + class WIRE { + name = ""; + visualName = ""; + description = ""; + + functionName = QFUNC(attackProfile_WIRE); + onFired = QFUNC(wire_onFired); + }; + class BEAM { + name = ""; + visualName = ""; + description = ""; + + functionName = QFUNC(attackProfile_BEAM); + onFired = QFUNC(wire_onFired); // since Beam guidance is pretty much the same as Wire guidance, we can reuse this + }; }; class GVAR(SeekerTypes) { @@ -58,4 +74,12 @@ class GVAR(SeekerTypes) { functionName = QFUNC(seekerType_Optic); }; + class SACLOS { + name = ""; + visualName = ""; + description = ""; + + functionName = QFUNC(seekerType_SACLOS); + onFired = QFUNC(SACLOS_onFired); + }; }; diff --git a/addons/missileguidance/XEH_PREP.hpp b/addons/missileguidance/XEH_PREP.hpp index ee2b7328cb..2580831e84 100644 --- a/addons/missileguidance/XEH_PREP.hpp +++ b/addons/missileguidance/XEH_PREP.hpp @@ -10,7 +10,7 @@ PREP(onFired); PREP(onIncomingMissile); PREP(guidancePFH); -PREP(doAttackProfile); +PREP(doAttackProfile); PREP(doSeekerSearch); PREP(doHandoff); @@ -22,6 +22,8 @@ PREP(attackProfile_DIR); PREP(attackProfile_HI); PREP(attackProfile_LIN); PREP(attackProfile_MID); +PREP(attackProfile_WIRE); +PREP(attackProfile_BEAM); // Javelin profiles PREP(attackProfile_JAV_DIR); @@ -30,3 +32,10 @@ PREP(attackProfile_JAV_TOP); // Seeker search functions PREP(seekerType_SALH); PREP(seekerType_Optic); +PREP(seekerType_SACLOS); + +// Attack Profiles OnFired +PREP(wire_onFired); + +// Seeker OnFired +PREP(SACLOS_onFired); diff --git a/addons/hot/functions/fnc_SACLOS_onFired.sqf b/addons/missileguidance/functions/fnc_SACLOS_onFired.sqf similarity index 76% rename from addons/hot/functions/fnc_SACLOS_onFired.sqf rename to addons/missileguidance/functions/fnc_SACLOS_onFired.sqf index 7702b330ee..7ef06487e0 100644 --- a/addons/hot/functions/fnc_SACLOS_onFired.sqf +++ b/addons/missileguidance/functions/fnc_SACLOS_onFired.sqf @@ -10,7 +10,7 @@ * None * * Example: - * [] call ace_hot_fnc_SACLOS_onFired + * [] call ace_missileguidance_fnc_SACLOS_onFired * * Public: No */ @@ -19,9 +19,8 @@ _firedEH params ["_shooter","_weapon","","","","","_projectile"]; _stateParams params ["", "_seekerStateParams"]; private _config = ([_projectile] call CBA_fnc_getObjectConfig) >> "ace_missileguidance"; -private _distanceAheadOfMissile = [_config >> "missileLeadDistance", "NUMBER", DEFAULT_LEAD_DISTANCE] call CBA_fnc_getConfigEntry; -if (_shooter isKindOf "Plane") then { WARNING("SACLOS fired from planes unsupported"); }; +if (_shooter isKindOf "Plane" && { !hasPilotCamera _shooter }) exitWith { WARNING("SACLOS fired from planes without camera unsupported"); }; private _turretPath = [_shooter, _weapon] call CBA_fnc_turretPathWeapon; private _turretConfig = [_shooter, _turretPath] call CBA_fnc_getTurret; @@ -31,5 +30,4 @@ private _animationSourceGun = getText(_turretConfig >> "animationSourceGun"); _seekerStateParams set [0, _memoryPointGunnerOptics]; _seekerStateParams set [1, _animationSourceBody]; _seekerStateParams set [2, _animationSourceGun]; -_seekerStateParams set [3, _distanceAheadOfMissile]; diff --git a/addons/missileguidance/functions/fnc_attackProfile_BEAM.sqf b/addons/missileguidance/functions/fnc_attackProfile_BEAM.sqf new file mode 100644 index 0000000000..7e9408b2d7 --- /dev/null +++ b/addons/missileguidance/functions/fnc_attackProfile_BEAM.sqf @@ -0,0 +1,47 @@ +#include "script_component.hpp" +/* + * Author: Brandon (TCVM) + * Attack profile: Beam guided. Exact same as wire-guided, except no wire cutting + * + * Arguments: + * 0: Seeker Target PosASL + * 1: Guidance Arg Array + * 2: Attack Profile State + * + * Return Value: + * Missile Aim PosASL + * + * Example: + * [[1,2,3], [], []] call ace_missileguidance_fnc_attackProfile_BEAM; + * + * Public: No + */ +params ["_seekerTargetPos", "_args", "_attackProfileStateParams"]; +_args params ["_firedEH"]; +_firedEH params ["_shooter","","","","","","_projectile"]; +_attackProfileStateParams params["_maxCorrectableDistance", "_wireCut", "_randomVector", "_crosshairOffset", "_seekerMaxRangeSqr", "_seekerMinRangeSqr", "_wireCutSource", "_distanceAheadOfMissile"]; + +private _projectilePos = getPosASL _projectile; +private _shooterPos = getPosASL _shooter; + +private _shooterDir = vectorNormalized(_seekerTargetPos vectorDiff _shooterPos); +private _distanceToProjectile = _shooterPos vectorDistanceSqr _projectilePos; + +if (_distanceToProjectile > _seekerMaxRangeSqr || { _seekerTargetPos isEqualTo [0, 0, 0] } || { _distanceToProjectile < _seekerMinRangeSqr }) exitWith { + // return position 50m infront of projectile + _projectilePos vectorAdd (_projectile vectorModelToWorld [0, 50, 0]) +}; + +private _relativeCorrection = _projectile vectorWorldToModel (_projectilePos vectorDiff _seekerTargetPos); +_relativeCorrection = _relativeCorrection vectorDiff _crosshairOffset; + +private _magnitude = vectorMagnitude [_relativeCorrection select 0, 0, _relativeCorrection select 2]; +private _fovImpulse = 1 min (_magnitude / _maxCorrectableDistance); // the simulated impulse for the missile being close to the center of the crosshair + +// Adjust the impulse due to near-zero values creating wobbly missiles? +private _correction = _fovImpulse; + + +_relativeCorrection = (vectorNormalized _relativeCorrection) vectorMultiply _correction; +private _returnPos = _projectilePos vectorDiff (_projectile vectorModelToWorld _relativeCorrection); +_returnPos vectorAdd (_shooterDir vectorMultiply _distanceAheadOfMissile) diff --git a/addons/hot/functions/fnc_attackProfile_WIRE.sqf b/addons/missileguidance/functions/fnc_attackProfile_WIRE.sqf similarity index 74% rename from addons/hot/functions/fnc_attackProfile_WIRE.sqf rename to addons/missileguidance/functions/fnc_attackProfile_WIRE.sqf index 5d4158418f..6d88197819 100644 --- a/addons/hot/functions/fnc_attackProfile_WIRE.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_WIRE.sqf @@ -12,18 +12,22 @@ * Missile Aim PosASL * * Example: - * [[1,2,3], [], []] call ace_hot_fnc_attackProfile_WIRE; + * [[1,2,3], [], []] call ace_missileguidance_fnc_attackProfile_WIRE; * * Public: No */ params ["_seekerTargetPos", "_args", "_attackProfileStateParams"]; _args params ["_firedEH"]; _firedEH params ["_shooter","","","","","","_projectile"]; -_attackProfileStateParams params["_maxCorrectableDistance", "_wireCut", "_randomVector", "_crosshairOffset", "_seekerMaxRangeSqr", "", "_wireCutSource"]; +_attackProfileStateParams params["_maxCorrectableDistance", "_wireCut", "_randomVector", "_crosshairOffset", "_seekerMaxRangeSqr", "_seekerMinRangeSqr", "_wireCutSource", "_distanceAheadOfMissile"]; private _projectilePos = getPosASL _projectile; +private _shooterPos = getPosASL _shooter; -if ((((getPosASL _shooter) vectorDistanceSqr _projectilePos) > _seekerMaxRangeSqr) || { _wireCut }) exitWith { +private _shooterDir = vectorNormalized(_seekerTargetPos vectorDiff _shooterPos); +private _distanceToProjectile = _shooterPos vectorDistanceSqr _projectilePos; + +if ((_distanceToProjectile > _seekerMaxRangeSqr) || { _wireCut }) exitWith { // wire snap, random direction if (_randomVector isEqualTo [0, 0, 0]) then { _randomVector = RANDOM_VECTOR_3D vectorMultiply 300; @@ -35,7 +39,7 @@ if ((((getPosASL _shooter) vectorDistanceSqr _projectilePos) > _seekerMaxRangeSq _projectilePos vectorAdd _randomVector }; -if (_seekerTargetPos isEqualTo [0, 0, 0]) exitWith { +if (_seekerTargetPos isEqualTo [0, 0, 0] || { _distanceToProjectile < _seekerMinRangeSqr }) exitWith { // cut wire if its caught on terrain /*if !(lineIntersectsSurfaces [getPosASL _shooter, _projectilePos, _shooter] isEqualTo []) then { _attackProfileStateParams set [1, true]; @@ -48,13 +52,12 @@ private _relativeCorrection = _projectile vectorWorldToModel (_projectilePos vec _relativeCorrection = _relativeCorrection vectorDiff _crosshairOffset; private _magnitude = vectorMagnitude [_relativeCorrection select 0, 0, _relativeCorrection select 2]; - private _fovImpulse = 1 min (_magnitude / _maxCorrectableDistance); // the simulated impulse for the missile being close to the center of the crosshair // Adjust the impulse due to near-zero values creating wobbly missiles? private _correction = _fovImpulse; + _relativeCorrection = (vectorNormalized _relativeCorrection) vectorMultiply _correction; - -_projectilePos vectorDiff (_projectile vectorModelToWorld _relativeCorrection); - +private _returnPos = _projectilePos vectorDiff (_projectile vectorModelToWorld _relativeCorrection); +_returnPos vectorAdd (_shooterDir vectorMultiply _distanceAheadOfMissile) diff --git a/addons/missileguidance/functions/fnc_onFired.sqf b/addons/missileguidance/functions/fnc_onFired.sqf index b77911e979..422639c452 100644 --- a/addons/missileguidance/functions/fnc_onFired.sqf +++ b/addons/missileguidance/functions/fnc_onFired.sqf @@ -123,27 +123,27 @@ TRACE_1("",_onFiredFunc); if (_onFiredFunc != "") then { _args call (missionNamespace getVariable _onFiredFunc); }; - + _onFiredFunc = getText (configFile >> QGVAR(AttackProfiles) >> _attackProfile >> "onFired"); TRACE_1("",_onFiredFunc); if (_onFiredFunc != "") then { _args call (missionNamespace getVariable _onFiredFunc); }; - + // Run the "onFired" function passing the full guidance args array _onFiredFunc = getText (_config >> "onFired"); TRACE_1("",_onFiredFunc); if (_onFiredFunc != "") then { _args call (missionNamespace getVariable _onFiredFunc); }; - + // Reverse: // _args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams"]; // _firedEH params ["_shooter","","","","_ammo","","_projectile"]; // _launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo"]; // _targetLaunchParams params ["_target", "_targetPos", "_launchPos"]; // _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState"]; -// _seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange"]; +// _seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange", "_seekerMinRange"]; [FUNC(guidancePFH), 0, _args ] call CBA_fnc_addPerFrameHandler; diff --git a/addons/hot/functions/fnc_seekerType_SACLOS.sqf b/addons/missileguidance/functions/fnc_seekerType_SACLOS.sqf similarity index 54% rename from addons/hot/functions/fnc_seekerType_SACLOS.sqf rename to addons/missileguidance/functions/fnc_seekerType_SACLOS.sqf index 06245d0708..539ee997d6 100644 --- a/addons/hot/functions/fnc_seekerType_SACLOS.sqf +++ b/addons/missileguidance/functions/fnc_seekerType_SACLOS.sqf @@ -11,7 +11,7 @@ * Position of wanted missile pos relative to the camera direction * * Example: - * [] call ace_hot_fnc_seekerType_SACLOS + * [] call ace_missileguidance_fnc_seekerType_SACLOS * * Public: No */ @@ -20,16 +20,28 @@ _args params ["_firedEH", "", "", "_seekerParams", "_stateParams"]; _firedEH params ["_shooter","_weapon","","","","","_projectile"]; _seekerParams params ["_seekerAngle"]; _stateParams params ["", "_seekerStateParams"]; -_seekerStateParams params ["_memoryPointGunnerOptics", "_animationSourceBody", "_animationSourceGun", "_distanceAheadOfMissile"]; +_seekerStateParams params ["_memoryPointGunnerOptics", "_animationSourceBody", "_animationSourceGun"]; private _shooterPos = AGLToASL (_shooter modelToWorld(_shooter selectionPosition _memoryPointGunnerOptics)); private _projPos = getPosASL _projectile; private _lookDirection = if !(_shooter isKindOf "CAManBase" || {_shooter isKindOf "StaticWeapon"}) then { - private _gBody = -deg(_shooter animationPhase _animationSourceBody); - private _gGun = deg(_shooter animationPhase _animationSourceGun); - - _shooter vectorModelToWorld ([1, _gBody, _gGun] call CBA_fnc_polar2vect); + private _finalLookDirection = if (_shooter isKindOf "Plane") then { + _shooterPos = _shooter modelToWorldVisualWorld getPilotCameraPosition _shooter; + private _trackingTarget = getPilotCameraTarget _shooter; + _trackingTarget params ["_isTracking", "_trackingPos"]; + // Because ARMA doesnt update the camera rotation if you are locked on immediatly, we have to calculate the look direction manually or else the SACLOS target will be wrong, especially if shooter is moving + if (_isTracking) then { + vectorNormalized (_trackingPos vectorDiff _shooterPos); + } else { + _shooter vectorModelToWorldVisual getPilotCameraDirection _shooter; + }; + } else { + private _gBody = -deg(_shooter animationPhase _animationSourceBody); + private _gGun = deg(_shooter animationPhase _animationSourceGun); + _shooter vectorModelToWorldVisual ([1, _gBody, _gGun] call CBA_fnc_polar2vect); + }; + _finalLookDirection } else { _shooterPos = eyePos _shooter; _shooter weaponDirection _weapon @@ -46,5 +58,5 @@ if ((_testDotProduct < (cos _seekerAngle)) || { !(_testIntersections isEqualTo [ [0, 0, 0] }; -_shooterPos vectorAdd (_lookDirection vectorMultiply (_distanceToProj + _distanceAheadOfMissile)); +_shooterPos vectorAdd (_lookDirection vectorMultiply _distanceToProj); diff --git a/addons/hot/functions/fnc_wire_onFired.sqf b/addons/missileguidance/functions/fnc_wire_onFired.sqf similarity index 83% rename from addons/hot/functions/fnc_wire_onFired.sqf rename to addons/missileguidance/functions/fnc_wire_onFired.sqf index 3e1ff2d03d..295d6a2b5a 100644 --- a/addons/hot/functions/fnc_wire_onFired.sqf +++ b/addons/missileguidance/functions/fnc_wire_onFired.sqf @@ -10,7 +10,7 @@ * None * * Example: - * [] call ace_hot_fnc_wire_onFired + * [] call ace_missileguidance_fnc_wire_onFired * * Public: No */ @@ -21,11 +21,12 @@ _seekerParams params ["", "", "_seekerMaxRange", "_seekerMinRange"]; private _config = ([_projectile] call CBA_fnc_getObjectConfig) >> "ace_missileguidance"; private _maxCorrectableDistance = [_config >> "correctionDistance", "NUMBER", DEFAULT_CORRECTION_DISTANCE] call CBA_fnc_getConfigEntry; +private _distanceAheadOfMissile = [_config >> "missileLeadDistance", "NUMBER", DEFAULT_LEAD_DISTANCE] call CBA_fnc_getConfigEntry; private _maxDistanceSqr = _seekerMaxRange * _seekerMaxRange; private _minDistanceSqr = _seekerMinRange * _seekerMinRange; // AI don't know how to use the crosshair offset becauze they dum dum -_crosshairOffset = if ((_gunner != ACE_PLAYER) && {_gunner != (ACE_controlledUAV select 1)}) then { +private _crosshairOffset = if ((_gunner != ACE_PLAYER) && {_gunner != (ACE_controlledUAV select 1)}) then { [0, 0, 0]; } else { [_config >> "offsetFromCrosshair", "ARRAY", [0, 0, 0]] call CBA_fnc_getConfigEntry @@ -43,4 +44,5 @@ _attackProfileStateParams set [3, _crosshairOffset]; // crosshair offset _attackProfileStateParams set [4, _maxDistanceSqr]; // max distance squared used for wire cut _attackProfileStateParams set [5, _minDistanceSqr]; _attackProfileStateParams set [6, _wireCutSource]; +_attackProfileStateParams set [7, _distanceAheadOfMissile]; diff --git a/addons/missileguidance/script_component.hpp b/addons/missileguidance/script_component.hpp index 298de3a051..1fd8d81756 100644 --- a/addons/missileguidance/script_component.hpp +++ b/addons/missileguidance/script_component.hpp @@ -16,3 +16,14 @@ #endif #include "\z\ace\addons\main\script_macros.hpp" + +#define RANDOM_VECTOR_3D (call {\ + private _z = random 2 - 1;\ + private _r = sqrt (1 - _z^2);\ + private _theta = random 360;\ + [_r * cos _theta, _r * sin _theta, _z]\ +}) + +#define DEFAULT_CORRECTION_DISTANCE 2 +#define DEFAULT_LEAD_DISTANCE 5 +