mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Handle pre-tracking
This commit is contained in:
parent
7460bb335e
commit
8da028b626
@ -1,7 +1,7 @@
|
|||||||
class CfgAmmo {
|
class CfgAmmo {
|
||||||
class MissileBase;
|
class MissileBase;
|
||||||
class M_Titan_AT: MissileBase {};
|
class M_Titan_AT: MissileBase {};
|
||||||
class GVAR(at): M_Titan_AT {
|
class GVAR(lr): M_Titan_AT {
|
||||||
timeToLive = 120;
|
timeToLive = 120;
|
||||||
|
|
||||||
manualControl = 0;
|
manualControl = 0;
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
class CfgMagazines {
|
class CfgMagazines {
|
||||||
class Titan_AT;
|
class Titan_AT;
|
||||||
class GVAR(at): Titan_AT {
|
class GVAR(lr): Titan_AT {
|
||||||
author = "Brandon (TCVM)";
|
author = "Brandon (TCVM)";
|
||||||
ammo = QGVAR(at);
|
ammo = QGVAR(lr);
|
||||||
|
|
||||||
displayName = "Spike AT";
|
displayName = "Spike AT";
|
||||||
displayNameShort = "foo";
|
displayNameShort = "foo";
|
||||||
|
@ -10,7 +10,7 @@ class CfgWeapons {
|
|||||||
class GVAR(launcher): GVAR(base) {
|
class GVAR(launcher): GVAR(base) {
|
||||||
scope = 2;
|
scope = 2;
|
||||||
GVAR(enabled) = 1;
|
GVAR(enabled) = 1;
|
||||||
//weaponInfoType = "ACE_RscOptics_javelin";
|
weaponInfoType = "ACE_RscOptics_spike";
|
||||||
//modelOptics = QPATHTOF(data\reticle_titan.p3d);
|
//modelOptics = QPATHTOF(data\reticle_titan.p3d);
|
||||||
|
|
||||||
canLock = 0;
|
canLock = 0;
|
||||||
@ -21,7 +21,7 @@ class CfgWeapons {
|
|||||||
displayName = "Spike AT";
|
displayName = "Spike AT";
|
||||||
displayNameShort = "Spike AT";
|
displayNameShort = "Spike AT";
|
||||||
|
|
||||||
magazines[] = {QGVAR(at)};
|
magazines[] = {QGVAR(lr)};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
118
addons/spike/RscInGameUI.hpp
Normal file
118
addons/spike/RscInGameUI.hpp
Normal file
@ -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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
@ -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 RscTitles {
|
||||||
class ACE_guidance_spike {
|
class ACE_guidance_spike {
|
||||||
|
@ -3,7 +3,6 @@ PREP(camera_cycleViewMode);
|
|||||||
PREP(camera_destroy);
|
PREP(camera_destroy);
|
||||||
PREP(camera_handleKeyPress);
|
PREP(camera_handleKeyPress);
|
||||||
PREP(camera_init);
|
PREP(camera_init);
|
||||||
PREP(camera_preTrack);
|
|
||||||
PREP(camera_setViewMode);
|
PREP(camera_setViewMode);
|
||||||
PREP(camera_setZoom);
|
PREP(camera_setZoom);
|
||||||
PREP(camera_switchAway);
|
PREP(camera_switchAway);
|
||||||
@ -16,4 +15,6 @@ PREP(onFired);
|
|||||||
PREP(seeker);
|
PREP(seeker);
|
||||||
PREP(navigation);
|
PREP(navigation);
|
||||||
PREP(midCourseTransition);
|
PREP(midCourseTransition);
|
||||||
|
PREP(mapHelperDraw);
|
||||||
|
PREP(getTargetPosition);
|
||||||
|
|
||||||
|
@ -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 "ACE_GuidanceConfig.hpp"
|
||||||
#include "RscTitles.hpp"
|
#include "RscTitles.hpp"
|
||||||
|
#include "RscInGameUI.hpp"
|
||||||
#include "CfgEventhandlers.hpp"
|
#include "CfgEventhandlers.hpp"
|
||||||
#include "CfgAmmo.hpp"
|
#include "CfgAmmo.hpp"
|
||||||
#include "CfgMagazines.hpp"
|
#include "CfgMagazines.hpp"
|
||||||
|
@ -19,8 +19,6 @@ params ["_key", "_down"];
|
|||||||
|
|
||||||
if !([objNull] call FUNC(camera_userInCamera)) exitWith {};
|
if !([objNull] call FUNC(camera_userInCamera)) exitWith {};
|
||||||
|
|
||||||
playSound "ACE_Sound_Click";
|
|
||||||
|
|
||||||
private _return = false;
|
private _return = false;
|
||||||
private _lookInput = GVAR(activeCamera) getVariable [QGVAR(lookInput), [0, 0, 0, 0]];
|
private _lookInput = GVAR(activeCamera) getVariable [QGVAR(lookInput), [0, 0, 0, 0]];
|
||||||
private _designateInput = GVAR(activeCamera) getVariable [QGVAR(designateInput), [0]];
|
private _designateInput = GVAR(activeCamera) getVariable [QGVAR(designateInput), [0]];
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
*
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
params ["_projectile", "_cameraArray", "_shooter"];
|
params ["_projectile", "_cameraArray", "_shooter", "_switchOnFireInit"];
|
||||||
_cameraArray params ["_enabled", "_fovLevels", "_initialFOV", "_thermalTypes", "_initialThermalType", "_switchOnFire", "_lerpFOV", "_fovChangeTime", "", "_gimbalData", "_reticleData", "_designating"];
|
_cameraArray params ["_enabled", "_fovLevels", "_initialFOV", "_thermalTypes", "_initialThermalType", "_switchOnFire", "_lerpFOV", "_fovChangeTime", "", "_gimbalData", "_reticleData", "_designating"];
|
||||||
_gimbalData params ["_hasGimbal", "_maxGimbalX", "_maxGimbalY", "_gimbalSpeedX", "_gimbalSpeedY", "_initGimbalAngleX", "_initGimbalAngleY", "_gimbalZoomSpeedModifiers"];
|
_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(missile), _projectile];
|
||||||
_activeCameraNamespace setVariable [QGVAR(logicPos), _projectile vectorModelToWorldVisual _logicPosition];
|
_activeCameraNamespace setVariable [QGVAR(logicPos), _projectile vectorModelToWorldVisual _logicPosition];
|
||||||
|
|
||||||
if (_switchOnFire) then {
|
if (_switchOnFire && _switchOnFireInit) then {
|
||||||
[_activeCameraNamespace] call FUNC(camera_switchTo);
|
[_activeCameraNamespace] call FUNC(camera_switchTo);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
92
addons/spike/functions/fnc_getTargetPosition.sqf
Normal file
92
addons/spike/functions/fnc_getTargetPosition.sqf
Normal file
@ -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 <ARRAY>
|
||||||
|
* 2: Direction <ARRAY>
|
||||||
|
* 3: If we are designating <NUMBER>
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* Missile Aim PosASL <ARRAY>
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
|
@ -17,4 +17,17 @@
|
|||||||
*/
|
*/
|
||||||
params ["_key", "_down"];
|
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);
|
_this call FUNC(camera_handleKeyPress);
|
||||||
|
94
addons/spike/functions/fnc_mapHelperDraw.sqf
Normal file
94
addons/spike/functions/fnc_mapHelperDraw.sqf
Normal file
@ -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;
|
||||||
|
};
|
||||||
|
|
@ -67,8 +67,9 @@ if (!(_cameraConfig isEqualTo configNull) && { (getNumber (_cameraConfig >> "ena
|
|||||||
_cameraArray set [12, (getNumber (_cameraConfig >> "canStopDesignating")) == 1];
|
_cameraArray set [12, (getNumber (_cameraConfig >> "canStopDesignating")) == 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
private _camera = [_projectile, _cameraArray, _shooter] call FUNC(camera_init);
|
private _preTarget = +(ACE_PLAYER getVariable [QGVAR(target), [0, 0, 0]]);
|
||||||
GVAR(projectileHashMap) set [hashValue _projectile, _camera];
|
private _camera = [_projectile, _cameraArray, _shooter, _preTarget isEqualTo [0, 0, 0]] call FUNC(camera_init);
|
||||||
|
GVAR(projectileHashMap) set [hashValue _projectile, [_camera, _preTarget]];
|
||||||
[{
|
[{
|
||||||
params ["_args", "_pfID"];
|
params ["_args", "_pfID"];
|
||||||
_args params ["_firedEH", "_cameraArray", "_lastUpdate", "_camera", "_projectileHash"];
|
_args params ["_firedEH", "_cameraArray", "_lastUpdate", "_camera", "_projectileHash"];
|
||||||
|
@ -17,13 +17,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
params ["", "_args", "_seekerStateParams", "", "_timestep"];
|
params ["", "_args", "_seekerStateParams", "", "_timestep"];
|
||||||
_args params ["_firedEH", "_launchParams", "", "_seekerParams", "_stateParams", "_targetData"];
|
_args params ["_firedEH", "", "", "", "", "_targetData"];
|
||||||
_firedEH params ["","","","","","","_projectile"];
|
_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 _seekerTargetPos = _cameraNamespace getVariable [QGVAR(seekerTargetPos), [0, 0, 0]];
|
||||||
private _cameraPos = _cameraNamespace getVariable [QGVAR(cameraPos), [0, 0, 0]];
|
private _cameraPos = _cameraNamespace getVariable [QGVAR(cameraPos), [0, 0, 0]];
|
||||||
private _logicPos = _cameraNamespace getVariable [QGVAR(logicPos), [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 _intersectObject = objNull;
|
||||||
private _designateInput = (_cameraNamespace getVariable [QGVAR(designateInput), [0]]) select 0;
|
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 {
|
if ((_seekerTargetPos isNotEqualTo [0, 0, 0]) || { (_designateInput == 1) }) then {
|
||||||
private _nearObjects = [];
|
_seekerTargetPos = [_cameraPos, vectorNormalized _logicPos, _designateInput, _seekerTargetPos] call FUNC(getTargetPosition);
|
||||||
|
|
||||||
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);
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
_cameraNamespace setVariable [QGVAR(seekerTargetPos), _seekerTargetPos];
|
_cameraNamespace setVariable [QGVAR(seekerTargetPos), _seekerTargetPos];
|
||||||
|
@ -40,6 +40,6 @@
|
|||||||
#define CRUISE_PRO_GAIN 0.3
|
#define CRUISE_PRO_GAIN 0.3
|
||||||
#define CRUISE_DER_GAIN 3
|
#define CRUISE_DER_GAIN 3
|
||||||
|
|
||||||
#define BATTERY_LIFE 30
|
#define BATTERY_LIFE (43 + random 10)
|
||||||
|
|
||||||
#define GIMBAL_LOGIC_OFFSET 10
|
#define GIMBAL_LOGIC_OFFSET 10
|
||||||
|
Loading…
Reference in New Issue
Block a user