diff --git a/AUTHORS.txt b/AUTHORS.txt index 906fc706a4..1932ff017b 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -76,4 +76,4 @@ ruPaladin BlackPixxel Asgar Serran Kavinsky -BlackPixxel + diff --git a/addons/javelin/RscInGameUI.hpp b/addons/javelin/RscInGameUI.hpp index 8c73f3d8d1..8b33c95c01 100644 --- a/addons/javelin/RscInGameUI.hpp +++ b/addons/javelin/RscInGameUI.hpp @@ -12,20 +12,10 @@ class RscLine; class RscInGameUI { class ACE_RscOptics_javelin { idd = 300; - controls[] = { "ACE_javelin_elements_group", "CA_Distance", "ACE_Targeting" }; //, "ACE_TargetingConstrains", "ACE_TargetingGate", "ACE_TargetingLines"}; + controls[] = { "ACE_javelin_elements_group", "ACE_Targeting" }; //, "ACE_TargetingConstrains", "ACE_TargetingGate", "ACE_TargetingLines"}; onLoad = QUOTE(_this call FUNC(onOpticLoad)); onUnload = "uiNameSpace setVariable ['ACE_RscOptics_javelin',nil];uiNameSpace setVariable ['ACE_RscOptics_javelin_PFH',nil];"; - class CA_Distance: RscOpticsValue { - idc = 151; - sizeEx = "0"; - colorText[] = {0,0,0,0}; - x = 0; - y = 0; - w = 0; - h = 0; - }; - class ACE_javelin_elements_group: RscControlsGroup { x = "SafezoneX"; @@ -45,6 +35,16 @@ class RscInGameUI { height = 0.001; }; class Controls { + class CA_Distance: RscOpticsValue { + idc = 151; + sizeEx = "0"; + colorText[] = {0,0,0,0}; + x = 0; + y = 0; + w = 0; + h = 0; + }; + class ACE_javelin_Day_mode_off: RscPicture { idc = 1001; x = "(SafezoneX+(SafezoneW -SafezoneH*3/4)/2)+ (0.03/4)*3*SafezoneH - SafezoneX"; @@ -58,7 +58,7 @@ class RscInGameUI { idc = 160; colorText[] = {0.2941,0.8745,0.2157,1}; }; - class ACE_javelin_WFOV_mode_off: ACE_javelin_Day_mode_off { + class CA_Javelin_WFOV_mode_off : ACE_javelin_Day_mode_off { idc = 1004; x = "(SafezoneX+(SafezoneW -SafezoneH*3/4)/2)+ (0.307/4)*3*SafezoneH - SafezoneX"; text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\wfov_co.paa"; @@ -81,13 +81,6 @@ class RscInGameUI { height = 0.001; }; class Controls { - class ACE_javelin_WFOV_mode: ACE_javelin_WFOV_mode_off { - idc = -1; - y = "0.031*SafezoneH - SafezoneY"; - x = "((SafezoneW -SafezoneH*3/4)/2)+ (0.307/4)*3*SafezoneH - SafezoneX"; - colorText[] = {0.2941,0.8745,0.2157,1}; - }; - /* class StadiaL: RscLine { x = "0.4899*SafezoneW - SafezoneX"; y = "0.171*SafezoneH - SafezoneY"; @@ -130,10 +123,10 @@ class RscInGameUI { h = 0; colorText[] = {0.2941,0.8745,0.2157,1}; }; - */ + }; }; - class ACE_javelin_NFOV_mode_off: ACE_javelin_Day_mode_off { + class CA_Javelin_NFOV_mode_off: ACE_javelin_Day_mode_off { idc = 1003; x = "(SafezoneX+(SafezoneW -SafezoneH*3/4)/2)+ (0.586/4)*3*SafezoneH - SafezoneX"; text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\nfov_co.paa"; @@ -156,13 +149,6 @@ class RscInGameUI { height = 0.001; }; class Controls { - class ACE_javelin_NFOV_mode: ACE_javelin_NFOV_mode_off { - idc = 699003; - x = "((SafezoneW -SafezoneH*3/4)/2)+ (0.586/4)*3*SafezoneH - SafezoneX"; - y = "0.031*SafezoneH - SafezoneY"; - colorText[] = {0.2941,0.8745,0.2157,1}; - }; - /* class StadiaL: RscLine { x = "0.4788*SafezoneW - SafezoneX"; y = "0.171*SafezoneH - SafezoneY"; @@ -205,7 +191,7 @@ class RscInGameUI { h = "0.1895*SafezoneH"; colorText[] = {0.2941,0.8745,0.2157,1}; }; - */ + }; }; diff --git a/addons/javelin/functions/fnc_cycleFireMode.sqf b/addons/javelin/functions/fnc_cycleFireMode.sqf index 4fed8e05cc..2245bb71e5 100644 --- a/addons/javelin/functions/fnc_cycleFireMode.sqf +++ b/addons/javelin/functions/fnc_cycleFireMode.sqf @@ -4,10 +4,10 @@ TRACE_1("enter", _this); private["_player", "_currentFireMode"]; -_currentFireMode = ACE_player getVariable["ace_missileguidance_attackProfile", "TOP"]; -if(_currentFireMode == "LIN") then { - _currentFireMode = "TOP"; +_currentFireMode = ACE_player getVariable["ace_missileguidance_attackProfile", "JAV_TOP"]; +if(_currentFireMode == "JAV_DIR") then { + _currentFireMode = "JAV_TOP"; } else { - _currentFireMode = "LIN"; + _currentFireMode = "JAV_DIR"; }; ACE_player setVariable["ace_missileguidance_attackProfile", _currentFireMode, false]; diff --git a/addons/javelin/functions/fnc_onOpticDraw.sqf b/addons/javelin/functions/fnc_onOpticDraw.sqf index 2412c2d5a1..e9d3e304ad 100644 --- a/addons/javelin/functions/fnc_onOpticDraw.sqf +++ b/addons/javelin/functions/fnc_onOpticDraw.sqf @@ -3,9 +3,8 @@ TRACE_1("enter", _this); #define __TRACKINTERVAL 0 // how frequent the check should be. -#define __LOCKONTIME 3.0 // Lock on won't occur sooner -#define __LOCKONTIMERANDOM 0.3 // Deviation in lock on time -#define __SENSORSQUARE 1 // Locking on sensor square side in angles +#define __LOCKONTIME 3 // Lock on won't occur sooner +#define __LOCKONTIMERANDOM 2 // Deviation in lock on time #define __OffsetX ((ctrlPosition __JavelinIGUITargetingLineV) select 0) - 0.5 #define __OffsetY ((ctrlPosition __JavelinIGUITargetingLineH) select 1) - 0.5 @@ -52,10 +51,16 @@ if ((velocity ACE_player) distance [0,0,0] > 0.5 && {cameraView == "GUNNER"} && // Refresh the firemode [] call FUNC(showFireMode); + +// bail on not loaded +if (ACE_player ammo (currentWeapon ACE_player) == 0) exitWith { }; + _range = parseNumber (ctrlText __JavelinIGUIRangefinder); +TRACE_1("Viewing range", _range); if (_range > 50 && {_range < 2500}) then { _pos = positionCameraToWorld [0,0,_range]; _targetArray = _pos nearEntities ["AllVehicles", _range/25]; + TRACE_1("Searching at range", _targetArray); if (count (_targetArray) > 0) then { _newTarget = _targetArray select 0; }; @@ -77,22 +82,45 @@ _offsetY = __OffsetY; __JavelinIGUITargeting ctrlShow true; __JavelinIGUITargetingConstrains ctrlShow true; +_zamerny = if (_currentTarget isKindOf "CAManBase") then {_currentTarget selectionPosition "body"} else {_currentTarget selectionPosition "zamerny"}; +_randomPosWithinBounds = [(_zamerny select 0) + 1 - (random 2.0),(_zamerny select 1) + 1 - (random 2.0),(_zamerny select 2) + 0.5 - (random 1.0)]; + +_apos = worldToScreen (_currentTarget modelToWorld _randomPosWithinBounds); + +_aposX = 0; +_aposY = 0; +if (count _apos < 2) then { + _aposX = 1; + _aposY = 0; +} else { + _aposX = (_apos select 0) + _offsetX; + _aposY = (_apos select 1) + _offsetY; +}; + +if((call CBA_fnc_getFoV) select 1 > 9) then { + __JavelinIGUINFOV ctrlSetTextColor __ColorGreen; + __JavelinIGUIWFOV ctrlSetTextColor __ColorGray; +} else { + __JavelinIGUINFOV ctrlSetTextColor __ColorGray; + __JavelinIGUIWFOV ctrlSetTextColor __ColorGreen; +}; + if (isNull _newTarget) then { // No targets found _currentTarget = objNull; _lockTime = 0; __JavelinIGUISeek ctrlSetTextColor __ColorGray; - __JavelinIGUINFOV ctrlSetTextColor __ColorGreen; __JavelinIGUITargeting ctrlShow false; __JavelinIGUITargetingGate ctrlShow false; __JavelinIGUITargetingLines ctrlShow false; __JavelinIGUITargetingConstraints ctrlShow false; - ACE_player setVariable ["ace_missileguidance_target",nil, false]; + ACE_player setVariable ["ace_missileguidance_target",nil, false]; // Disallow fire - //if (ACE_player ammo "Javelin" > 0 || {ACE_player ammo "ACE_Javelin_Direct" > 0}) then {ACE_player setWeaponReloadingTime //[player, "Javelin", 0.2];}; + if (ACE_player ammo (currentWeapon ACE_player) > 0) then { ACE_player setWeaponReloadingTime [player, (currentWeapon ACE_player), 0.2]; }; + } else { if (_newTarget distance ACE_player < 2500 && {(call CBA_fnc_getFoV) select 1 > 9} @@ -107,36 +135,20 @@ if (isNull _newTarget) then { playSound "ACE_Javelin_Locking"; } else { - if(diag_tickTime - _lockTime > __LOCKONTIME) then { + if(diag_tickTime - _lockTime > __LOCKONTIME + (random __LOCKONTIMERANDOM)) then { TRACE_2("LOCKED!", _currentTarget, _lockTime); __JavelinIGUISeek ctrlSetTextColor __ColorGreen; - __JavelinIGUINFOV ctrlSetTextColor __ColorNull; __JavelinIGUITargeting ctrlShow true; __JavelinIGUITargetingConstrains ctrlShow false; __JavelinIGUITargetingGate ctrlShow true; __JavelinIGUITargetingLines ctrlShow true; - - _zamerny = if (_currentTarget isKindOf "CAManBase") then {_currentTarget selectionPosition "body"} else {_currentTarget selectionPosition "zamerny"}; - _randomPosWithinBounds = [(_zamerny select 0) + 1 - (random 2.0),(_zamerny select 1) + 1 - (random 2.0),(_zamerny select 2) + 0.5 - (random 1.0)]; - _apos = worldToScreen (_currentTarget modelToWorld _randomPosWithinBounds); - - _aposX = 0; - _aposY = 0; - if (count _apos < 2) then { - _aposX = 1; - _aposY = 0; - } else { - _aposX = (_apos select 0) + _offsetX; - _aposY = (_apos select 1) + _offsetY; - }; - // Move target marker to coords. - __JavelinIGUITargetingLineV ctrlSetPosition [_aposX,ctrlPosition __JavelinIGUITargetingLineV select 1]; - __JavelinIGUITargetingLineH ctrlSetPosition [ctrlPosition __JavelinIGUITargetingLineH select 0,_aposY]; - {_x ctrlCommit __TRACKINTERVAL} forEach [__JavelinIGUITargetingLineH,__JavelinIGUITargetingLineV]; + //__JavelinIGUITargetingLineV ctrlSetPosition [_aposX,ctrlPosition __JavelinIGUITargetingLineV select 1]; + //__JavelinIGUITargetingLineH ctrlSetPosition [ctrlPosition __JavelinIGUITargetingLineH select 0,_aposY]; + //{_x ctrlCommit __TRACKINTERVAL} forEach [__JavelinIGUITargetingLineH,__JavelinIGUITargetingLineV]; _boundsInput = if (_currentTarget isKindOf "CAManBase") then { [_currentTarget,[-1,-1,-2],_currentTarget selectionPosition "body"]; @@ -162,6 +174,9 @@ if (isNull _newTarget) then { ACE_player setVariable["ace_missileguidance_target", _currentTarget, false]; + // Allow fire + ACE_player setWeaponReloadingTime [player, (currentWeapon ACE_player), 0]; + if(diag_tickTime > _soundTime) then { playSound "ACE_Javelin_Locked"; _soundTime = diag_tickTime + 0.25; @@ -169,6 +184,7 @@ if (isNull _newTarget) then { } else { __JavelinIGUITargeting ctrlShow true; __JavelinIGUITargetingGate ctrlShow true; + __JavelinIGUITargetingConstrains ctrlShow true; __JavelinIGUITargetingLines ctrlShow false; ACE_player setVariable["ace_missileguidance_target", nil, false]; @@ -186,6 +202,8 @@ if (isNull _newTarget) then { _maxX = ((_bpos select 2) + _offsetX) min (_constraintRight - 0.025*(3/4)*SafezoneH); _maxY = ((_bpos select 3) + _offsetY) min (_constraintBottom - 0.025*SafezoneH); + TRACE_4("", _boundsInput, _bpos, _minX, _minY); + __JavelinIGUITargetingGateTL ctrlSetPosition [_minX,_minY]; __JavelinIGUITargetingGateTR ctrlSetPosition [_maxX,_minY]; __JavelinIGUITargetingGateBL ctrlSetPosition [_minX,_maxY]; @@ -197,22 +215,26 @@ if (isNull _newTarget) then { playSound "ACE_Javelin_Locking"; _soundTime = diag_tickTime + 0.25; }; + // Disallow fire + if (ACE_player ammo (currentWeapon ACE_player) > 0) then { ACE_player setWeaponReloadingTime [player, (currentWeapon ACE_player), 0.2]; }; }; }; } else { - // Something is wrong with our seek + // No targets found _currentTarget = objNull; - ACE_player setVariable["ace_missileguidance_target", nil, false]; + _lockTime = 0; __JavelinIGUISeek ctrlSetTextColor __ColorGray; - __JavelinIGUINFOV ctrlSetTextColor __ColorGray; __JavelinIGUITargeting ctrlShow false; __JavelinIGUITargetingGate ctrlShow false; __JavelinIGUITargetingLines ctrlShow false; - + __JavelinIGUITargetingConstraints ctrlShow false; + ACE_player setVariable ["ace_missileguidance_target",nil, false]; - }; - + + // Disallow fire + if (ACE_player ammo (currentWeapon ACE_player) > 0) then { ACE_player setWeaponReloadingTime [player, (currentWeapon ACE_player), 0.2]; }; + }; }; //TRACE_2("", _newTarget, _currentTarget); diff --git a/addons/javelin/script_component.hpp b/addons/javelin/script_component.hpp index 6aa34b6bc8..7234a1e3d4 100644 --- a/addons/javelin/script_component.hpp +++ b/addons/javelin/script_component.hpp @@ -24,7 +24,9 @@ #define __JavelinIGUISeek (__JavelinIGUI displayCtrl 699000) #define __JavelinIGUITop (__JavelinIGUI displayCtrl 699001) #define __JavelinIGUIDir (__JavelinIGUI displayCtrl 699002) -#define __JavelinIGUINFOV (__JavelinIGUI displayCtrl 699003) +#define __JavelinIGUINFOV (__JavelinIGUI displayCtrl 1003) +#define __JavelinIGUIWFOV (__JavelinIGUI displayCtrl 1004) +#define __JavelinIGUIRangefinder (__JavelinIGUI displayCtrl 151) // Constrains #define __JavelinIGUITargetingConstrains (__JavelinIGUI displayCtrl 699100) diff --git a/addons/missileguidance/ACE_GuidanceConfig.hpp b/addons/missileguidance/ACE_GuidanceConfig.hpp index 4c0122c8e4..f3434fef9b 100644 --- a/addons/missileguidance/ACE_GuidanceConfig.hpp +++ b/addons/missileguidance/ACE_GuidanceConfig.hpp @@ -27,19 +27,19 @@ class GVAR(AttackProfiles) { functionName = QFUNC(attackProfile_HI); }; - class TOP { + class JAV_DIR { name = ""; visualName = ""; description = ""; - functionName = QFUNC(attackProfile_TOP); + functionName = QFUNC(attackProfile_JAV_DIR); }; - class PYM { + class JAV_TOP { name = ""; visualName = ""; description = ""; - functionName = QFUNC(attackProfile_PYM); + functionName = QFUNC(attackProfile_JAV_TOP); }; }; diff --git a/addons/missileguidance/CfgAmmo.hpp b/addons/missileguidance/CfgAmmo.hpp index 5aaee5ff2f..a05ecee9bc 100644 --- a/addons/missileguidance/CfgAmmo.hpp +++ b/addons/missileguidance/CfgAmmo.hpp @@ -40,12 +40,12 @@ class CfgAmmo { trackLead = 0; // Begin ACE guidance Configs - class ACE_MissileGuidance { + class ADDON { enabled = 1; - minDeflection = 0.005; // Minium flap deflection for guidance - maxDeflection = 0.025; // Maximum flap deflection for guidance - incDeflection = 0.005; // The incrmeent in which deflection adjusts. + minDeflection = 0.00025; // Minium flap deflection for guidance + maxDeflection = 0.001; // Maximum flap deflection for guidance + incDeflection = 0.0005; // The incrmeent in which deflection adjusts. //minDeflection = 0.005; //maxDeflection = 0.5; //incDeflection = 0.005; @@ -65,7 +65,7 @@ class CfgAmmo { // Attack profile type selection defaultAttackProfile = "LIN"; - attackProfiles[] = { "LIN", "DIR", "MID", "HI", "TOP", "PYM" }; + attackProfiles[] = { "LIN", "DIR", "MID", "HI" }; }; }; @@ -110,12 +110,12 @@ class CfgAmmo { //trackLead = 0; // Begin ACE guidance Configs - class ACE_MissileGuidance { + class ADDON { enabled = 1; - minDeflection = 0.005; // Minium flap deflection for guidance - maxDeflection = 0.25; // Maximum flap deflection for guidance - incDeflection = 0.005; // The incrmeent in which deflection adjusts. + minDeflection = 0.00005; // Minium flap deflection for guidance + maxDeflection = 0.025; // Maximum flap deflection for guidance + incDeflection = 0.00005; // The incrmeent in which deflection adjusts. //minDeflection = 0.005; //maxDeflection = 0.5; //incDeflection = 0.005; @@ -127,15 +127,15 @@ class CfgAmmo { defaultSeekerLockMode = "LOBL"; seekerLockModes[] = { "LOBL" }; - seekerAngle = 90; // Angle in front of the missile which can be searched + seekerAngle = 180; // Angle in front of the missile which can be searched seekerAccuracy = 1; // seeker accuracy multiplier - seekerMinRange = 1; + seekerMinRange = 0; seekerMaxRange = 2500; // Range from the missile which the seeker can visually search // Attack profile type selection - defaultAttackProfile = "LIN"; - attackProfiles[] = { "TOP", "LIN" }; + defaultAttackProfile = "JAV_TOP"; + attackProfiles[] = { "JAV_TOP", "JAV_DIR" }; }; }; }; \ No newline at end of file diff --git a/addons/missileguidance/XEH_pre_init.sqf b/addons/missileguidance/XEH_pre_init.sqf index 403d6245ca..8d277bc3b0 100644 --- a/addons/missileguidance/XEH_pre_init.sqf +++ b/addons/missileguidance/XEH_pre_init.sqf @@ -2,6 +2,7 @@ PREP(rotateVectLineGetMap); PREP(rotateVectLine); +PREP(changeMissileDirection); PREP(checkSeekerAngle); PREP(checkLos); @@ -17,10 +18,12 @@ PREP(attackProfile_LIN); PREP(attackProfile_DIR); PREP(attackProfile_MID); PREP(attackProfile_HI); -PREP(attackProfile_TOP); -PREP(attackprofile_PYM); PREP(attackProfile_AIR); +// Javelin profiles +PREP(attackProfile_JAV_DIR); +PREP(attackProfile_JAV_TOP); + // Seeker search functions PREP(seekerType_SALH); PREP(seekerType_Optic); \ No newline at end of file diff --git a/addons/missileguidance/functions/fnc_attackProfile_AIR.sqf b/addons/missileguidance/functions/fnc_attackProfile_AIR.sqf index d416b6a9e2..498b754287 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_AIR.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_AIR.sqf @@ -1,54 +1,4 @@ //#define DEBUG_MODE_FULL #include "script_component.hpp" -EXPLODE_7_PVT(((_this select 1) select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile); -private["_targetPos", "_projectilePos", "_target", "_seekerTargetPos", "_launchParams", "_targetLaunchParams"]; -private["_distanceToTarget", "_distanceToShooter", "_addHeight", "_returnTargetPos"]; -_seekerTargetPos = _this select 0; -_launchParams = _this select 1; - -_target = _launchParams select 0; -_targetLaunchParams = _launchParams select 1; - -_shooterPos = getPosASL _shooter; -_projectilePos = getPosASL _projectile; - -_distanceToTarget = _projectilePos vectorDistance _seekerTargetPos; -_distanceToShooter = _projectilePos vectorDistance _shooterPos; - -TRACE_2("", _distanceToTarget, _distanceToShooter); - -// Add height depending on distance for compensate -_addHeight = [0,0,0]; - -// Always climb an arc on initial launch if we are close to the round -if( ((ASLtoATL _projectilePos) select 2) < 5 && _distanceToShooter < 15) then { - _addHeight = _addHeight vectorAdd [0,0,_distanceToTarget]; -} else { - // If we are below the target, increase the climbing arc - if((_projectilePos select 2) < (_seekerTargetPos select 2) && _distanceToTarget > 100) then { - _addHeight = _addHeight vectorAdd [0,0, ((_seekerTargetPos select 2) - (_projectilePos select 2))]; - }; -}; - -// Handle arcing terminal low for high decent -if( (_projectilePos select 2) > (_seekerTargetPos select 2) && _distanceToTarget < 100) then { - _addHeight = _addHeight vectorDiff [0,0, ((_projectilePos select 2) - (_seekerTargetPos select 2))]; -} else { - if((_projectilePos select 2) > (_seekerTargetPos select 2) && _distanceToTarget > 100) then { - _addHeight = _addHeight vectorAdd [0,0, _distanceToTarget]; - }; -}; - - - -TRACE_3("", _distanceToTarget,_distanceToShooter,_addHeight); - - _returnTargetPos = _seekerTargetPos vectorAdd _addHeight; - -#ifdef DEBUG_MODE_FULL -drawLine3D [(ASLtoATL _returnTargetPos) vectorAdd _addHeight, ASLtoATL _returnTargetPos, [0,1,0,1]]; -#endif - -TRACE_1("Adjusted target position", _returnTargetPos); -_returnTargetPos; \ No newline at end of file +_this call FUNC(attackProfile_LIN); \ No newline at end of file diff --git a/addons/missileguidance/functions/fnc_attackProfile_JAV_DIR.sqf b/addons/missileguidance/functions/fnc_attackProfile_JAV_DIR.sqf new file mode 100644 index 0000000000..da01b7d900 --- /dev/null +++ b/addons/missileguidance/functions/fnc_attackProfile_JAV_DIR.sqf @@ -0,0 +1,69 @@ +//#define DEBUG_MODE_FULL +#include "script_component.hpp" + +#define STAGE_LAUNCH 1 +#define STAGE_CLIMB 2 +#define STAGE_COAST 3 +#define STAGE_TERMINAL 4 + +EXPLODE_7_PVT(((_this select 1) select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile); +private["_targetPos", "_projectilePos", "_target", "_seekerTargetPos", "_launchParams", "_targetLaunchParams"]; +private["_distanceToTarget", "_distanceToShooter", "_addHeight", "_returnTargetPos", "_state"]; +_seekerTargetPos = _this select 0; +_launchParams = _this select 1; + +_target = _launchParams select 0; +_targetLaunchParams = _launchParams select 1; + +_state = _this select 2; +if( (count _state) < 1) then { + _state set[0, STAGE_LAUNCH]; +}; + +_shooterPos = getPosASL _shooter; +_projectilePos = getPosASL _projectile; + +_distanceToTarget = _projectilePos vectorDistance _seekerTargetPos; +_distanceToShooter = _projectilePos vectorDistance _shooterPos; +_distanceShooterToTarget = _shooterPos vectorDistance _seekerTargetPos; + +TRACE_2("", _distanceToTarget, _distanceToShooter); + +// Add height depending on distance for compensate +_returnTargetPos = _seekerTargetPos; + +switch( (_state select 0) ) do { + case STAGE_LAUNCH: { + TRACE_1("STAGE_LAUNCH",""); + if(_distanceToShooter < 10) then { + _returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget*2]; + } else { + _state set[0, STAGE_CLIMB]; + }; + }; + case STAGE_CLIMB: { + TRACE_1("STAGE_CLIMB",""); + _cruisAlt = 60; + if(_distanceShooterToTarget < w) then { + _cruisAlt = 60 * (_distanceShooterToTarget/2000); + TRACE_1("_cruisAlt", _cruisAlt); + }; + + if( ((ASLToATL _projectilePos) select 2) - ((ASLToATL _seekerTargetPos) select 2) >= _cruisAlt) then { + _state set[0, STAGE_TERMINAL]; + } else { + _returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget*2]; + }; + }; + case STAGE_TERMINAL: { + TRACE_1("STAGE_TERMINAL",""); + //_returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget * 0.02]; + }; +}; + +#ifdef DEBUG_MODE_FULL +drawLine3D [(ASLtoATL _returnTargetPos), (ASLtoATL _seekerTargetPos), [0,1,0,1]]; +#endif + +TRACE_1("Adjusted target position", _returnTargetPos); +_returnTargetPos; \ No newline at end of file diff --git a/addons/missileguidance/functions/fnc_attackProfile_JAV_TOP.sqf b/addons/missileguidance/functions/fnc_attackProfile_JAV_TOP.sqf new file mode 100644 index 0000000000..4e83e046ff --- /dev/null +++ b/addons/missileguidance/functions/fnc_attackProfile_JAV_TOP.sqf @@ -0,0 +1,76 @@ +//#define DEBUG_MODE_FULL +#include "script_component.hpp" + +#define STAGE_LAUNCH 1 +#define STAGE_CLIMB 2 +#define STAGE_COAST 3 +#define STAGE_TERMINAL 4 + +EXPLODE_7_PVT(((_this select 1) select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile); +private["_targetPos", "_projectilePos", "_target", "_seekerTargetPos", "_launchParams", "_targetLaunchParams"]; +private["_distanceToTarget", "_distanceToShooter", "_addHeight", "_returnTargetPos", "_state"]; +_seekerTargetPos = _this select 0; +_launchParams = _this select 1; + +_target = _launchParams select 0; +_targetLaunchParams = _launchParams select 1; + +_state = _this select 2; +if( (count _state) < 1) then { + _state set[0, STAGE_LAUNCH]; +}; + +_shooterPos = getPosASL _shooter; +_projectilePos = getPosASL _projectile; + +_distanceToTarget = _projectilePos vectorDistance _seekerTargetPos; +_distanceToShooter = _projectilePos vectorDistance _shooterPos; +_distanceShooterToTarget = _shooterPos vectorDistance _seekerTargetPos; + +TRACE_2("", _distanceToTarget, _distanceToShooter); + +// Add height depending on distance for compensate +_returnTargetPos = _seekerTargetPos; + +switch( (_state select 0) ) do { + case STAGE_LAUNCH: { + TRACE_1("STAGE_LAUNCH",""); + if(_distanceToShooter < 10) then { + _returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget*2]; + } else { + _state set[0, STAGE_CLIMB]; + }; + }; + case STAGE_CLIMB: { + TRACE_1("STAGE_CLIMB",""); + _cruisAlt = 140; + if(_distanceShooterToTarget < 1250) then { + _cruisAlt = 140 * (_distanceShooterToTarget/1250); + TRACE_1("_cruisAlt", _cruisAlt); + }; + + if( ((ASLToATL _projectilePos) select 2) - ((ASLToATL _seekerTargetPos) select 2) >= _cruisAlt) then { + _state set[0, STAGE_COAST]; + } else { + _returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget*2]; + }; + }; + case STAGE_COAST: { + TRACE_1("STAGE_COAST",""); + if(_distanceShooterToTarget < 1250 || _distanceToTarget < ( ((ASLToATL _projectilePos) select 2) - (( ASLToATL _seekerTargetPos) select 2) )) then { + _state set[0, STAGE_TERMINAL]; + }; + _returnTargetPos = _seekerTargetPos vectorAdd [0,0,(_projectilePos select 2)]; + }; + case STAGE_TERMINAL: { + TRACE_1("STAGE_TERMINAL",""); + //_returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget * 0.02]; + }; +}; + +#ifdef DEBUG_MODE_FULL +drawLine3D [(ASLtoATL _returnTargetPos), (ASLtoATL _seekerTargetPos), [0,1,0,1]]; +#endif + +TRACE_1("Adjusted target position", _returnTargetPos); +_returnTargetPos; \ No newline at end of file diff --git a/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf b/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf index 90ec75ad7f..032ae51791 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf @@ -16,7 +16,7 @@ _projectilePos = getPosASL _projectile; _distanceToTarget = _projectilePos vectorDistance _seekerTargetPos; _distanceToShooter = _projectilePos vectorDistance _shooterPos; -TRACE_2("", _distanceToTarget, _distanceToShooter); +TRACE_3("", _distanceToTarget, _distanceToShooter, _seekerTargetPos); // Add height depending on distance for compensate _addHeight = [0,0,0]; @@ -40,11 +40,7 @@ if( (_projectilePos select 2) > (_seekerTargetPos select 2) && _distanceToTarget }; }; - - -TRACE_3("", _distanceToTarget,_distanceToShooter,_addHeight); - - _returnTargetPos = _seekerTargetPos vectorAdd _addHeight; +_returnTargetPos = _seekerTargetPos vectorAdd _addHeight; #ifdef DEBUG_MODE_FULL drawLine3D [(ASLtoATL _returnTargetPos) vectorAdd _addHeight, ASLtoATL _returnTargetPos, [0,1,0,1]]; diff --git a/addons/missileguidance/functions/fnc_attackProfile_PYM.sqf b/addons/missileguidance/functions/fnc_attackProfile_PYM.sqf deleted file mode 100644 index 498b754287..0000000000 --- a/addons/missileguidance/functions/fnc_attackProfile_PYM.sqf +++ /dev/null @@ -1,4 +0,0 @@ -//#define DEBUG_MODE_FULL -#include "script_component.hpp" - -_this call FUNC(attackProfile_LIN); \ No newline at end of file diff --git a/addons/missileguidance/functions/fnc_attackProfile_TOP.sqf b/addons/missileguidance/functions/fnc_attackProfile_TOP.sqf deleted file mode 100644 index 767f5df351..0000000000 --- a/addons/missileguidance/functions/fnc_attackProfile_TOP.sqf +++ /dev/null @@ -1,52 +0,0 @@ -//#define DEBUG_MODE_FULL -#include "script_component.hpp" - -EXPLODE_7_PVT(((_this select 1) select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile); -private["_targetPos", "_projectilePos", "_target", "_seekerTargetPos", "_launchParams", "_targetLaunchParams"]; -private["_distanceToTarget", "_distanceToShooter", "_addHeight", "_returnTargetPos"]; -_seekerTargetPos = _this select 0; -_launchParams = _this select 1; - -_target = _launchParams select 0; -_targetLaunchParams = _launchParams select 1; - -_shooterPos = getPosASL _shooter; -_projectilePos = getPosASL _projectile; - -_distanceToTarget = _projectilePos vectorDistance _seekerTargetPos; -_distanceToShooter = _projectilePos vectorDistance _shooterPos; - -TRACE_2("", _distanceToTarget, _distanceToShooter); - -// Add height depending on distance for compensate -_addHeight = [0,0,0]; - -// Always climb an arc on initial launch if we are close to the round -if( ((ASLtoATL _projectilePos) select 2) < 140 && _distanceToShooter < 50) then { - _addHeight = _addHeight vectorAdd [0,0,_distanceToTarget]; -} else { - // If we are below the target, increase the climbing arc - if((_projectilePos select 2) < (_seekerTargetPos select 2) + 140 && _distanceToTarget > 100) then { - _addHeight = _addHeight vectorAdd [0,0, ((_seekerTargetPos select 2) - (_projectilePos select 2))+50]; - }; -}; - -// Handle arcing terminal low for high decent -if( (_projectilePos select 2) > (_seekerTargetPos select 2) && _distanceToTarget < 140) then { - _addHeight = _addHeight vectorDiff [0,0, ((_projectilePos select 2) - (_seekerTargetPos select 2)) * 0.5]; -} else { - if((_projectilePos select 2) > (_seekerTargetPos select 2) && _distanceToTarget > 140) then { - _addHeight = _addHeight vectorAdd [0,0, ((_projectilePos select 2) - (_seekerTargetPos select 2)) * 0.02]; - }; -}; - -TRACE_3("", _distanceToTarget,_distanceToShooter,_addHeight); - - _returnTargetPos = _seekerTargetPos vectorAdd _addHeight; - -#ifdef DEBUG_MODE_FULL -drawLine3D [(ASLtoATL _returnTargetPos) vectorAdd _addHeight, ASLtoATL _returnTargetPos, [0,1,0,1]]; -#endif - -TRACE_1("Adjusted target position", _returnTargetPos); -_returnTargetPos; \ No newline at end of file diff --git a/addons/missileguidance/functions/fnc_changeMissileDirection.sqf b/addons/missileguidance/functions/fnc_changeMissileDirection.sqf new file mode 100644 index 0000000000..fda7ba9d07 --- /dev/null +++ b/addons/missileguidance/functions/fnc_changeMissileDirection.sqf @@ -0,0 +1,11 @@ +#include "script_component.hpp" +private ["_projectile", "_v", "_l", "_r"]; + +_projectile = _this select 0; +_v = _this select 1; + +_l = sqrt ((_v select 0) ^ 2 + (_v select 1) ^ 2); +_r = -(_v select 2) / _l; + +_projectile setVectorDirAndUp [ _v, [(_v select 0) * _r,(_v select 1) * _r, _l] ]; +_projectile setVelocity (_v vectorMultiply (vectorMagnitude (velocity _projectile))); \ No newline at end of file diff --git a/addons/missileguidance/functions/fnc_checkSeekerAngle.sqf b/addons/missileguidance/functions/fnc_checkSeekerAngle.sqf index 7308ce1723..d85cb01fcd 100644 --- a/addons/missileguidance/functions/fnc_checkSeekerAngle.sqf +++ b/addons/missileguidance/functions/fnc_checkSeekerAngle.sqf @@ -12,7 +12,7 @@ * Boolean */ - #define DEBUG_MODE_FULL +//#define DEBUG_MODE_FULL #include "script_component.hpp" private["_seeker", "_targetPos", "_seekerMaxAngle", "_vectorTo", "_sensorPos", "_vertOk", "_horzOk", "_dir", "_headingPitch"]; diff --git a/addons/missileguidance/functions/fnc_fired.sqf b/addons/missileguidance/functions/fnc_fired.sqf index bb162e1f09..8b90b2353f 100644 --- a/addons/missileguidance/functions/fnc_fired.sqf +++ b/addons/missileguidance/functions/fnc_fired.sqf @@ -13,7 +13,7 @@ PARAMS_7(_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile); // Bail on not missile if(! (_ammo isKindOf "MissileBase") ) exitWith { false }; -_config = configFile >> "CfgAmmo" >> _ammo >> "ACE_MissileGuidance"; +_config = configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON); _enabled = getNumber ( _config >> "enabled"); // Bail if guidance is not enabled @@ -68,7 +68,7 @@ TRACE_4("Beginning ACE guidance system",_target,_ammo,_seekerType,_attackProfile getNumber ( _config >> "seekerAccuracy" ), getNumber ( _config >> "seekerMaxRange" ) ], - [ diag_tickTime ] + [ diag_tickTime, [], [] ] ] ] call cba_fnc_addPerFrameHandler; diff --git a/addons/missileguidance/functions/fnc_guidancePFH.sqf b/addons/missileguidance/functions/fnc_guidancePFH.sqf index 7041201ded..f7fd56c164 100644 --- a/addons/missileguidance/functions/fnc_guidancePFH.sqf +++ b/addons/missileguidance/functions/fnc_guidancePFH.sqf @@ -3,14 +3,18 @@ #define TIMESTEP_FACTOR 0.01 -private["_args", "_stateParams", "_launchParams", "_targetLaunchParams", "_config", "_flightParams", "_seekerParams", "_seekerTargetPos"]; -private["_lastRunTime", "_runtimeDelta", "_profileAdjustedTargetPos", "_targetVectorSeeker", "_targetVector"]; -private["_minDeflection", "_maxDeflection", "_incDeflection"]; -private["_yVec", "_zVec", "_xVec"]; - +private["_launchParams", "_targetLaunchParams", "_flightParams", "_seekerParams", "_stateParams"]; +private["_lastRunTime", "_runtimeDelta", "_adjustTime", "_args", "_seekerTargetPos", "_projectilePos"]; +private["_profileAdjustedTargetPos", "_incDeflection", "_minDeflection", "_maxDeflection"]; +private["_targetVector", "_adjustVector", "_finalAdjustVector", "_changeVector", "_pitch", "_yaw", "_roll"]; + _args = _this select 0; EXPLODE_7_PVT((_args select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile); +if(!alive _projectile || isNull _projectile || isNull _shooter) exitWith { + [(_this select 1)] call cba_fnc_removePerFrameHandler; +}; + _launchParams = _args select 1; _targetLaunchParams = _launchParams select 1; _flightParams = _args select 2; @@ -20,76 +24,76 @@ _stateParams = _args select 4; _lastRunTime = _stateParams select 0; _runtimeDelta = diag_tickTime - _lastRunTime; +_adjustTime = 1; -_config = configFile >> "CfgAmmo" >> _ammo >> "ACE_MissileGuidance"; - -if(!alive _projectile || isNull _projectile || isNull _shooter) exitWith { - [(_this select 1)] call cba_fnc_removePerFrameHandler; +if(accTime > 0) then { + _adjustTime = 1/accTime; + _adjustTime = _adjustTime * (_runtimeDelta / TIMESTEP_FACTOR); + TRACE_4("Adjust timing", 1/accTime, _adjustTime, _runtimeDelta, (_runtimeDelta / TIMESTEP_FACTOR) ); +} else { + _adjustTime = 0; }; -// TODO: placeholder for "last seek target position" -_seekerTargetPos = [ [0,0,0], _args] call FUNC(doSeekerSearch); -if(!isNil "_seekerTargetPos") then { +_minDeflection = ((_flightParams select 0) - ((_flightParams select 0) * _adjustTime)) max 0; +_maxDeflection = (_flightParams select 1) * _adjustTime; +_incDeflection = _flightParams select 2; - _profileAdjustedTargetPos = [_seekerTargetPos,_args] call FUNC(doAttackProfile); +_projectilePos = getPosASL _projectile; - _minDeflection = _flightParams select 0; - _maxDeflection = _flightParams select 1; - _incDeflection = _flightParams select 2; - - _yVec = vectorDir _projectile; - _zVec = vectorUp _projectile; - _xVec = vectorNormalized (_yVec vectorCrossProduct _zVec); - - _projectilePos = getPosASL _projectile; - - _targetVectorSeeker = [_projectile, [_xVec, _yVec, _zVec], _profileAdjustedTargetPos] call EFUNC(common,translateToWeaponSpace); - _targetVector = [0,0,0] vectorFromTo _targetVectorSeeker; - TRACE_1("", _targetVectorSeeker, _targetVector); - - private["_yaw", "_pitch"]; - _yaw = 0; - _pitch = 0; - - if((_targetVectorSeeker select 0) < 0) then { - _yaw = - ( (_minDeflection max (abs(_targetVector select 0) min _maxDeflection) ) ); - } else { - if((_targetVectorSeeker select 0) > 0) then { - _yaw = ( (_minDeflection max ((_targetVector select 0) min _maxDeflection) ) ); - }; +// @TODO: placeholder for "last seek target position" +// Last target pos should be optional based on the seeker unit +_seekerTargetPos = [ [0,0,0], _args, (_stateParams select 1)] call FUNC(doSeekerSearch); +if(isNil "_seekerTargetPos") then { + _seekerTargetPos = _seekerTargetPos vectorAdd ((velocity _projectile) vectorMultiply 5); +} else { + if( (vectorMagnitude _seekerTargetPos) == 0) then { + _seekerTargetPos = _seekerTargetPos vectorAdd ((velocity _projectile) vectorMultiply 5); }; - if((_targetVectorSeeker select 2) < 0) then { - _pitch = - ( (_minDeflection max (abs(_targetVector select 2) min _maxDeflection) ) ); - } else { - if((_targetVectorSeeker select 2) > 0) then { - _pitch = ( (_minDeflection max ((_targetVector select 2) min _maxDeflection) ) ); - }; +}; + +_profileAdjustedTargetPos = [_seekerTargetPos,_args, (_stateParams select 2)] call FUNC(doAttackProfile); +_targetVector = _projectilePos vectorFromTo _profileAdjustedTargetPos; +_adjustVector = _targetVector vectorDiff (vectorDir _projectile); + +_yaw = 0; +_pitch = 0; +_roll = 0; +if((_adjustVector select 0) < 0) then { + _yaw = - ( (_minDeflection max (abs(_adjustVector select 0) min _maxDeflection) ) ); +} else { + if((_adjustVector select 0) > 0) then { + _yaw = ( (_minDeflection max ((_adjustVector select 0) min _maxDeflection) ) ); }; - +}; +if((_adjustVector select 1) < 0) then { + _roll = - ( (_minDeflection max (abs(_adjustVector select 1) min _maxDeflection) ) ); +} else { + if((_adjustVector select 1) > 0) then { + _roll = ( (_minDeflection max ((_adjustVector select 1) min _maxDeflection) ) ); + }; +}; +if((_adjustVector select 2) < 0) then { + _pitch = - ( (_minDeflection max (abs(_adjustVector select 2) min _maxDeflection) ) ); +} else { + if((_adjustVector select 2) > 0) then { + _pitch = ( (_minDeflection max ((_adjustVector select 2) min _maxDeflection) ) ); + }; +}; +_finalAdjustVector = [_yaw, _roll, _pitch]; +TRACE_2("", _pitch, _yaw); +TRACE_4("", _targetVector, _targetRelativeVector, _adjustVector, _finalAdjustVector); + +if(accTime > 0) then { + _changeVector = (vectorDir _projectile) vectorAdd _finalAdjustVector; + [_projectile, _changeVector] call FUNC(changeMissileDirection); +}; + #ifdef DEBUG_MODE_FULL - drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,1,1,1], ASLtoATL _projectilePos, 0.75, 0.75, 0, str _vectorTo, 1, 0.025, "TahomaB"]; - drawLine3D [ASLtoATL _projectilePos, ASLtoATL _profileAdjustedTargetPos, [1,0,0,1]]; -#endif +drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,1,1,1], ASLtoATL _projectilePos, 0.75, 0.75, 0, str _vectorTo, 1, 0.025, "TahomaB"]; +drawLine3D [ASLtoATL _projectilePos, ASLtoATL _profileAdjustedTargetPos, [1,0,0,1]]; - if(accTime > 0) then { - private["_adjustTime", "_outVector", "_vectorTo"]; - _adjustTime = 1/accTime; - _adjustTime = _adjustTime * (_runtimeDelta / TIMESTEP_FACTOR); - TRACE_4("Adjust timing", 1/accTime, _adjustTime, _runtimeDelta, (_runtimeDelta / TIMESTEP_FACTOR) ); - - // @TODO: Apply velocity multiplier to yaw/pitch. Basically, it can adjust faster at lower speeds - //_adjustDeflection = (vectorMagnitude velocity _projectile); - - _outVector = [_projectile, [_xVec, _yVec, _zVec], [_yaw, _adjustTime, _pitch]] call EFUNC(common,translateToModelSpace); - _vectorTo = _projectilePos vectorFromTo _outVector; - - _projectile setVectorDirAndUp [_vectorTo, vectorUp _projectile]; - }; - -#ifdef DEBUG_MODE_FULL - hintSilent format["d: %1", _distanceToTarget]; +hintSilent format["d: %1", _distanceToTarget]; #endif -}; _stateParams set[0, diag_tickTime]; diff --git a/addons/missileguidance/functions/fnc_seekerType_Optic.sqf b/addons/missileguidance/functions/fnc_seekerType_Optic.sqf index 9539c2c8f6..74d3b0fc71 100644 --- a/addons/missileguidance/functions/fnc_seekerType_Optic.sqf +++ b/addons/missileguidance/functions/fnc_seekerType_Optic.sqf @@ -19,7 +19,7 @@ if(!isNil "_target") then { _foundTargetPos = getPosASL _target; }; -/* @TODO: This is seeker LOS and angle checks for LOAL only; LOBL does not need visual +// @TODO: This is seeker LOS and angle checks for LOAL only; LOBL does not need visual _angleFov = _seekerParams select 0; _angleOkay = [_projectile, _foundTargetPos, _angleFov] call FUNC(checkSeekerAngle); @@ -34,7 +34,7 @@ if(!_angleOkay || !_losOkay) then { _foundTargetPos = _sensorPos vectorAdd ((velocity _projectile) vectorMultiply 5); } else { TRACE_2("", _target, _foundTargetPos); - + private["_projectileSpeed", "_distanceToTarget", "_eta", "_adjustVelocity"]; // @TODO: Configurable lead for seekers _projectileSpeed = (vectorMagnitude velocity _projectile); _distanceToTarget = (getPosASL _projectile) vectorDistance _foundTargetPos; @@ -45,5 +45,5 @@ if(!_angleOkay || !_losOkay) then { _foundTargetPos = _foundTargetPos vectorAdd _adjustVelocity; }; -*/ + _foundTargetPos; \ No newline at end of file