diff --git a/framework/CfgFunctions.hpp b/framework/CfgFunctions.hpp index 9885428..5b5291d 100644 --- a/framework/CfgFunctions.hpp +++ b/framework/CfgFunctions.hpp @@ -61,9 +61,13 @@ class DOUBLES(PREFIX,emp) { class applyServerObjectEffects {}; class deploy {}; - class getObjectsToAffect {}; + class getObjectsAndGroupsToAffect {}; class playLocalEffects {}; class playLocalEffectsForObject {}; + + class isItemElectronic {}; + class removeUnitElectricInventoryItems {}; + class removeVehicleElectricInventoryItems {}; }; }; diff --git a/framework/common/functions/fn_log.sqf b/framework/common/functions/fn_log.sqf index 716c0df..16af110 100644 --- a/framework/common/functions/fn_log.sqf +++ b/framework/common/functions/fn_log.sqf @@ -27,7 +27,16 @@ private _hash = createHashMapFromArray _data; _message regexReplace ['(\[)', "("]; _message regexReplace ['(\])', ")"]; +private _levelText = switch (_logLevel) do { + case (_logLevel isEqualTo -1) : {"TRACE"}; + case (_logLevel isEqualTo 0) : {"DEBUG"}; + case (_logLevel isEqualTo 1) : {"INFO"}; + case (_logLevel isEqualTo 2) : {"WARN"}; + case (_logLevel isEqualTo 3) : {"ERROR"}; + default {"INFO"}; +}; + private _json = [_hash] call CBA_fnc_encodeJSON; -_log = format ["[%1] [%2] [%3] [%4] :: %5", QUOTE(PREFIX), _component, _fnc_scriptNameParent, _message, _json]; +_log = format ["[%1] [%2] [%3] [%4] [%5] :: %6", QUOTE(PREFIX), _component, _fnc_scriptNameParent, _levelText, _message, _json]; diag_log text _log; \ No newline at end of file diff --git a/framework/emp/CfgSounds.hpp b/framework/emp/CfgSounds.hpp index 45d89b3..3313e39 100644 --- a/framework/emp/CfgSounds.hpp +++ b/framework/emp/CfgSounds.hpp @@ -2,36 +2,36 @@ class GVAR(sound_zap1) { name = QGVAR(sound_zap1); - sound[] = {"sounds\zap1.wss", db+10, 1}; + sound[] = {"framework\emp\sounds\zap1.wss", db+10, 1}; titles[] = {}; }; class GVAR(sound_zap2) { name = QGVAR(sound_zap2); - sound[] = {"sounds\zap2.wss", db+10, 1}; + sound[] = {"framework\emp\sounds\zap2.wss", db+10, 1}; titles[] = {}; }; class GVAR(sound_zap3) { name = QGVAR(sound_zap3); - sound[] = {"sounds\zap3.wss", db+10, 1}; + sound[] = {"framework\emp\sounds\zap3.wss", db+10, 1}; titles[] = {}; }; class GVAR(sound_zap4) { name = QGVAR(sound_zap4); - sound[] = {"sounds\zap4.wss", db+10, 1}; + sound[] = {"framework\emp\sounds\zap4.wss", db+10, 1}; titles[] = {}; }; class GVAR(sound_electric_explsion_impact_large) { name = QGVAR(sound_electric_explsion_impact_large); - sound[] = {"sounds\electric_explsion_impact_large.wss", db+750, 1}; + sound[] = {"framework\emp\sounds\electric_explsion_impact_large.wss", db+750, 1}; titles[] = {}; }; class GVAR(sound_echo3) { name = QGVAR(sound_echo3); - sound[] = {"sounds\echo3.wss", db+500, 1}; + sound[] = {"framework\emp\sounds\echo3.wss", db+500, 1}; titles[] = {1,""}; }; class GVAR(sound_ecou) { name = QGVAR(sound_ecou); - sound[] = {"sounds\ecou.wss", db+100, 1}; + sound[] = {"framework\emp\sounds\ecou.wss", db+100, 1}; titles[] = {1,""}; }; \ No newline at end of file diff --git a/framework/emp/functions/fn_addACEActions.sqf b/framework/emp/functions/fn_addACEActions.sqf index 124f4dd..49fd215 100644 --- a/framework/emp/functions/fn_addACEActions.sqf +++ b/framework/emp/functions/fn_addACEActions.sqf @@ -1,5 +1,7 @@ #include "..\script_component.hpp" +if (!hasInterface) exitWith {}; + private _rootAction = [ QGVAR(action_deploy), "Deploy EMP Device", @@ -27,20 +29,9 @@ private _rootAction = [ nil, [_radius] ] call ace_interact_menu_fnc_createAction; - [ - LEVEL_TRACE, - QUOTE(COMPONENT), - format["parsed child action: %1", _action] - ] call EFUNC(common,log); - _childActions pushBack _action; + _childActions pushBack [_action, [], _target]; false } count [100,500,3000]; - [ - LEVEL_TRACE, - QUOTE(COMPONENT), - format["parsed child actions: %1", _childActions] - ] call EFUNC(common,log); - _childActions; } ] call ace_interact_menu_fnc_createAction; diff --git a/framework/emp/functions/fn_applyLocalObjectEffects.sqf b/framework/emp/functions/fn_applyLocalObjectEffects.sqf index 87c33ab..6b281d3 100644 --- a/framework/emp/functions/fn_applyLocalObjectEffects.sqf +++ b/framework/emp/functions/fn_applyLocalObjectEffects.sqf @@ -11,38 +11,16 @@ _object disableAI "LIGHTS"; _object setPilotLight false; _object setCollisionLight false; -//for player units -if (isPlayer _object) then { - _object action ["IRLaserOff", _object]; - _object action ["nvGogglesOff", _object]; +if (_object isKindOf "CAManBase") then { + [_object] call FUNC(removeUnitElectricInventoryItems); +} else { + [_object] call FUNC(removeVehicleElectricInventoryItems); }; -private _primaryFlashlightOrPointer = (primaryWeaponItems _object)#1; -if (_primaryFlashlightOrPointer != "") then { - _object removePrimaryWeaponItem _primaryFlashlightOrPointer; - _object removeItem _primaryFlashlightOrPointer; -}; -private _secondaryFlashlightOrPointer = (secondaryWeaponItems _object)#1; -if (_secondaryFlashlightOrPointer != "") then { - _object removeSecondaryWeaponItem _secondaryFlashlightOrPointer; - _object removeItem _secondaryFlashlightOrPointer; -}; - -_nvgs = hmd _object; -_object unassignItem _nvgs; -_object removeItem _nvgs; -_radio = _object getSlotItemName 611; -_gps = _object getSlotItemName 612; -_object unassignItem _radio; -_object removeItem _radio; -_object unassignItem _gps; -_object removeItem _gps; -_object unassignItem "ACE_microDAGR"; -_object removeItem "ACE_microDAGR"; -_object unassignItem "MineDetector"; -_object removeItem "MineDetector"; - -[{scriptDone (_object getVariable [QGVAR(flickerHandle), scriptNull])}, { +[{ // once flicker effects are done, permanently disable lights + private _flickerHandle = _object getVariable QGVAR(flickerHandle); + !isNil "_flickerHandle" && {scriptDone _flickerHandle} +}, { _object setHit ["light_1_hitpoint", 0.97]; //all possible light hitpoints _object setHit ["light_2_hitpoint", 0.97]; //no lights escape this _object setHit ["light_3_hitpoint", 0.97]; diff --git a/framework/emp/functions/fn_applyServerObjectEffects.sqf b/framework/emp/functions/fn_applyServerObjectEffects.sqf index abf4f41..91c3f30 100644 --- a/framework/emp/functions/fn_applyServerObjectEffects.sqf +++ b/framework/emp/functions/fn_applyServerObjectEffects.sqf @@ -10,4 +10,4 @@ if (isNull _object) exitWith {}; _object disableTIEquipment true; _object disableNVGEquipment true; -_object setVariable ["A3TI_Disable", true, true]; \ No newline at end of file +_object setVariable ["A3TI_Disable", true, true]; diff --git a/framework/emp/functions/fn_deploy.sqf b/framework/emp/functions/fn_deploy.sqf index 69b7214..503d777 100644 --- a/framework/emp/functions/fn_deploy.sqf +++ b/framework/emp/functions/fn_deploy.sqf @@ -7,7 +7,7 @@ if (!isServer) exitWith {}; //get center and radius -params [["_origin", objNull, [[], objNull]],["_rad",1500, [300]]]; +params [["_origin", objNull, [[], objNull]],["_radius",1500, [300]]]; if (_origin isEqualType []) then { if (count _origin != 3) exitWith { @@ -22,14 +22,10 @@ if (_origin isEqualType objNull) then { _origin = getPosASL _origin; }; -private _objectsToAffect = [_origin, _rad] call FUNC(getObjectsToAffect); - -// for groups, deduplicate and get AI groups only -private _groupsToAffect = _objectsToAffect apply {group _x}; -_groupsToAffect = _groupsToAffect arrayIntersect _groupsToAffect; -_groupsToAffect = _groupsToAffect select {!isPlayer (leader _x)}; - - -[QGVAR(event_empDeployed), [_origin, _objectsToAffect, _groupsToAffect]] call CBA_fnc_globalEvent; +[QGVAR(event_empDeployedPreCheck), [ + random 100000, + _origin, + _radius +]] call CBA_fnc_globalEvent; true; \ No newline at end of file diff --git a/framework/emp/functions/fn_getObjectsToAffect.sqf b/framework/emp/functions/fn_getObjectsAndGroupsToAffect.sqf similarity index 78% rename from framework/emp/functions/fn_getObjectsToAffect.sqf rename to framework/emp/functions/fn_getObjectsAndGroupsToAffect.sqf index 2431aa3..c737104 100644 --- a/framework/emp/functions/fn_getObjectsToAffect.sqf +++ b/framework/emp/functions/fn_getObjectsAndGroupsToAffect.sqf @@ -19,7 +19,7 @@ if (_origin isEqualType objNull) then { }; //search for and return objects -nearestObjects [ +private _objectsToAffect = nearestObjects [ _origin, [ "Car", @@ -55,7 +55,14 @@ nearestObjects [ "Land_Mil_Guardhouse", "Land_NAV_Lighthouse", "Land_Mil_House", - "Land_LightHouse_F" + "Land_LightHouse_F", + "Land_Hospital_side2_F" ], _radius -]; \ No newline at end of file +]; + +private _affectedLocalGroups = _objectsToAffect apply {group _x}; +_affectedLocalGroups = _affectedLocalGroups arrayIntersect _affectedLocalGroups; +_affectedLocalGroups = _affectedLocalGroups select {local _x} select {!isPlayer (leader _x)}; + +[_objectsToAffect, _affectedLocalGroups]; diff --git a/framework/emp/functions/fn_init.sqf b/framework/emp/functions/fn_init.sqf index ac9e962..fcae06f 100644 --- a/framework/emp/functions/fn_init.sqf +++ b/framework/emp/functions/fn_init.sqf @@ -1,20 +1,165 @@ #include "..\script_component.hpp" GVAR(maxBrightDelay) = 3.25; -GVAR(zapSounds) = [QGVAR(sound_zap1),QGVAR(sound_zap2),QGVAR(sound_zap3),QGVAR(sound_zap4)]; -// call FUNC(addACEActions); +GVAR(zapSounds) = createHashMap; +{ + private _cfg = missionConfigFile >> "CfgSounds" >> _x; + private _dataArr = getArray(_cfg >> "sound"); + GVAR(zapSounds) set [_x, createHashMapFromArray [ + ["filename", _dataArr#0], + ["volume", _dataArr#1], + ["pitch", _dataArr#2] + ]]; + true; +} count [QGVAR(sound_zap1),QGVAR(sound_zap2),QGVAR(sound_zap3),QGVAR(sound_zap4)]; + +GVAR(echoSounds) = createHashMap; +{ + private _cfg = missionConfigFile >> "CfgSounds" >> _x; + private _dataArr = getArray(_cfg >> "sound"); + GVAR(echoSounds) set [_x, createHashMapFromArray [ + ["filename", _dataArr#0], + ["volume", _dataArr#1], + ["pitch", _dataArr#2] + ]]; + true; +} count [QGVAR(sound_ecou),QGVAR(sound_echo3)]; -[QGVAR(event_empDeployed), { - params ["_origin", "_affectedObjects", "_affectedGroups"]; +private _lgExplosionCfg = missionConfigFile >> "CfgSounds" >> QGVAR(sound_electric_explsion_impact_large); +private _lgExplosionDataArray = getArray(_lgExplosionCfg >> "sound"); +GVAR(sound_electric_explsion_impact_large) = createHashMapFromArray [ + ["filename", _lgExplosionDataArray#0], + ["volume", _lgExplosionDataArray#1], + ["pitch", _lgExplosionDataArray#2] +]; + +if (hasInterface) then { + call FUNC(addACEActions); +}; +GVAR(activeEMPs) = createHashMap; + +// this precheck is sent to all clients from FUNC(deploy) +// machines will precache affected objects and signal they're ready in return +[QGVAR(event_empDeployedPreCheck), { + params ["_id", "_origin", "_radius"]; + + ([_origin, _radius] call FUNC(getObjectsAndGroupsToAffect)) params ["_affectedObjects", "_affectedLocalGroups"]; + GVAR(activeEMPs) set [_id, createHashMapFromArray [ + ["origin", _origin], + ["radius", _radius], + ["objects", _affectedObjects], + ["localGroups", _affectedLocalGroups], + ["machinesReady", []] + ]]; + + [ + LEVEL_DEBUG, + QUOTE(COMPONENT), + "EMP deployed precheck", + [ + ["id", _id], + ["origin", _origin], + ["radius", _radius], + ["affectedObjects", count _affectedObjects], + ["affectedLocalGroups", count _affectedLocalGroups] + ] + ] call EFUNC(common,log); + + // notify the server we're ready to play effects + [QGVAR(event_readyForEmpEffects), [_id, clientOwner]] call CBA_fnc_serverEvent; + + if (isServer) then { + // on the server, create a waiter for all machines to be ready + [{ + _this params ["_id"]; + private _empData = GVAR(activeEMPs) get _id; + count (_empData get "machinesReady") isEqualTo (count allUsers); + }, { + // when all machines are ready, play effects + _this params ["_id"]; + private _empData = GVAR(activeEMPs) get _id; + + [ + LEVEL_DEBUG, + QUOTE(COMPONENT), + "Initiating EMP effects", + [ + ["id", _id], + ["readyCount", count (_empData get "machinesReady")], + ["allUsers", count allUsers] + ] + ] call EFUNC(common,log); + + [QGVAR(event_initiateEMPEffects), [_id]] call CBA_fnc_globalEvent; + }, [_id]] call CBA_fnc_waitUntilAndExecute; + }; +}] call CBA_fnc_addEventHandler; + +// when a machine is ready to play effects, they'll trigger this on the server +if (isServer) then { + [QGVAR(event_readyForEmpEffects), { + params ["_id", "_machineID"]; + private _empData = GVAR(activeEMPs) get _id; + private _machinesReady = _empData get "machinesReady"; + if (!(_machineID in _machinesReady)) then { + _machinesReady pushBack _machineID; + _empData set ["machinesReady", _machinesReady]; + [ + LEVEL_DEBUG, + QUOTE(COMPONENT), + "Machine ready for EMP effects", + [ + ["id", _id], + ["machineID", _machineID], + ["readyCount", count _machinesReady] + ] + ] call EFUNC(common,log); + }; + }] call CBA_fnc_addEventHandler; +}; + +// when all machines are ready, the server will trigger this on all machines to start effects +[QGVAR(event_initiateEMPEffects), { + params ["_id"]; + private _empData = GVAR(activeEMPs) get _id; + private _origin = _empData get "origin"; + private _affectedObjects = _empData get "objects"; + private _affectedLocalGroups = _empData get "localGroups"; if (hasInterface) then { + [ + LEVEL_DEBUG, + QUOTE(COMPONENT), + "Initiating EMP effects", + [ + ["id", _id], + ["origin", _origin], + ["affectedObjects", count _affectedObjects], + ["affectedLocalGroups", count _affectedLocalGroups] + ] + ] call EFUNC(common,log); + [_origin] call FUNC(playLocalEffects); + // when emp effects reach max brightness, execute object effects [{ + params ["_affectedObjects", "_affectedLocalGroups"]; private _countLocalObjectEffectsPlayed = { // play effects on this machine - [_x] call FUNC(playLocalEffectsForObject); + try { + [_x] call FUNC(playLocalEffectsForObject); + } catch { + [ + LEVEL_WARNING, + QUOTE(COMPONENT), + "Failed to play local EMP effects for object", + [ + ["object", typeOf _x], + ["error", _exception] + ] + ] call EFUNC(common,log); + }; true; } count _affectedObjects; @@ -26,29 +171,79 @@ GVAR(zapSounds) = [QGVAR(sound_zap1),QGVAR(sound_zap2),QGVAR(sound_zap3),QGVAR(s ["localObjectEffectsPlayed", _countLocalObjectEffectsPlayed] ] ] call EFUNC(common,log); - }, _this, GVAR(maxBrightDelay)] call CBA_fnc_waitAndExecute; + }, [_affectedObjects, _affectedLocalGroups], GVAR(maxBrightDelay)] call CBA_fnc_waitAndExecute; }; - // one second after peak brightness + // around peak brightness [{ + params ["_affectedObjects", "_affectedLocalGroups"]; + private _countLocalObjectEffectsApplied = { // apply affects to objects owned by this machine, start propagation to other machines - [_x] call FUNC(applyLocalObjectEffects); + try { + [_x] call FUNC(applyLocalObjectEffects); + } catch { + [ + LEVEL_WARNING, + QUOTE(COMPONENT), + "Failed to apply local EMP effects for object", + [ + ["object", typeOf _x], + ["error", _exception] + ] + ] call EFUNC(common,log); + }; true; } count (_affectedObjects select {local _x}); private _countLocalGroupEffectsApplied = { // apply affects to groups owned by this machine, start propagation to other machines - [_x] call FUNC(applyLocalGroupEffects); + try { + [_x] call FUNC(applyLocalGroupEffects); + } catch { + [ + LEVEL_WARNING, + QUOTE(COMPONENT), + "Failed to apply local EMP effects for group", + [ + ["group", _x], + ["error", _exception] + ] + ] call EFUNC(common,log); + }; true; - } count (_affectedGroups select {local _x}); + } count _affectedLocalGroups; if (isServer) then { private _countServerObjectEffectsApplied = { - [_x] call FUNC(applyServerObjectEffects); + try { + [_x] call FUNC(applyServerObjectEffects); + } catch { + [ + LEVEL_WARNING, + QUOTE(COMPONENT), + "Failed to apply server EMP effects for object", + [ + ["object", typeOf _x], + ["error", _exception] + ] + ] call EFUNC(common,log); + }; true; } count _affectedObjects; }; private _countGlobalObjectEffectsApplied = { - [_x] call FUNC(applyGlobalObjectEffects); + try { + [_x] call FUNC(applyGlobalObjectEffects); + } catch { + [ + LEVEL_WARNING, + QUOTE(COMPONENT), + "Failed to apply global EMP effects for object", + [ + ["object", typeOf _x], + ["error", _exception] + ] + ] call EFUNC(common,log); + }; true; } count _affectedObjects; @@ -63,6 +258,23 @@ GVAR(zapSounds) = [QGVAR(sound_zap1),QGVAR(sound_zap2),QGVAR(sound_zap3),QGVAR(s ["globalObjectEffects", _countGlobalObjectEffectsApplied] ] ] call EFUNC(common,log); - }, _this, GVAR(maxBrightDelay) + 2] call CBA_fnc_waitAndExecute; + }, [_affectedObjects, _affectedLocalGroups], GVAR(maxBrightDelay)] call CBA_fnc_waitAndExecute; + + // clear EMP data after 30 seconds + [{ + params ["_id"]; + private _empData = GVAR(activeEMPs) get _id; + [ + LEVEL_DEBUG, + QUOTE(COMPONENT), + "EMP effects finished", + [ + ["id", _id], + ["affectedObjects", count (_empData get "objects")], + ["affectedLocalGroups", count (_empData get "localGroups")] + ] + ] call EFUNC(common,log); + GVAR(activeEMPs) deleteAt _id; + }, [_id], 30] call CBA_fnc_waitAndExecute; }] call CBA_fnc_addEventHandler; \ No newline at end of file diff --git a/framework/emp/functions/fn_isItemElectronic.sqf b/framework/emp/functions/fn_isItemElectronic.sqf new file mode 100644 index 0000000..1ab4bea --- /dev/null +++ b/framework/emp/functions/fn_isItemElectronic.sqf @@ -0,0 +1,38 @@ +#include "..\script_component.hpp" + +params [ + ["_itemClassname", "", [""]] +]; + +if (_itemClassname isEqualTo "") exitWith { + ["Param _itemClassname is empty", ""] call BIS_fnc_error; + false +}; + +private _isTFARRadio = if (isClass (configFile >> "CfgPatches" >> "tfar_core")) then {_itemClassname call TFAR_fnc_isRadio} else {false}; +if (_isTFARRadio) exitWith {true}; + +private _matchedSpecificClassnames = {(toLower _x) in (toLower _className)} count [ + "ACE_microDAGR", + "Vector21", + "MineDetector", + "GPS" +]; + +if (_matchedSpecificClassnames > 0) exitWith {true}; + +// find items with NVG or TI capabilities +private _cfg = _className call CBA_fnc_getItemConfig; +private _modes = getArray(configfile >> "CfgWeapons" >> _className >> "visionMode"); +private _subModes = [configfile >> "CfgWeapons" >> _className >> "ItemInfo" >> "OpticsModes", 1] call BIS_fnc_returnChildren; +{ + _modes append getArray( _x >> "visionMode" ); +} forEach _subModes; + +private _hasTI = "ti" in (_modes apply { toLower _x }); +private _hasNVG = "nvg" in (_modes apply { toLower _x }); + +if (_hasTI || _hasNVG) exitWith {true}; + + +false; \ No newline at end of file diff --git a/framework/emp/functions/fn_playLocalEffects.sqf b/framework/emp/functions/fn_playLocalEffects.sqf index 7d8bb9e..f0a86a9 100644 --- a/framework/emp/functions/fn_playLocalEffects.sqf +++ b/framework/emp/functions/fn_playLocalEffects.sqf @@ -33,8 +33,9 @@ _light_emp setLightAttenuation [5,1,1,1,5,1000]; _brit = 0; +private _explSoundData = GVAR(sound_electric_explsion_impact_large); // local only, last param -playSound3D [QGVAR(sound_electric_explsion_impact_large), nil, false, _origin, 1, 1, 3500, 0, true]; +playSound3D [_explSoundData get "filename", nil, false, _origin, _explSoundData get "volume", _explSoundData get "pitch", 3500, 0, true]; [_light_emp, _brit, _ripple2] spawn { params ["_light_emp", "_brit", "_ripple2"]; @@ -67,19 +68,16 @@ playSound3D [QGVAR(sound_electric_explsion_impact_large), nil, false, _origin, 1 _ripple setParticleParams [["\A3\data_f\ParticleEffects\Universal\Refract.p3d",1,0,1], "", "Billboard", 1, 1.5, [0, 0, 1], [0, 0, 0],0,10,7.9,0, [0,500], [[1, 1, 1, 1], [1, 1, 1, 1]], [0.05], 1, 0, "", "", objNull]; _ripple setDropInterval 10; - [{deleteVehicle _this}, _ripple, GVAR(maxBrightDelay) + 0.65] call CBA_fnc_waitAndExecute; + [{deleteVehicle _this}, _ripple, 0.65] call CBA_fnc_waitAndExecute; [{ - params [ - ["_toDelete", [], [[]]], - ["_toProcess", [], [[]]] - ]; + params ["_e_static2", "_e_static3", "_brit", "_light_emp", "_wave"]; { deleteVehicle _x; - } forEach _toDelete; + } forEach [_e_static2, _e_static3]; - _toProcess spawn { - params ["_brit", "_light_emp", "_wave"]; + [_light_emp, _brit, _wave] spawn { + params ["_light_emp", "_brit", "_wave"]; while {_brit > 0} do { _light_emp setLightBrightness _brit; _brit = _brit-2; @@ -88,7 +86,7 @@ playSound3D [QGVAR(sound_electric_explsion_impact_large), nil, false, _origin, 1 deleteVehicle _light_emp; deleteVehicle _wave; }; - }, [[_e_static2, _e_static3], [6.5, _light_emp, _wave]], GVAR(maxBrightDelay) + 0.85] call CBA_fnc_waitAndExecute; + }, [[_e_static2, _e_static3, 6.5, _light_emp, _wave]], 0.85] call CBA_fnc_waitAndExecute; }, [_origin, _light_emp], GVAR(maxBrightDelay)] call CBA_fnc_waitAndExecute; @@ -96,7 +94,8 @@ playSound3D [QGVAR(sound_electric_explsion_impact_large), nil, false, _origin, 1 [{ params ["_origin"]; - _echosound = selectRandom [QGVAR(sound_ecou),QGVAR(sound_echo3)]; + private _echosound = selectRandom (keys GVAR(echoSounds)); + private _echoSoundData = GVAR(echoSounds) get _echosound; // local only, last param - playSound3d [_echosound, nil, false, _origin, 1, 1, 4000, 0, true]; + playSound3D [_echoSoundData get "filename", nil, false, _origin, _echoSoundData get "volume", _echoSoundData get "pitch", 4000, 0, true]; }, [_origin], GVAR(maxBrightDelay) + 0.65 + 2] call CBA_fnc_waitAndExecute; \ No newline at end of file diff --git a/framework/emp/functions/fn_playLocalEffectsForObject.sqf b/framework/emp/functions/fn_playLocalEffectsForObject.sqf index a81cb81..32bafaa 100644 --- a/framework/emp/functions/fn_playLocalEffectsForObject.sqf +++ b/framework/emp/functions/fn_playLocalEffectsForObject.sqf @@ -24,8 +24,9 @@ private _flickerHandle = [_object] spawn { _object setVariable [QGVAR(flickerHandle), _flickerHandle]; // sound -private _spark_sound = GVAR(zapSounds) call BIS_fnc_selectRandom; -playSound3D [_spark_sound, _object, false, getPosASL _object, 1, 1, 20, 0, true]; +private _spark_sound = selectRandom (keys GVAR(zapSounds)); +private _sparkSoundData = GVAR(zapSounds) get _spark_sound; +playSound3D [_sparkSoundData get "filename", _object, false, getPosASL _object, _sparkSoundData get "volume", _sparkSoundData get "pitch", 75, 0, true]; // particle effect private _e_static = "#particlesource" createVehicleLocal (getPosATL _object); @@ -65,7 +66,8 @@ if (_spark_type=="orange") then _scantei_spark setDropInterval 0.001; }; -private _spark_sound = GVAR(zapSounds) call BIS_fnc_selectRandom; -playSound3D [_spark_sound, _scantei_spark, false, getPosASL _object, 1, 1, 20, 0, true]; +private _spark_sound = selectRandom (keys GVAR(zapSounds)); +private _sparkSoundData = GVAR(zapSounds) get _spark_sound; +playSound3D [_sparkSoundData get "filename", _object, false, getPosASL _object, _sparkSoundData get "volume", _sparkSoundData get "pitch", 75, 0, true]; [{deleteVehicle _this;}, _scantei_spark, 0.4 + (random 0.7)] call CBA_fnc_waitAndExecute; \ No newline at end of file diff --git a/framework/emp/functions/fn_removeUnitElectricInventoryItems.sqf b/framework/emp/functions/fn_removeUnitElectricInventoryItems.sqf new file mode 100644 index 0000000..18eb3d7 --- /dev/null +++ b/framework/emp/functions/fn_removeUnitElectricInventoryItems.sqf @@ -0,0 +1,53 @@ +#include "..\script_component.hpp" + +// Executed where object is local and removes electronics from inventory + +params [["_object", objNull, [objNull]]]; +if (isNull _object) exitWith {}; +if (not (_object isKindOf "CAManBase")) exitWith {["Param _object is not a unit", _object] call BIS_fnc_error}; + +// process unit inventory +{ + _object unassignItem _x; + _object removeItem _x; +} forEach ((items _object) + (assignedItems _object)) select {[_x] call FUNC(isItemElectronic)}; + +// replace backpack radio with base and restore items +if (isClass (configFile >> "CfgPatches" >> "tfar_core")) then { + private _backpackRadio = _object call TFAR_fnc_backpackLR; + if (!isNil "_backpackRadio") then { + _backpackRadio params ["_actualBackpack", "settings"]; + private _baseBackpack = _actualBackpack call BIS_fnc_basicBackpack; + private _backpackItems = backpackItems _object; + + removeBackpack _object; + _object addBackpack _baseBackpack; + + { + _object addItemToBackpack _x; + } forEach _backpackItems; + }; +}; + +//for player units +if (isPlayer _object) then { + _object action ["IRLaserOff", _object]; + _object action ["nvGogglesOff", _object]; +}; + +// remove flashlights/pointers on weapons +private _primaryFlashlightOrPointer = (primaryWeaponItems _object)#1; +if (_primaryFlashlightOrPointer != "") then { + _object removePrimaryWeaponItem _primaryFlashlightOrPointer; + _object removeItem _primaryFlashlightOrPointer; +}; +private _secondaryFlashlightOrPointer = (secondaryWeaponItems _object)#1; +if (_secondaryFlashlightOrPointer != "") then { + _object removeSecondaryWeaponItem _secondaryFlashlightOrPointer; + _object removeItem _secondaryFlashlightOrPointer; +}; +private _handgunFlashlightOrPointer = (handgunItems _object)#1; +if (_handgunFlashlightOrPointer != "") then { + _object removeHandgunItem _handgunFlashlightOrPointer; + _object removeItem _handgunFlashlightOrPointer; +}; diff --git a/framework/emp/functions/fn_removeVehicleElectricInventoryItems.sqf b/framework/emp/functions/fn_removeVehicleElectricInventoryItems.sqf new file mode 100644 index 0000000..766c667 --- /dev/null +++ b/framework/emp/functions/fn_removeVehicleElectricInventoryItems.sqf @@ -0,0 +1,34 @@ +#include "..\script_component.hpp" + +// Executed where object is local and removes electronics from inventory + +params [["_object", objNull, [objNull]]]; +if (isNull _object) exitWith {}; +if (_object isKindOf "CAManBase") exitWith {["Param _object is not a vehicle: %1", _object] call BIS_fnc_error}; + + +// get all items in vehicle that are electronic +private _vehicleItems = itemCargo _object; +// filter array to identify electronic items +_vehicleItems = _vehicleItems select {[_x] call FUNC(isItemElectronic)}; +{ + // remove item from vehicle + _object addItemCargoGlobal [_x, -1]; + true; +} count _vehicleItems; + +{ // forEach everyContainer _object - process vests, uniforms, backpacks in a vehicle + _x params ["_containerClass", "_containerObject"]; + private _subItemsOfContainer = itemCargo _containerObject; + // filter array to identify electronic items + _subItemsOfContainer = _subItemsOfContainer select {[_x] call FUNC(isItemElectronic)}; + { + // remove item from container + _subContainer addItemCargoGlobal [_x, -1]; + true; + } count _subItemsOfContainer; +} forEach (everyContainer _object); + + +// vehicle is now empty of electronics +// built-in vehicle radios cannot be removed and are left in place \ No newline at end of file