Common - Improve persistent lights/lasers (#10118)

* 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>
This commit is contained in:
johnb432 2024-08-08 10:01:39 +02:00 committed by GitHub
parent 80a310d4c6
commit 7838dea543
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 132 additions and 38 deletions

View File

@ -178,6 +178,7 @@ PREP(setupLocalUnitsHandler);
PREP(setVariableJIP);
PREP(setVariablePublic);
PREP(setVolume);
PREP(setWeaponLightLaserState);
PREP(showHud);
PREP(statusEffect_addType);
PREP(statusEffect_get);

View File

@ -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

View File

@ -1,6 +1,6 @@
#include "..\script_component.hpp"
/*
* Author: Dystopian
* Author: Dystopian, johnb43
* Controls persistent laser state.
*
* Arguments:
@ -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;
[
{
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 _fnc_getLightLaserState = {
private _currentWeapon = currentWeapon ACE_player;
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 {};
[
// 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;
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;
};
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;
// 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;
[
_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"];
[
_unit,
_unit getVariable [QGVAR(laserEnabled_) + str ([_unit, currentWeapon _unit] call FUNC(getWeaponIndex)), false]
] call FUNC(setWeaponLightLaserState);
};
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;