-
Notifications
You must be signed in to change notification settings - Fork 740
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Marking Laser - IR marking laser for aircraft (#7761)
Co-authored-by: PabstMirror <[email protected]> Co-authored-by: Jouni Järvinen <[email protected]> Co-authored-by: johnb432 <[email protected]> Co-authored-by: Grim <[email protected]> Co-authored-by: BrettMayson <[email protected]>
- Loading branch information
1 parent
a54c4da
commit f5a838e
Showing
16 changed files
with
421 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
z\ace\addons\markinglaser |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
class Extended_PreStart_EventHandlers { | ||
class ADDON { | ||
init = QUOTE(call COMPILE_FILE(XEH_preStart)); | ||
}; | ||
}; | ||
|
||
class Extended_PreInit_EventHandlers { | ||
class ADDON { | ||
init = QUOTE(call COMPILE_FILE(XEH_preInit)); | ||
}; | ||
}; | ||
|
||
class Extended_PostInit_EventHandlers { | ||
class ADDON { | ||
init = QUOTE(call COMPILE_FILE(XEH_postInit)); | ||
}; | ||
}; | ||
|
||
class Extended_InitPost_EventHandlers { | ||
class Air { | ||
class ADDON { | ||
init = QUOTE(_this call FUNC(onAircraftInit)); | ||
}; | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
class CfgIRLaserSettings { | ||
laserMaxRange = LASER_MAX; // 4000 is max range of the laser in engine | ||
maxViewDistance = 6000; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
class CfgVehicles { | ||
class AllVehicles; | ||
class Air: AllVehicles { | ||
class Attributes { | ||
class GVAR(enabled) { | ||
displayName = CSTRING(Attribute_Enabled_DisplayName); | ||
tooltip = CSTRING(Attribute_Enabled_Tooltip); | ||
property = QGVAR(enabled); | ||
control = "Checkbox"; | ||
typeName = "BOOL"; | ||
expression = QUOTE(_this setVariable [ARR_3(QQGVAR(enabled),_value,true)]); | ||
defaultValue = "true"; | ||
condition = "objectVehicle"; | ||
}; | ||
}; | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
ace_markinglaser | ||
=================== | ||
|
||
Adds an IR marking laser for aircraft. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
PREP(findTurret); | ||
PREP(onAircraftInit); | ||
PREP(onLaserOn); | ||
PREP(renderPFH); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#include "script_component.hpp" | ||
#include "\a3\ui_f\hpp\defineDIKCodes.inc" | ||
|
||
if (!hasInterface) exitWith {}; | ||
|
||
// Keybinds | ||
["ACE3 Vehicles", QGVAR(toggleLaser), LLSTRING(ToggleLaser), { | ||
// Ignore when in Zeus | ||
if (!isNull curatorCamera) exitWith {false}; | ||
|
||
private _vehicle = cameraOn; | ||
if !(_vehicle getVariable [QGVAR(enabled), false]) exitWith {false}; | ||
|
||
private _controlledUnit = [ACE_player, ACE_controlledUAV # 1] select (unitIsUAV _vehicle); | ||
|
||
private _turretInfo = _vehicle getVariable [QGVAR(turretInfo), []]; | ||
private _canTurnOn = _controlledUnit == _vehicle turretUnit _turretInfo; | ||
if (!_canTurnOn) exitWith { false }; | ||
|
||
playSound "ACE_Sound_Click"; | ||
private _currentMode = _vehicle getVariable [QGVAR(laserMode), MODE_OFF]; | ||
private _newMode = (_currentMode + 1) % 3; | ||
_vehicle setVariable [QGVAR(laserMode), _newMode, true]; | ||
true | ||
}, "", [DIK_L, [false, false, true]]] call CBA_fnc_addKeybind; // ALT-L | ||
|
||
["CBA_settingsInitialized", { | ||
TRACE_1("settingsInitialized",1); | ||
|
||
GVAR(pfEH) = -1; | ||
["visionMode", LINKFUNC(onLaserOn), true] call CBA_fnc_addPlayerEventHandler; | ||
["ace_laserOn", { | ||
params ["", "_args"]; | ||
_args params ["_object"]; | ||
if !(_object getVariable [QGVAR(enabled), false]) exitWith {}; | ||
_object setVariable [QGVAR(smoothing), []]; | ||
_object setVariable [QGVAR(flashOffset), random 1]; // make flashes not synchronized | ||
|
||
[] call LINKFUNC(onLaserOn); | ||
}] call CBA_fnc_addEventHandler; | ||
}] call CBA_fnc_addEventHandler; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#include "script_component.hpp" | ||
|
||
ADDON = false; | ||
|
||
PREP_RECOMPILE_START; | ||
#include "XEH_PREP.hpp" | ||
PREP_RECOMPILE_END; | ||
|
||
ADDON = true; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#include "script_component.hpp" | ||
|
||
#include "XEH_PREP.hpp" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#include "script_component.hpp" | ||
|
||
class CfgPatches { | ||
class ADDON { | ||
name = COMPONENT_NAME; | ||
units[] = {}; | ||
weapons[] = {}; | ||
requiredVersion = REQUIRED_VERSION; | ||
requiredAddons[] = {"ace_common", "ace_laser"}; | ||
author = ECSTRING(common,ACETeam); | ||
authors[] = {"BaerMitUmlaut"}; | ||
url = ECSTRING(main,URL); | ||
VERSION_CONFIG; | ||
}; | ||
}; | ||
|
||
#include "CfgIRLaserSettings.hpp" | ||
#include "CfgEventHandlers.hpp" | ||
#include "CfgVehicles.hpp" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
#include "..\script_component.hpp" | ||
/* | ||
* Author: BaerMitUmlaut | ||
* Finds the turret that has control over the marking laser. | ||
* | ||
* Arguments: | ||
* 0: Aircraft config <OBJECT> | ||
* | ||
* Return Value: | ||
* <ARRAY> | ||
* | ||
* Example: | ||
* [configOf _plane] call ace_markinglaser_fnc_findTurret | ||
* | ||
* Public: No | ||
*/ | ||
|
||
params ["_config"]; | ||
|
||
private _copilotPath = nil; | ||
private _copilotConfig = configNull; | ||
private _primaryPath = nil; | ||
private _primaryConfig = configNull; | ||
private _isUAV = getNumber (_config >> "isUAV") == 1; | ||
|
||
private _walkTurrets = { | ||
params ["_path", "_turrets"]; | ||
|
||
{ | ||
// Check turret rotation for symmetry, filters door gunner turrets | ||
if (abs getNumber (_x >> "minTurn") != abs getNumber (_x >> "maxTurn")) then { | ||
continue; | ||
}; | ||
|
||
// Check if turret has a optics with night or thermal vision | ||
private _visionModes = flatten (("true" configClasses (_x >> "OpticsIn")) apply { | ||
(getArray (_x >> "visionMode")) apply {toLowerANSI _x} | ||
}); | ||
|
||
if !("nvg" in _visionModes || {"ti" in _visionModes}) then { | ||
continue; | ||
}; | ||
|
||
// Use copilot turret if possible | ||
// Not all helicopter gun turrets use this flag (for example the Kajman) | ||
if (getNumber (_x >> "isCopilot") == 1) then { | ||
_copilotPath = _path + [_forEachIndex]; | ||
_copilotConfig = _x; | ||
break; | ||
}; | ||
|
||
// Fallback to primary gunner | ||
if (isNil "_primaryPath" && {getNumber (_x >> "primaryGunner") == 1}) then { | ||
_primaryPath = _path + [_forEachIndex]; | ||
_primaryConfig = _x; | ||
}; | ||
|
||
// Search subturrets | ||
if (isClass (_x >> "Turrets")) then { | ||
private _turrets = "true" configClasses (_x >> "Turrets"); | ||
[_path + [_forEachIndex], _turrets] call _walkTurrets; | ||
}; | ||
} forEach _turrets; | ||
}; | ||
|
||
[[], "true" configClasses (_config >> "Turrets")] call _walkTurrets; | ||
|
||
if (!isNil "_copilotPath") exitWith { | ||
[_copilotPath, _copilotConfig] | ||
}; | ||
if (!isNil "_primaryPath") exitWith { | ||
[_primaryPath, _primaryConfig] | ||
}; | ||
|
||
[] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
#include "..\script_component.hpp" | ||
/* | ||
* Author: BaerMitUmlaut | ||
* Equips an aircraft with a marking laser. | ||
* | ||
* Arguments: | ||
* 0: Aircraft <OBJECT> | ||
* | ||
* Return Value: | ||
* None | ||
* | ||
* Example: | ||
* [plane] call ace_markinglaser_fnc_onAircraftInit | ||
* | ||
* Public: No | ||
*/ | ||
|
||
params ["_aircraft"]; | ||
TRACE_2("onAircraftInit",_aircraft,typeOf _aircraft); | ||
|
||
// Assume enabled by default | ||
if !(_aircraft getVariable [QGVAR(enabled), true]) exitWith {}; | ||
|
||
private _config = configOf _aircraft; | ||
private _turretData = [_config] call FUNC(findTurret); | ||
private _hasPilotCamera = getNumber (_config >> "PilotCamera" >> "controllable") > 0; | ||
|
||
if ((_turretData isEqualTo []) && {!_hasPilotCamera}) exitWith { | ||
_aircraft setVariable [QGVAR(enabled), false]; | ||
WARNING_1("Class %1 does not have a pilot camera nor a turret that could be equipped with an IR marking laser.",configName _config); | ||
}; | ||
|
||
_aircraft setVariable [QGVAR(enabled), true]; | ||
_aircraft setVariable [QGVAR(smoothing), []]; | ||
|
||
if (_turretData isEqualTo []) then { | ||
TRACE_1("pilot",_turretData); | ||
// Use pilot camera if no turrets are available | ||
_aircraft setVariable [QGVAR(turretInfo), [-1]]; | ||
} else { | ||
TRACE_1("turret",_turretData); | ||
_turretData params ["_turretPath"]; | ||
_aircraft setVariable [QGVAR(turretInfo), _turretPath]; | ||
}; | ||
|
||
|
||
TRACE_1("Add interaction",_aircraft); | ||
private _condition = { | ||
if !(_target getVariable [QGVAR(enabled), false]) exitWith {false}; | ||
private _controlledUnit = [ACE_player, ACE_controlledUAV # 1] select (unitIsUAV _target); | ||
private _turretInfo = _target getVariable [QGVAR(turretInfo), []]; | ||
private _canTurnOn = _controlledUnit == _target turretUnit _turretInfo; | ||
_canTurnOn | ||
}; | ||
|
||
private _getChildren = { | ||
private _statement = { | ||
_target setVariable [QGVAR(laserMode), _actionParams, true]; | ||
}; | ||
private _current = _target getVariable [QGVAR(laserMode), 0]; | ||
[[MODE_OFF, LELSTRING(common,disabled)], [MODE_ON, LELSTRING(common,enabled)], [MODE_FLASH, LLSTRING(Flashing)]] apply { | ||
_x params ["_mode", "_text"]; | ||
if (_current == _mode) then { _text = ">" + _text }; | ||
[[str _mode, _text, "", _statement, {true}, {}, _mode] call EFUNC(interact_menu,createAction), [], _target] | ||
} | ||
}; | ||
private _actionBase = [QGVAR(actionBase), LLSTRING(Name), "", {}, _condition, _getChildren] call EFUNC(interact_menu,createAction); | ||
private _basePath = [_aircraft, 1, ["ACE_SelfActions"], _actionBase] call EFUNC(interact_menu,addActionToObject); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#include "..\script_component.hpp" | ||
/* | ||
* Author: BaerMitUmlaut, PabstMirror | ||
* Starts render PFEH | ||
* | ||
* Arguments: | ||
* 0: Aircraft <OBJECT> | ||
* | ||
* Return Value: | ||
* None | ||
* | ||
* Example: | ||
* [] call ace_markinglaser_fnc_onLaserOn | ||
* | ||
* Public: No | ||
*/ | ||
|
||
if (GVAR(pfEH) != -1) exitWith {}; | ||
if (((currentVisionMode focusOn) != 1) || {EGVAR(laser,laserEmitters) isEqualTo []}) exitWith {}; | ||
|
||
GVAR(pfEH) = [LINKFUNC(renderPFH), 0, []] call CBA_fnc_addPerFrameHandler; | ||
TRACE_1("start PFEH",GVAR(pfEH)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
#include "..\script_component.hpp" | ||
/* | ||
* Author: BaerMitUmlaut, PabstMirror | ||
* Renders all marking lasers. | ||
* | ||
* Arguments: | ||
* None | ||
* | ||
* Return Value: | ||
* None | ||
* | ||
* Example: | ||
* [] call ace_markinglaser_fnc_renderPFH | ||
* | ||
* Public: No | ||
*/ | ||
|
||
if (((currentVisionMode focusOn) != 1) || {EGVAR(laser,laserEmitters) isEqualTo []}) exitWith { | ||
GVAR(pfEH) call CBA_fnc_removePerFrameHandler; | ||
GVAR(pfEH) = -1; | ||
TRACE_1("end PFEH",GVAR(pfEH)); | ||
}; | ||
|
||
{ | ||
_y params ["_aircraft", "", "_laserMethod"]; | ||
|
||
private _currentMode = _aircraft getVariable [QGVAR(laserMode), MODE_OFF]; | ||
if (_currentMode == MODE_OFF) then { continue }; | ||
if (_laserMethod != QEFUNC(laser,findLaserSource)) then { continue }; // Normal vanilla laserTarget func | ||
|
||
if ((_currentMode == MODE_FLASH) && { | ||
private _cycle = (CBA_missionTime + (_aircraft getVariable [QGVAR(flashOffset), 0])) % (1/3); | ||
_cycle > 1/6 | ||
}) then { continue }; | ||
|
||
(_y call EFUNC(laser,findLaserSource)) params ["_laserPosASL", "_laserDir"]; | ||
|
||
#ifdef DEBUG_MODE_FULL | ||
private _targetObject = _aircraft getVariable [QEGVAR(laser,targetObject), objNull]; | ||
private _targetPosASL = getPosASL _targetObject; | ||
|
||
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [1,0,1,1], (ASLToAGL _targetPosASL), 0.5, 0.5, 0, "Laser", 0.5, 0.025, "TahomaB"]; | ||
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [1,0,1,1], (ASLToAGL _laserPosASL), 0.5, 0.5, 0, "Origin", 0.5, 0.025, "TahomaB"]; | ||
#endif | ||
|
||
// If our camera is the laser source, offset it just a bit so it isn't dead center | ||
if (((AGLToASL positionCameraToWorld [0,0,0]) distance _laserPosASL) < 0.09) then { | ||
_laserPosASL = AGLToASL positionCameraToWorld [-0.02, -0.05, 0]; | ||
}; | ||
|
||
private _smoothing = _aircraft getVariable [QGVAR(smoothing), []]; | ||
_smoothing pushBack _laserDir; | ||
if (count _smoothing > 5) then { _smoothing deleteAt 0 }; | ||
private _smoothDir = [0,0,0]; | ||
{ _smoothDir = _smoothDir vectorAdd _x } forEach _smoothing; | ||
_smoothDir = _smoothDir vectorMultiply (1/count _smoothing); | ||
|
||
private _startPos = _laserPosASL vectorAdd (_smoothDir vectorMultiply 0.25); // go forward a bit so first drawLaser doesn't hit aircraft | ||
private _endPos = _laserPosASL vectorAdd (_smoothDir vectorMultiply LASER_MAX); | ||
private _intersects = []; | ||
while { _intersects isEqualTo [] } do { | ||
// drawLaser has an internal maximum distance it can draw, so we may need to draw multiple segments | ||
drawLaser [_startPos, _smoothDir, [250, 0, 0, 1], [], 0, 1, LASER_MAX, true]; // Draw a segment | ||
if ((_startPos distance _laserPosASL) > 9999) exitWith {}; // just exit loop if we've drawn far enough | ||
_intersects = lineIntersectsSurfaces [_startPos, _endPos, _aircraft]; | ||
if (_intersects isEqualTo []) then { // Check if we hit anything | ||
_startPos = _endPos; // if we didn't then move up the startpos to where the last draw ended | ||
_endPos = _endPos vectorAdd (_smoothDir vectorMultiply LASER_MAX); | ||
}; | ||
}; | ||
drawLaser [_laserPosASL, _smoothDir, [250, 0, 0, 1], [], 0.5, 1, LASER_MAX, true]; // final draw from actual origin | ||
} forEach EGVAR(laser,laserEmitters); |
Oops, something went wrong.