diff --git a/addons/events/CfgFunctions.hpp b/addons/events/CfgFunctions.hpp index 6a274659f..670a274c9 100644 --- a/addons/events/CfgFunctions.hpp +++ b/addons/events/CfgFunctions.hpp @@ -88,6 +88,7 @@ class CfgFunctions { PATHTO_FNC(addMarkerEventHandler); PATHTO_FNC(removeMarkerEventHandler); PATHTO_FNC(registerChatCommand); + PATHTO_FNC(weaponEvents); }; }; }; diff --git a/addons/events/config.cpp b/addons/events/config.cpp index 340cb1003..1f6c46ab2 100644 --- a/addons/events/config.cpp +++ b/addons/events/config.cpp @@ -24,3 +24,25 @@ class RscDisplayChat { false\ ); }; + +//#define DEBUG_MODE_FULL +#ifdef DEBUG_MODE_FULL +class CfgWeapons { + class arifle_MX_Base_F; + class arifle_MX_F: arifle_MX_Base_F { + class EventHandlers { + fired = "_this call CBA_fnc_weaponEvents"; // this weapon eventhandler is required! + }; + class CBA_weaponEvents { + handAction = "gestureNo"; // hand animation, from CfgGesturesMale\States + sound = "Alarm"; // from CfgSounds + soundLocation = "LeftHandMiddle1"; // Where the sound is played. Selection on the soldier, not the weapon! Alternative: RightHandMiddle1 + delay = 0.5; // delay for sound and hand animation, in seconds + onEmpty = 0; // 1: play sound and action defined above on the last round, 0: don't, default 1; the sound below is played anyway + hasOptic = 1; // Set to 1 to do optic check with inbuild optic (no attachment) + soundEmpty = ""; // sound played on the last round + soundLocationEmpty = ""; // Where the sound for the last round is played. + }; + }; +}; +#endif diff --git a/addons/events/fnc_weaponEvents.sqf b/addons/events/fnc_weaponEvents.sqf new file mode 100644 index 000000000..8636f2c38 --- /dev/null +++ b/addons/events/fnc_weaponEvents.sqf @@ -0,0 +1,117 @@ +/* ---------------------------------------------------------------------------- +Function: CBA_fnc_weaponEvents + +Description: + Execute weapon events framework. + + class MyWeapon: MyWeapon_base { + class EventHandlers { + fired = "_this call CBA_fnc_weaponEvents"; + }; + }; + +Parameters: + _unit - Unit that fired the weapon + _weapon - The weapon fired by the unit + +Returns: + Nothing + +Examples: + (begin example) + fired = "_this call CBA_fnc_weaponEvents"; + (end) + +Author: + commy2 +---------------------------------------------------------------------------- */ +#include "script_component.hpp" + +params ["_unit", "_weapon", "_muzzle"]; + +private _config = configFile >> "CfgWeapons" >> _weapon >> "CBA_WeaponEvents"; + +private _isEmpty = _unit ammo _weapon == 0; +private _onEmpty = true; + +if (isNumber (_config >> "onEmpty")) then { + _onEmpty = getNumber (_config >> "onEmpty") == 1; +}; + +private _fnc_soundSource = { + private _soundSourceName = format [QGVAR(soundSource_%1), _soundLocation]; + private _soundSource = _unit getVariable [_soundSourceName, objNull]; + + if (isNull _soundSource) then { + _soundSource = "#particlesource" createVehicleLocal [0,0,0]; + }; + + if !(_soundSource in attachedObjects _unit) then { + _soundSource attachTo [_unit, [0,0,0], _soundLocation]; + _unit setVariable [_soundSourceName, _soundSource]; + }; + + _soundSource +}; + +if (_isEmpty) then { + private _sound = getText (_config >> "soundEmpty"); + private _soundLocation = getText (_config >> "soundLocationEmpty"); + + if (_sound != "") then { + (call _fnc_soundSource) say3D _sound; + }; +}; + +if (!_isEmpty || _onEmpty) then { + private _handAction = getText (_config >> "handAction"); + private _sound = getText (_config >> "sound"); + private _soundLocation = getText (_config >> "soundLocation"); + private _delay = getNumber (_config >> "delay"); + private _hasOptic = getNumber (_config >> "hasOptic") == 1; + + private _expectedMagazineCount = count magazines _unit; + private _optic = weaponsItems _unit select {_x select 0 == _weapon} param [0, []] param [3, ""]; + + if (_optic isEqualTo "" && _hasOptic) then { + _optic = _weapon; + }; + + [{ + params [ + "_unit", "_weapon", "_muzzle", "_optic", + "_handAction", "_sound", "_soundSource", + "_expectedMagazineCount", "_time", "_delay" + ]; + + // exit if unit switched weapon + if (currentWeapon _unit != _weapon) exitWith {true}; + + // exit if unit started reloading + if (count magazines _unit != _expectedMagazineCount) exitWith {true}; + + // while in gunner view, keep waiting + if (cameraView == "GUNNER" && _optic != "") exitWith { + _this set [8, CBA_missionTime]; + _unit setWeaponReloadingTime [_unit, _muzzle, 1]; + false + }; + + // keep waiting until time over + if (CBA_missionTime < _time + _delay) exitWith {false}; + + if (local _unit) then { + _unit playAction _handAction; + }; + + if (_sound != "") then { + _soundSource say3D _sound; + }; + + true // exit loop + }, {}, [ + _unit, _weapon, _muzzle, _optic, + _handAction, _sound, call _fnc_soundSource, + _expectedMagazineCount, CBA_missionTime, _delay + ]] call CBA_fnc_waitUntilAndExecute; +};