mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Separate iron dome
This commit is contained in:
parent
bcb6ed7c68
commit
ec608b27f2
1
addons/iron_dome/$PBOPREFIX$
Normal file
1
addons/iron_dome/$PBOPREFIX$
Normal file
@ -0,0 +1 @@
|
|||||||
|
z\ace\addons\iron_dome
|
17
addons/iron_dome/CfgEventHandlers.hpp
Normal file
17
addons/iron_dome/CfgEventHandlers.hpp
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
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));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
class Extended_PostInit_EventHandlers {
|
||||||
|
class ADDON {
|
||||||
|
init = QUOTE(call COMPILE_SCRIPT(XEH_postInit));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
11
addons/iron_dome/README.md
Normal file
11
addons/iron_dome/README.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
ace_iron_dome
|
||||||
|
===================
|
||||||
|
|
||||||
|
Adds an Iron Dome projectile interceptor system
|
||||||
|
|
||||||
|
|
||||||
|
## Maintainers
|
||||||
|
|
||||||
|
The people responsible for merging changes to this component or answering potential questions.
|
||||||
|
|
||||||
|
- [Dani (TCVM)](https://github.com/TheCandianVendingMachine)
|
2
addons/iron_dome/XEH_PREP.hpp
Normal file
2
addons/iron_dome/XEH_PREP.hpp
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
PREP(projectileTrackerPFH);
|
||||||
|
PREP(proximityFusePFH);
|
7
addons/iron_dome/XEH_postInit.sqf
Normal file
7
addons/iron_dome/XEH_postInit.sqf
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
if (isServer && { GVAR(enable) }) then {
|
||||||
|
[LINKFUNC(projectileTrackerPFH)] call CBA_fnc_addPerFrameHandler;
|
||||||
|
[LINKFUNC(proximityFusePFH)] call CBA_fnc_addPerFrameHandler;
|
||||||
|
};
|
||||||
|
|
97
addons/iron_dome/XEH_preInit.sqf
Normal file
97
addons/iron_dome/XEH_preInit.sqf
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
ADDON = false;
|
||||||
|
|
||||||
|
PREP_RECOMPILE_START;
|
||||||
|
#include "XEH_PREP.hpp"
|
||||||
|
PREP_RECOMPILE_END;
|
||||||
|
|
||||||
|
#include "initSettings.inc.sqf"
|
||||||
|
|
||||||
|
// Server handles the tracking of all projectiles. It dispatches events to launchers to fire at specific targets
|
||||||
|
// The tracker and launcher array are global to allow for early-out if it is impossible to kill any projectiles to avoid wasting bandwidth
|
||||||
|
GVAR(trackers) = [];
|
||||||
|
GVAR(launchers) = [];
|
||||||
|
|
||||||
|
if (isServer) then {
|
||||||
|
GVAR(nonTrackingProjectiles) = [];
|
||||||
|
GVAR(trackingProjectiles) = [];
|
||||||
|
|
||||||
|
GVAR(interceptors) = [];
|
||||||
|
// Put these into hash table to avoid massive amounts of loops
|
||||||
|
GVAR(toBeShot) = call CBA_fnc_hashCreate;
|
||||||
|
|
||||||
|
[QGVAR(track), {
|
||||||
|
params ["_projectile"];
|
||||||
|
GVAR(nonTrackingProjectiles) pushBack _projectile;
|
||||||
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
|
[QGVAR(registerInterceptor), {
|
||||||
|
params ["_interceptor", "_target"];
|
||||||
|
GVAR(interceptors) pushBack [_interceptor, _target, getPosASLVisual _interceptor, _interceptor distance _target];
|
||||||
|
[GVAR(toBeShot), _target] call CBA_fnc_hashRem;
|
||||||
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
};
|
||||||
|
|
||||||
|
[QGVAR(registerLaunchers), {
|
||||||
|
{
|
||||||
|
GVAR(launchers) pushBackUnique _x;
|
||||||
|
_x setVariable [QGVAR(targetList), []];
|
||||||
|
_x setVariable [QGVAR(launchState), LAUNCH_STATE_IDLE];
|
||||||
|
_x setVariable [QGVAR(lastLaunchTime), 0];
|
||||||
|
_x setVariable [QGVAR(engagedTargets), [[], objNull] call CBA_fnc_hashCreate];
|
||||||
|
_x setVariable [QEGVAR(missileguidance,target), objNull];
|
||||||
|
|
||||||
|
if (local _x) then {
|
||||||
|
_x addEventHandler ["Fired", {
|
||||||
|
params ["_launcher", "", "", "", "", "", "_projectile"];
|
||||||
|
private _target = _launcher getVariable [QEGVAR(missileguidance,target), objNull];
|
||||||
|
if !(isNull _target) then {
|
||||||
|
[QGVAR(registerInterceptor), [_projectile, _target]] call CBA_fnc_serverEvent;
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
} forEach _this;
|
||||||
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
|
[QGVAR(registerTrackers), {
|
||||||
|
{
|
||||||
|
_x params ["_tracker", "_range"];
|
||||||
|
GVAR(trackers) pushBack [_tracker, _range];
|
||||||
|
} forEach _this;
|
||||||
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
|
// When something is fired, determine if we want to track it. If so, send it to the server for processing
|
||||||
|
GVAR(projectilesToIntercept) = [];
|
||||||
|
|
||||||
|
[QGVAR(addProjectilesToIntercept), {
|
||||||
|
{
|
||||||
|
GVAR(projectilesToIntercept) pushBackUnique _x;
|
||||||
|
} forEach _this;
|
||||||
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
|
["All", "fired", {
|
||||||
|
params ["", "", "", "", "", "", "_projectile"];
|
||||||
|
if (local _projectile && { (typeOf _projectile) in GVAR(projectilesToIntercept) }) then {
|
||||||
|
// avoid extra bandwidth: don't make a call to the server if we don't have any systems up
|
||||||
|
GVAR(launchers) = GVAR(launchers) select {
|
||||||
|
alive _x
|
||||||
|
};
|
||||||
|
GVAR(trackers) = GVAR(trackers) select {
|
||||||
|
_x params ["_tracker"];
|
||||||
|
alive _tracker
|
||||||
|
};
|
||||||
|
if !(GVAR(launchers) isEqualTo [] || { GVAR(trackers) isEqualTo [] }) then {
|
||||||
|
[QGVAR(track), [_projectile]] call CBA_fnc_serverEvent;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}] call CBA_fnc_addClassEventHandler;
|
||||||
|
|
||||||
|
// Needed on all clients to properly destroy it. Despite the fact that deleteVehicle is AG EG, unless if you delete it on all clients there will still be missiles seen
|
||||||
|
[QGVAR(destroyProjectile), {
|
||||||
|
params ["_projectile"];
|
||||||
|
deleteVehicle _projectile;
|
||||||
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
|
ADDON = true;
|
||||||
|
|
3
addons/iron_dome/XEH_preStart.sqf
Normal file
3
addons/iron_dome/XEH_preStart.sqf
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
#include "XEH_PREP.hpp"
|
19
addons/iron_dome/config.cpp
Normal file
19
addons/iron_dome/config.cpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
class CfgPatches {
|
||||||
|
class ADDON {
|
||||||
|
name = COMPONENT_NAME;
|
||||||
|
units[] = {};
|
||||||
|
weapons[] = {};
|
||||||
|
requiredVersion = REQUIRED_VERSION;
|
||||||
|
// no point having this system without missile guidance: nothing would happen
|
||||||
|
requiredAddons[] = {"ace_common","ace_missileguidance"};
|
||||||
|
author = ECSTRING(common,ACETeam);
|
||||||
|
authors[] = {"Dani (TCVM)"};
|
||||||
|
url = ECSTRING(main,URL);
|
||||||
|
VERSION_CONFIG;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "CfgEventHandlers.hpp"
|
||||||
|
|
204
addons/iron_dome/functions/fnc_projectileTrackerPFH.sqf
Normal file
204
addons/iron_dome/functions/fnc_projectileTrackerPFH.sqf
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
#include "..\script_component.hpp"
|
||||||
|
/*
|
||||||
|
* Author: tcvm
|
||||||
|
* Handles tracking of incoming projectiles per frame
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 0: Args <ARRAY>
|
||||||
|
* 1: Handle <NUMBER>
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [ace_iron_dome_projectileTrackerPFH] call CBA_fnc_addPerFrameHandler
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
|
||||||
|
GVAR(trackers) = GVAR(trackers) select {
|
||||||
|
_x params ["_tracker", "_range"];
|
||||||
|
#ifdef DRAW_TRACKING_INFO
|
||||||
|
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,1,0,1], getPos _tracker, 0.75, 0.75, 0, format ["TRACKER [%1m]", _range], 1, 0.025, "TahomaB"];
|
||||||
|
#endif
|
||||||
|
alive _tracker
|
||||||
|
};
|
||||||
|
|
||||||
|
GVAR(launchers) = GVAR(launchers) select {
|
||||||
|
alive _x
|
||||||
|
};
|
||||||
|
|
||||||
|
[GVAR(toBeShot), {
|
||||||
|
(CBA_missionTime - _value) < GVAR(targetRecycleTime)
|
||||||
|
}] call CBA_fnc_hashFilter;
|
||||||
|
|
||||||
|
private _idleLaunchers = GVAR(launchers) select {
|
||||||
|
(_x getVariable QGVAR(launchState)) isEqualTo LAUNCH_STATE_IDLE && { someAmmo _x }
|
||||||
|
};
|
||||||
|
|
||||||
|
// no point filtering if we don't have a launcher. Don't waste cycles
|
||||||
|
if (_idleLaunchers isNotEqualTo []) then {
|
||||||
|
|
||||||
|
GVAR(nonTrackingProjectiles) = GVAR(nonTrackingProjectiles) select {
|
||||||
|
private _projectile = _x;
|
||||||
|
if (isNull _projectile) then {continueWith false};
|
||||||
|
|
||||||
|
private _keep = true;
|
||||||
|
private _bestRange = 1e10;
|
||||||
|
|
||||||
|
{
|
||||||
|
_x params ["_tracker", "_range"];
|
||||||
|
_bestRange = _bestRange min (_projectile distanceSqr _tracker);
|
||||||
|
if (_projectile distanceSqr _tracker <= _range * _range) exitWith {
|
||||||
|
GVAR(trackingProjectiles) pushBack [_projectile, 0];
|
||||||
|
_keep = false;
|
||||||
|
[QGVAR(projectileInRange), [_projectile, _tracker]] call CBA_fnc_localEvent;
|
||||||
|
};
|
||||||
|
} forEach GVAR(trackers);
|
||||||
|
|
||||||
|
#ifdef DRAW_TRACKING_INFO
|
||||||
|
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,1], getPos _projectile, 0.75, 0.75, 0, format ["%1 %2m", typeOf _projectile, sqrt _bestRange], 1, 0.025, "TahomaB"];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_keep
|
||||||
|
};
|
||||||
|
|
||||||
|
GVAR(trackingProjectiles) = GVAR(trackingProjectiles) select {
|
||||||
|
_x params ["_projectile", "_lastFired"];
|
||||||
|
|
||||||
|
private _keep = false;
|
||||||
|
if (alive _projectile) then {
|
||||||
|
{
|
||||||
|
_x params ["_tracker", "_range"];
|
||||||
|
private _withinRange = _projectile distanceSqr _tracker <= _range * _range;
|
||||||
|
|
||||||
|
if (_withinRange) exitWith {
|
||||||
|
_keep = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
} forEach GVAR(trackers);
|
||||||
|
|
||||||
|
if !(_keep) then {
|
||||||
|
GVAR(nonTrackingProjectiles) pushBack _projectile;
|
||||||
|
} else {
|
||||||
|
private _bestLauncher = objNull;
|
||||||
|
private _bestAmmo = 0;
|
||||||
|
|
||||||
|
private _engagedFuture = [GVAR(toBeShot), _projectile] call CBA_fnc_hashHasKey;
|
||||||
|
|
||||||
|
private _engagedPast = GVAR(interceptors) findIf {
|
||||||
|
_x params ["", "_target"];
|
||||||
|
_projectile isEqualTo _target;
|
||||||
|
};
|
||||||
|
|
||||||
|
private _engaged = _engagedFuture || (_engagedPast != -1);
|
||||||
|
if !(_engaged) then {
|
||||||
|
// launch a missile
|
||||||
|
// pick first idle launcher. Could use a heuristic, but that would require O(k*l) operations, and that could be a lot
|
||||||
|
// 20 launchers * 100 projectiles = 2000 loops. Way too slow
|
||||||
|
private _bestLauncher = _idleLaunchers select 0;
|
||||||
|
_idleLaunchers deleteAt 0;
|
||||||
|
|
||||||
|
private _targetList = _bestLauncher getVariable QGVAR(targetList);
|
||||||
|
_targetList pushBackUnique _projectile;
|
||||||
|
_bestLauncher setVariable [QGVAR(targetList), _targetList];
|
||||||
|
|
||||||
|
// avoid re-engaging same target
|
||||||
|
[GVAR(toBeShot), _projectile, CBA_missionTime] call CBA_fnc_hashSet;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef DRAW_TRACKING_INFO
|
||||||
|
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0,1,0,1], getPos _projectile, 0.75, 0.75, 0, format ["%1 %2m %3s", typeOf _projectile, _bestLauncher distance _projectile], 1, 0.025, "TahomaB"];
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
_keep
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
private _launcher = _x;
|
||||||
|
private _state = _launcher getVariable QGVAR(launchState);
|
||||||
|
|
||||||
|
switch (_state) do {
|
||||||
|
case LAUNCH_STATE_IDLE: {
|
||||||
|
private _targetList = _x getVariable QGVAR(targetList);
|
||||||
|
private _engagedTargets = _x getVariable QGVAR(engagedTargets);
|
||||||
|
|
||||||
|
_targetList = _targetList select {
|
||||||
|
private _timeFiredAt = [_engagedTargets, _x, 0] call CBA_fnc_hashGet;
|
||||||
|
alive _x && (_timeFiredAt == 0 || { (CBA_missionTime - _timeFiredAt) >= GVAR(targetRecycleTime) })
|
||||||
|
};
|
||||||
|
|
||||||
|
private _bestTarget = objNull;
|
||||||
|
private _bestDistance = 1e10;
|
||||||
|
{
|
||||||
|
if (_x distanceSqr _launcher < _bestDistance) then {
|
||||||
|
_bestTarget = _x;
|
||||||
|
_bestDistance = _x distanceSqr _launcher;
|
||||||
|
};
|
||||||
|
} forEach _targetList;
|
||||||
|
|
||||||
|
if !(isNull _bestTarget) then {
|
||||||
|
_launcher setVariable [QEGVAR(missileguidance,target), _bestTarget];
|
||||||
|
_launcher setVariable [QGVAR(launchState), LAUNCH_STATE_TRACKING];
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef DRAW_TRACKING_INFO
|
||||||
|
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1, 1, 1, 1], getPos _launcher, 0.75, 0.75, 0, format ["IDLE [AMMO: %1]", someAmmo _launcher], 1, 0.025, "TahomaB"];
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
case LAUNCH_STATE_TRACKING: {
|
||||||
|
private _target = _launcher getVariable QEGVAR(missileguidance,target);
|
||||||
|
_launcher lookAt getPosVisual _target;
|
||||||
|
|
||||||
|
if (isNull _target) then {
|
||||||
|
_launcher setVariable [QGVAR(launchState), LAUNCH_STATE_IDLE];
|
||||||
|
} else {
|
||||||
|
private _directionToTarget = (getPosASLVisual _launcher) vectorFromTo (getPosASLVisual _target);
|
||||||
|
private _turretDirection = _launcher weaponDirection currentWeapon _launcher;
|
||||||
|
private _localDirection = _launcher vectorWorldToModelVisual _turretDirection;
|
||||||
|
|
||||||
|
private _elevation = 90 - ((_localDirection#1) atan2 (_localDirection#2));
|
||||||
|
private _angle = acos (_turretDirection vectorCos _directionToTarget);
|
||||||
|
|
||||||
|
if (_angle <= GVAR(launchAcceptableAngle) && _elevation >= GVAR(launchAcceptableElevation)) then {
|
||||||
|
_launcher setVariable [QGVAR(launchState), LAUNCH_STATE_FIRING];
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef DRAW_TRACKING_INFO
|
||||||
|
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0, 0, 1, 1], getPos _launcher, 0.75, 0.75, 0, format ["TRACKING: %1 %2", _angle, _elevation], 1, 0.025, "TahomaB"];
|
||||||
|
drawLine3D [getPos _launcher, getPos _target, [0, 0, 1, 1]];
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
};
|
||||||
|
case LAUNCH_STATE_FIRING: {
|
||||||
|
private _turret = [_launcher, (crew _launcher) select 0] call CBA_fnc_turretPath;
|
||||||
|
[_launcher, _launcher currentWeaponTurret _turret] call BIS_fnc_fire;
|
||||||
|
|
||||||
|
_launcher setVariable [QGVAR(lastLaunchTime), CBA_missionTime];
|
||||||
|
_launcher setVariable [QGVAR(launchState), LAUNCH_STATE_COOLDOWN];
|
||||||
|
|
||||||
|
private _target = _launcher getVariable QEGVAR(missileguidance,target);
|
||||||
|
private _engagedTargets = _x getVariable QGVAR(engagedTargets);
|
||||||
|
[_engagedTargets, _target, CBA_missionTime] call CBA_fnc_hashSet;
|
||||||
|
_x setVariable [QGVAR(engagedTargets), _engagedTargets];
|
||||||
|
|
||||||
|
#ifdef DRAW_TRACKING_INFO
|
||||||
|
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1, 0, 0, 1], getPos _launcher, 0.75, 0.75, 0, format ["FIRING"], 1, 0.025, "TahomaB"];
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
case LAUNCH_STATE_COOLDOWN: {
|
||||||
|
private _lastLaunchTime = _launcher getVariable QGVAR(lastLaunchTime);
|
||||||
|
if (CBA_missionTime - _lastLaunchTime >= GVAR(timeBetweenLaunches)) then {
|
||||||
|
_launcher setVariable [QGVAR(launchState), LAUNCH_STATE_IDLE];
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef DRAW_TRACKING_INFO
|
||||||
|
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0, 0, 1, 1], getPos _launcher, 0.75, 0.75, 0, format ["COOLDOWN %1", CBA_missionTime - _lastLaunchTime], 1, 0.025, "TahomaB"];
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} forEach GVAR(launchers);
|
||||||
|
|
54
addons/iron_dome/functions/fnc_proximityFusePFH.sqf
Normal file
54
addons/iron_dome/functions/fnc_proximityFusePFH.sqf
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#include "..\script_component.hpp"
|
||||||
|
/*
|
||||||
|
* Author: tcvm
|
||||||
|
* Handles the fusing and detonation of any and all interceptors in the air
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [ace_iron_dome_proximityFusePFH] call CBA_fnc_addPerFrameHandler
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
|
||||||
|
GVAR(interceptors) = GVAR(interceptors) select {
|
||||||
|
_x params ["_projectile", "_target", "_lastPosition", "_lastDistance"];
|
||||||
|
// Sweep along path to ensure we don't overshoot target
|
||||||
|
private _minDistance = 0;
|
||||||
|
|
||||||
|
private _currentPosition = getPosASLVisual _projectile;
|
||||||
|
private _targetPosition = getPosASLVisual _target;
|
||||||
|
|
||||||
|
private _posDiff = (_currentPosition vectorDiff _lastPosition);
|
||||||
|
private _lengthSqr = _posDiff vectorDotProduct _posDiff;
|
||||||
|
if (_lengthSqr - 0.001 <= 0) then {
|
||||||
|
_minDistance = _lastPosition vectorDistance _targetPosition
|
||||||
|
} else {
|
||||||
|
private _d = (_targetPosition vectorDiff _lastPosition) vectorDotProduct (_currentPosition vectorDiff _lastPosition);
|
||||||
|
private _t = 0 max (1 min (_d / _lengthSqr));
|
||||||
|
private _projection = _lastPosition vectorAdd ((_currentPosition vectorDiff _lastPosition) vectorMultiply _t);
|
||||||
|
_minDistance = _projection vectorDistance _targetPosition;
|
||||||
|
};
|
||||||
|
|
||||||
|
_x set [2, _currentPosition];
|
||||||
|
_x set [3, _minDistance];
|
||||||
|
|
||||||
|
#ifdef DRAW_TRACKING_INFO
|
||||||
|
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0,0,1,1], (getPos _target) vectorAdd [0, 0, 0.5], 0.75, 0.75, 0, format ["%1m", _minDistance], 1, 0.025, "TahomaB"];
|
||||||
|
#endif
|
||||||
|
if (!alive _target || { _minDistance <= GVAR(proximityFuseRange) } || { _minDistance > _lastDistance }) then {
|
||||||
|
triggerAmmo _projectile;
|
||||||
|
// if we overshot target, dont take out target
|
||||||
|
if (_minDistance <= _lastDistance && { GVAR(proximityFuseFailureChance) <= random 1 }) then {
|
||||||
|
private _explosion = createVehicle ["SmallSecondary", _target, [], 0, "CAN_COLLIDE"];
|
||||||
|
[QGVAR(destroyProjectile), [_target]] call CBA_fnc_globalEvent;
|
||||||
|
};
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
};
|
70
addons/iron_dome/initSettings.inc.sqf
Normal file
70
addons/iron_dome/initSettings.inc.sqf
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
[
|
||||||
|
QGVAR(enable), "CHECKBOX",
|
||||||
|
[ELSTRING(common,Enabled), LSTRING(enable_description)],
|
||||||
|
LSTRING(category),
|
||||||
|
false, // default value
|
||||||
|
true, // isGlobal
|
||||||
|
{[QGVAR(enable), _this] call EFUNC(common,cbaSettings_settingChanged)},
|
||||||
|
true // Needs mission restart
|
||||||
|
] call CBA_fnc_addSetting;
|
||||||
|
|
||||||
|
[
|
||||||
|
QGVAR(targetRecycleTime), "SLIDER",
|
||||||
|
[LSTRING(targetRecycleTime_setting), LSTRING(targetRecycleTime_description)],
|
||||||
|
LSTRING(category),
|
||||||
|
[0, 60, 15, 0, false], // default value
|
||||||
|
true, // isGlobal
|
||||||
|
{[QGVAR(targetRecycleTime), _this] call EFUNC(common,cbaSettings_settingChanged)},
|
||||||
|
true // Needs mission restart
|
||||||
|
] call CBA_fnc_addSetting;
|
||||||
|
|
||||||
|
[
|
||||||
|
QGVAR(launchAcceptableAngle), "SLIDER",
|
||||||
|
[LSTRING(launchAcceptableAngle_setting), LSTRING(launchAcceptableAngle_description)],
|
||||||
|
LSTRING(category),
|
||||||
|
[1, 60, 10, 0, false], // default value
|
||||||
|
true, // isGlobal
|
||||||
|
{[QGVAR(launchAcceptableAngle), _this] call EFUNC(common,cbaSettings_settingChanged)},
|
||||||
|
true // Needs mission restart
|
||||||
|
] call CBA_fnc_addSetting;
|
||||||
|
|
||||||
|
[
|
||||||
|
QGVAR(launchAcceptableElevation), "SLIDER",
|
||||||
|
[LSTRING(launchAcceptableElevation_setting), LSTRING(launchAcceptableElevation_description)],
|
||||||
|
LSTRING(category),
|
||||||
|
[-90, 90, 5, 0, false], // default value
|
||||||
|
true, // isGlobal
|
||||||
|
{[QGVAR(launchAcceptableElevation), _this] call EFUNC(common,cbaSettings_settingChanged)},
|
||||||
|
true // Needs mission restart
|
||||||
|
] call CBA_fnc_addSetting;
|
||||||
|
|
||||||
|
[
|
||||||
|
QGVAR(timeBetweenLaunches), "SLIDER",
|
||||||
|
[LSTRING(timeBetweenLaunches_setting), LSTRING(timeBetweenLaunches_description)],
|
||||||
|
LSTRING(category),
|
||||||
|
[0, 60, 1, 0, false], // default value
|
||||||
|
true, // isGlobal
|
||||||
|
{[QGVAR(timeBetweenLaunches), _this] call EFUNC(common,cbaSettings_settingChanged)},
|
||||||
|
true // Needs mission restart
|
||||||
|
] call CBA_fnc_addSetting;
|
||||||
|
|
||||||
|
[
|
||||||
|
QGVAR(proximityFuseRange), "SLIDER",
|
||||||
|
[LSTRING(proximityFuseRange_setting), LSTRING(proximityFuseRange_description)],
|
||||||
|
LSTRING(category),
|
||||||
|
[1, 50, 10, 0, false], // default value
|
||||||
|
true, // isGlobal
|
||||||
|
{[QGVAR(timeBetweenLaunches), _this] call EFUNC(common,cbaSettings_settingChanged)},
|
||||||
|
true // Needs mission restart
|
||||||
|
] call CBA_fnc_addSetting;
|
||||||
|
|
||||||
|
[
|
||||||
|
QGVAR(proximityFuseFailureChance), "SLIDER",
|
||||||
|
[LSTRING(proximityFuseFailureChance_setting), LSTRING(proximityFuseFailureChance_description)],
|
||||||
|
LSTRING(category),
|
||||||
|
[0, 1, 0, 2, true], // default value
|
||||||
|
true, // isGlobal
|
||||||
|
{[QGVAR(proximityFuseFailureChance), _this] call EFUNC(common,cbaSettings_settingChanged)},
|
||||||
|
true // Needs mission restart
|
||||||
|
] call CBA_fnc_addSetting;
|
||||||
|
|
23
addons/iron_dome/script_component.hpp
Normal file
23
addons/iron_dome/script_component.hpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#define COMPONENT iron_dome
|
||||||
|
#define COMPONENT_BEAUTIFIED Iron Dome
|
||||||
|
#include "\z\ace\addons\main\script_mod.hpp"
|
||||||
|
|
||||||
|
// #define DRAW_TRACKING_INFO
|
||||||
|
// #define DEBUG_MODE_FULL
|
||||||
|
// #define DISABLE_COMPILE_CACHE
|
||||||
|
// #define ENABLE_PERFORMANCE_COUNTERS
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED_IRON_DOME
|
||||||
|
#define DEBUG_MODE_FULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG_SETTINGS_IRON_DOME
|
||||||
|
#define DEBUG_SETTINGS DEBUG_SETTINGS_IRON_DOME
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LAUNCH_STATE_IDLE 0
|
||||||
|
#define LAUNCH_STATE_TRACKING 1
|
||||||
|
#define LAUNCH_STATE_FIRING 2
|
||||||
|
#define LAUNCH_STATE_COOLDOWN 3
|
||||||
|
|
||||||
|
#include "\z\ace\addons\main\script_macros.hpp"
|
47
addons/iron_dome/stringtable.xml
Normal file
47
addons/iron_dome/stringtable.xml
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project name="ACE">
|
||||||
|
<Package name="IRON_DOME">
|
||||||
|
<Key ID="STR_ACE_IRON_DOME_enable_description">
|
||||||
|
<English>Enable the Iron Dome system</English>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_IRON_DOME_category">
|
||||||
|
<English>ACE Iron Dome</English>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_IRON_DOME_targetRecycleTime_setting">
|
||||||
|
<English>Target Recycle Time</English>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_IRON_DOME_targetRecycleTime_description">
|
||||||
|
<English>How many seconds until another launcher can consider firing at the target</English>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_IRON_DOME_launchAcceptableAngle_setting">
|
||||||
|
<English>Launch Acceptable Angle</English>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_IRON_DOME_launchAcceptableAngle_description">
|
||||||
|
<English>How many degrees offset the launcher can be before firing</English>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_IRON_DOME_launchAcceptableElevation_setting">
|
||||||
|
<English>Launch Acceptable Elevation</English>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_IRON_DOME_launchAcceptableElevation_description">
|
||||||
|
<English>The minimum number of degrees the launcher has to be pointing up/down before firing</English>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_IRON_DOME_timeBetweenLaunches_setting">
|
||||||
|
<English>Time Between Launches</English>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_IRON_DOME_timeBetweenLaunches_description">
|
||||||
|
<English>Minimum number of seconds between each launch of an interceptor for a single launcher</English>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_IRON_DOME_proximityFuseRange_setting">
|
||||||
|
<English>Proximity Fuse Range</English>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_IRON_DOME_proximityFuseRange_description">
|
||||||
|
<English>How close the interceptor has to be to the target in order to detonate</English>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_IRON_DOME_proximityFuseFailureChance_setting">
|
||||||
|
<English>Proximity Fuse Failure Chance</English>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_IRON_DOME_proximityFuseFailureChance_description">
|
||||||
|
<English>Chance for proximity fuse to fail to destroy target</English>
|
||||||
|
</Key>
|
||||||
|
</Package>
|
||||||
|
</Project>
|
Loading…
Reference in New Issue
Block a user