mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Laser guidance for all designators (#3308)
* Fix laser and missileguidance over water * Return a normalized vector in EFUNC(common,getTurretDirection) * Make laser dispersion simulation optional, default off * Prototype for ace_laser_designate * Remove vanilla laser handling from ace_laser in favor of the new code on ace_laser_designate * Simplify laser into one module Rewrite large parts of laser Merge laser_designate Delete lase_selfDesignate * Cleanup missile guidance * Headers, fix laser over water * Cleanup * Test * Change setting to scalar, more cleanup * Add seeker debug drawing
This commit is contained in:
parent
74dfa6ca33
commit
ab6fc8efca
@ -38,5 +38,5 @@ if (_pov == "pip0_pos") then {
|
|||||||
|
|
||||||
_povDir = _gunBeginPos vectorDiff _gunEndPos;
|
_povDir = _gunBeginPos vectorDiff _gunEndPos;
|
||||||
};
|
};
|
||||||
|
_povDir = vectorNormalized _povDir;
|
||||||
[_povPos, _povDir]
|
[_povPos, _povDir]
|
||||||
|
7
addons/laser/ACE_Settings.hpp
Normal file
7
addons/laser/ACE_Settings.hpp
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
class ACE_Settings {
|
||||||
|
class GVAR(dispersionCount) {
|
||||||
|
value = 2;
|
||||||
|
typeName = "SCALAR";
|
||||||
|
displayName = CSTRING(dispersionCount_displayName);
|
||||||
|
};
|
||||||
|
};
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
class Extended_PreStart_EventHandlers {
|
class Extended_PreStart_EventHandlers {
|
||||||
class ADDON {
|
class ADDON {
|
||||||
init = QUOTE(call COMPILE_FILE(XEH_preStart));
|
init = QUOTE(call COMPILE_FILE(XEH_preStart));
|
||||||
@ -7,20 +6,13 @@ class Extended_PreStart_EventHandlers {
|
|||||||
|
|
||||||
class Extended_PreInit_EventHandlers {
|
class Extended_PreInit_EventHandlers {
|
||||||
class ADDON {
|
class ADDON {
|
||||||
init = QUOTE(call COMPILE_FILE(XEH_pre_init));
|
init = QUOTE(call COMPILE_FILE(XEH_preInit));
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
class Extended_PostInit_EventHandlers {
|
class Extended_PostInit_EventHandlers {
|
||||||
class ADDON {
|
class ADDON {
|
||||||
init = QUOTE(call COMPILE_FILE(XEH_post_init));
|
init = QUOTE(call COMPILE_FILE(XEH_postInit));
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
class Extended_Init_EventHandlers {
|
|
||||||
class LaserTargetBase {
|
|
||||||
class ADDON {
|
|
||||||
init = QUOTE(_this call DFUNC(laser_init));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
@ -1,44 +1,31 @@
|
|||||||
class CfgVehicles {
|
class CfgVehicles {
|
||||||
class All;
|
class All;
|
||||||
|
|
||||||
class LaserTarget: All {
|
class LaserTarget: All {
|
||||||
// @TODO: Changing the model and simulation hides it, but THEN IT DOESNT SPAWN WTF!?
|
// @TODO: Changing the model and simulation hides it, but THEN IT DOESNT SPAWN WTF!?
|
||||||
model = "\A3\Weapons_F\empty.p3d";
|
// model = "\A3\Weapons_F\empty.p3d";
|
||||||
destrType = "DestructNo";
|
|
||||||
simulation = "LaserTarget";
|
|
||||||
|
|
||||||
class EventHandlers {
|
class EventHandlers {
|
||||||
init = QUOTE(_this call FUNC(laser_init));
|
class ADDON {
|
||||||
|
init = QUOTE(_this call FUNC(handleLaserTargetCreation));
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Visual laserTarget override
|
// laserTarget fails if the turret does not have "primaryGunner" config
|
||||||
class ACE_LaserTarget_Visual : LaserTarget {
|
// This only effects the indfor strider who's commander is not the primaryGunner
|
||||||
simulation = "LaserTarget";
|
class LandVehicle;
|
||||||
model = "\A3\Weapons_f\laserTgt.p3d";
|
class Car: LandVehicle {
|
||||||
|
class NewTurret;
|
||||||
};
|
};
|
||||||
|
class Car_F: Car {
|
||||||
// Vehicle lockable configurations
|
|
||||||
|
|
||||||
class AllVehicles;
|
|
||||||
class Air: AllVehicles {
|
|
||||||
class Turrets;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Helicopter: Air {
|
|
||||||
class Turrets {
|
class Turrets {
|
||||||
class MainTurret;
|
class MainTurret: NewTurret {};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
class MRAP_03_base_F: Car_F {
|
||||||
class Helicopter_Base_F: Helicopter {};
|
|
||||||
|
|
||||||
class Heli_Attack_01_base_F: Helicopter_Base_F {};
|
|
||||||
|
|
||||||
class B_Heli_Attack_01_F: Heli_Attack_01_base_F {
|
|
||||||
class Turrets: Turrets {
|
class Turrets: Turrets {
|
||||||
class MainTurret: MainTurret {
|
class CommanderTurret: MainTurret {
|
||||||
GVAR(CanLockLaser) = 1; // Enable laser locking selection
|
primaryGunner = 1;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -10,3 +10,5 @@ The people responsible for merging changes to this component or answering potent
|
|||||||
|
|
||||||
- [walterpearce](https://github.com/walterpearce)
|
- [walterpearce](https://github.com/walterpearce)
|
||||||
- [NouberNou](https://github.com/NouberNou)
|
- [NouberNou](https://github.com/NouberNou)
|
||||||
|
- [esteldunedain](https://github.com/esteldunedain)
|
||||||
|
- [PabstMirror](https://github.com/PabstMirror)
|
||||||
|
@ -1,26 +1,15 @@
|
|||||||
|
|
||||||
PREP(rotateVectLineGetMap);
|
PREP(addLaserTarget);
|
||||||
PREP(rotateVectLine);
|
PREP(dev_drawVisibleLaserTargets);
|
||||||
PREP(shootRay);
|
PREP(findLaserSource);
|
||||||
PREP(shootCone);
|
PREP(handleLaserTargetCreation);
|
||||||
PREP(checkLos);
|
PREP(keyLaserCodeChange);
|
||||||
|
|
||||||
PREP(findStrongestRay);
|
|
||||||
|
|
||||||
PREP(onLaserDesignatorDraw);
|
|
||||||
|
|
||||||
PREP(seekerFindLaserSpot);
|
|
||||||
PREP(laserOn);
|
|
||||||
PREP(laserOff);
|
PREP(laserOff);
|
||||||
PREP(handleLaserOn);
|
PREP(laserOn);
|
||||||
PREP(handleLaserOff);
|
|
||||||
|
|
||||||
PREP(drawVisibleLaserTargets);
|
|
||||||
|
|
||||||
PREP(laser_init);
|
|
||||||
PREP(vanillaLaserSeekerHandler);
|
|
||||||
PREP(laserTargetPFH);
|
PREP(laserTargetPFH);
|
||||||
|
PREP(onLaserDesignatorDraw);
|
||||||
PREP(unitTurretCanLockLaser);
|
PREP(rotateVectLine);
|
||||||
PREP(keyLaserCodeUp);
|
PREP(rotateVectLineGetMap);
|
||||||
PREP(keyLaserCodeDown);
|
PREP(seekerFindLaserSpot);
|
||||||
|
PREP(shootCone);
|
||||||
|
PREP(shootRay);
|
||||||
|
23
addons/laser/XEH_postInit.sqf
Normal file
23
addons/laser/XEH_postInit.sqf
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
#include "initKeybinds.sqf"
|
||||||
|
|
||||||
|
// Global Laser EHs
|
||||||
|
["ace_laserOn", {
|
||||||
|
params ["_uuid", "_args"];
|
||||||
|
TRACE_2("ace_laserOn eh",_uuid,_args);
|
||||||
|
[GVAR(laserEmitters), _uuid, _args] call CBA_fnc_hashSet;
|
||||||
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
|
["ace_laserOff", {
|
||||||
|
params ["_uuid"];
|
||||||
|
TRACE_1("ace_laserOn eh",_uuid);
|
||||||
|
if ([GVAR(laserEmitters), _uuid] call CBA_fnc_hashHasKey) then {
|
||||||
|
[GVAR(laserEmitters), _uuid] call CBA_fnc_hashRem;
|
||||||
|
};
|
||||||
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
|
// Shows detector and mine posistions in 3d when debug is on
|
||||||
|
#ifdef DRAW_LASER_INFO
|
||||||
|
addMissionEventHandler ["Draw3D", {_this call FUNC(dev_drawVisibleLaserTargets)}];
|
||||||
|
#endif
|
@ -1,7 +0,0 @@
|
|||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
#include "initKeybinds.sqf"
|
|
||||||
|
|
||||||
["ace_laserOn", {_this call DFUNC(handleLaserOn)}] call CBA_fnc_addEventHandler;
|
|
||||||
["ace_laserOff", {_this call DFUNC(handleLaserOff)}] call CBA_fnc_addEventHandler;
|
|
||||||
|
|
@ -4,13 +4,13 @@ ADDON = false;
|
|||||||
|
|
||||||
#include "XEH_PREP.hpp"
|
#include "XEH_PREP.hpp"
|
||||||
|
|
||||||
GVAR(VanillaLasers) = [];
|
|
||||||
|
|
||||||
// Laser default variables
|
// Laser default variables
|
||||||
ACE_DEFAULT_LASER_CODE = 1001;
|
ACE_DEFAULT_LASER_CODE = 1111;
|
||||||
ACE_DEFAULT_LASER_WAVELENGTH = 1550;
|
ACE_DEFAULT_LASER_WAVELENGTH = 1550;
|
||||||
ACE_DEFAULT_LASER_BEAMSPREAD = 1;
|
ACE_DEFAULT_LASER_BEAMSPREAD = 1;
|
||||||
|
|
||||||
GVAR(laserEmitters) = [] call CBA_fnc_hashCreate;
|
GVAR(laserEmitters) = [] call CBA_fnc_hashCreate;
|
||||||
|
GVAR(trackedLaserTargets) = [];
|
||||||
|
GVAR(pfehID) = -1;
|
||||||
|
|
||||||
ADDON = true;
|
ADDON = true;
|
@ -13,6 +13,7 @@ class CfgPatches {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#include "ACE_Settings.hpp"
|
||||||
#include "CfgEventhandlers.hpp"
|
#include "CfgEventhandlers.hpp"
|
||||||
#include "CfgVehicles.hpp"
|
#include "CfgVehicles.hpp"
|
||||||
#include "CfgWeapons.hpp"
|
#include "CfgWeapons.hpp"
|
||||||
|
59
addons/laser/functions/fnc_addLaserTarget.sqf
Normal file
59
addons/laser/functions/fnc_addLaserTarget.sqf
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Author: esteldunedain
|
||||||
|
* Adds a vanilla laser target to the tracker PFH and globaly turns it on
|
||||||
|
*
|
||||||
|
* Argument:
|
||||||
|
* 0: TargetObject (vanilla laser) <OBJECT>
|
||||||
|
* 1: Vehicle <OBJECT>
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [laserTarget player, player] call ace_laser_fnc_addLaserTarget;
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
params ["_targetObject", "_vehicle"];
|
||||||
|
TRACE_2("params",_targetObject,_vehicle);
|
||||||
|
|
||||||
|
// Get the designator variables, or use defaults
|
||||||
|
private _waveLength = _vehicle getVariable [QEGVAR(laser,waveLength), ACE_DEFAULT_LASER_WAVELENGTH];
|
||||||
|
private _laserCode = _vehicle getVariable [QEGVAR(laser,code), ACE_DEFAULT_LASER_CODE];
|
||||||
|
private _beamSpread = _vehicle getVariable [QEGVAR(laser,beamSpread), ACE_DEFAULT_LASER_BEAMSPREAD];
|
||||||
|
TRACE_3("codes",_waveLength,_laserCode,_beamSpread);
|
||||||
|
|
||||||
|
// Laser method is the method ACE_Laser will use to determine from where to where it should project the designator cone
|
||||||
|
_vehicle setVariable [QGVAR(targetObject), _targetObject, true];
|
||||||
|
|
||||||
|
private _laserMethod = QFUNC(findLaserSource);
|
||||||
|
|
||||||
|
private _vehicleSourceSelection = "";
|
||||||
|
if (_vehicle isKindOf "CaManBase") then {
|
||||||
|
_vehicleSourceSelection = "pilot";
|
||||||
|
} else {
|
||||||
|
{ // Go through turrets on vehicle and find the laser
|
||||||
|
private _turretPath = _x;
|
||||||
|
{
|
||||||
|
if ((getNumber (configFile >> "CfgWeapons" >> _x >> "laser")) > 0) exitWith {
|
||||||
|
_vehicleSourceSelection = getText (([_vehicle, _turretPath] call CBA_fnc_getTurret) >> "memoryPointGunnerOptics");
|
||||||
|
TRACE_3("",_turretPath,_x,_vehicleSourceSelection);
|
||||||
|
};
|
||||||
|
} forEach (_vehicle weaponsTurret _turretPath);
|
||||||
|
} forEach (allTurrets [_vehicle, true]);
|
||||||
|
};
|
||||||
|
|
||||||
|
private _methodArgs = [_vehicleSourceSelection];
|
||||||
|
|
||||||
|
TRACE_6("Laser on:",_vehicle,_laserMethod,_waveLength,_laserCode,_beamSpread,_methodArgs);
|
||||||
|
private _laserUuid = [_vehicle, _vehicle, _laserMethod, _waveLength, _laserCode, _beamSpread, _methodArgs] call FUNC(laserOn);
|
||||||
|
|
||||||
|
GVAR(trackedLaserTargets) pushBack [_targetObject, _vehicle, _laserUuid];
|
||||||
|
TRACE_1("",GVAR(trackedLaserTargets));
|
||||||
|
|
||||||
|
if (GVAR(pfehID) == -1) then {
|
||||||
|
TRACE_1("starting pfeh",count GVAR(trackedLaserTargets));
|
||||||
|
GVAR(pfehID) = [DFUNC(laserTargetPFH), 0, []] call CBA_fnc_addPerFrameHandler;
|
||||||
|
};
|
@ -1,28 +0,0 @@
|
|||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
params ["_pos1", "_pos2", "_designator", "_seeker"];
|
|
||||||
|
|
||||||
private _spacing = 100;
|
|
||||||
if((count _this) > 4) then {
|
|
||||||
_spacing = _this select 4;
|
|
||||||
};
|
|
||||||
|
|
||||||
private _return = true;
|
|
||||||
private _vectorTo = [_pos2, _pos1] call BIS_fnc_vectorFromXToY;
|
|
||||||
|
|
||||||
private _x = (_vectorTo select 0)*0.25;
|
|
||||||
private _y = (_vectorTo select 1)*0.25;
|
|
||||||
private _z = (_vectorTo select 2)*0.25;
|
|
||||||
|
|
||||||
_pos2 = [(_pos2 select 0) + _x, (_pos2 select 1) + _y, (_pos2 select 2) + _z];
|
|
||||||
|
|
||||||
// player sideChat format["new los check"];
|
|
||||||
if(terrainIntersect [_pos2, _pos1]) then {
|
|
||||||
_return = false;
|
|
||||||
} else {
|
|
||||||
if(lineIntersects [_pos2, _pos1]) then { // should take as arguments and add to this command objects to exclude - target and observer
|
|
||||||
// player sideChat format["with: %1", lineIntersectsWith [_pos1, _pos2]];
|
|
||||||
_return = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
_return;
|
|
61
addons/laser/functions/fnc_dev_drawVisibleLaserTargets.sqf
Normal file
61
addons/laser/functions/fnc_dev_drawVisibleLaserTargets.sqf
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
// Dev Debug Function
|
||||||
|
// Displays lasers and attempts to lock on to codes 1111 and 1112 from a target vehicle's view
|
||||||
|
// On Screen Debug:
|
||||||
|
// Red - Vanilla Laser Targets
|
||||||
|
// Yellow - Array (vehicle pos/weapon) Laser Targets
|
||||||
|
// Green - Rays
|
||||||
|
// Blue - Seeker Locks
|
||||||
|
|
||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
// Try searching for lasers from a given vehicle position [BLUE]:
|
||||||
|
private _seekerVehicle = vehicle ace_player;
|
||||||
|
private _testSeekerPosASL = AGLtoASL (_seekerVehicle modelToWorldVisual [0,0,1]);
|
||||||
|
private _testSeekerDir = vectorDirVisual _seekerVehicle;
|
||||||
|
{
|
||||||
|
private _code = _x;
|
||||||
|
private _results = [_testSeekerPosASL, _testSeekerDir, 45, [1550,1550], _code, _seekerVehicle] call FUNC(seekerFindLaserSpot);
|
||||||
|
private _resultPos = _results select 0;
|
||||||
|
if (!isNil "_resultPos") then {
|
||||||
|
// Draw lock results
|
||||||
|
drawLine3D [ASLtoAGL _testSeekerPosASL, ASLtoAGL _resultPos, [0,0,1,1]];
|
||||||
|
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [0,0,1,1], (ASLtoAGL _resultPos), 1.5, 1.5, 45, format ["%1 from %2", _code, _results select 1], 0.5, 0.025, "TahomaB"];
|
||||||
|
};
|
||||||
|
} forEach [1111, 1112]; // Scan at codes 1111 and 1112
|
||||||
|
|
||||||
|
|
||||||
|
// Draw all lasers
|
||||||
|
[GVAR(laserEmitters), {
|
||||||
|
// TRACE_2("",_key,_value);
|
||||||
|
_value params ["_obj", "_owner", "_laserMethod", "_waveLength", "_laserCode", "_beamSpread"];
|
||||||
|
|
||||||
|
// Draw vanila lasers [RED]
|
||||||
|
if (_laserMethod isEqualTo QFUNC(findLaserSource)) then { // Normal vanilla laserTarget func
|
||||||
|
private _targetObject = _obj getVariable [QGVAR(targetObject), objNull];
|
||||||
|
private _targetPosASL = getPosASL _targetObject;
|
||||||
|
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [1,0,0,1], (ASLtoAGL _targetPosASL), 0.5, 0.5, 0, "", 0.5, 0.025, "TahomaB"];
|
||||||
|
|
||||||
|
(_value call FUNC(findLaserSource)) params ["_laserPosASL", "_laserDir"];
|
||||||
|
private _resultsRay = [_laserPosASL, _laserDir, _obj] call FUNC(shootRay);
|
||||||
|
|
||||||
|
private _rayPos = _resultsRay select 0;
|
||||||
|
if (isNil "_rayPos") then {
|
||||||
|
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [1,0,0,1], (ASLtoAGL _targetPosASL), 2, 2, 0, "Nil Ray", 0.5, 0.025, "TahomaB"];
|
||||||
|
} else {
|
||||||
|
private _diff = _rayPos vectorDistance (getPosASL _targetObject); // Diff from ray position compared to actual
|
||||||
|
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [1,0,0,1], (ASLtoAGL _rayPos), 2, 2, 0, format ["Diff %1",_diff], 0.5, 0.025, "TahomaB"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
// Draw array weapon lasers [YELLOW]
|
||||||
|
if ((_laserMethod isEqualType []) && {(count _laserMethod) == 2}) then {
|
||||||
|
_laserMethod params ["_modelPosition", "_weaponName"];
|
||||||
|
private _laserPosASL = AGLtoASL (_obj modelToWorldVisual _modelPosition);
|
||||||
|
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [1,1,0,1], (ASLtoAGL _laserPosASL), 0.5, 0.5, 0, _weaponName, 0.5, 0.025, "TahomaB"];
|
||||||
|
private _laserDir = _obj weaponDirection _weaponName;
|
||||||
|
private _resultsRay = [_laserPosASL, _laserDir, _obj] call FUNC(shootRay);
|
||||||
|
private _rayPos = _resultsRay select 0;
|
||||||
|
if (!isNil "_rayPos") then {
|
||||||
|
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [1,1,0,1], (ASLtoAGL _rayPos), 2, 2, 0, _weaponName, 0.5, 0.025, "TahomaB"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}] call CBA_fnc_hashEachPair;
|
@ -1,9 +0,0 @@
|
|||||||
// This is a debug function for displaying visible lasers for ourselves
|
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
INFO("Laser Emitter Dump");
|
|
||||||
|
|
||||||
{
|
|
||||||
INFO_1(" %1", _x);
|
|
||||||
INFO_1(" %1",[ARR_2(GVAR(laserEmitters),_x)] call CBA_fnc_hashGet);
|
|
||||||
} forEach (GVAR(laserEmitters) select 1);
|
|
41
addons/laser/functions/fnc_findLaserSource.sqf
Normal file
41
addons/laser/functions/fnc_findLaserSource.sqf
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Author: esteldunedain
|
||||||
|
* Handler function for finding position and direction of a vanilla laser.
|
||||||
|
*
|
||||||
|
* Argument:
|
||||||
|
* 0: Vehicle (shooter of laser) <OBJECT>
|
||||||
|
* 6: Method Args <ARRAY>
|
||||||
|
* 0: Laser Source selection on Vehicle
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* [position, direction]
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [player, x,x,x,x,x, ["pilot"]] call ace_laser_fnc_findLaserSource;
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
params ["_vehicle", "", "", "", "", "", "_methodArgs"];
|
||||||
|
_methodArgs params ["_ownerSelection"];
|
||||||
|
|
||||||
|
// Get the laser target object stored in the unit
|
||||||
|
private _targetObject = _vehicle getVariable [QGVAR(targetObject), objNull];
|
||||||
|
private _targetPos = getPosASL _targetObject;
|
||||||
|
if (surfaceIsWater _targetPos && {(_targetPos select 2) < 0}) then {
|
||||||
|
// Vanilla lasers seem to give position at ocean floor heigh, even though the x and y are correct??
|
||||||
|
_targetPos set [2, 0.25];
|
||||||
|
};
|
||||||
|
|
||||||
|
private _povPos = AGLtoASL (_vehicle modelToWorldVisual (_vehicle selectionPosition _ownerSelection));
|
||||||
|
private _povDir = _povPos vectorFromTo _targetPos;
|
||||||
|
|
||||||
|
TRACE_4("",_vehicle,_targetObject,_povPos,_povDir);
|
||||||
|
|
||||||
|
if(isNil "_povPos" || isNil "_povDir") exitWith {
|
||||||
|
WARNING_2("bad data [%1][%2]",_povPos,_povDir);
|
||||||
|
[-1,-1]
|
||||||
|
};
|
||||||
|
|
||||||
|
[_povPos, _povDir]
|
@ -1,48 +0,0 @@
|
|||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
params ["_list", "_checkPos"];
|
|
||||||
private _spots = [];
|
|
||||||
private _outliers = [];
|
|
||||||
private _spot = [];
|
|
||||||
(_list select 0) params ["_testPos"];
|
|
||||||
{
|
|
||||||
_x params ["_samplePos"];
|
|
||||||
if(!lineIntersects [_samplePos, _checkPos] && {!terrainIntersectASL [_samplePos, _checkPos]}) then {
|
|
||||||
if(_samplePos distance _testPos < 2) then {
|
|
||||||
_spot pushBack _samplePos;
|
|
||||||
} else {
|
|
||||||
_outliers pushBack _samplePos;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
} forEach _list;
|
|
||||||
_spots pushBack _spot;
|
|
||||||
|
|
||||||
if(count _outliers > 0) then {
|
|
||||||
for "_i" from 1 to 3 do {
|
|
||||||
private _remainingSpots = _outliers;
|
|
||||||
_outliers = [];
|
|
||||||
_spot = [];
|
|
||||||
_testPos = (_remainingSpots select 0);
|
|
||||||
{
|
|
||||||
private _samplePos = _x;
|
|
||||||
if(!lineIntersects [_samplePos, _checkPos] && {!terrainIntersectASL [_samplePos, _checkPos]}) then {
|
|
||||||
if(_samplePos distance _testPos < 2) then {
|
|
||||||
_spot pushBack _samplePos;
|
|
||||||
} else {
|
|
||||||
_outliers pushBack _samplePos;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
} forEach _remainingSpots;
|
|
||||||
_spots pushBack _spot;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
private _largest = 0;
|
|
||||||
private _largestSpot = [];
|
|
||||||
{
|
|
||||||
if(count _x > _largest) then {
|
|
||||||
_largest = count _x;
|
|
||||||
_largestSpot = _x;
|
|
||||||
};
|
|
||||||
} forEach _spots;
|
|
||||||
// player sideChat format["g: %1", _spots];
|
|
||||||
_largestSpot select (random (floor(count _largestSpot)));
|
|
@ -1,7 +0,0 @@
|
|||||||
//fnc_handleLaserOff.sqf
|
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
params ["_uuid"];
|
|
||||||
if ([GVAR(laserEmitters), _uuid] call CBA_fnc_hashHasKey) then {
|
|
||||||
[GVAR(laserEmitters), _uuid] call CBA_fnc_hashRem;
|
|
||||||
};
|
|
@ -1,5 +0,0 @@
|
|||||||
//fnc_handleLaserOn.sqf
|
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
params ["_uuid", "_args"];
|
|
||||||
[GVAR(laserEmitters), _uuid, _args] call CBA_fnc_hashSet;
|
|
41
addons/laser/functions/fnc_handleLaserTargetCreation.sqf
Normal file
41
addons/laser/functions/fnc_handleLaserTargetCreation.sqf
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Author: esteldunedain
|
||||||
|
* Associates a newly created laser target to it's owner
|
||||||
|
*
|
||||||
|
* Argument:
|
||||||
|
* 0: Vanilla Laser (base type LaserTarget) <OBJECT>
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [laserTarget player] call ace_laser_fnc_handleLaserTargetCreation;
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
TRACE_1("params",_this);
|
||||||
|
[{
|
||||||
|
params ["_targetObject"];
|
||||||
|
|
||||||
|
// Only handle locally created lasers
|
||||||
|
if(!(local _targetObject)) exitWith {TRACE_1("not local",_targetObject);};
|
||||||
|
|
||||||
|
private _owners = allUnits select {(lasertarget _x) == _targetObject};
|
||||||
|
if (count _owners == 1) exitWith {
|
||||||
|
TRACE_2("Laser target owner [allUnits]", _targetObject, _owners select 0);
|
||||||
|
[_targetObject, _owners select 0] call FUNC(addLaserTarget);
|
||||||
|
};
|
||||||
|
|
||||||
|
_owners = vehicles select {(lasertarget _x) == _targetObject};
|
||||||
|
if (count _owners == 1) exitWith {
|
||||||
|
TRACE_2("Laser target owner [vehicles]", _targetObject, _owners select 0);
|
||||||
|
[_targetObject, _owners select 0] call FUNC(addLaserTarget);
|
||||||
|
};
|
||||||
|
|
||||||
|
TRACE_1("Laser target doesn't have owner", _targetObject);
|
||||||
|
}, _this] call CBA_fnc_execNextFrame;
|
59
addons/laser/functions/fnc_keyLaserCodeChange.sqf
Normal file
59
addons/laser/functions/fnc_keyLaserCodeChange.sqf
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Author: PabstMirror
|
||||||
|
* Change the laser key code (both seeker and transmitter)
|
||||||
|
*
|
||||||
|
* Argument:
|
||||||
|
* 0: Change in code <NUMBER>
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* Key Handled <BOOL>
|
||||||
|
|
||||||
|
* Example:
|
||||||
|
* [1] call ace_laser_fnc_keyLaserCodeChange;
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
params [["_codeChange", 0, [0]]];
|
||||||
|
|
||||||
|
TRACE_1("params",_codeChange);
|
||||||
|
|
||||||
|
if ((!alive ACE_player) || {!([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith))}) exitWith {false};
|
||||||
|
|
||||||
|
private _currentShooter = objNull;
|
||||||
|
private _currentWeapon = "";
|
||||||
|
|
||||||
|
if (ACE_player call CBA_fnc_canUseWeapon) then {
|
||||||
|
_currentShooter = ACE_player;
|
||||||
|
_currentWeapon = currentWeapon ACE_player;
|
||||||
|
} else {
|
||||||
|
_currentShooter = vehicle ACE_player;
|
||||||
|
private _turret = [ACE_player] call ace_common_fnc_getTurretIndex;
|
||||||
|
_currentWeapon = _currentShooter currentWeaponTurret _turret;
|
||||||
|
};
|
||||||
|
|
||||||
|
TRACE_2("",_currentShooter,_currentWeapon);
|
||||||
|
if ((getNumber (configFile >> "CfgWeapons" >> _currentWeapon >> "laser")) == 0) exitWith {false};
|
||||||
|
|
||||||
|
private _oldLaserCode = _currentShooter getVariable [QGVAR(code), ACE_DEFAULT_LASER_CODE];
|
||||||
|
private _newLaserCode = _oldLaserCode;
|
||||||
|
|
||||||
|
// "Four-digit code equipment settings range from 1111 to 1788"
|
||||||
|
// While there is a 0 or 9 in code, keep adding change
|
||||||
|
|
||||||
|
if (((_codeChange < 0) && {_oldLaserCode > ACE_DEFAULT_LASER_CODE}) || {(_codeChange > 0) && {_oldLaserCode < 1788}}) then {
|
||||||
|
_newLaserCode = _oldLaserCode + _codeChange;
|
||||||
|
while {(((str _newLaserCode) find "0") >= 0) || {((str _newLaserCode) find "9") >= 0}} do {
|
||||||
|
_newLaserCode = _newLaserCode + _codeChange;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
TRACE_2("",_oldLaserCode,_newLaserCode);
|
||||||
|
|
||||||
|
if (_oldLaserCode != _newLaserCode) then {
|
||||||
|
_currentShooter setVariable [QGVAR(code), _newLaserCode, false];
|
||||||
|
};
|
||||||
|
[format ["%1: %2", localize LSTRING(laserCode), _newLaserCode]] call EFUNC(common,displayTextStructured);
|
||||||
|
|
||||||
|
true
|
@ -1,12 +0,0 @@
|
|||||||
//#define DEBUG_MODE_FULL
|
|
||||||
#include "script_component.hpp"
|
|
||||||
private ["_oldLaserCode", "_laserCode"];
|
|
||||||
|
|
||||||
_oldLaserCode = ACE_player getVariable [QGVAR(code), ACE_DEFAULT_LASER_CODE];
|
|
||||||
if(_oldLaserCode > ACE_DEFAULT_LASER_CODE) then {
|
|
||||||
_laserCode = _oldLaserCode - 1;
|
|
||||||
ACE_player setVariable [QGVAR(code), _laserCode, false];
|
|
||||||
};
|
|
||||||
if(_laserCode != _oldLaserCode) then {
|
|
||||||
[format ["%1: %2", localize LSTRING(laserCode), _laserCode]] call EFUNC(common,displayTextStructured);
|
|
||||||
};
|
|
@ -1,10 +0,0 @@
|
|||||||
//#define DEBUG_MODE_FULL
|
|
||||||
#include "script_component.hpp"
|
|
||||||
private ["_oldLaserCode", "_laserCode"];
|
|
||||||
|
|
||||||
_oldLaserCode = ACE_player getVariable [QGVAR(code), ACE_DEFAULT_LASER_CODE];
|
|
||||||
_laserCode = _oldLaserCode + 1;
|
|
||||||
ACE_player setVariable [QGVAR(code), _laserCode, false];
|
|
||||||
if(_laserCode != _oldLaserCode) then {
|
|
||||||
[format ["%1: %2", localize LSTRING(laserCode), _laserCode]] call EFUNC(common,displayTextStructured);
|
|
||||||
};
|
|
@ -3,13 +3,20 @@
|
|||||||
* Turn a laser designator off.
|
* Turn a laser designator off.
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* 0: UUID (from laserOn) <string>
|
* 0: UUID (from laserOn) <STRING>
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Return value:
|
||||||
* None
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* ["yourLaserUID"] call ace_laser_fnc_laserOff;
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
|
|
||||||
params ["_uuid"];
|
params ["_uuid"];
|
||||||
|
|
||||||
|
TRACE_1("Sending Global Laser Off Event",_uuid);
|
||||||
|
|
||||||
["ace_laserOff", [_uuid]] call CBA_fnc_globalEvent;
|
["ace_laserOff", [_uuid]] call CBA_fnc_globalEvent;
|
||||||
|
@ -3,20 +3,33 @@
|
|||||||
* Turn a laser designator on.
|
* Turn a laser designator on.
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* 0: Emitter <object>
|
* 0: Emitter <OBJECT>
|
||||||
* 1: Owner <object>
|
* 1: Owner <OBJECT>
|
||||||
* 2: Method, can be code, which emitter and owner are passed to, a string function name, an array with a position memory point and weapon name, or an array with a position memory point, a vector begining memory point, and vector ending memory point.
|
* 2: Method, can be code, which emitter and owner are passed to, a string function name, an array with a position memory point and weapon name, or an array with a position memory point, a vector begining memory point, and vector ending memory point. <STRING><CODE><ARRAY>
|
||||||
* 3: Wavelength (1550nm is common eye safe) <number>
|
* 3: Wavelength (1550nm is common eye safe) <NUMBER>
|
||||||
* 4: Laser code <number>
|
* 4: Laser code <NUMBER>
|
||||||
* 5: Beam divergence (in mils off beam center).
|
* 5: Beam divergence (in mils off beam center). <NUMBER>
|
||||||
|
* 6: Method Args <OPTIONAL><ANY>
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* String, UUID for sending to laserOff function.
|
* <String> UUID for sending to laserOff function.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [hmg, hmg, [[0,0,1], "HMG_static"], 1550, 1111, 1] call ace_laser_fnc_laserOn;
|
||||||
|
* [player, player, "ace_laser_fnc_findLaserSource", 1550, 1111, 1, ["pilot"]] call ace_laser_fnc_laserOn;
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
// params [["_emitter", objNull, [objNull]],["_owner", objNull, [objNull]],["_method", "", ["", {}, []]],["_wavelength", 0, [0]],["_code", 0, [0]],["_beamSpread", 0, [0]],"_methodArgs"];
|
||||||
|
|
||||||
private _uuid = format["%1%2%3", floor diag_tickTime, floor random 1000, floor random 10000];
|
private _uuid = format["%1%2%3", floor diag_tickTime, floor random 1000, floor random 10000];
|
||||||
private _args = [_uuid, _this];
|
private _args = [_uuid, _this];
|
||||||
|
|
||||||
|
TRACE_2("Sending Global Laser On Event",_uuid,_this);
|
||||||
|
|
||||||
["ace_laserOn", _args] call CBA_fnc_globalEvent;
|
["ace_laserOn", _args] call CBA_fnc_globalEvent;
|
||||||
|
|
||||||
_uuid;
|
_uuid;
|
||||||
|
@ -1,27 +1,40 @@
|
|||||||
//#define DEBUG_MODE_FULL
|
/*
|
||||||
|
* Author: esteldunedain
|
||||||
|
* Maintains the tracked lasers, deleting any laser that is turned off
|
||||||
|
*
|
||||||
|
* Argument:
|
||||||
|
* PFEH Args
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [[], 1]] call ace_laser_fnc_laserTargetPFH;
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
TRACE_1("enter", _this);
|
|
||||||
|
|
||||||
//TRACE_1("enter", _this);
|
params ["", "_pfhuid"];
|
||||||
params ["_args"];
|
|
||||||
_args params ["_laserTarget", "_shooter", "_uuid"];
|
|
||||||
|
|
||||||
if(isNull _laserTarget || !alive _shooter) exitWith {
|
GVAR(trackedLaserTargets) = GVAR(trackedLaserTargets) select {
|
||||||
[(_this select 1)] call CBA_fnc_removePerFrameHandler;
|
_x params ["_targetObject", "_owner", "_laserUuid"];
|
||||||
REM(GVAR(VanillaLasers), _laserTarget);
|
if ((isNull _targetObject) ||
|
||||||
|
{!(alive _targetObject)} ||
|
||||||
|
{isNull _owner} ||
|
||||||
|
{!(alive _owner)}) then {
|
||||||
|
|
||||||
// Remove laseron
|
// Turn off the laser in ace_laser
|
||||||
[_uuid] call FUNC(laserOff);
|
[_laserUuid] call FUNC(laserOff);
|
||||||
|
TRACE_1("Laser off:", _laserUuid);
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef DEBUG_MODE_FULL
|
if (GVAR(trackedLaserTargets) isEqualTo []) then {
|
||||||
// Iconize the location of the actual laserTarget
|
TRACE_1("ending pfeh",count GVAR(trackedLaserTargets));
|
||||||
_pos = getPosASL _laserTarget;
|
[_pfhuid] call CBA_fnc_removePerFrameHandler;
|
||||||
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [1,0,0,1], (ASLtoATL _pos), 0.75, 0.75, 0, "", 0.5, 0.025, "TahomaB"];
|
GVAR(pfehID) = -1;
|
||||||
|
};
|
||||||
{
|
|
||||||
drawLine3D [ASLtoATL (_x select 0), ASLtoATL (_x select 1), (_x select 2)];
|
|
||||||
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", (_x select 2), ASLtoATL (_x select 1), 0.75, 0.75, 0, "", 0.5, 0.025, "TahomaB"];
|
|
||||||
} forEach DRAW_LINES;
|
|
||||||
DRAW_LINES = [];
|
|
||||||
#endif
|
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
//#define DEBUG_MODE_FULL
|
|
||||||
#include "script_component.hpp"
|
|
||||||
TRACE_1("enter", _this);
|
|
||||||
|
|
||||||
PARAMS_1(_laserTarget);
|
|
||||||
private ["_uuid"];
|
|
||||||
|
|
||||||
// Add the target to the global targets array
|
|
||||||
// Everyone tracks them
|
|
||||||
// Add the laser localized to the laser array, and give it the default localized code
|
|
||||||
PUSH(GVAR(VanillaLasers), _laserTarget);
|
|
||||||
|
|
||||||
// Check the vehicle, otherwise use the default
|
|
||||||
_laserTarget setVariable [QGVAR(code), ACE_DEFAULT_LASER_CODE, false];
|
|
||||||
_laserTarget setVariable [QGVAR(beamSpread), ACE_DEFAULT_LASER_BEAMSPREAD, false];
|
|
||||||
_laserTarget setVariable [QGVAR(waveLength), ACE_DEFAULT_LASER_WAVELENGTH, false];
|
|
||||||
|
|
||||||
// Clean the lasers of any null objects while we are here
|
|
||||||
REM(GVAR(VanillaLasers), objNull);
|
|
||||||
|
|
||||||
if(!(local _laserTarget)) exitWith { };
|
|
||||||
|
|
||||||
// The target is local, so its on this client
|
|
||||||
if(!isDedicated) then {
|
|
||||||
// @TODO: Get ownership variables and set them on the vehicle
|
|
||||||
|
|
||||||
_uuid = [(vehicle ACE_player), ACE_player, QFUNC(vanillaLaserSeekerHandler), ACE_DEFAULT_LASER_WAVELENGTH, ACE_DEFAULT_LASER_CODE, ACE_DEFAULT_LASER_BEAMSPREAD] call FUNC(laserOn);
|
|
||||||
_laserTarget setVariable [QGVAR(uuid), _uuid, false];
|
|
||||||
[FUNC(laserTargetPFH), 0, [_laserTarget, ACE_player, _uuid]] call CBA_fnc_addPerFrameHandler;
|
|
||||||
} else {
|
|
||||||
// server side ownership of laser
|
|
||||||
_laserTarget setVariable [QGVAR(owner), nil, true];
|
|
||||||
};
|
|
@ -1,15 +1,28 @@
|
|||||||
//#define DEBUG_MODE_FULL
|
/*
|
||||||
|
* Author: Nou
|
||||||
|
* Update distance when rangefinder laser is on
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [] call ace_laser_fnc_onLaserDesignatorDraw
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
private ["_laserCode"];
|
|
||||||
|
|
||||||
_laserCode = ACE_player getVariable[QGVAR(code), ACE_DEFAULT_LASER_CODE];
|
private _laserCode = ACE_player getVariable[QGVAR(code), ACE_DEFAULT_LASER_CODE];
|
||||||
if(!isNil "_laserCode") then {
|
if (!isNil "_laserCode") then {
|
||||||
__LaserDesignatorIGUI_LaserCode ctrlSetText format["Code: %1", [_laserCode, 4, 0, false] call CBA_fnc_formatNumber];
|
__LaserDesignatorIGUI_LaserCode ctrlSetText format["Code: %1", [_laserCode, 4, 0, false] call CBA_fnc_formatNumber];
|
||||||
};
|
};
|
||||||
|
|
||||||
if(! (ctrlShown __LaserDesignatorIGUI_LaserOn) ) then {
|
if (! (ctrlShown __LaserDesignatorIGUI_LaserOn) ) then {
|
||||||
// TODO: hide distance
|
// TODO: hide distance
|
||||||
__LaserDesignatorIGUI_ACE_Distance ctrlSetText "----";
|
__LaserDesignatorIGUI_ACE_Distance ctrlSetText "----";
|
||||||
} else {
|
} else {
|
||||||
__LaserDesignatorIGUI_ACE_Distance ctrlSetText (ctrlText __LaserDesignatorIGUI_CA_Distance);
|
__LaserDesignatorIGUI_ACE_Distance ctrlSetText (ctrlText __LaserDesignatorIGUI_CA_Distance);
|
||||||
};
|
};
|
||||||
|
@ -1,16 +1,9 @@
|
|||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
private ["_d", "_map", "_p", "_theta", "_u"];
|
|
||||||
_map = _this select 0;
|
|
||||||
_theta = _this select 1;
|
|
||||||
|
|
||||||
_p = _map select 0;
|
params ["_map", "_theta"];
|
||||||
_p1 = _map select 1;
|
_map params ["_p", "_p1", "_p2", "_q1", "_q2", "_u", "_d"];
|
||||||
_p2 = _map select 2;
|
_q1 = +_q1;
|
||||||
|
_q2 = +_q2;
|
||||||
_q1 = +(_map select 3);
|
|
||||||
_q2 = +(_map select 4);
|
|
||||||
_u = _map select 5;
|
|
||||||
_d = _map select 6;
|
|
||||||
|
|
||||||
/* Step 4 */
|
/* Step 4 */
|
||||||
_q2 set[0, (_q1 select 0) * cos(_theta) - (_q1 select 1) * sin(_theta)];
|
_q2 set[0, (_q1 select 0) * cos(_theta) - (_q1 select 1) * sin(_theta)];
|
||||||
@ -33,4 +26,4 @@ if (_d != 0) then {
|
|||||||
|
|
||||||
/* Inverse of step 1 */
|
/* Inverse of step 1 */
|
||||||
_q1 = _q2 vectorAdd _p1;
|
_q1 = _q2 vectorAdd _p1;
|
||||||
_q1;
|
_q1;
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
|
|
||||||
private ["_p", "_theta", "_p1", "_p2", "_q1", "_q2", "_u", "_d"];
|
params ["_p", "_p1", "_p2"];
|
||||||
_p = _this select 0;
|
|
||||||
_p1 = _this select 1;
|
|
||||||
_p2 = _this select 2;
|
|
||||||
|
|
||||||
_q2 = [];
|
private _q2 = [];
|
||||||
|
|
||||||
/* Step 1 */
|
/* Step 1 */
|
||||||
_q1 = _p vectorDiff _p1;
|
private _q1 = _p vectorDiff _p1;
|
||||||
_u = _p2 vectorDiff _p1;
|
private _u = _p2 vectorDiff _p1;
|
||||||
_u = vectorNormalized _u;
|
_u = vectorNormalized _u;
|
||||||
_d = sqrt((_u select 1)*(_u select 1) + (_u select 2)*(_u select 2));
|
private _d = sqrt((_u select 1)*(_u select 1) + (_u select 2)*(_u select 2));
|
||||||
|
|
||||||
/* Step 2 */
|
/* Step 2 */
|
||||||
if (_d != 0) then {
|
if (_d != 0) then {
|
||||||
@ -27,4 +24,4 @@ _q1 set[0, (_q2 select 0) * _d - (_q2 select 2) * (_u select 0)];
|
|||||||
_q1 set[1, (_q2 select 1)];
|
_q1 set[1, (_q2 select 1)];
|
||||||
_q1 set[2, (_q2 select 0) * (_u select 0) + (_q2 select 2) * _d];
|
_q1 set[2, (_q2 select 0) * (_u select 0) + (_q2 select 2) * _d];
|
||||||
|
|
||||||
[_p, _p1, _p2, _q1, _q2, _u, _d]
|
[_p, _p1, _p2, _q1, _q2, _u, _d]
|
||||||
|
@ -1,92 +1,116 @@
|
|||||||
/*
|
/*
|
||||||
* Author: Nou
|
* Author: Nou
|
||||||
* Turn a laser designator on.
|
* Searches for a laser spot given a seekers params.
|
||||||
|
* Provides the interface for Missile Guidance
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* 0: Position of seeker (ASL) <position>
|
* 0: Position of seeker (ASL) <ARRAY>
|
||||||
* 1: Direction vector (will be normalized) <vector>
|
* 1: Direction vector (will be normalized) <ARRAY>
|
||||||
* 2: Seeker FOV in degrees <number>
|
* 2: Seeker FOV in degrees <NUMBER>
|
||||||
* 3: Seeker wavelength sensitivity range, [1550,1550] is common eye safe. <array>
|
* 3: Seeker wavelength sensitivity range, [1550,1550] is common eye safe. <ARRAY>
|
||||||
* 4: Seeker laser code. <number>
|
* 4: Seeker laser code. <NUMBER>
|
||||||
|
* 5: Ignore 1 (e.g. Player's vehicle) <OPTIONAL><OBJECT>
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* Array, [Strongest compatible laser spot ASL pos, owner object] Nil array values if nothing found.
|
* Array, [Strongest compatible laser spot ASL pos, owner object] Nil array values if nothing found.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [getPosASL player, [0,1,0], 90, [1500, 1500], 1111, player] call ace_laser_fnc_seekerFindLaserSpot;
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
*/
|
*/
|
||||||
|
// #define DEBUG_MODE_FULL
|
||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
|
|
||||||
private ["_pos", "_seekerWavelengths", "_seekerCode", "_spots", "_buckets", "_excludes", "_bucketIndex", "_finalPos", "_owner", "_obj", "_x", "_method"];
|
BEGIN_COUNTER(seekerFindLaserSpot);
|
||||||
private ["_emitterWavelength", "_laserCode", "_divergence", "_laser", "_res", "_bucketPos", "_bucketList", "_c", "_forEachIndex", "_index"];
|
|
||||||
private ["_testPos", "_finalBuckets", "_largest", "_largestIndex", "_finalBucket", "_owners", "_avgX", "_avgY", "_avgZ", "_count", "_maxOwner", "_maxOwnerIndex", "_finalOwner"];
|
|
||||||
private ["_dir", "_seekerCos", "_seekerFov", "_testDotProduct", "_testPoint", "_testPointVector"];
|
|
||||||
|
|
||||||
_pos = _this select 0;
|
params ["_posASL", "_dir", "_seekerFov", "_seekerWavelengths", "_seekerCode", ["_ignoreObj1", objNull]];
|
||||||
_dir = vectorNormalized (_this select 1);
|
|
||||||
_seekerFov = _this select 2;
|
|
||||||
_seekerWavelengths = _this select 3;
|
|
||||||
_seekerCode = _this select 4;
|
|
||||||
|
|
||||||
|
_dir = vectorNormalized _dir;
|
||||||
|
_seekerWavelengths params ["_seekerWavelengthMin", "_seekerWavelengthMax"];
|
||||||
|
private _seekerCos = cos _seekerFov;
|
||||||
|
|
||||||
_seekerCos = cos _seekerFov;
|
TRACE_5("",_posASL,_dir,_seekerFov,_seekerWavelengths,_seekerCode);
|
||||||
|
|
||||||
_spots = [];
|
private _spots = [];
|
||||||
_buckets = [];
|
private _finalPos = nil;
|
||||||
_excludes = [];
|
private _finalOwner = objNull;
|
||||||
_bucketIndex = 0;
|
|
||||||
_finalPos = nil;
|
|
||||||
_finalOwner = nil;
|
|
||||||
|
|
||||||
|
// Go through all lasers in GVAR(laserEmitters)
|
||||||
{
|
{
|
||||||
_obj = _x select 0;
|
_x params ["_obj", "_owner", "_laserMethod", "_emitterWavelength", "_laserCode", "_divergence"];
|
||||||
_owner = _x select 1;
|
TRACE_6("laser",_obj,_owner,_laserMethod,_emitterWavelength,_laserCode,_divergence);
|
||||||
_method = _x select 2;
|
|
||||||
_emitterWavelength = _x select 3;
|
if (alive _obj && {_emitterWavelength >= _seekerWavelengthMin} && {_emitterWavelength <= _seekerWavelengthMax} && {_laserCode == _seekerCode}) then {
|
||||||
_laserCode = _x select 4;
|
|
||||||
_divergence = _x select 5;
|
private _laser = [];
|
||||||
if(alive _obj && {_emitterWavelength >= (_seekerWavelengths select 0)} && {_emitterWavelength <= (_seekerWavelengths select 1)} && {_laserCode == _seekerCode}) then {
|
// Find laser pos and dir of the laser depending on type
|
||||||
_laser = [];
|
if (IS_STRING(_laserMethod)) then {
|
||||||
if(IS_CODE(_method)) then {
|
_laser = _x call (missionNamespace getVariable [_laserMethod, []]);
|
||||||
_laser = _x call _method;
|
|
||||||
} else {
|
} else {
|
||||||
if(IS_STRING(_method)) then {
|
if (IS_CODE(_laserMethod)) then {
|
||||||
_laser = _x call (missionNamespace getVariable [_method, {}]);
|
_laser = _x call _laserMethod;
|
||||||
} else {
|
} else {
|
||||||
if(IS_ARRAY(_method)) then {
|
|
||||||
if(count _method == 2) then {
|
if (IS_ARRAY(_laserMethod)) then {
|
||||||
_laser = [ATLtoASL (_obj modelToWorldVisual (_method select 0)), _obj weaponDirection (_method select 1)];
|
if (count _laserMethod == 2) then { // [modelPosition, weaponName] for _obj
|
||||||
|
_laser = [AGLtoASL (_obj modelToWorldVisual (_laserMethod select 0)), _obj weaponDirection (_laserMethod select 1)];
|
||||||
} else {
|
} else {
|
||||||
if(count _method == 3) then {
|
if (count _laserMethod == 3) then {
|
||||||
_laser = [ATLtoASL (_obj modelToWorldVisual (_method select 0)), (ATLtoASL (_obj modelToWorldVisual (_method select 1))) vectorFromTo (ATLtoASL (_obj modelToWorldVisual (_method select 2)))];
|
_laser = [AGLtoASL (_obj modelToWorldVisual (_laserMethod select 0)), (AGLtoASL (_obj modelToWorldVisual (_laserMethod select 1))) vectorFromTo (AGLtoASL (_obj modelToWorldVisual (_laserMethod select 2)))];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
//Handle Weird Data Return
|
TRACE_1("",_laser);
|
||||||
if (_laser params [["_laserPos", [], [[]], 3], ["_laserDir", [], [[]], 3]]) then {
|
//Handle Weird Data Return - skips over this laser in the for loop
|
||||||
_res = [_laserPos, _laserDir, _divergence] call FUNC(shootCone);
|
if ((_laser isEqualTo []) || {_laser isEqualTo [-1, -1]}) exitWith {WARNING_1("Bad Laser Return",_laser);};
|
||||||
|
_laser params [["_laserPos", [], [[]], 3], ["_laserDir", [], [[]], 3]];
|
||||||
|
|
||||||
|
if (GVAR(dispersionCount) > 0) then {
|
||||||
|
// Shoot a cone with dispersion
|
||||||
|
([_laserPos, _laserDir, _divergence, GVAR(dispersionCount), _obj] call FUNC(shootCone)) params ["", "", "_resultPositions"];
|
||||||
{
|
{
|
||||||
_testPoint = _x select 0;
|
_testPoint = _x select 0;
|
||||||
_testPointVector = vectorNormalized (_testPoint vectorDiff _pos);
|
private _testPointVector = _posASL vectorFromTo _testPoint;
|
||||||
_testDotProduct = _dir vectorDotProduct _testPointVector;
|
private _testDotProduct = _dir vectorDotProduct _testPointVector;
|
||||||
if(_testDotProduct > _seekerCos) then {
|
if (_testDotProduct > _seekerCos) then {
|
||||||
_spots pushBack [_testPoint, _owner];
|
_spots pushBack [_testPoint, _owner];
|
||||||
};
|
};
|
||||||
} forEach (_res select 2);
|
} forEach _resultPositions;
|
||||||
|
} else {
|
||||||
|
// Shoot a single perfect ray from source to target (note, increased chance to "miss" on weird objects like bushes / rocks)
|
||||||
|
([_laserPos, _laserDir, _obj] call FUNC(shootRay)) params ["_resultPos", "_distance"];
|
||||||
|
TRACE_2("spot",_resultPos,_distance);
|
||||||
|
if (_distance > 0) then {
|
||||||
|
private _testPointVector = _posASL vectorFromTo _resultPos;
|
||||||
|
private _testDotProduct = _dir vectorDotProduct _testPointVector;
|
||||||
|
if (_testDotProduct > _seekerCos) then {
|
||||||
|
_spots pushBack [_resultPos, _owner];
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
} forEach (GVAR(laserEmitters) select 2);
|
} forEach (GVAR(laserEmitters) select 2); // Go through all values in hash
|
||||||
|
|
||||||
if((count _spots) > 0) then {
|
TRACE_2("",count _spots, _spots);
|
||||||
_bucketPos = nil;
|
|
||||||
_bucketList = nil;
|
if ((count _spots) > 0) then {
|
||||||
_c = 0;
|
private _bucketList = nil;
|
||||||
|
private _bucketPos = nil;
|
||||||
|
private _c = 0;
|
||||||
|
private _buckets = [];
|
||||||
|
private _excludes = [];
|
||||||
|
private _bucketIndex = 0;
|
||||||
|
|
||||||
|
// Put close points together into buckets
|
||||||
while { count(_spots) != count(_excludes) && _c < (count _spots) } do {
|
while { count(_spots) != count(_excludes) && _c < (count _spots) } do {
|
||||||
scopeName "mainSearch";
|
scopeName "mainSearch";
|
||||||
{
|
{
|
||||||
if(!(_forEachIndex in _excludes)) then {
|
if (!(_forEachIndex in _excludes)) then {
|
||||||
_index = _buckets pushBack [_x, [_x]];
|
private _index = _buckets pushBack [_x, [_x]];
|
||||||
_excludes pushBack _forEachIndex;
|
_excludes pushBack _forEachIndex;
|
||||||
_bucketPos = _x select 0;
|
_bucketPos = _x select 0;
|
||||||
_bucketList = (_buckets select _index) select 1;
|
_bucketList = (_buckets select _index) select 1;
|
||||||
@ -94,9 +118,9 @@ if((count _spots) > 0) then {
|
|||||||
};
|
};
|
||||||
} forEach _spots;
|
} forEach _spots;
|
||||||
{
|
{
|
||||||
if(!(_forEachIndex in _excludes)) then {
|
if (!(_forEachIndex in _excludes)) then {
|
||||||
_testPos = (_x select 0);
|
private _testPos = (_x select 0);
|
||||||
if(_testPos vectorDistanceSqr _bucketPos <= 100) then {
|
if ((_testPos vectorDistanceSqr _bucketPos) <= 100) then {
|
||||||
_bucketList pushBack _x;
|
_bucketList pushBack _x;
|
||||||
_excludes pushBack _forEachIndex;
|
_excludes pushBack _forEachIndex;
|
||||||
};
|
};
|
||||||
@ -104,55 +128,71 @@ if((count _spots) > 0) then {
|
|||||||
} forEach _spots;
|
} forEach _spots;
|
||||||
_c = _c + 1;
|
_c = _c + 1;
|
||||||
};
|
};
|
||||||
_finalBuckets = [];
|
|
||||||
_largest = -1;
|
TRACE_1("",_buckets);
|
||||||
_largestIndex = 0;
|
|
||||||
|
private _finalBuckets = [];
|
||||||
|
private _largest = -1;
|
||||||
|
private _largestIndex = 0;
|
||||||
{
|
{
|
||||||
_index = _finalBuckets pushBack [];
|
// find bucket with largest number of points we can see
|
||||||
|
private _index = _finalBuckets pushBack [];
|
||||||
_bucketList = _finalBuckets select _index;
|
_bucketList = _finalBuckets select _index;
|
||||||
{
|
{
|
||||||
_testPos = (_x select 0);
|
private _testPos = (_x select 0) vectorAdd [0,0,0.05];
|
||||||
if(!terrainIntersectASL [_pos, _testPos] && {!lineIntersects [_pos, _testPos]}) then {
|
private _testIntersections = lineIntersectsSurfaces [_posASL, _testPos, _ignoreObj1];
|
||||||
|
if ([] isEqualTo _testIntersections) then {
|
||||||
_bucketList pushBack _x;
|
_bucketList pushBack _x;
|
||||||
};
|
};
|
||||||
} forEach (_x select 1);
|
} forEach (_x select 1);
|
||||||
if((count _bucketList) > _largest) then {
|
if ((count _bucketList) > _largest) then {
|
||||||
_largest = (count _bucketList);
|
_largest = (count _bucketList);
|
||||||
_largestIndex = _index;
|
_largestIndex = _index;
|
||||||
};
|
};
|
||||||
} forEach _buckets;
|
} forEach _buckets;
|
||||||
|
|
||||||
_finalBucket = _finalBuckets select _largestIndex;
|
private _finalBucket = _finalBuckets select _largestIndex;
|
||||||
_owners = [] call CBA_fnc_hashCreate;
|
private _ownersHash = [] call CBA_fnc_hashCreate;
|
||||||
|
|
||||||
if(count _finalBucket > 0) then {
|
TRACE_2("",_finalBucket,_finalBuckets);
|
||||||
_avgX = 0;
|
|
||||||
_avgY = 0;
|
if (count _finalBucket > 0) then {
|
||||||
_avgZ = 0;
|
// merge all points in the best bucket into an average point and find effective owner
|
||||||
|
_finalPos = [0,0,0];
|
||||||
{
|
{
|
||||||
//player sideChat format["x: %1", _x];
|
_x params ["_xPos", "_owner"];
|
||||||
_avgX = _avgX + ((_x select 0) select 0);
|
_finalPos = _finalPos vectorAdd _xPos;
|
||||||
_avgY = _avgY + ((_x select 0) select 1);
|
if ([_ownersHash, _owner] call CBA_fnc_hashHasKey) then {
|
||||||
_avgZ = _avgZ + ((_x select 0) select 2);
|
private _count = [_ownersHash, _owner] call CBA_fnc_hashGet;
|
||||||
_owner = _x select 1;
|
[_ownersHash, _owner, _count + 1] call CBA_fnc_hashSet;
|
||||||
if ([_owners, _owner] call CBA_fnc_hashHasKey) then {
|
|
||||||
private _count = [_owners, _owner] call CBA_fnc_hashGet;
|
|
||||||
[_owners, _owner, _count + 1] call CBA_fnc_hashSet;
|
|
||||||
} else {
|
} else {
|
||||||
[_owners, _owner, 1] call CBA_fnc_hashSet;
|
[_ownersHash, _owner, 1] call CBA_fnc_hashSet;
|
||||||
};
|
};
|
||||||
} forEach _finalBucket;
|
} forEach _finalBucket;
|
||||||
_count = count _finalBucket;
|
|
||||||
_finalPos = [_avgX/_count, _avgY/_count, _avgZ/_count];
|
_finalPos = _finalPos vectorMultiply (1 / (count _finalBucket));
|
||||||
_maxOwner = -1;
|
|
||||||
_maxOwnerIndex = 0;
|
private _maxOwnerCount = -1;
|
||||||
{
|
|
||||||
if((_owners select 1) select _forEachIndex > _maxOwner) then {
|
[_ownersHash, {
|
||||||
_maxOwner = (_owners select 1) select _forEachIndex;
|
if (_value > _maxOwnerCount) then {
|
||||||
_maxOwnerIndex = _forEachIndex;
|
_finalOwner = _key;
|
||||||
};
|
};
|
||||||
} forEach (_owners select 0);
|
}] call CBA_fnc_hashEachPair;
|
||||||
_finalOwner = (_owners select 0) select _maxOwnerIndex;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
[_finalPos, _owner];
|
|
||||||
|
END_COUNTER(seekerFindLaserSpot);
|
||||||
|
|
||||||
|
#ifdef DRAW_LASER_INFO
|
||||||
|
if (isNil "_finalPos") then {
|
||||||
|
drawIcon3D ["\A3\ui_f\data\map\vehicleicons\iconMan_ca.paa", [0.9,1,0,1], (ASLtoAGL _posASL), 1, 1, 0, format ["Seeker: %1", _code], 0.5, 0.025, "TahomaB"];
|
||||||
|
} else {
|
||||||
|
drawIcon3D ["\A3\ui_f\data\map\vehicleicons\iconManAT_ca.paa", [0.5,1,0,1], (ASLtoAGL _posASL), 1, 1, 0, format ["Seeker: %1", _code], 0.5, 0.025, "TahomaB"];
|
||||||
|
drawLine3D [ASLtoAGL _posASL, ASLtoAGL _finalPos, [0.5,1,0,1]];
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TRACE_2("return",_finalPos,_finalOwner);
|
||||||
|
if (isNil "_finalPos") exitWith {[nil, _finalOwner]};
|
||||||
|
[_finalPos, _finalOwner];
|
||||||
|
@ -1,68 +1,71 @@
|
|||||||
#include "script_component.hpp"
|
/*
|
||||||
|
* Author: Nou
|
||||||
|
* Shoots multiple rays in a dispersion pattern
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 0: Origin position ASL <ARRAY>
|
||||||
|
* 1: Direction (normalized) <ARRAY>
|
||||||
|
* 2: Divergence (mils) <OPTIONAL><NUMBER>
|
||||||
|
* 3: Count at each divergence level <OPTIONAL><NUMBER>
|
||||||
|
* 4: Ignore vehicle 1 (e.g. Player's vehicle) <OPTIONAL><OBJECT>
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* <ARRAY> [_longestReturn, _shortestReturn, _resultPositions]
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [getPosASL player, [0,1,0]] call ace_laser_fnc_shootCone;
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
//#define DEBUG_MODE_FULL
|
//#define DEBUG_MODE_FULL
|
||||||
private ["_i", "_divergence","_pos","_vec","_longestReturn","_shortestReturn","_resultPositions","_p1","_p2","_p","_v","_cp","_vecRotateMap","_result", "_resultPos","_distance","_count","_pos2","_radOffset","_offset","_offsetPos","_offsetVector"];
|
#include "script_component.hpp"
|
||||||
_divergence = 0.3;
|
|
||||||
_pos = _this select 0;
|
|
||||||
_vec = _this select 1;
|
|
||||||
if(count _this > 2) then {
|
|
||||||
_divergence = _this select 2;
|
|
||||||
};
|
|
||||||
_count = 3;
|
|
||||||
if(count _this > 3) then {
|
|
||||||
_count = _this select 3;
|
|
||||||
};
|
|
||||||
_longestReturn = -1000000000;
|
|
||||||
_shortestReturn = 1000000000;
|
|
||||||
_resultPositions = [];
|
|
||||||
_p1 = [0,0,0];
|
|
||||||
_p2 = +_vec;
|
|
||||||
_p = (_vec call CBA_fnc_vect2polar);
|
|
||||||
_v = [(_p select 0), (_p select 1), (_p select 2)+90] call CBA_fnc_polar2vect;
|
|
||||||
_cp = _vec vectorCrossProduct _v;
|
|
||||||
|
|
||||||
_vecRotateMap = [_cp, _p1, _p2] call FUNC(rotateVectLineGetMap);
|
BEGIN_COUNTER(shootCone);
|
||||||
|
|
||||||
_result = [_pos, _vec] call FUNC(shootRay);
|
params ["_pos", "_vec", ["_divergence", 0.3], ["_count", 3], ["_ignoreObj1", objNull]];
|
||||||
_resultPos = _result select 0;
|
|
||||||
if(!isNil "_resultPos") then {
|
private _longestReturn = -1000000000;
|
||||||
_distance = _result select 1;
|
private _shortestReturn = 1000000000;
|
||||||
if(_distance < _shortestReturn) then {
|
private _resultPositions = [];
|
||||||
_shortestReturn = _distance;
|
private _p1 = [0,0,0];
|
||||||
};
|
private _p2 = +_vec;
|
||||||
if(_distance > _longestReturn) then {
|
private _p = (_vec call CBA_fnc_vect2polar);
|
||||||
_longestReturn = _distance;
|
private _v = [(_p select 0), (_p select 1), (_p select 2)+90] call CBA_fnc_polar2vect;
|
||||||
};
|
private _cp = _vec vectorCrossProduct _v;
|
||||||
|
|
||||||
|
private _vecRotateMap = [_cp, _p1, _p2] call FUNC(rotateVectLineGetMap);
|
||||||
|
|
||||||
|
// Check first with a perfect ray to the center
|
||||||
|
private _result = [_pos, _vec, _ignoreObj1] call FUNC(shootRay);
|
||||||
|
private _resultPos = _result select 0;
|
||||||
|
|
||||||
|
if (!isNil "_resultPos") then {
|
||||||
|
private _distance = _result select 1;
|
||||||
|
if (_distance < _shortestReturn) then { _shortestReturn = _distance; };
|
||||||
|
if (_distance > _longestReturn) then { _longestReturn = _distance; };
|
||||||
_resultPositions pushBack _result;
|
_resultPositions pushBack _result;
|
||||||
#ifdef DEBUG_MODE_FULL
|
|
||||||
// DRAW_LINES set[(count DRAW_LINES), [_pos, _resultPos, [0, 1, 0, 1]]];
|
|
||||||
drawLine3D [ASLtoATL _pos, ASLtoATL _resultPos, [1,0,0,1]];
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private _pos2 = _pos vectorAdd (_vec vectorMultiply 1000);
|
||||||
_pos2 = _pos vectorAdd (_vec vectorMultiply 1000);
|
// Try at 3 radius (full, half, quarter of specified divergence)
|
||||||
{
|
{
|
||||||
for "_i" from 0 to ceil(_count*_x) do {
|
private _radOffset = random 360;
|
||||||
_radOffset = random 360;
|
for "_i" from 1 to ceil(_count*_x) do { // Will always do at least 1
|
||||||
_offset = [_vecRotateMap, (((360/_count)*_i)+_radOffset) mod 360] call FUNC(rotateVectLine);
|
private _offset = [_vecRotateMap, (((360/_count)*_i)+_radOffset) mod 360] call FUNC(rotateVectLine);
|
||||||
_offsetPos = _pos2 vectorAdd (_offset vectorMultiply (_divergence*_x));
|
private _offsetPos = _pos2 vectorAdd (_offset vectorMultiply (_divergence*_x));
|
||||||
_offsetVector = _pos vectorFromTo _offsetPos;
|
|
||||||
_result = [_pos, _offsetVector] call FUNC(shootRay);
|
private _offsetVector = _pos vectorFromTo _offsetPos;
|
||||||
|
_result = [_pos, _offsetVector, _ignoreObj1] call FUNC(shootRay);
|
||||||
_resultPos = _result select 0;
|
_resultPos = _result select 0;
|
||||||
if(!isNil "_resultPos") then {
|
if (!isNil "_resultPos") then {
|
||||||
_distance = _result select 1;
|
private _distance = _result select 1;
|
||||||
if(_distance < _shortestReturn) then {
|
if (_distance < _shortestReturn) then { _shortestReturn = _distance; };
|
||||||
_shortestReturn = _distance;
|
if (_distance > _longestReturn) then { _longestReturn = _distance; };
|
||||||
};
|
|
||||||
if(_distance > _longestReturn) then {
|
|
||||||
_longestReturn = _distance;
|
|
||||||
};
|
|
||||||
_resultPositions pushBack _result;
|
_resultPositions pushBack _result;
|
||||||
#ifdef DEBUG_MODE_FULL
|
|
||||||
// DRAW_LINES set[(count DRAW_LINES), [_pos, _resultPos, [0, 1, 0, 1]]];
|
|
||||||
drawLine3D [ASLtoATL _pos, ASLtoATL _resultPos, [1,0,0,1]];
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
} forEach [1,0.5,0.25];
|
} forEach [1,0.5,0.25];
|
||||||
[_longestReturn, _shortestReturn, _resultPositions];
|
|
||||||
|
END_COUNTER(shootCone);
|
||||||
|
|
||||||
|
[_longestReturn, _shortestReturn, _resultPositions];
|
||||||
|
@ -1,24 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Author: Nou, PabstMirror
|
||||||
|
* Shoots a ray from a source to a direction and finds first intersction and distance
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 0: Origin position ASL <ARRAY>
|
||||||
|
* 1: Direction (normalized) <ARRAY>
|
||||||
|
* 2: Ignore 1 (e.g. Player's vehicle) <OPTIONAL><OBJECT>
|
||||||
|
* 2: Ignore 2 (e.g. Player's vehicle) <OPTIONAL><OBJECT>
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* <ARRAY> [posASL, distance] - pos will be nil if no intersection
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [getPosASL player, [0,1,0], player] call ace_laser_fnc_shootRay;
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
|
|
||||||
private ["_pos", "_vec", "_distance", "_resultPos", "_fidelity", "_lastPos", "_i", "_nextPos"];
|
BEGIN_COUNTER(shootRay);
|
||||||
scopeName "main";
|
|
||||||
_pos = _this select 0;
|
params ["_posASL", "_dir", ["_ignoreVehicle1", objNull], ["_ignoreVehicle2", objNull]];
|
||||||
_vec = _this select 1;
|
// TRACE_2("ray origin:", _posASL, _dir);
|
||||||
_distance = 0;
|
|
||||||
_resultPos = nil;
|
private _distance = 0;
|
||||||
_fidelity = [1000,100,10,1,0.1];
|
private _resultPos = nil;
|
||||||
_lastPos = +_pos;
|
|
||||||
{
|
private _farPoint = _posASL vectorAdd (_dir vectorMultiply 10000);
|
||||||
scopeName "mainSearch";
|
private _intersects = lineIntersectsSurfaces [_posASL, _farPoint, _ignoreVehicle1, _ignoreVehicle2];
|
||||||
for "_i" from 1 to 10 do {
|
|
||||||
_nextPos = _lastPos vectorAdd (_vec vectorMultiply _x);
|
if (!(_intersects isEqualTo [])) then {
|
||||||
if(terrainIntersectASL [_lastPos, _nextPos] || {lineIntersects [_lastPos, _nextPos]}) then {
|
(_intersects select 0) params ["_intersectPosASL", "", "_intersectObject"];
|
||||||
_resultPos = _lastPos;
|
// Move back slightly to prevents issues with it going below terrain
|
||||||
breakTo "mainSearch";
|
_distance = (_posASL vectorDistance _intersectPosASL) - 0.005;
|
||||||
} else {
|
_resultPos = _posASL vectorAdd (_dir vectorMultiply _distance);
|
||||||
_distance = _distance + _x;
|
};
|
||||||
_lastPos = _nextPos;
|
|
||||||
};
|
TRACE_3("", _resultPos, _distance, _intersects);
|
||||||
};
|
|
||||||
} forEach _fidelity;
|
#ifdef DRAW_LASER_INFO
|
||||||
[_resultPos, _distance];
|
if !(isNil "_resultPos") then {
|
||||||
|
private _text = [_distance, 4, 0] call CBA_fnc_formatNumber;
|
||||||
|
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0, 1, 0, 1], ASLtoAGL _resultPos, 0.5, 0.5, 0, _text, 0.4, 0.025, "TahomaB"];
|
||||||
|
drawLine3D [ASLtoAGL _posASL, ASLtoAGL _resultPos, [0,1,0,1]];
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
END_COUNTER(shootRay);
|
||||||
|
[_resultPos, _distance];
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
/*
|
|
||||||
* Author: jaynus
|
|
||||||
* Checks if the turret occupied by the given unit can lock a laser designator and select laser code.
|
|
||||||
*
|
|
||||||
* Arguments:
|
|
||||||
* 0: Unit <OBJECT>
|
|
||||||
*
|
|
||||||
* Return Value:
|
|
||||||
* Has designator? <BOOL>
|
|
||||||
*/
|
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
EXPLODE_1_PVT(_this,_unit);
|
|
||||||
|
|
||||||
// Get the player turret path
|
|
||||||
private ["_turret","_config","_turretConfig"];
|
|
||||||
_turret = [_unit] call EFUNC(common,getTurretIndex);
|
|
||||||
_config = configFile >> "CfgVehicles" >> typeOf vehicle _unit;
|
|
||||||
_turretConfig = [_config, _turret] call EFUNC(common,getTurretConfigPath);
|
|
||||||
|
|
||||||
getNumber (_turretConfig >> QGVAR(CanLockLaser)) > 0
|
|
@ -1,26 +0,0 @@
|
|||||||
/*
|
|
||||||
* Author: jaynus
|
|
||||||
* Handler function for laser network code.
|
|
||||||
*
|
|
||||||
* Arguments:
|
|
||||||
* 0: Emitter
|
|
||||||
* 1: Owner
|
|
||||||
*
|
|
||||||
* Return Value:
|
|
||||||
* [position, direction]
|
|
||||||
*/
|
|
||||||
//#define DEBUG_MODE_FULL
|
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
private ["_emmiter", "_owner", "_gunnerInfo", "_turretInfo", "_povPos", "_povDir"];
|
|
||||||
|
|
||||||
_emmiter = _this select 0;
|
|
||||||
_owner = _this select 1;
|
|
||||||
|
|
||||||
// Not in a vehicle....
|
|
||||||
// @TODO: handle lasering from turrets
|
|
||||||
if( (vehicle _emmiter) == _emmiter && alive _emmiter && (currentWeapon _emmiter) == "LaserDesignator") exitWith {
|
|
||||||
[(eyePos _emmiter), (eyeDirection _emmiter)]
|
|
||||||
};
|
|
||||||
|
|
||||||
[-1,-1]
|
|
@ -1,27 +1,16 @@
|
|||||||
|
|
||||||
|
|
||||||
["ACE3 Equipment", QGVAR(LaserCodeUp), localize LSTRING(laserCodeUp),
|
["ACE3 Equipment", QGVAR(LaserCodeUp), localize LSTRING(laserCodeUp),
|
||||||
{
|
{
|
||||||
if( EGVAR(laser_selfdesignate,active)
|
[1] call FUNC(keyLaserCodeChange);
|
||||||
||
|
|
||||||
{ (currentWeapon ACE_player) == "Laserdesignator" && (call CBA_fnc_getFoV) select 1 > 5 } // If laserdesignator & FOV, we are in scope.
|
|
||||||
||
|
|
||||||
{ [ACE_player] call FUNC(unitTurretCanLockLaser) }
|
|
||||||
) then {
|
|
||||||
[] call FUNC(keyLaserCodeUp);
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
{false},
|
{false},
|
||||||
[16, [false, true, true]], false, 0] call CBA_fnc_addKeybind; // (ALT+CTRL+Q)
|
[16, [false, true, true]], false, 0] call CBA_fnc_addKeybind; // (ALT+CTRL+Q)
|
||||||
|
|
||||||
["ACE3 Equipment", QGVAR(LaserCodeDown), localize LSTRING(laserCodeDown),
|
["ACE3 Equipment", QGVAR(LaserCodeDown), localize LSTRING(laserCodeDown),
|
||||||
{
|
{
|
||||||
if( EGVAR(laser_selfdesignate,active)
|
|
||||||
||
|
[-1] call FUNC(keyLaserCodeChange);
|
||||||
{ (currentWeapon ACE_player) == "Laserdesignator" && (call CBA_fnc_getFoV) select 1 > 5 } // If laserdesignator & FOV, we are in scope.
|
|
||||||
||
|
|
||||||
{ [ACE_player] call FUNC(unitTurretCanLockLaser) }
|
|
||||||
) then {
|
|
||||||
[] call FUNC(keyLaserCodeDown);
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
{false},
|
{false},
|
||||||
[18, [false, true, true]], false, 0] call CBA_fnc_addKeybind; // (ALT+CTRL+E)
|
[18, [false, true, true]], false, 0] call CBA_fnc_addKeybind; // (ALT+CTRL+E)
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define COMPONENT_BEAUTIFIED Laser
|
#define COMPONENT_BEAUTIFIED Laser
|
||||||
#include "\z\ace\addons\main\script_mod.hpp"
|
#include "\z\ace\addons\main\script_mod.hpp"
|
||||||
|
|
||||||
|
// #define DRAW_LASER_INFO
|
||||||
// #define DEBUG_MODE_FULL
|
// #define DEBUG_MODE_FULL
|
||||||
// #define DISABLE_COMPILE_CACHE
|
// #define DISABLE_COMPILE_CACHE
|
||||||
// #define ENABLE_PERFORMANCE_COUNTERS
|
// #define ENABLE_PERFORMANCE_COUNTERS
|
||||||
@ -17,9 +18,6 @@
|
|||||||
#include "\z\ace\addons\main\script_macros.hpp"
|
#include "\z\ace\addons\main\script_macros.hpp"
|
||||||
|
|
||||||
|
|
||||||
#define FIREMODE_DIRECT_LOAL 1
|
|
||||||
|
|
||||||
|
|
||||||
#define __LaserDesignatorIGUI (uiNamespace getVariable ["ACE_RscOptics_LaserDesignator", nil])
|
#define __LaserDesignatorIGUI (uiNamespace getVariable ["ACE_RscOptics_LaserDesignator", nil])
|
||||||
#define __LaserDesignatorIGUI_LaserCode (__LaserDesignatorIGUI displayCtrl 123001)
|
#define __LaserDesignatorIGUI_LaserCode (__LaserDesignatorIGUI displayCtrl 123001)
|
||||||
#define __LaserDesignatorIGUI_ACE_Distance (__LaserDesignatorIGUI displayCtrl 123002)
|
#define __LaserDesignatorIGUI_ACE_Distance (__LaserDesignatorIGUI displayCtrl 123002)
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project name="ACE">
|
<Project name="ACE">
|
||||||
<Package name="Laser">
|
<Package name="Laser">
|
||||||
|
<Key ID="STR_ACE_Laser_dispersionCount_displayName">
|
||||||
|
<English>Laser Dispersion Simulation Count</English>
|
||||||
|
</Key>
|
||||||
<Key ID="STR_ACE_Laser_laserCode">
|
<Key ID="STR_ACE_Laser_laserCode">
|
||||||
<English>Laser Code</English>
|
<English>Laser Code</English>
|
||||||
<German>Lasercode</German>
|
<German>Lasercode</German>
|
||||||
|
@ -1 +0,0 @@
|
|||||||
z\ace\addons\laser_selfdesignate
|
|
@ -1,26 +0,0 @@
|
|||||||
|
|
||||||
class Extended_PreStart_EventHandlers {
|
|
||||||
class ADDON {
|
|
||||||
init = QUOTE(call COMPILE_FILE(XEH_preStart));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
class Extended_PreInit_EventHandlers {
|
|
||||||
class ADDON {
|
|
||||||
init = QUOTE(call COMPILE_FILE(XEH_pre_init));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
class Extended_PostInit_EventHandlers {
|
|
||||||
class ADDON {
|
|
||||||
init = QUOTE(call COMPILE_FILE(XEH_post_init));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
class Extended_Init_EventHandlers {
|
|
||||||
class Helicopter {
|
|
||||||
class ADDON {
|
|
||||||
init = QUOTE(_this call DFUNC(initDesignatorActions));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
@ -1,49 +0,0 @@
|
|||||||
class CfgVehicles {
|
|
||||||
class AllVehicles;
|
|
||||||
class Air: AllVehicles {
|
|
||||||
class Turrets;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Helicopter: Air {
|
|
||||||
class Turrets {
|
|
||||||
class MainTurret;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
class Helicopter_Base_F: Helicopter {};
|
|
||||||
|
|
||||||
class Heli_Attack_01_base_F: Helicopter_Base_F {};
|
|
||||||
|
|
||||||
class B_Heli_Attack_01_F: Heli_Attack_01_base_F {
|
|
||||||
class Turrets: Turrets {
|
|
||||||
class MainTurret: MainTurret {
|
|
||||||
GVAR(Enabled) = 0; // Enable laser self-designation
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
class Plane: Air {};
|
|
||||||
class Plane_Base_F: Plane {
|
|
||||||
class Turrets {
|
|
||||||
class CopilotTurret;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/* @TODO: LGB GBU
|
|
||||||
class Plane_CAS_01_base_F: Plane_Base_F {
|
|
||||||
class Turrets: Turrets {
|
|
||||||
class MainTurret: MainTurret {
|
|
||||||
GVAR(Enabled) = 1; // Enable laser self-designation
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
class Plane_CAS_02_base_F: Plane_Base_F {
|
|
||||||
class Turrets: Turrets {
|
|
||||||
class MainTurret: MainTurret {
|
|
||||||
GVAR(Enabled) = 1; // Enable laser self-designation
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
};
|
|
@ -1,11 +0,0 @@
|
|||||||
class CfgWeapons {
|
|
||||||
// Disable locking unless newb mode
|
|
||||||
class LauncherCore;
|
|
||||||
class RocketPods: LauncherCore {
|
|
||||||
// canLock = 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
class missiles_DAGR: RocketPods {
|
|
||||||
//canLock = 1;
|
|
||||||
};
|
|
||||||
};
|
|
@ -1,12 +0,0 @@
|
|||||||
ace_laser_selfdesignate
|
|
||||||
=======================
|
|
||||||
|
|
||||||
Allows gunners to lase their own targets.
|
|
||||||
|
|
||||||
|
|
||||||
## Maintainers
|
|
||||||
|
|
||||||
The people responsible for merging changes to this component or answering potential questions.
|
|
||||||
|
|
||||||
- [walterpearce](https://github.com/walterpearce)
|
|
||||||
- [NouberNou](https://github.com/NouberNou)
|
|
@ -1,7 +0,0 @@
|
|||||||
|
|
||||||
PREP(initDesignatorActions);
|
|
||||||
PREP(laserHudDesignateOn);
|
|
||||||
PREP(laserHudDesignateOff);
|
|
||||||
PREP(unitTurretHasDesignator);
|
|
||||||
|
|
||||||
PREP(findLaserSource);
|
|
@ -1,2 +0,0 @@
|
|||||||
#include "script_component.hpp"
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
|||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
#include "XEH_PREP.hpp"
|
|
@ -1,11 +0,0 @@
|
|||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
ADDON = false;
|
|
||||||
|
|
||||||
#include "XEH_PREP.hpp"
|
|
||||||
|
|
||||||
GVAR(active) = false;
|
|
||||||
|
|
||||||
FUNC(getPosASL) = {visiblePositionASL (_this select 0)};
|
|
||||||
|
|
||||||
ADDON = true;
|
|
@ -1,18 +0,0 @@
|
|||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
class CfgPatches {
|
|
||||||
class ADDON {
|
|
||||||
name = COMPONENT_NAME;
|
|
||||||
units[] = {};
|
|
||||||
weapons[] = {};
|
|
||||||
requiredVersion = REQUIRED_VERSION;
|
|
||||||
requiredAddons[] = {"ace_laser"};
|
|
||||||
author = ECSTRING(common,ACETeam);
|
|
||||||
url = ECSTRING(main,URL);
|
|
||||||
VERSION_CONFIG;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#include "CfgEventhandlers.hpp"
|
|
||||||
#include "CfgWeapons.hpp"
|
|
||||||
#include "CfgVehicles.hpp"
|
|
@ -1,23 +0,0 @@
|
|||||||
/*
|
|
||||||
* Author: jaynus
|
|
||||||
* Handler function for laser network code.
|
|
||||||
*
|
|
||||||
* Arguments:
|
|
||||||
* 0: Emitter <OBJECT>
|
|
||||||
*
|
|
||||||
* Return Value:
|
|
||||||
* 0: position <ARRAY>
|
|
||||||
* 1: direction <ARRAY>
|
|
||||||
*
|
|
||||||
* Public: No
|
|
||||||
*/
|
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
private ["_gunnerInfo", "_turretInfo"];
|
|
||||||
params ["_emmiter"];
|
|
||||||
|
|
||||||
_gunnerInfo = [_emmiter, (currentWeapon _emmiter)] call CBA_fnc_getFirer;
|
|
||||||
_turretInfo = [_emmiter, _gunnerInfo select 1] call EFUNC(common,getTurretDirection);
|
|
||||||
_turretInfo params [["_povPos", -1], ["_povDir", -1]];
|
|
||||||
|
|
||||||
[_povPos, _povDir]
|
|
@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* Author: esteldunedain
|
|
||||||
* Initializes the actions for turning on/off the laser for vehicles that have them
|
|
||||||
*
|
|
||||||
* Arguments:
|
|
||||||
* 0: Vehicle <OBJECT>
|
|
||||||
*
|
|
||||||
* Return Value:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
* Public: No
|
|
||||||
*/
|
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
params ["_vehicle"];
|
|
||||||
|
|
||||||
// Add action to class if it is not already done
|
|
||||||
private ["_type", "_initializedClasses"];
|
|
||||||
_type = typeOf _vehicle;
|
|
||||||
_initializedClasses = GETGVAR(initializedClasses,[]);
|
|
||||||
|
|
||||||
// do nothing if the class is already initialized
|
|
||||||
if (_type in _initializedClasses) exitWith {};
|
|
||||||
_initializedClasses pushBack _type;
|
|
||||||
GVAR(initializedClasses) = _initializedClasses;
|
|
||||||
|
|
||||||
{
|
|
||||||
private ["_turretConfig","_onAction","_offAction"];
|
|
||||||
_turretConfig = [configFile >> "CfgVehicles" >> _type, _x] call EFUNC(common,getTurretConfigPath);
|
|
||||||
|
|
||||||
if (getNumber (_turretConfig >> QGVAR(Enabled)) == 1) exitWith {
|
|
||||||
// @todo: Add the state variables to the vehicle, instead of to the client
|
|
||||||
// e.g.: _vehicle setVariable [format ["%1_%2", QGVAR(active), _x], false];
|
|
||||||
|
|
||||||
// Add actions
|
|
||||||
_onAction = [QGVAR(LaserOn), localize LSTRING(DesignatorOn), "",
|
|
||||||
{
|
|
||||||
// Statement
|
|
||||||
_this call FUNC(laserHudDesignateOn)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// Condition
|
|
||||||
!GVAR(active) && {[ACE_player] call FUNC(unitTurretHasDesignator)}
|
|
||||||
}] call EFUNC(interact_menu,createAction);
|
|
||||||
|
|
||||||
_offAction = [QGVAR(LaserOff), localize LSTRING(DesignatorOff), "",
|
|
||||||
{
|
|
||||||
// Statement
|
|
||||||
_this call FUNC(laserHudDesignateOff)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// Condition
|
|
||||||
GVAR(active) && {[ACE_player] call FUNC(unitTurretHasDesignator)}
|
|
||||||
}] call EFUNC(interact_menu,createAction);
|
|
||||||
|
|
||||||
[_type, 1, ["ACE_SelfActions"], _onAction] call EFUNC(interact_menu,addActionToClass);
|
|
||||||
[_type, 1, ["ACE_SelfActions"], _offAction] call EFUNC(interact_menu,addActionToClass);
|
|
||||||
};
|
|
||||||
} forEach allTurrets _vehicle;
|
|
@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
* Author: jaynus
|
|
||||||
* Turns off passed laser self designation.
|
|
||||||
*
|
|
||||||
* Arguments:
|
|
||||||
* 0: Shooter, player shooting the laser
|
|
||||||
* 1: LaserUUID, the UUID of the laser returned by EFUNC(laser,laserOn)
|
|
||||||
* 2: Local laser target, unused.
|
|
||||||
*
|
|
||||||
* Return Value:
|
|
||||||
* True <BOOL>
|
|
||||||
*/
|
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
if( (count _this) > 2) then {
|
|
||||||
params ["", "_laserUuid"];
|
|
||||||
[_laserUuid] call EFUNC(laser,laserOff);
|
|
||||||
// @TODO: Nou gets to field all tickets about missing lasers.
|
|
||||||
//deleteVehicle _localLaserTarget;
|
|
||||||
};
|
|
||||||
|
|
||||||
GVAR(active) = false;
|
|
||||||
|
|
||||||
if(!isNil QGVAR(selfDesignateHandle)) then {
|
|
||||||
[GVAR(selfDesignateHandle)] call CBA_fnc_removePerFrameHandler;
|
|
||||||
GVAR(selfDesignateHandle) = nil;
|
|
||||||
};
|
|
||||||
|
|
||||||
true
|
|
@ -1,90 +0,0 @@
|
|||||||
/*
|
|
||||||
* Author: jaynus
|
|
||||||
* Turns on laser self designation from this vehicle based on the turret.
|
|
||||||
* There are no arguments, because it is all strictly based on the users vehicle.
|
|
||||||
*
|
|
||||||
* Arguments:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
* Return Value:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
* Public: No
|
|
||||||
*/
|
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
TRACE_1("enter", _this);
|
|
||||||
|
|
||||||
#define FCS_UPDATE_DELAY 1
|
|
||||||
|
|
||||||
FUNC(laserHudDesignatePFH) = {
|
|
||||||
private ["_strongestResultPos", "_args", "_localLaserTarget", "_laserResultPosition", "_laserResult", "_shooter", "_vehicle", "_weapon", "_gunnerInfo", "_turretInfo", "_pov", "_gunBeg", "_gunEnd", "_povPos", "_povDir", "_result", "_resultPositions", "_firstResult", "_forceUpdateTime"];
|
|
||||||
params ["_args"];
|
|
||||||
_args params ["_shooter", "_localLaserTarget"];
|
|
||||||
_vehicle = vehicle _shooter;
|
|
||||||
TRACE_1("", _args);
|
|
||||||
|
|
||||||
if((vehicle _shooter) == _shooter || {!alive _shooter} || {isNull _vehicle} || {!GVAR(active)} ) exitWith {
|
|
||||||
_args call FUNC(laserHudDesignateOff);
|
|
||||||
};
|
|
||||||
if(!([_shooter] call FUNC(unitTurretHasDesignator)) ) exitWith {
|
|
||||||
_args call FUNC(laserHudDesignateOff);
|
|
||||||
};
|
|
||||||
|
|
||||||
if( (count _args) < 4) then {
|
|
||||||
_args set[3, diag_tickTime + FCS_UPDATE_DELAY];
|
|
||||||
};
|
|
||||||
_forceUpdateTime = _args select 3;
|
|
||||||
|
|
||||||
// @TODO: We don't have anything here we need to do the calculations for right now
|
|
||||||
/*
|
|
||||||
|
|
||||||
_gunnerInfo = [_vehicle, (currentWeapon _vehicle)] call CBA_fnc_getFirer;
|
|
||||||
_turretInfo = [_vehicle, _gunnerInfo select 1] call EFUNC(common,getTurretDirection);
|
|
||||||
_povPos = _turretInfo select 0;
|
|
||||||
|
|
||||||
_laserCode = (vehicle ACE_player) getVariable["ace_laser_code", ACE_DEFAULT_LASER_CODE];
|
|
||||||
_waveLength = (vehicle ACE_player) getVariable["ace_laser_waveLength", ACE_DEFAULT_LASER_WAVELENGTH];
|
|
||||||
|
|
||||||
|
|
||||||
_laserResult = [_povPos, [_waveLength,_waveLength], _laserCode] call EFUNC(laser,seekerFindLaserSpot);
|
|
||||||
_laserResultPosition = _laserResult select 0;
|
|
||||||
TRACE_1("Search", _laserResult);
|
|
||||||
|
|
||||||
if((count _laserResult) > 0) then {
|
|
||||||
// @TODO: Nou gets to field all tickets about missing lasers.
|
|
||||||
//_localLaserTarget setPosASL _laserResultPosition;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
if(diag_tickTime > _forceUpdateTime) then {
|
|
||||||
["ace_fcs_forceUpdate", []] call ace_common_fnc_localEvent;
|
|
||||||
_args set[3, diag_tickTime + FCS_UPDATE_DELAY];
|
|
||||||
};
|
|
||||||
|
|
||||||
_this set[0, _args];
|
|
||||||
};
|
|
||||||
|
|
||||||
private ["_laserTarget", "_handle", "_vehicle", "_laserUuid", "_waveLength", "_beamSpread", "_laserCode"];
|
|
||||||
|
|
||||||
if(!GVAR(active)) then {
|
|
||||||
GVAR(active) = true;
|
|
||||||
|
|
||||||
TRACE_1("Activating laser", "");
|
|
||||||
|
|
||||||
// Get the self-designation variables, or use defaults
|
|
||||||
_laserCode = (vehicle ACE_player) getVariable["ace_laser_code", ACE_DEFAULT_LASER_CODE];
|
|
||||||
_waveLength = (vehicle ACE_player) getVariable["ace_laser_waveLength", ACE_DEFAULT_LASER_WAVELENGTH];
|
|
||||||
_beamSpread = (vehicle ACE_player) getVariable["ace_laser_beamSpread", ACE_DEFAULT_LASER_BEAMSPREAD];
|
|
||||||
|
|
||||||
_laserUuid = [(vehicle ACE_player), ACE_player, QFUNC(findLaserSource), _waveLength, _laserCode, _beamSpread] call EFUNC(laser,laserOn);
|
|
||||||
|
|
||||||
// @TODO: Create the local target for the players side
|
|
||||||
// @TODO: Nou gets to field all tickets about missing lasers.
|
|
||||||
//_localLaserTarget = "LaserTargetW" createVehicleLocal (getpos ACE_player);
|
|
||||||
|
|
||||||
GVAR(selfDesignateHandle) = [FUNC(laserHudDesignatePFH), 0.1, [ACE_player, _laserUuid, nil]] call CBA_fnc_addPerFrameHandler;
|
|
||||||
} else {
|
|
||||||
[] call FUNC(laserHudDesignateOff);
|
|
||||||
[] call FUNC(laserHudDesignateOn);
|
|
||||||
};
|
|
@ -1,23 +0,0 @@
|
|||||||
/*
|
|
||||||
* Author: esteldunedain
|
|
||||||
* Checks if the turret occupied by the given unit has a laser designator
|
|
||||||
*
|
|
||||||
* Arguments:
|
|
||||||
* 0: Unit <OBJECT>
|
|
||||||
*
|
|
||||||
* Return Value:
|
|
||||||
* Has unit designator <BOOL>
|
|
||||||
*
|
|
||||||
* Public: No
|
|
||||||
*/
|
|
||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
params ["_unit"];
|
|
||||||
|
|
||||||
// Get the player turret path
|
|
||||||
private ["_turret","_config","_turretConfig"];
|
|
||||||
_turret = [_unit] call EFUNC(common,getTurretIndex);
|
|
||||||
_config = configFile >> "CfgVehicles" >> typeOf vehicle _unit;
|
|
||||||
_turretConfig = [_config, _turret] call EFUNC(common,getTurretConfigPath);
|
|
||||||
|
|
||||||
getNumber (_turretConfig >> QGVAR(Enabled)) > 0
|
|
@ -1 +0,0 @@
|
|||||||
#include "\z\ace\addons\laser_selfdesignate\script_component.hpp"
|
|
@ -1,17 +0,0 @@
|
|||||||
#define COMPONENT laser_selfdesignate
|
|
||||||
#define COMPONENT_BEAUTIFIED Laser Selfdesignate
|
|
||||||
#include "\z\ace\addons\main\script_mod.hpp"
|
|
||||||
|
|
||||||
// #define DEBUG_MODE_FULL
|
|
||||||
// #define DISABLE_COMPILE_CACHE
|
|
||||||
// #define ENABLE_PERFORMANCE_COUNTERS
|
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED_LASER_SELFDESIGNATE
|
|
||||||
#define DEBUG_MODE_FULL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEBUG_SETTINGS_LASER_SELFDESIGNATE
|
|
||||||
#define DEBUG_SETTINGS DEBUG_SETTINGS_LASER_SELFDESIGNATE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "\z\ace\addons\main\script_macros.hpp"
|
|
@ -1,31 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project name="ACE">
|
|
||||||
<Package name="Laser_SelfDesignate">
|
|
||||||
<Key ID="STR_ACE_Laser_SelfDesignate_DesignatorOn">
|
|
||||||
<English>Laser Designator On</English>
|
|
||||||
<German>Lasermarkierer an</German>
|
|
||||||
<Spanish>Designador láser encendido</Spanish>
|
|
||||||
<Russian>ЛЦУ ВКЛ</Russian>
|
|
||||||
<Czech>Laserový značkovač zapnut</Czech>
|
|
||||||
<Polish>Desygnator laserowy wł.</Polish>
|
|
||||||
<French>Désignateur laser allumé</French>
|
|
||||||
<Hungarian>Lézeres Megjelölő Be</Hungarian>
|
|
||||||
<Italian>Designatore laser acceso</Italian>
|
|
||||||
<Portuguese>Designador Laser Ligado</Portuguese>
|
|
||||||
<Japanese>レーザー指示を起動</Japanese>
|
|
||||||
</Key>
|
|
||||||
<Key ID="STR_ACE_Laser_SelfDesignate_DesignatorOff">
|
|
||||||
<English>Laser Designator Off</English>
|
|
||||||
<German>Lasermarkierer aus</German>
|
|
||||||
<Spanish>Designador láser apagado</Spanish>
|
|
||||||
<Russian>ЛЦУ ВЫКЛ</Russian>
|
|
||||||
<Czech>Laserový značkovat vypnut</Czech>
|
|
||||||
<Polish>Desygnator laserowy wył.</Polish>
|
|
||||||
<French>Désignateur laser éteint</French>
|
|
||||||
<Hungarian>Lézeres Megjelölő Ki</Hungarian>
|
|
||||||
<Italian>Designatore laser spento</Italian>
|
|
||||||
<Portuguese>Designador Laser Desligado</Portuguese>
|
|
||||||
<Japanese>レーザー指示を停止</Japanese>
|
|
||||||
</Key>
|
|
||||||
</Package>
|
|
||||||
</Project>
|
|
@ -1,44 +1,7 @@
|
|||||||
enum {
|
|
||||||
ACE_LOBL = 1,
|
|
||||||
ACE_LOAL = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
class CfgAmmo {
|
class CfgAmmo {
|
||||||
class MissileBase;
|
class MissileBase;
|
||||||
|
|
||||||
class M_PG_AT: MissileBase {
|
class M_PG_AT: MissileBase {};
|
||||||
model = "\A3\Weapons_F\Ammo\Rocket_01_fly_F";
|
|
||||||
proxyShape = "\A3\Weapons_F\Ammo\Rocket_01_F";
|
|
||||||
|
|
||||||
// Reenable this settings when ACE laser targeting and missile guidance is reenabled
|
|
||||||
//laserLock = 1;
|
|
||||||
//airLock = 0;
|
|
||||||
//irLock = 0;
|
|
||||||
//weaponLockSystem = "4 + 16";
|
|
||||||
//fuseDistance = 2;
|
|
||||||
//timeToLive = 60;
|
|
||||||
// Turn off arma crosshair-guidance
|
|
||||||
//manualControl = 0;
|
|
||||||
// ACE uses these values
|
|
||||||
//trackOversteer = 1;
|
|
||||||
//trackLead = 0;
|
|
||||||
|
|
||||||
maxSpeed = 720;
|
|
||||||
maxControlRange = 5000;
|
|
||||||
maneuvrability = 8;
|
|
||||||
|
|
||||||
simulationStep = 0.01;
|
|
||||||
airFriction = 0.1;
|
|
||||||
sideAirFriction = 0.16;
|
|
||||||
initTime = 0.002;
|
|
||||||
thrustTime = 1.07;
|
|
||||||
thrust = 530;
|
|
||||||
|
|
||||||
effectsMissileInit = "MissileDAR1";
|
|
||||||
effectsMissile = "missile2";
|
|
||||||
whistleDist = 4;
|
|
||||||
muzzleEffect = "";
|
|
||||||
};
|
|
||||||
|
|
||||||
class ACE_Hydra70_DAGR: M_PG_AT {
|
class ACE_Hydra70_DAGR: M_PG_AT {
|
||||||
displayName = CSTRING(Hydra70_DAGR);
|
displayName = CSTRING(Hydra70_DAGR);
|
||||||
@ -47,13 +10,18 @@ class CfgAmmo {
|
|||||||
description = CSTRING(Hydra70_DAGR_Desc);
|
description = CSTRING(Hydra70_DAGR_Desc);
|
||||||
descriptionShort = CSTRING(Hydra70_DAGR_Desc);
|
descriptionShort = CSTRING(Hydra70_DAGR_Desc);
|
||||||
|
|
||||||
|
irLock = 0;
|
||||||
|
laserLock = 0;
|
||||||
|
manualControl = 0;
|
||||||
|
maxSpeed = 300;
|
||||||
|
|
||||||
EGVAR(rearm,caliber) = 70;
|
EGVAR(rearm,caliber) = 70;
|
||||||
|
|
||||||
class ADDON {
|
class ADDON {
|
||||||
enabled = 1;
|
enabled = 1;
|
||||||
|
|
||||||
minDeflection = 0.00025; // Minium flap deflection for guidance
|
minDeflection = 0.0005; // Minium flap deflection for guidance
|
||||||
maxDeflection = 0.001; // Maximum flap deflection for guidance
|
maxDeflection = 0.0025; // Maximum flap deflection for guidance
|
||||||
incDeflection = 0.0005; // The incrmeent in which deflection adjusts.
|
incDeflection = 0.0005; // The incrmeent in which deflection adjusts.
|
||||||
|
|
||||||
canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode
|
canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode
|
||||||
|
@ -1,24 +1,20 @@
|
|||||||
class CfgVehicles {
|
class CfgVehicles {
|
||||||
|
class Air;
|
||||||
class AllVehicles;
|
class Helicopter: Air {
|
||||||
class Air: AllVehicles {
|
|
||||||
class Turrets;
|
class Turrets;
|
||||||
};
|
};
|
||||||
|
class Helicopter_Base_F: Helicopter {
|
||||||
class Helicopter: Air {
|
|
||||||
class Turrets {
|
|
||||||
class MainTurret;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
class Helicopter_Base_F: Helicopter {};
|
|
||||||
class Heli_Attack_01_base_F: Helicopter_Base_F {};
|
|
||||||
class B_Heli_Attack_01_F : Heli_Attack_01_base_F {
|
|
||||||
class Turrets: Turrets {
|
class Turrets: Turrets {
|
||||||
class MainTurret;
|
class MainTurret;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
class Heli_Attack_01_base_F: Helicopter_Base_F {
|
||||||
class ACE_Comanche_Test : B_Heli_Attack_01_F {
|
class Turrets: Turrets {
|
||||||
|
class MainTurret: MainTurret {};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
class B_Heli_Attack_01_F: Heli_Attack_01_base_F {};
|
||||||
|
class ACE_Comanche_Test : B_Heli_Attack_01_F { // Comanche testbed (Hidden: Scope=1)
|
||||||
scope = 1;
|
scope = 1;
|
||||||
scopeCurator = 0;
|
scopeCurator = 0;
|
||||||
displayName = "ACE_Comanche_Test";
|
displayName = "ACE_Comanche_Test";
|
||||||
@ -28,9 +24,9 @@ class CfgVehicles {
|
|||||||
};
|
};
|
||||||
class Turrets: Turrets {
|
class Turrets: Turrets {
|
||||||
class MainTurret: MainTurret {
|
class MainTurret: MainTurret {
|
||||||
magazines[] = {"ACE_500Rnd_20mm_shells_Comanche", "24Rnd_ACE_Hellfire_AGM114K"};
|
weapons[] = {"gatling_20mm", "ace_missileguidance_dagr", "Laserdesignator_mounted"};
|
||||||
|
magazines[] = {"ACE_500Rnd_20mm_shells_Comanche", "6Rnd_ACE_Hydra70_DAGR", "Laserbatteries"};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
class Mode_SemiAuto;
|
|
||||||
class CfgWeapons {
|
class CfgWeapons {
|
||||||
class CannonCore;
|
class missiles_DAGR;
|
||||||
class LauncherCore;
|
|
||||||
|
|
||||||
class RocketPods: LauncherCore {
|
class GVAR(dagr): missiles_DAGR {
|
||||||
// canLock = 1;
|
canLock = 0;
|
||||||
};
|
magazines[] = {"6Rnd_ACE_Hydra70_DAGR","12Rnd_ACE_Hydra70_DAGR","24Rnd_ACE_Hydra70_DAGR"};
|
||||||
class missiles_DAGR : RocketPods {
|
lockingTargetSound[] = {"",0,1};
|
||||||
canLock = 2;
|
lockedTargetSound[] = {"",0,1};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -7,9 +7,9 @@
|
|||||||
#define STAGE_TERMINAL 4
|
#define STAGE_TERMINAL 4
|
||||||
|
|
||||||
EXPLODE_7_PVT(((_this select 1) select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
EXPLODE_7_PVT(((_this select 1) select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||||
private ["_targetPos", "_projectilePos", "_target", "_seekerTargetPos", "_launchParams", "_targetLaunchParams"];
|
private["_targetPos", "_projectilePos", "_target", "_seekerTargetPos", "_launchParams", "_targetLaunchParams"];
|
||||||
private ["_distanceToTarget", "_distanceToShooter", "_addHeight", "_returnTargetPos", "_state"];
|
private["_distanceToTarget", "_distanceToShooter", "_addHeight", "_returnTargetPos", "_state"];
|
||||||
private ["_cruisAlt", "_distanceShooterToTarget", "_shooterPos"];
|
private["_cruisAlt", "_distanceShooterToTarget", "_shooterPos"];
|
||||||
_seekerTargetPos = _this select 0;
|
_seekerTargetPos = _this select 0;
|
||||||
_launchParams = _this select 1;
|
_launchParams = _this select 1;
|
||||||
|
|
||||||
@ -37,19 +37,19 @@ switch( (_state select 0) ) do {
|
|||||||
case STAGE_LAUNCH: {
|
case STAGE_LAUNCH: {
|
||||||
TRACE_1("STAGE_LAUNCH","");
|
TRACE_1("STAGE_LAUNCH","");
|
||||||
if(_distanceToShooter < 10) then {
|
if(_distanceToShooter < 10) then {
|
||||||
_returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget * 2];
|
_returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget*2];
|
||||||
} else {
|
} else {
|
||||||
_state set [0, STAGE_CLIMB];
|
_state set[0, STAGE_CLIMB];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
case STAGE_CLIMB: {
|
case STAGE_CLIMB: {
|
||||||
TRACE_1("STAGE_CLIMB","");
|
TRACE_1("STAGE_CLIMB","");
|
||||||
_cruisAlt = 60 * (_distanceShooterToTarget/2000);
|
_cruisAlt = 60 * (_distanceShooterToTarget/2000);
|
||||||
|
|
||||||
if( ((ASLToATL _projectilePos) select 2) - ((ASLToATL _seekerTargetPos) select 2) >= _cruisAlt) then {
|
if( ((ASLToAGL _projectilePos) select 2) - ((ASLToAGL _seekerTargetPos) select 2) >= _cruisAlt) then {
|
||||||
_state set [0, STAGE_TERMINAL];
|
_state set[0, STAGE_TERMINAL];
|
||||||
} else {
|
} else {
|
||||||
_returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget * 1.5];
|
_returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget*1.5];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
case STAGE_TERMINAL: {
|
case STAGE_TERMINAL: {
|
||||||
@ -59,7 +59,7 @@ switch( (_state select 0) ) do {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#ifdef DEBUG_MODE_FULL
|
#ifdef DEBUG_MODE_FULL
|
||||||
drawLine3D [(ASLtoATL _returnTargetPos), (ASLtoATL _seekerTargetPos), [0, 1, 0, 1]];
|
drawLine3D [(ASLtoAGL _returnTargetPos), (ASLtoAGL _seekerTargetPos), [0,1,0,1]];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TRACE_1("Adjusted target position", _returnTargetPos);
|
TRACE_1("Adjusted target position", _returnTargetPos);
|
||||||
|
@ -7,9 +7,9 @@
|
|||||||
#define STAGE_TERMINAL 4
|
#define STAGE_TERMINAL 4
|
||||||
|
|
||||||
EXPLODE_7_PVT(((_this select 1) select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
EXPLODE_7_PVT(((_this select 1) select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||||
private ["_targetPos", "_projectilePos", "_target", "_seekerTargetPos", "_launchParams", "_targetLaunchParams"];
|
private["_targetPos", "_projectilePos", "_target", "_seekerTargetPos", "_launchParams", "_targetLaunchParams"];
|
||||||
private ["_distanceToTarget", "_distanceToShooter", "_addHeight", "_returnTargetPos", "_state"];
|
private["_distanceToTarget", "_distanceToShooter", "_addHeight", "_returnTargetPos", "_state"];
|
||||||
private ["_cruisAlt", "_distanceShooterToTarget", "_shooterPos"];
|
private["_cruisAlt", "_distanceShooterToTarget", "_shooterPos"];
|
||||||
|
|
||||||
_seekerTargetPos = _this select 0;
|
_seekerTargetPos = _this select 0;
|
||||||
_launchParams = _this select 1;
|
_launchParams = _this select 1;
|
||||||
@ -38,7 +38,7 @@ switch( (_state select 0) ) do {
|
|||||||
case STAGE_LAUNCH: {
|
case STAGE_LAUNCH: {
|
||||||
TRACE_1("STAGE_LAUNCH","");
|
TRACE_1("STAGE_LAUNCH","");
|
||||||
if(_distanceToShooter < 10) then {
|
if(_distanceToShooter < 10) then {
|
||||||
_returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget * 2];
|
_returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget*2];
|
||||||
} else {
|
} else {
|
||||||
_state set[0, STAGE_CLIMB];
|
_state set[0, STAGE_CLIMB];
|
||||||
};
|
};
|
||||||
@ -50,34 +50,34 @@ switch( (_state select 0) ) do {
|
|||||||
_cruisAlt = 140 * (_distanceShooterToTarget/1250);
|
_cruisAlt = 140 * (_distanceShooterToTarget/1250);
|
||||||
TRACE_1("_cruisAlt", _cruisAlt);
|
TRACE_1("_cruisAlt", _cruisAlt);
|
||||||
};
|
};
|
||||||
if(((ASLToATL _projectilePos) select 2) - ((ASLToATL _seekerTargetPos) select 2) >= _cruisAlt) then {
|
if( ((ASLToAGL _projectilePos) select 2) - ((ASLToAGL _seekerTargetPos) select 2) >= _cruisAlt) then {
|
||||||
if(_cruisAlt < 140) then {
|
if(_cruisAlt < 140) then {
|
||||||
_state set[0, STAGE_TERMINAL];
|
_state set[0, STAGE_TERMINAL];
|
||||||
} else {
|
} else {
|
||||||
_state set[0, STAGE_COAST];
|
_state set[0, STAGE_COAST];
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
_returnTargetPos = _seekerTargetPos vectorAdd [0, 0, _distanceToTarget * 1.5];
|
_returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget*1.5];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
case STAGE_COAST: {
|
case STAGE_COAST: {
|
||||||
TRACE_1("STAGE_COAST","");
|
TRACE_1("STAGE_COAST","");
|
||||||
TRACE_1("", ((ASLToATL _projectilePos) select 2) - (( ASLToATL _seekerTargetPos) select 2) );
|
TRACE_1("", ((ASLToAGL _projectilePos) select 2) - (( ASLToAGL _seekerTargetPos) select 2) );
|
||||||
if(_distanceToTarget < (((ASLToATL _projectilePos) select 2) - (( ASLToATL _seekerTargetPos) select 2)) * 1.5) then {
|
if(_distanceToTarget < ( ((ASLToAGL _projectilePos) select 2) - (( ASLToAGL _seekerTargetPos) select 2) ) * 1.5) then {
|
||||||
_state set[0, STAGE_TERMINAL];
|
_state set[0, STAGE_TERMINAL];
|
||||||
} else {
|
} else {
|
||||||
_returnTargetPos = _seekerTargetPos vectorAdd [0, 0, (_projectilePos select 2)];
|
_returnTargetPos = _seekerTargetPos vectorAdd [0,0,(_projectilePos select 2)];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
case STAGE_TERMINAL: {
|
case STAGE_TERMINAL: {
|
||||||
TRACE_1("STAGE_TERMINAL","");
|
TRACE_1("STAGE_TERMINAL","");
|
||||||
//_returnTargetPos = _seekerTargetPos vectorAdd [0, 0, _distanceToTarget * 0.02];
|
//_returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget * 0.02];
|
||||||
_returnTargetPos = _seekerTargetPos;
|
_returnTargetPos = _seekerTargetPos;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef DEBUG_MODE_FULL
|
#ifdef DEBUG_MODE_FULL
|
||||||
drawLine3D [(ASLtoATL _returnTargetPos), (ASLtoATL _seekerTargetPos), [0, 1, 0, 1]];
|
drawLine3D [(ASLtoAGL _returnTargetPos), (ASLtoAGL _seekerTargetPos), [0,1,0,1]];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TRACE_1("Adjusted target position", _returnTargetPos);
|
TRACE_1("Adjusted target position", _returnTargetPos);
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
|
|
||||||
EXPLODE_7_PVT(((_this select 1) select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
EXPLODE_7_PVT(((_this select 1) select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||||
private ["_targetPos", "_projectilePos", "_target", "_seekerTargetPos", "_launchParams", "_targetLaunchParams"];
|
private["_targetPos", "_projectilePos", "_target", "_seekerTargetPos", "_launchParams", "_targetLaunchParams"];
|
||||||
private ["_distanceToTarget", "_distanceToShooter", "_addHeight", "_returnTargetPos", "_shooterPos"];
|
private["_distanceToTarget", "_distanceToShooter", "_addHeight", "_returnTargetPos", "_shooterPos"];
|
||||||
_seekerTargetPos = _this select 0;
|
_seekerTargetPos = _this select 0;
|
||||||
_launchParams = _this select 1;
|
_launchParams = _this select 1;
|
||||||
|
|
||||||
@ -13,7 +13,7 @@ _targetLaunchParams = _launchParams select 1;
|
|||||||
_shooterPos = getPosASL _shooter;
|
_shooterPos = getPosASL _shooter;
|
||||||
_projectilePos = getPosASL _projectile;
|
_projectilePos = getPosASL _projectile;
|
||||||
|
|
||||||
_distanceToTarget = _projectilePos vectorDistance _seekerTargetPos;
|
_distanceToTarget = _projectilePos vectorDistance _seekerTargetPos;
|
||||||
_distanceToShooter = _projectilePos vectorDistance _shooterPos;
|
_distanceToShooter = _projectilePos vectorDistance _shooterPos;
|
||||||
|
|
||||||
TRACE_3("", _distanceToTarget, _distanceToShooter, _seekerTargetPos);
|
TRACE_3("", _distanceToTarget, _distanceToShooter, _seekerTargetPos);
|
||||||
@ -22,7 +22,7 @@ TRACE_3("", _distanceToTarget, _distanceToShooter, _seekerTargetPos);
|
|||||||
_addHeight = [0,0,0];
|
_addHeight = [0,0,0];
|
||||||
|
|
||||||
// Always climb an arc on initial launch if we are close to the round
|
// Always climb an arc on initial launch if we are close to the round
|
||||||
if( ((ASLtoATL _projectilePos) select 2) < 5 && _distanceToShooter < 15) then {
|
if( ((ASLtoAGL _projectilePos) select 2) < 5 && _distanceToShooter < 15) then {
|
||||||
_addHeight = _addHeight vectorAdd [0,0,_distanceToTarget];
|
_addHeight = _addHeight vectorAdd [0,0,_distanceToTarget];
|
||||||
} else {
|
} else {
|
||||||
// If we are below the target, increase the climbing arc
|
// If we are below the target, increase the climbing arc
|
||||||
@ -43,8 +43,8 @@ if( (_projectilePos select 2) > (_seekerTargetPos select 2) && _distanceToTarget
|
|||||||
_returnTargetPos = _seekerTargetPos vectorAdd _addHeight;
|
_returnTargetPos = _seekerTargetPos vectorAdd _addHeight;
|
||||||
|
|
||||||
#ifdef DEBUG_MODE_FULL
|
#ifdef DEBUG_MODE_FULL
|
||||||
drawLine3D [(ASLtoATL _returnTargetPos) vectorAdd _addHeight, ASLtoATL _returnTargetPos, [0,1,0,1]];
|
drawLine3D [(ASLtoAGL _returnTargetPos) vectorAdd _addHeight, ASLtoAGL _returnTargetPos, [0,1,0,1]];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TRACE_1("Adjusted target position", _returnTargetPos);
|
TRACE_1("Adjusted target position", _returnTargetPos);
|
||||||
_returnTargetPos;
|
_returnTargetPos;
|
||||||
|
@ -58,7 +58,7 @@ _adjustVector = _targetVector vectorDiff (vectorDir _projectile);
|
|||||||
|
|
||||||
_yaw = 0;
|
_yaw = 0;
|
||||||
_pitch = 0;
|
_pitch = 0;
|
||||||
_roll = 0;
|
_roll = 0;
|
||||||
if((_adjustVector select 0) < 0) then {
|
if((_adjustVector select 0) < 0) then {
|
||||||
_yaw = - ( (_minDeflection max (abs(_adjustVector select 0) min _maxDeflection) ) );
|
_yaw = - ( (_minDeflection max (abs(_adjustVector select 0) min _maxDeflection) ) );
|
||||||
} else {
|
} else {
|
||||||
@ -90,17 +90,17 @@ if(accTime > 0) then {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#ifdef DEBUG_MODE_FULL
|
#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"];
|
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,1,1,1], ASLtoAGL _projectilePos, 0.75, 0.75, 0, str _vectorTo, 1, 0.025, "TahomaB"];
|
||||||
drawLine3D [ASLtoATL _projectilePos, ASLtoATL _profileAdjustedTargetPos, [1,0,0,1]];
|
drawLine3D [ASLtoAGL _projectilePos, ASLtoAGL _profileAdjustedTargetPos, [1,0,0,1]];
|
||||||
|
|
||||||
_ps = "#particlesource" createVehicleLocal (ASLtoATL _projectilePos);
|
_ps = "#particlesource" createVehicleLocal (ASLtoAGL _projectilePos);
|
||||||
_PS setParticleParams [["\A3\Data_f\cl_basic", 8, 3, 1], "", "Billboard", 1, 3.0141, [0, 0, 2], [0, 0, 0], 1, 1.275, 1, 0, [1, 1], [[1, 0, 0, 1], [1, 0, 0, 1], [1, 0, 0, 1]], [1], 1, 0, "", "", nil];
|
_PS setParticleParams [["\A3\Data_f\cl_basic", 8, 3, 1], "", "Billboard", 1, 3.0141, [0, 0, 2], [0, 0, 0], 1, 1.275, 1, 0, [1, 1], [[1, 0, 0, 1], [1, 0, 0, 1], [1, 0, 0, 1]], [1], 1, 0, "", "", nil];
|
||||||
_PS setDropInterval 3.0;
|
_PS setDropInterval 3.0;
|
||||||
|
|
||||||
hintSilent format["d: %1", _distanceToTarget];
|
//hintSilent format["d: %1", _distanceToTarget];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_stateParams set[0, diag_tickTime];
|
_stateParams set[0, diag_tickTime];
|
||||||
|
|
||||||
_args set[4, _stateParams];
|
_args set[4, _stateParams];
|
||||||
_this set[0, _args];
|
_this set[0, _args];
|
||||||
|
@ -1,32 +1,32 @@
|
|||||||
//#define DEBUG_MODE_FULL
|
// #define DEBUG_MODE_FULL
|
||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
|
|
||||||
EXPLODE_7_PVT(((_this select 1) select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
params ["_lastSeekTargetPos", "_args"];
|
||||||
private ["_angleFov", "_canSeeTarget", "_foundTargetPos", "_laserResult", "_launchParams", "_seekerParams", "_laserCode", "_laserParams", "_seekerTargetPos", "_sensorPos", "_target"];
|
_args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams"];
|
||||||
_seekerTargetPos = _this select 0;
|
_firedEH params ["_shooter","_weapon","_muzzle","_mode","_ammo","_magazine","_projectile"];
|
||||||
_launchParams = _this select 1;
|
_launchParams params ["","","","","","_laserParams"];
|
||||||
_seekerParams = _launchParams select 3;
|
_seekerParams params ["_seekerAngle", "", "_seekerMaxRange"];
|
||||||
_angleFov = _seekerParams select 0;
|
_laserParams params ["_code", "_wavelengthMin", "_wavelengthMax"];
|
||||||
|
|
||||||
_laserParams = (_launchParams select 1) select 5;
|
private "_foundTargetPos";
|
||||||
TRACE_2("", _launchParams, _laserParams);
|
|
||||||
if(!isNil "_target") then {
|
if (!isNil "_target") then {
|
||||||
// Handle AI or moving vanilla lasers
|
// Handle AI or moving vanilla lasers
|
||||||
_foundTargetPos = getPosASL _target;
|
_foundTargetPos = getPosASL _target;
|
||||||
} else {
|
} else {
|
||||||
_laserResult = [(getPosASL _projectile), (velocity _projectile), _angleFov, [(_laserParams select 1),(_laserParams select 2)], (_laserParams select 0)] call EFUNC(laser,seekerFindLaserSpot);
|
private _laserResult = [(getPosASL _projectile), (velocity _projectile), _seekerAngle, [_wavelengthMin, _wavelengthMax], _code, _projectile] call EFUNC(laser,seekerFindLaserSpot);
|
||||||
_foundTargetPos = _laserResult select 0;
|
_foundTargetPos = _laserResult select 0;
|
||||||
TRACE_1("Search", _laserResult);
|
TRACE_1("Search", _laserResult);
|
||||||
};
|
};
|
||||||
|
|
||||||
if(!isNil "_foundTargetPos") then {
|
if(!isNil "_foundTargetPos") then {
|
||||||
//_canSeeTarget = [_projectile, _foundTargetPos, _angleFov] call FUNC(checkSeekerAngle);
|
// Fov is already checked by laser func, check if distance
|
||||||
|
|
||||||
|
private _canSeeTarget = _seekerMaxRange >= (_foundTargetPos vectorDistance (getPosASL _projectile));
|
||||||
// If we got here, it was an invalid target, just return a spot 5m in front of the missile
|
// If we got here, it was an invalid target, just return a spot 5m in front of the missile
|
||||||
if(!_canSeeTarget) then {
|
if(!_canSeeTarget) then {
|
||||||
_foundTargetPos = _sensorPos vectorAdd ((velocity _projectile) vectorMultiply 5);
|
_foundTargetPos = _sensorPos vectorAdd ((velocity _projectile) vectorMultiply 5);
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
_foundTargetPos;
|
_foundTargetPos;
|
||||||
|
@ -33,7 +33,7 @@ GVAR(distanceIndex) = -1;
|
|||||||
[_this select 1] call CBA_fnc_removePerFrameHandler;
|
[_this select 1] call CBA_fnc_removePerFrameHandler;
|
||||||
};
|
};
|
||||||
|
|
||||||
_result = [eyePos ACE_player, ACE_player weaponDirection (currentWeapon ACE_player)] call EFUNC(laser,shootRay);
|
_result = [eyePos ACE_player, ACE_player weaponDirection (currentWeapon ACE_player), ACE_player] call EFUNC(laser,shootRay);
|
||||||
_distance = _result select 1;
|
_distance = _result select 1;
|
||||||
|
|
||||||
_distance = _distance - 1 + (random 2);
|
_distance = _distance - 1 + (random 2);
|
||||||
|
Loading…
Reference in New Issue
Block a user