Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add IR marking laser for aircraft #7761

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions addons/markinglaser/$PBOPREFIX$
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
z\ace\addons\markinglaser
23 changes: 23 additions & 0 deletions addons/markinglaser/CfgEventHandlers.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
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 {
ADDON = QUOTE(call FUNC(onAircraftInit));
};
};
71 changes: 71 additions & 0 deletions addons/markinglaser/CfgVehicles.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
class CBA_Extended_EventHandlers;

class CfgVehicles {
class FloatingStructure_F;
class ACE_MarkingLaser: FloatingStructure_F {
class EventHandlers {
class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {};
johnb432 marked this conversation as resolved.
Show resolved Hide resolved
};

scope = 2;
displayName = "";
model = QPATHTOF(data\laser.p3d);
hiddenSelections[] = {"camo"};

class AnimationSources {
class AdjustLength {
source = "user";
animPeriod = 0;
initPhase = -10000;
minValue = -10000;
maxValue = 0;
};
};

class Reflectors {
class LightEnd {
position = "light_end";
direction = "end";
selection = "end";
hitpoint = "";
innerAngle = 360;
outerAngle = 360;
coneFadeCoef = 1;
ambient[] = {1, 1, 1};
color[] = {1, 1, 1};
dayLight = 0;
useFlare = 0;
size = 1;
intensity = 1000;
class Attenuation {
start = 0.1;
constant = 0;
linear = 1000;
quadratic = 10;
hardLimitStart = 10;
hardLimitEnd = 15;
};
};

class LightStart: LightEnd {
position = "start";
direction = "end";
selection = "start";
innerAngle = 1;
outerAngle = 135;
ambient[] = {0.1, 0.1, 0.1};
useFlare = 1;
flareSize = 1.5;
flareMaxDistance = 10000;
class Attenuation: Attenuation {
start = 0;
constant = 2;
linear = 10;
quadratic = 20;
hardLimitStart = 5;
hardLimitEnd = 6;
};
};
};
};
};
11 changes: 11 additions & 0 deletions addons/markinglaser/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
ace_markinglaser
===================

Adds a marking laser for aircraft.


## Maintainers

The people responsible for merging changes to this component or answering potential questions.

- [BaerMitUmlaut](https://github.com/BaerMitUmlaut)
LinkIsGrim marked this conversation as resolved.
Show resolved Hide resolved
6 changes: 6 additions & 0 deletions addons/markinglaser/XEH_PREP.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
PREP(getVector);
PREP(onAircraftInit);
PREP(onLaserOff);
PREP(onLaserOn);
PREP(renderPFH);
PREP(updatePFH);
32 changes: 32 additions & 0 deletions addons/markinglaser/XEH_postInit.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include "script_component.hpp"
#include "\a3\ui_f\hpp\defineDIKCodes.inc"

// Events
[QGVAR(laserOn), FUNC(onLaserOn)] call CBA_fnc_addEventHandler;
[QGVAR(laserOff), FUNC(onLaserOff)] call CBA_fnc_addEventHandler;

// Keybinds
["ACE3 Vehicles", QGVAR(toggleLaser), localize LSTRING(ToggleLaser), {
private _vehicle = vehicle ACE_Player;

if (_vehicle isKindOf "Air" && {hasPilotCamera _vehicle}) then {
if (_vehicle getVariable [QGVAR(laserOn), false]) then {
[QGVAR(laserOff), [_vehicle]] call CBA_fnc_globalEvent;
} else {
[QGVAR(laserOn), [_vehicle]] call CBA_fnc_globalEvent;
};

true
} else {
false
};
}, "", [DIK_L, [false, false, true]]] call CBA_fnc_addKeybind;

// JIP init
if (didJIP) then {
{
if (_x getVariable [QGVAR(laserOn), false]) then {
[_x] call FUNC(onLaserOn);
};
} forEach (allMissionObjects "Air");
};
johnb432 marked this conversation as resolved.
Show resolved Hide resolved
12 changes: 12 additions & 0 deletions addons/markinglaser/XEH_preInit.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include "script_component.hpp"

ADDON = false;

PREP_RECOMPILE_START;
#include "XEH_PREP.hpp"
PREP_RECOMPILE_END;

GVAR(lasers) = [];
GVAR(localLasers) = [];

ADDON = true;
3 changes: 3 additions & 0 deletions addons/markinglaser/XEH_preStart.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "script_component.hpp"

#include "XEH_PREP.hpp"
18 changes: 18 additions & 0 deletions addons/markinglaser/config.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "script_component.hpp"

class CfgPatches {
class ADDON {
name = COMPONENT_NAME;
units[] = {};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"ace_common"};
author = ECSTRING(common,ACETeam);
authors[] = {"BaerMitUmlaut"};
url = ECSTRING(main,URL);
VERSION_CONFIG;
};
};

#include "CfgEventHandlers.hpp"
#include "CfgVehicles.hpp"
Binary file added addons/markinglaser/data/laser - Kopie.p3d
Binary file not shown.
Binary file added addons/markinglaser/data/laser.p3d
Binary file not shown.
82 changes: 82 additions & 0 deletions addons/markinglaser/data/laser.rvmat
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
ambient[] = {1, 1, 1, 1};
diffuse[] = {1, 1, 1, 1};
forcedDiffuse[] = {0, 0, 0, 1};
emmisive[] = {1000, 1000, 1000, 0};
specular[] = {1, 1, 1, 1};
specularPower = 30;
PixelShaderID = "Super";
VertexShaderID = "Super";
class Stage1 {
texture = "#(argb,8,8,3)color(0.5,0.5,1,1,NOHQ)";
uvSource = "tex";
class uvTransform {
aside[] = {1, 0, 0};
up[] = {0, 1, 0};
dir[] = {0, 0, 1};
pos[] = {0, 0, 0};
};
};
class Stage2 {
texture = "#(argb,8,8,3)color(0.5,0.5,0.5,0.5,DT)";
uvSource = "tex";
class uvTransform {
aside[] = {1, 0, 0};
up[] = {0, 1, 0};
dir[] = {0, 0, 1};
pos[] = {0, 0, 0};
};
};
class Stage3 {
texture = "#(argb,8,8,3)color(0,0,0,0,MC)";
uvSource = "tex";
class uvTransform {
aside[] = {1, 0, 0};
up[] = {0, 1, 0};
dir[] = {0, 0, 1};
pos[] = {0, 0, 0};
};
};
class Stage4 {
texture = "#(argb,8,8,3)color(1,1,1,1,AS)";
uvSource = "tex";
class uvTransform {
aside[] = {1, 0, 0};
up[] = {0, 1, 0};
dir[] = {0, 0, 1};
pos[] = {0, 0, 0};
};
};
class Stage5 {
texture = "#(argb,8,8,3)color(1,0,1,0,SMDI)";
uvSource = "tex";
class uvTransform {
aside[] = {1, 0, 0};
up[] = {0, 1, 0};
dir[] = {0, 0, 1};
pos[] = {0, 0, 0};
};
};
class Stage6 {
texture = "#(ai,64,64,1)fresnel(0.4,0.2)";
uvSource = "tex";
class uvTransform {
aside[] = {1, 0, 0};
up[] = {0, 1, 0};
dir[] = {0, 0, 1};
pos[] = {0, 0, 0};
};
};
class Stage7 {
texture = "a3\data_f\env_land_co.paa";
useWorldEnvMap = "true";
uvSource = "tex";
class uvTransform {
aside[] = {1, 0, 0};
up[] = {0, 1, 0};
dir[] = {0, 0, 1};
pos[] = {0, 0, 0};
};
};
class StageTI {
texture = "a3\data_f\default_vehicle_ti_ca.paa";
};
36 changes: 36 additions & 0 deletions addons/markinglaser/data/model.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
class CfgSkeletons {
class Default {
isDiscrete = 1;
skeletonInherit = "";
skeletonBones[] = {};
};
class ACE_MarkingLaser: Default {
skeletonInherit = "Default";
skeletonBones[] = {
"end", ""
};
};
};

class CfgModels {
class Default {
sectionsInherit = "";
sections[] = {};
skeletonName = "";
};
class laser: Default {
sectionsInherit = "Default";
sections[] = {"camo"};
skeletonName = "ACE_MarkingLaser";

class Animations {
class AdjustLength {
source = "user";
type = "translationY";
selection = "end";
minValue = -10000;
maxValue = 0;
};
};
};
};
78 changes: 78 additions & 0 deletions addons/markinglaser/functions/fnc_getVector.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#include "script_component.hpp"
/*
* Author: BaerMitUmlaut
* Calculates the directional vector of the marking laser.
*
* Arguments:
* 0: Aircraft <OBJECT>
* 1: Laser <OBJECT>
*
* Return Value:
* Directional vector of laser in world space <ARRAY>
*
* Example:
* [plane, laser] call ace_markinglaser_fnc_getVector
*
* Public: No
*/
params ["_aircraft", "_laser"];

#ifndef DEBUG_MODE_FULL
if (local _aircraft) exitWith {
_aircraft vectorModelToWorldVisual getPilotCameraDirection _aircraft
};
#endif

// _type - Target type
// _target - Locked target, either an object, a position or a vector
// _time - When this info was last synched
// _isNewInfo - NIL when this info was just updated, otherwise true (not synched)
private _laserInfo = _laser getVariable [QGVAR(laserInfo), []];
_laserInfo params ["_type", "_target", "_time", ["_isNewInfo", true]];

private _originModel = _aircraft getVariable [QGVAR(laserOrigin), [0, 0, 0]];
private _origin = _aircraft modelToWorldVisualWorld _originModel;
private _deltaTime = CBA_missionTime - _time;

// If an update is older than 2s, the laser movement is stopped
// This would indicate a lot of lag and cause the laser to go off into nowhere
if (_deltaTime > UPDATE_INTERVAL * 2) exitWith {
_aircraft vectorModelToWorld vectorUp _laser;
};

private _interpolationInfo = _laser getVariable [QGVAR(interpolationInfo), []];
_interpolationInfo params ["_lastTarget", "_cachedTarget", ["_cachedType", ""]];

// If laser info was just synched, use previous position/vector for interpolation start
if (_isNewInfo) then {
// TYPE_VECTOR doesn't clip interpolation, use current orientation instead
_cachedTarget = [_cachedTarget, _aircraft vectorWorldToModelVisual vectorUp _laser] select (_type == TYPE_VECTOR);

// Do not interpolate if type changed - might cause a snap when locking but should be OK
_lastTarget = [_target, _cachedTarget] select (_type == _cachedType);

// Update info arrays
_laser setVariable [QGVAR(interpolationInfo), [_lastTarget, _target, _type]];
_laserInfo set [3, false];
};

private _vector = [0, 0, 0];
switch (_type) do {
case TYPE_OBJECT: {
// Don't interpolate because laser should always directly point at object
_vector = _origin vectorFromTo getPosASLVisual _target;
};
case TYPE_GROUND: {
// Interpolate between last position and current position
private _interpolatedPos = vectorLinearConversion [0, UPDATE_INTERVAL, _deltaTime, _lastTarget, _target, true];
_vector = _origin vectorFromTo _interpolatedPos;
};
case TYPE_VECTOR: {
// Interpolate between last vector and current vector
// Interpolation is deliberately not clipped to smoothen movement with delayed updates
private _interpolatedVec = vectorLinearConversion [0, UPDATE_INTERVAL, _deltaTime, _lastTarget, _target, false];
_vector = _aircraft vectorModelToWorldVisual _interpolatedVec;
};
};

_vector
Loading