From 8da028b626a321e767b14083e90b3fe05c1de124 Mon Sep 17 00:00:00 2001 From: Brandon Danyluk Date: Sun, 12 Dec 2021 01:26:40 -0700 Subject: [PATCH] Handle pre-tracking --- addons/spike/CfgAmmo.hpp | 2 +- addons/spike/CfgMagazines.hpp | 4 +- addons/spike/CfgWeapons.hpp | 4 +- addons/spike/RscInGameUI.hpp | 118 ++++++++++++++++++ addons/spike/RscTitles.hpp | 9 -- addons/spike/XEH_PREP.hpp | 3 +- addons/spike/config.cpp | 11 ++ .../functions/fnc_camera_handleKeyPress.sqf | 2 - addons/spike/functions/fnc_camera_init.sqf | 4 +- .../spike/functions/fnc_getTargetPosition.sqf | 92 ++++++++++++++ addons/spike/functions/fnc_keyDown.sqf | 13 ++ addons/spike/functions/fnc_mapHelperDraw.sqf | 94 ++++++++++++++ addons/spike/functions/fnc_onFired.sqf | 5 +- addons/spike/functions/fnc_seeker.sqf | 77 ++---------- addons/spike/script_component.hpp | 2 +- 15 files changed, 349 insertions(+), 91 deletions(-) create mode 100644 addons/spike/RscInGameUI.hpp create mode 100644 addons/spike/functions/fnc_getTargetPosition.sqf create mode 100644 addons/spike/functions/fnc_mapHelperDraw.sqf diff --git a/addons/spike/CfgAmmo.hpp b/addons/spike/CfgAmmo.hpp index a5f3c50c30..a18d8d44d5 100644 --- a/addons/spike/CfgAmmo.hpp +++ b/addons/spike/CfgAmmo.hpp @@ -1,7 +1,7 @@ class CfgAmmo { class MissileBase; class M_Titan_AT: MissileBase {}; - class GVAR(at): M_Titan_AT { + class GVAR(lr): M_Titan_AT { timeToLive = 120; manualControl = 0; diff --git a/addons/spike/CfgMagazines.hpp b/addons/spike/CfgMagazines.hpp index 2ca84cea5d..19a75d8b89 100644 --- a/addons/spike/CfgMagazines.hpp +++ b/addons/spike/CfgMagazines.hpp @@ -1,8 +1,8 @@ class CfgMagazines { class Titan_AT; - class GVAR(at): Titan_AT { + class GVAR(lr): Titan_AT { author = "Brandon (TCVM)"; - ammo = QGVAR(at); + ammo = QGVAR(lr); displayName = "Spike AT"; displayNameShort = "foo"; diff --git a/addons/spike/CfgWeapons.hpp b/addons/spike/CfgWeapons.hpp index 1b684df4d3..bbfc51b3e9 100644 --- a/addons/spike/CfgWeapons.hpp +++ b/addons/spike/CfgWeapons.hpp @@ -10,7 +10,7 @@ class CfgWeapons { class GVAR(launcher): GVAR(base) { scope = 2; GVAR(enabled) = 1; - //weaponInfoType = "ACE_RscOptics_javelin"; + weaponInfoType = "ACE_RscOptics_spike"; //modelOptics = QPATHTOF(data\reticle_titan.p3d); canLock = 0; @@ -21,7 +21,7 @@ class CfgWeapons { displayName = "Spike AT"; displayNameShort = "Spike AT"; - magazines[] = {QGVAR(at)}; + magazines[] = {QGVAR(lr)}; }; }; diff --git a/addons/spike/RscInGameUI.hpp b/addons/spike/RscInGameUI.hpp new file mode 100644 index 0000000000..a6f93fb799 --- /dev/null +++ b/addons/spike/RscInGameUI.hpp @@ -0,0 +1,118 @@ + +// Taken from AGM for optics management. + +class RscInGameUI { + class ACE_RscOptics_spike { + idd = 141000; + controls[] = { reticle, GVAR(mapHelper) }; + onLoad = QUOTE(with uiNamespace do {ACE_RscOptics_spike = _this select 0;};); + + class GVAR(mapHelper): RscMapControl { + onDraw = QUOTE(_this call FUNC(mapHelperDraw);); + x = 0; + y = 0; + w = 0; + h = 0; + }; + + class reticle: RscControlsGroupNoScrollbars { + idc = 242000; + x = "safeZoneX"; + y = "safeZoneY"; + w = "safeZoneW-safeZoneX"; + h = "safeZoneH-safeZoneY"; + enabled = 1; + show = 0; + class controls { + class lineV: RscControlsGroupNoScrollbars { + idc = 243100; + enabled = 1; + show = 1; + class Controls { + class lineBlack: RscText { + x = "safeZoneX + (SafeZoneW * 0.501)"; + y = "safeZoneY + (SafeZoneH * 0.53)"; + w = "safeZoneW * 0.0025"; + h = "safeZoneH * 0.1"; + colorBackground[] = COLOR_BLACK; + }; + class lineWhite: RscText { + x = "safeZoneX + (SafeZoneW * 0.504)"; + y = "safeZoneY + (SafeZoneH * 0.53)"; + w = "safeZoneW * 0.0025"; + h = "safeZoneH * 0.1"; + colorBackground[] = COLOR_WHITE; + }; + class squareB: RscText { + idc = 243101; + x = "safeZoneX + safeZoneW * 0.499"; + y = "safeZoneY + safeZoneH * 0.52"; + w = "safeZoneH * 0.006"; + h = "safeZoneW * 0.006"; + colorBackground[] = COLOR_BLACK; + }; + }; + }; + class lineHL: RscControlsGroupNoScrollbars { + idc = 243200; + enabled = 1; + show = 1; + class Controls { + class lineBlack: RscText { + x = "safeZoneY + (SafeZoneH * 0.37)"; + y = "safeZoneX + (SafeZoneW * 0.5)"; + w = "safeZoneH * 0.1"; + h = "safeZoneW * 0.003"; + colorBackground[] = COLOR_BLACK; + }; + class lineWhite: RscText { + x = "safeZoneY + (SafeZoneH * 0.37)"; + y = "safeZoneX + (SafeZoneW * 0.504)"; + w = "safeZoneH * 0.1"; + h = "safeZoneW * 0.0023"; + colorBackground[] = COLOR_WHITE; + }; + class squareL: RscText { + idc = 243201; + x = "safeZoneX + (SafeZoneW * 0.485)"; + y = "safeZoneY + safeZoneH * 0.5"; + w = "safeZoneH * 0.006"; + h = "safeZoneW * 0.006"; + colorBackground[] = COLOR_BLACK; + }; + }; + }; + class lineHR: RscControlsGroupNoScrollbars { + idc = 243300; + enabled = 1; + show = 1; + class Controls { + class lineBlack: RscText { + x = "safeZoneY + (SafeZoneH * 0.53)"; + y = "safeZoneX + (SafeZoneW * 0.5)"; + w = "safeZoneH * 0.1"; + h = "safeZoneW * 0.003"; + colorBackground[] = COLOR_BLACK; + }; + class lineWhite: RscText { + x = "safeZoneY + (SafeZoneH * 0.53)"; + y = "safeZoneX + (SafeZoneW * 0.504)"; + w = "safeZoneH * 0.1"; + h = "safeZoneW * 0.0023"; + colorBackground[] = COLOR_WHITE; + }; + class squareR: RscText { + idc = 243301; + x = "safeZoneX + (SafeZoneW * 0.515)"; + y = "safeZoneY + safeZoneH * 0.5"; + w = "safeZoneH * 0.006"; + h = "safeZoneW * 0.006"; + colorBackground[] = COLOR_BLACK; + }; + }; + }; + }; + }; + }; +}; + diff --git a/addons/spike/RscTitles.hpp b/addons/spike/RscTitles.hpp index 27d4818390..5dd23f0b59 100644 --- a/addons/spike/RscTitles.hpp +++ b/addons/spike/RscTitles.hpp @@ -1,12 +1,3 @@ -class RscOpticsValue; -class RscControlsGroupNoScrollbars; -class RscPicture; -class RscLine; -class RscMapControl; -class RscText; - -#define COLOR_WHITE {0.8745,0.8745,0.8745,1} -#define COLOR_BLACK {0,0,0,1} class RscTitles { class ACE_guidance_spike { diff --git a/addons/spike/XEH_PREP.hpp b/addons/spike/XEH_PREP.hpp index 0db716b40a..686f1a8207 100644 --- a/addons/spike/XEH_PREP.hpp +++ b/addons/spike/XEH_PREP.hpp @@ -3,7 +3,6 @@ PREP(camera_cycleViewMode); PREP(camera_destroy); PREP(camera_handleKeyPress); PREP(camera_init); -PREP(camera_preTrack); PREP(camera_setViewMode); PREP(camera_setZoom); PREP(camera_switchAway); @@ -16,4 +15,6 @@ PREP(onFired); PREP(seeker); PREP(navigation); PREP(midCourseTransition); +PREP(mapHelperDraw); +PREP(getTargetPosition); diff --git a/addons/spike/config.cpp b/addons/spike/config.cpp index b018a30e40..6cf3d389e0 100644 --- a/addons/spike/config.cpp +++ b/addons/spike/config.cpp @@ -14,8 +14,19 @@ class CfgPatches { }; }; +class RscOpticsValue; +class RscControlsGroupNoScrollbars; +class RscPicture; +class RscLine; +class RscMapControl; +class RscText; + +#define COLOR_WHITE {0.8745,0.8745,0.8745,1} +#define COLOR_BLACK {0,0,0,1} + #include "ACE_GuidanceConfig.hpp" #include "RscTitles.hpp" +#include "RscInGameUI.hpp" #include "CfgEventhandlers.hpp" #include "CfgAmmo.hpp" #include "CfgMagazines.hpp" diff --git a/addons/spike/functions/fnc_camera_handleKeyPress.sqf b/addons/spike/functions/fnc_camera_handleKeyPress.sqf index 3969aa0caa..fa577da651 100644 --- a/addons/spike/functions/fnc_camera_handleKeyPress.sqf +++ b/addons/spike/functions/fnc_camera_handleKeyPress.sqf @@ -19,8 +19,6 @@ params ["_key", "_down"]; if !([objNull] call FUNC(camera_userInCamera)) exitWith {}; -playSound "ACE_Sound_Click"; - private _return = false; private _lookInput = GVAR(activeCamera) getVariable [QGVAR(lookInput), [0, 0, 0, 0]]; private _designateInput = GVAR(activeCamera) getVariable [QGVAR(designateInput), [0]]; diff --git a/addons/spike/functions/fnc_camera_init.sqf b/addons/spike/functions/fnc_camera_init.sqf index 6c1e323484..0d767c2937 100644 --- a/addons/spike/functions/fnc_camera_init.sqf +++ b/addons/spike/functions/fnc_camera_init.sqf @@ -15,7 +15,7 @@ * * Public: No */ -params ["_projectile", "_cameraArray", "_shooter"]; +params ["_projectile", "_cameraArray", "_shooter", "_switchOnFireInit"]; _cameraArray params ["_enabled", "_fovLevels", "_initialFOV", "_thermalTypes", "_initialThermalType", "_switchOnFire", "_lerpFOV", "_fovChangeTime", "", "_gimbalData", "_reticleData", "_designating"]; _gimbalData params ["_hasGimbal", "_maxGimbalX", "_maxGimbalY", "_gimbalSpeedX", "_gimbalSpeedY", "_initGimbalAngleX", "_initGimbalAngleY", "_gimbalZoomSpeedModifiers"]; @@ -78,7 +78,7 @@ _activeCameraNamespace setVariable [QGVAR(logic), _logic]; _activeCameraNamespace setVariable [QGVAR(missile), _projectile]; _activeCameraNamespace setVariable [QGVAR(logicPos), _projectile vectorModelToWorldVisual _logicPosition]; -if (_switchOnFire) then { +if (_switchOnFire && _switchOnFireInit) then { [_activeCameraNamespace] call FUNC(camera_switchTo); }; diff --git a/addons/spike/functions/fnc_getTargetPosition.sqf b/addons/spike/functions/fnc_getTargetPosition.sqf new file mode 100644 index 0000000000..4c052f2a55 --- /dev/null +++ b/addons/spike/functions/fnc_getTargetPosition.sqf @@ -0,0 +1,92 @@ +#include "script_component.hpp" +/* + * Author: Brandon (TCVM) + * Return the position of a potential EO target via a "edge detection" algorithm. Compares object bounding boxes to see what we are most likely hitting + * + * Arguments: + * 1: Origin + * 2: Direction + * 3: If we are designating + * + * Return Value: + * Missile Aim PosASL + * + * Example: + * [[], [], []] call ace_spike_fnc_getTargetPosition; + * + * Public: No + */ +params ["_origin", "_direction", "_designateInput", "_seekerTargetPos", ["_ignoreObject", objNull]]; + +private _nearObjects = []; + +private _intersections = lineIntersectsSurfaces [_origin, _origin vectorAdd (_direction vectorMultiply 5000), _ignoreObject, objNull, true, 1, "FIRE", "VIEW", true]; +if (_intersections isNotEqualTo []) then { + (_intersections#0) params ["_intersectPos", "", "_object"]; + + if (_designateInput == 1) then { + _seekerTargetPos = _intersectPos; + }; + + _nearObjects = (ASLtoAGL _seekerTargetPos) nearObjects ["AllVehicles", 5]; + + if (_designateInput == 1 && { !isNull _object }) then { + _nearObjects pushBack _object; + }; +}; + +if (_nearObjects isNotEqualTo []) then { + // I want to prefer the designated position on the object moreso than the bounds of the object + private _averagePosition = _seekerTargetPos vectorMultiply 15; + private _averagePositionCounter = 15; + + private _closestObject = objNull; + private _closestDistance = 1e10; + + { + if ((getPosASLVisual _x) vectorDistanceSqr _seekerTargetPos < _closestDistance) then { + _closestDistance = (getPosASLVisual _x) vectorDistanceSqr _seekerTargetPos; + _closestObject = _x; + }; + } forEach _nearObjects; + + private _boundingBox = 0 boundingBoxReal _closestObject; + + // Project target bounding box onto screen and do a real bad edge detection check + _boundingBox params ["_min", "_max"]; + _min params ["_x0", "_y0", "_z0"]; + _max params ["_x1", "_y1", "_z1"]; + + private _utl = _closestObject modelToWorldVisualWorld [_x0, _y0, _z0]; + private _utr = _closestObject modelToWorldVisualWorld [_x1, _y0, _z0]; + private _ubr = _closestObject modelToWorldVisualWorld [_x1, _y1, _z0]; + private _ubl = _closestObject modelToWorldVisualWorld [_x0, _y1, _z0]; + + private _dtl = _closestObject modelToWorldVisualWorld [_x0, _y0, _z1]; + private _dtr = _closestObject modelToWorldVisualWorld [_x1, _y0, _z1]; + private _dbr = _closestObject modelToWorldVisualWorld [_x1, _y1, _z1]; + private _dbl = _closestObject modelToWorldVisualWorld [_x0, _y1, _z1]; + + { + private _intersections = lineIntersectsSurfaces [_origin, _x, _ignoreObject, objNull, false, 16]; + if (_intersections isEqualTo []) then { + _averagePosition = _averagePosition vectorAdd _x; + _averagePositionCounter = _averagePositionCounter + 1; + } else { + { + _x params ["_surfacePosition"]; + _averagePosition = _averagePosition vectorAdd _surfacePosition; + _averagePositionCounter = _averagePositionCounter + 1; + } forEach _intersections; + } + } forEach [_utl, _utr, _ubr, _ubl, _dtl, _dtr, _dbr, _dbl]; + + _seekerTargetPos = _averagePosition vectorMultiply (1 / _averagePositionCounter); +} else { + if (_designateInput == 1) then { + _seekerTargetPos = [0, 0, 0]; + }; +}; + +_seekerTargetPos + diff --git a/addons/spike/functions/fnc_keyDown.sqf b/addons/spike/functions/fnc_keyDown.sqf index 43e02a7572..0f18272281 100644 --- a/addons/spike/functions/fnc_keyDown.sqf +++ b/addons/spike/functions/fnc_keyDown.sqf @@ -17,4 +17,17 @@ */ params ["_key", "_down"]; +if (_key == SPIKE_KEY_DESIGNATE) then { + if (cameraView == "GUNNER") then { + playSound "ACE_Sound_Click"; + }; + private _designateInput = 0; + if (_down) then { + _designateInput = 1; + } else { + _designateInput = 0; + }; + (uiNamespace getVariable "ACE_RscOptics_spike") setVariable [QGVAR(designate), _designateInput]; +}; + _this call FUNC(camera_handleKeyPress); diff --git a/addons/spike/functions/fnc_mapHelperDraw.sqf b/addons/spike/functions/fnc_mapHelperDraw.sqf new file mode 100644 index 0000000000..e0c3021847 --- /dev/null +++ b/addons/spike/functions/fnc_mapHelperDraw.sqf @@ -0,0 +1,94 @@ +#include "script_component.hpp" +/* + * Author: Brandon (TCVM) + * Handles the map helper's draw event + * Resets arguments if not run recently + * And starts a watchdog to detect when weapon display unloaded + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_spike_fnc_mapHelperDraw + * + * Public: No + */ +#define __SPIKE_DISPLAY (uinamespace getVariable "ACE_RscOptics_spike") +#define __SPIKE_RETICLE (__SPIKE_DISPLAY displayCtrl 242000) + +private _currentShooter = if (ACE_player call CBA_fnc_canUseWeapon) then {ACE_player} else {vehicle ACE_player}; +if (isNil QGVAR(arguments)) then { + TRACE_1("Starting optic draw", _this); + + // reset shooter var: + _currentShooter setVariable ["ace_missileguidance_target", nil, false]; + + GVAR(arguments) = [ + diag_frameno, // Last run frame + [0, 0, 0] // currentTargetObject + ]; + + // Start up a watchdog for when the display is no longer shown (but might not be unloaded or null) + [{ + if (isNull (uiNamespace getVariable ["ACE_RscOptics_spike", displayNull])) exitWith {true}; + GVAR(arguments) params ["_lastRunFrame"]; + (diag_frameno < _lastRunFrame) || {diag_frameno > (_lastRunFrame + 1)} + }, { + TRACE_1("old/null display - ending optic draw",_this); + GVAR(arguments) = nil; + }, []] call CBA_fnc_waitUntilAndExecute; +}; + + +if (cameraView isEqualTo "GUNNER") then { + GVAR(arguments) set [0, diag_frameNo]; + + __SPIKE_RETICLE ctrlShow true; + GVAR(arguments) params ["", "_targetPosition"]; + + private _currentAmmo = _currentShooter ammo currentWeapon _currentShooter; + + private _designating = __SPIKE_DISPLAY getVariable [QGVAR(designate), 0]; + if (_currentAmmo != 0 && { _designating == 1 || _targetPosition isNotEqualTo [0, 0, 0] }) then { + _targetPosition = [eyePos _currentShooter, getCameraViewDirection _currentShooter, _designating, _targetPosition, _currentShooter] call FUNC(getTargetPosition); + GVAR(arguments) set [1, _targetPosition]; + }; + + if (_currentAmmo == 0) then { + __SPIKE_RETICLE ctrlShow false; + } else { + if (_targetPosition isEqualTo [0, 0, 0]) then { + __SPIKE_RETICLE ctrlSetPosition [0, 0]; + + (__SPIKE_DISPLAY displayCtrl 243101) ctrlShow false; + (__SPIKE_DISPLAY displayCtrl 243201) ctrlShow false; + (__SPIKE_DISPLAY displayCtrl 243301) ctrlShow false; + } else { + (__SPIKE_DISPLAY displayCtrl 243101) ctrlShow true; + (__SPIKE_DISPLAY displayCtrl 243201) ctrlShow true; + (__SPIKE_DISPLAY displayCtrl 243301) ctrlShow true; + + _seekerPositionScreen = worldToScreen ASLtoAGL _targetPosition; + if (_seekerPositionScreen isEqualTo []) then { + _seekerPositionScreen = [0, 0]; + }; + _seekerPositionScreen set [0, _seekerPositionScreen#0 - 0.5]; + _seekerPositionScreen set [1, _seekerPositionScreen#1 - 0.5]; + + __SPIKE_RETICLE ctrlSetPosition _seekerPositionScreen; + + if (abs (_seekerPositionScreen#0) > 0.2 || abs (_seekerPositionScreen#1) > 0.2) then { + GVAR(arguments) set [1, [0, 0, 0]]; + }; + }; + _currentShooter setVariable [QGVAR(target), _targetPosition]; + }; + + __SPIKE_RETICLE ctrlCommit 0; +} else { + __SPIKE_RETICLE ctrlShow false; +}; + diff --git a/addons/spike/functions/fnc_onFired.sqf b/addons/spike/functions/fnc_onFired.sqf index 8f35f4177a..e1c0e3c86a 100644 --- a/addons/spike/functions/fnc_onFired.sqf +++ b/addons/spike/functions/fnc_onFired.sqf @@ -67,8 +67,9 @@ if (!(_cameraConfig isEqualTo configNull) && { (getNumber (_cameraConfig >> "ena _cameraArray set [12, (getNumber (_cameraConfig >> "canStopDesignating")) == 1]; }; -private _camera = [_projectile, _cameraArray, _shooter] call FUNC(camera_init); -GVAR(projectileHashMap) set [hashValue _projectile, _camera]; +private _preTarget = +(ACE_PLAYER getVariable [QGVAR(target), [0, 0, 0]]); +private _camera = [_projectile, _cameraArray, _shooter, _preTarget isEqualTo [0, 0, 0]] call FUNC(camera_init); +GVAR(projectileHashMap) set [hashValue _projectile, [_camera, _preTarget]]; [{ params ["_args", "_pfID"]; _args params ["_firedEH", "_cameraArray", "_lastUpdate", "_camera", "_projectileHash"]; diff --git a/addons/spike/functions/fnc_seeker.sqf b/addons/spike/functions/fnc_seeker.sqf index 86cd182075..e92717108c 100644 --- a/addons/spike/functions/fnc_seeker.sqf +++ b/addons/spike/functions/fnc_seeker.sqf @@ -17,13 +17,11 @@ */ params ["", "_args", "_seekerStateParams", "", "_timestep"]; -_args params ["_firedEH", "_launchParams", "", "_seekerParams", "_stateParams", "_targetData"]; +_args params ["_firedEH", "", "", "", "", "_targetData"]; _firedEH params ["","","","","","","_projectile"]; -_launchParams params ["", "_targetParams"]; -_targetParams params ["_target"]; -_seekerParams params ["_seekerAngle", "", "_seekerMaxRange"]; -private _cameraNamespace = GVAR(projectileHashMap) get hashValue _projectile; +(GVAR(projectileHashMap) get hashValue _projectile) params ["_cameraNamespace", "_preTarget"]; + private _seekerTargetPos = _cameraNamespace getVariable [QGVAR(seekerTargetPos), [0, 0, 0]]; private _cameraPos = _cameraNamespace getVariable [QGVAR(cameraPos), [0, 0, 0]]; private _logicPos = _cameraNamespace getVariable [QGVAR(logicPos), [0, 0, 0]]; @@ -33,71 +31,12 @@ private _seekerTargetInfo = _cameraNamespace getVariable [QGVAR(seekerTargetInfo private _intersectObject = objNull; private _designateInput = (_cameraNamespace getVariable [QGVAR(designateInput), [0]]) select 0; +if (_seekerTargetPos isEqualTo [0, 0, 0]) then { + _seekerTargetPos = _preTarget; +}; + if ((_seekerTargetPos isNotEqualTo [0, 0, 0]) || { (_designateInput == 1) }) then { - private _nearObjects = []; - - private _intersections = lineIntersectsSurfaces [_cameraPos, _cameraPos vectorAdd ((vectorNormalized _logicPos) vectorMultiply 5000), objNull, objNull, true, 1, "FIRE", "VIEW", true]; - if (_intersections isNotEqualTo []) then { - (_intersections#0) params ["_intersectPos", "", "_object"]; - - if (_designateInput == 1) then { - _seekerTargetPos = _intersectPos; - }; - - _nearObjects = (ASLtoAGL _seekerTargetPos) nearObjects ["AllVehicles", 5]; - if (_designateInput == 1 && { !isNull _object }) then { - _nearObjects pushBack _object; - }; - }; - - if (_nearObjects isNotEqualTo []) then { - // I want to prefer the designated position on the object moreso than the bounds of the object - private _averagePosition = _seekerTargetPos vectorMultiply 15; - private _averagePositionCounter = 15; - - private _closestObject = objNull; - private _closestDistance = 1e10; - - { - if ((getPosASLVisual _x) vectorDistanceSqr _seekerTargetPos < _closestDistance) then { - _closestDistance = (getPosASLVisual _x) vectorDistanceSqr _seekerTargetPos; - _closestObject = _x; - }; - } forEach _nearObjects; - - private _boundingBox = 0 boundingBoxReal _closestObject; - - // Project target bounding box onto screen and do a real bad edge detection check - _boundingBox params ["_min", "_max"]; - _min params ["_x0", "_y0", "_z0"]; - _max params ["_x1", "_y1", "_z1"]; - - private _utl = _closestObject modelToWorldVisualWorld [_x0, _y0, _z0]; - private _utr = _closestObject modelToWorldVisualWorld [_x1, _y0, _z0]; - private _ubr = _closestObject modelToWorldVisualWorld [_x1, _y1, _z0]; - private _ubl = _closestObject modelToWorldVisualWorld [_x0, _y1, _z0]; - - private _dtl = _closestObject modelToWorldVisualWorld [_x0, _y0, _z1]; - private _dtr = _closestObject modelToWorldVisualWorld [_x1, _y0, _z1]; - private _dbr = _closestObject modelToWorldVisualWorld [_x1, _y1, _z1]; - private _dbl = _closestObject modelToWorldVisualWorld [_x0, _y1, _z1]; - - { - private _intersections = lineIntersectsSurfaces [_cameraPos, _x, objNull, objNull, false, 16]; - if (_intersections isEqualTo []) then { - _averagePosition = _averagePosition vectorAdd _x; - _averagePositionCounter = _averagePositionCounter + 1; - } else { - { - _x params ["_surfacePosition"]; - _averagePosition = _averagePosition vectorAdd _surfacePosition; - _averagePositionCounter = _averagePositionCounter + 1; - } forEach _intersections; - } - } forEach [_utl, _utr, _ubr, _ubl, _dtl, _dtr, _dbr, _dbl]; - - _seekerTargetPos = _averagePosition vectorMultiply (1 / _averagePositionCounter); - }; + _seekerTargetPos = [_cameraPos, vectorNormalized _logicPos, _designateInput, _seekerTargetPos] call FUNC(getTargetPosition); }; _cameraNamespace setVariable [QGVAR(seekerTargetPos), _seekerTargetPos]; diff --git a/addons/spike/script_component.hpp b/addons/spike/script_component.hpp index 6d554ba954..0774879647 100644 --- a/addons/spike/script_component.hpp +++ b/addons/spike/script_component.hpp @@ -40,6 +40,6 @@ #define CRUISE_PRO_GAIN 0.3 #define CRUISE_DER_GAIN 3 -#define BATTERY_LIFE 30 +#define BATTERY_LIFE (43 + random 10) #define GIMBAL_LOGIC_OFFSET 10