Skip to content

Commit

Permalink
Common - Improve persistent lights/lasers (acemod#10118)
Browse files Browse the repository at this point in the history
* Improve persistent lasers

* Update addons/common/functions/fnc_switchPersistentLaser.sqf

Co-authored-by: PabstMirror <pabstmirror@gmail.com>

* Fix inventory changes toggling laser, removed alignment code

* Update addons/common/functions/fnc_switchPersistentLaser.sqf

Co-authored-by: PabstMirror <pabstmirror@gmail.com>

* Added API for setting weapon lights/lasers

* Fix undefined variables

---------

Co-authored-by: PabstMirror <pabstmirror@gmail.com>
  • Loading branch information
2 people authored and blake8090 committed Aug 18, 2024
1 parent 2749da7 commit a192c86
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 37 deletions.
1 change: 1 addition & 0 deletions addons/common/XEH_PREP.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ PREP(setupLocalUnitsHandler);
PREP(setVariableJIP);
PREP(setVariablePublic);
PREP(setVolume);
PREP(setWeaponLightLaserState);
PREP(showHud);
PREP(statusEffect_addType);
PREP(statusEffect_get);
Expand Down
59 changes: 59 additions & 0 deletions addons/common/functions/fnc_setWeaponLightLaserState.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#include "..\script_component.hpp"
/*
* Author: johnb43
* Toggles the unit's current weapon's light & laser.
* API for persistent lasers. Doesn't work on AI, as they have their own logic.
*
* Arguments:
* 0: Unit <OBJECT>
* 1: Weapon light/laser state <BOOL> (default: false)
*
* Return Value:
* None
*
* Example:
* [player, true] call ace_common_fnc_setWeaponLightLaserState
*
* Public: Yes
*/

params [["_unit", objNull, [objNull]], ["_state", false, [false]]];

if (!local _unit || {!alive _unit} || {!(_unit call FUNC(isPlayer))}) exitWith {};

if !(_unit call CBA_fnc_canUseWeapon) exitWith {};

private _currentWeapon = currentWeapon _unit;

// Exit if unit has no weapon selected
if (_currentWeapon == "") exitWith {};

private _weaponIndex = [_unit, _currentWeapon] call FUNC(getWeaponIndex);

// Ignore binoculars
if (_weaponIndex == -1) exitWith {};

_unit setVariable [QGVAR(laserEnabled_) + str _weaponIndex, _state];

// Turn off light/laser (switching between weapons can leave previous weapon laser on)
action ["GunLightOff", _unit];
action ["IRLaserOff", _unit];

// Light/laser is off, don't need to do anything more
if (!_state) exitWith {};

// Turn laser on next frame (if weapon hasn't changed)
[{
params ["_unit", "_currentWeapon"];

private _weaponState = (weaponState _unit) select [0, 3];

if (_weaponState select 0 != _currentWeapon) exitWith {};

action ["GunLightOn", _unit];
action ["IRLaserOn", _unit];

_unit selectWeapon _weaponState;
}, [_unit, _currentWeapon]] call CBA_fnc_execNextFrame;

nil
108 changes: 71 additions & 37 deletions addons/common/functions/fnc_switchPersistentLaser.sqf
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "..\script_component.hpp"
/*
* Author: Dystopian
* Author: Dystopian, johnb43
* Controls persistent laser state.
*
* Arguments:
Expand All @@ -17,51 +17,85 @@

params ["_enabled"];

if (!hasInterface) exitwith {};

// Reset state
{
ACE_player setVariable [QGVAR(laserEnabled_) + str _x, nil];
} forEach [0, 1, 2];

if (!_enabled) exitWith {
if (isNil QGVAR(laserKeyDownEH)) exitWith {};
["KeyDown", GVAR(laserKeyDownEH)] call CBA_fnc_removeDisplayHandler;

removeUserActionEventHandler ["headlights", "Activate", GVAR(laserKeyDownEH)];

["loadout", GVAR(laserLoadoutEH)] call CBA_fnc_removePlayerEventHandler;
["turret", GVAR(laserTurretEH)] call CBA_fnc_removePlayerEventHandler;
["vehicle", GVAR(laserVehicleEH)] call CBA_fnc_removePlayerEventHandler;
["weapon", GVAR(laserWeaponEH)] call CBA_fnc_removePlayerEventHandler;

GVAR(laserKeyDownEH) = nil;
GVAR(laserLoadoutEH) = nil;
GVAR(laserTurretEH) = nil;
GVAR(laserVehicleEH) = nil;
GVAR(laserWeaponEH) = nil;
};

GVAR(laserKeyDownEH) = ["KeyDown", {
if !((_this select 1) in actionKeys "headlights") exitWith {false};
private _weapon = currentWeapon ACE_player;
private _fnc_getLightLaserState = {
private _currentWeapon = currentWeapon ACE_player;

if (_currentWeapon == "") exitWith {};

// Ignore in vehicle except FFV
if !(ACE_player call CBA_fnc_canUseWeapon) exitWith {};

private _weaponIndex = [ACE_player, _currentWeapon] call FUNC(getWeaponIndex);

if (_weaponIndex == -1) exitWith {};

// Light/laser state only changes in the next frame
[{
ACE_player setVariable [
QGVAR(laserEnabled_) + str (_this select 1),
ACE_player isIRLaserOn (_this select 0) || {ACE_player isFlashlightOn (_this select 0)}
];
}, [_currentWeapon, _weaponIndex]] call CBA_fnc_execNextFrame;
};

// Get current weapon light/laser state
call _fnc_getLightLaserState;

// Update state every time it's changed
GVAR(laserKeyDownEH) = addUserActionEventHandler ["headlights", "Activate", _fnc_getLightLaserState];

// Dropping weapons turns off lights/lasers
GVAR(lastWeapons) = [primaryWeapon ACE_player, handgunWeapon ACE_player, secondaryWeapon ACE_player];

// Monitor weapon addition/removal here
GVAR(laserLoadoutEH) = ["loadout", {
params ["_unit"];

private _weapons = [primaryWeapon _unit, handgunWeapon _unit, secondaryWeapon _unit];

if (_weapons isEqualTo GVAR(lastWeapons)) exitWith {};

GVAR(lastWeapons) = _weapons;

[
{
params ["_weapon", "_laserWasEnabled"];
private _laserEnabled = ACE_player isIRLaserOn _weapon || {ACE_player isFlashlightOn _weapon};
if (_laserEnabled && {_laserWasEnabled} || {!_laserEnabled && {!_laserWasEnabled}}) exitWith {};
private _weaponIndex = [ACE_player, _weapon] call FUNC(getWeaponIndex);
ACE_player setVariable [QGVAR(laserEnabled_) + str _weaponIndex, [nil, true] select _laserEnabled];
},
[_weapon, ACE_player isIRLaserOn _weapon || {ACE_player isFlashlightOn _weapon}]
] call CBA_fnc_execNextFrame;
false
}] call CBA_fnc_addDisplayHandler;

private _laserEH = {
if (sunOrMoon == 1) exitWith {};
params ["_player"];
private _weaponIndex = [_player, currentWeapon _player] call FUNC(getWeaponIndex);
if (
!(_player getVariable [QGVAR(laserEnabled_) + str _weaponIndex, false])
|| {_weaponIndex > 0 && {"" != primaryWeapon _player}} // Arma switches to primary weapon if exists
|| {!(_player call CBA_fnc_canUseWeapon)} // ignore in vehicle except FFV
) exitWith {};
_unit,
_unit getVariable [QGVAR(laserEnabled_) + str ([_unit, currentWeapon _unit] call FUNC(getWeaponIndex)), false]
] call FUNC(setWeaponLightLaserState);
}] call CBA_fnc_addPlayerEventHandler;

private _fnc_switchPersistentLaserEH = {
params ["_unit"];

[
// wait for weapon in "ready to fire" direction
{0.01 > getCameraViewDirection _this vectorDistance (_this weaponDirection currentWeapon _this)},
{{_this action [_x, _this]} forEach ["GunLightOn", "IRLaserOn"]},
_player,
3,
{{_this action [_x, _this]} forEach ["GunLightOn", "IRLaserOn"]}
] call CBA_fnc_waitUntilAndExecute;
_unit,
_unit getVariable [QGVAR(laserEnabled_) + str ([_unit, currentWeapon _unit] call FUNC(getWeaponIndex)), false]
] call FUNC(setWeaponLightLaserState);
};

GVAR(laserLoadoutEH) = ["loadout", _laserEH] call CBA_fnc_addPlayerEventHandler;
GVAR(laserTurretEH) = ["turret", _laserEH] call CBA_fnc_addPlayerEventHandler;
GVAR(laserVehicleEH) = ["vehicle", _laserEH] call CBA_fnc_addPlayerEventHandler;
GVAR(laserWeaponEH) = ["weapon", _laserEH] call CBA_fnc_addPlayerEventHandler;
GVAR(laserTurretEH) = ["turret", _fnc_switchPersistentLaserEH] call CBA_fnc_addPlayerEventHandler;
GVAR(laserVehicleEH) = ["vehicle", _fnc_switchPersistentLaserEH] call CBA_fnc_addPlayerEventHandler;
GVAR(laserWeaponEH) = ["weapon", _fnc_switchPersistentLaserEH] call CBA_fnc_addPlayerEventHandler;

0 comments on commit a192c86

Please sign in to comment.