From 6ca44739951a4fa633a309842779175f7a5e2a1a Mon Sep 17 00:00:00 2001 From: McDiod Date: Wed, 14 Nov 2018 19:09:41 +0100 Subject: [PATCH 01/10] waverespawn improvements --- functions/endings/fn_endMissionServer.sqf | 1 + functions/endings/fn_presetElimination.sqf | 69 +++++++++++++------ functions/endings/fn_startPreset.sqf | 2 +- functions/waverespawn/cfgFunctions.hpp | 2 + functions/waverespawn/fn_addToWaiting.sqf | 27 ++++++++ functions/waverespawn/fn_addToWave.sqf | 24 +++---- functions/waverespawn/fn_canRespawn.sqf | 6 +- .../waverespawn/fn_checkEnoughForWave.sqf | 35 ++++++++++ functions/waverespawn/fn_getStatus.sqf | 6 +- functions/waverespawn/fn_init.sqf | 15 ++-- functions/waverespawn/fn_onPlayerKilled.sqf | 9 ++- functions/waverespawn/fn_onPlayerRespawn.sqf | 3 + functions/waverespawn/fn_prepareRespawn.sqf | 1 + functions/waverespawn/fn_removeFromWave.sqf | 30 ++++---- functions/waverespawn/fn_startWaveLoops.sqf | 8 +-- onPlayerRespawn.sqf | 2 +- 16 files changed, 173 insertions(+), 67 deletions(-) create mode 100644 functions/waverespawn/fn_addToWaiting.sqf create mode 100644 functions/waverespawn/fn_checkEnoughForWave.sqf diff --git a/functions/endings/fn_endMissionServer.sqf b/functions/endings/fn_endMissionServer.sqf index 94cf786..3f428d8 100644 --- a/functions/endings/fn_endMissionServer.sqf +++ b/functions/endings/fn_endMissionServer.sqf @@ -1,5 +1,6 @@ #include "component.hpp" +// do not add default values here - some params are nil by design and will be read from config in fnc_endMissionClient params ["_configName","_winText","_winners","_winTextParams"]; if (missionNamespace getVariable ["grad_endings_endingInProgress",false]) exitWith {}; diff --git a/functions/endings/fn_presetElimination.sqf b/functions/endings/fn_presetElimination.sqf index aa15499..6a0842c 100644 --- a/functions/endings/fn_presetElimination.sqf +++ b/functions/endings/fn_presetElimination.sqf @@ -1,45 +1,70 @@ #include "component.hpp" -#define PLAYABLE_UNITS (playableUnits + switchableUnits) -params ["_winName","_sides"]; -_sides = _sides apply {call compile _x}; +params ["_winName","_sides",["_isRecursion",false],["_taskID","taskElimination"]]; -private _winners = [missionConfigFile >> "CfgWinConditions" >> _winName, "winners",[]] call BIS_fnc_returnConfigEntry; -_winners = _winners apply {call compile _x}; -//CREATE TASK ================================================================== -private _taskID = "taskElimination"; -{_taskID = _taskID + "_w" + str _x} forEach _winners; -{_taskID = _taskID + "_l" + str _x} forEach _sides; +if (!_isRecursion) then { + _sides = _sides apply {call compile _x}; -private _taskDesc = format ["Eliminate all players of side %1",[_sides select 0] call grad_common_fnc_getSideDisplayName]; + _winners = [missionConfigFile >> "CfgWinConditions" >> _winName, "winners",[]] call BIS_fnc_returnConfigEntry; + _winners = _winners apply {call compile _x}; + + //CREATE TASK ================================================================== + {_taskID = _taskID + "_w" + str _x} forEach _winners; + {_taskID = _taskID + "_l" + str _x} forEach _sides; + + _taskDesc = format ["Eliminate all players of side %1",[_sides select 0] call grad_common_fnc_getSideDisplayName]; + { + if (_forEachIndex > 0) then { + _taskDesc = _taskDesc + "and " + ([_x] call grad_common_fnc_getSideDisplayName); + }; + } forEach _sides; + _taskDesc = _taskDesc + "."; + + [_taskID,_winners,[_taskDesc,"Eliminate Enemies",""],objNull,"AUTOASSIGNED",3,true,true,"kill"] call BIS_fnc_setTask; +}; + +//PFH ========================================================================== +private _respawningPlayersArrays = []; { - if (_forEachIndex > 0) then { - _taskDesc = _taskDesc + "and " + ([_x] call grad_common_fnc_getSideDisplayName); + _array = switch (_x) do { + case (WEST): {waitingPlayersBlu}; + case (EAST): {waitingPlayersOpf}; + case (INDEPENDENT): {waitingPlayersInd}; + default {[]}; }; + _respawningPlayersArrays pushBack _array; } forEach _sides; -_taskDesc = _taskDesc + "."; -[_taskID,_winners,[_taskDesc,"Eliminate Enemies",""],objNull,"AUTOASSIGNED",3,true,true,"kill"] call BIS_fnc_setTask; +private _fnc_check = [ + { + {(side _x) in _sides} count playableUnits == 0 + }, + { + {(side _x) in _sides} count playableUnits == 0 && + {{({!isNull _x} count _x) > 0} count _respawningPlayersArrays == 0} + } +] select (([missionConfigFile >> "missionsettings","waveRespawnEnabled",0] call BIS_fnc_returnConfigEntry) == 1); + +diag_log ["_fnc_check",_fnc_check]; -//PFH ========================================================================== [{ params ["_args","_handle"]; - _args params ["_winName","_sides","_taskID"]; + _args params ["_winName","_sides","_taskID","_fnc_check","_respawningPlayersArrays"]; - if ({_side = _x; ({side _x == _side} count PLAYABLE_UNITS) > 0} count _sides == 0) exitWith { + if (call _fnc_check) exitWith { [{ - params ["_winName","_sides","_taskID"]; - if ({_side = _x; ({side _x == _side} count PLAYABLE_UNITS) > 0} count _sides == 0) then { + params ["_winName","_sides","_taskID","_fnc_check","_respawningPlayersArrays"]; + if (call _fnc_check) then { [_taskID,"SUCCEEDED",true] call BIS_fnc_taskSetState; [_winName] call grad_endings_fnc_endMissionServer; } else { - _this call grad_endings_fnc_presetElimination; + [_winName,_sides,true,_taskID] call grad_endings_fnc_presetElimination; }; - }, [_winName,_sides,_taskID], 10] call CBA_fnc_waitAndExecute; + }, [_winName,_sides,_taskID,_fnc_check,_respawningPlayersArrays], 10] call CBA_fnc_waitAndExecute; [_handle] call CBA_fnc_removePerFrameHandler; }; -},10,[_winName,_sides,_taskID]] call CBA_fnc_addPerFrameHandler; +},10,[_winName,_sides,_taskID,_fnc_check,_respawningPlayersArrays]] call CBA_fnc_addPerFrameHandler; diff --git a/functions/endings/fn_startPreset.sqf b/functions/endings/fn_startPreset.sqf index 7b665a6..d9c2353 100644 --- a/functions/endings/fn_startPreset.sqf +++ b/functions/endings/fn_startPreset.sqf @@ -3,7 +3,7 @@ params ["_winCondition"]; private _preset = [_winCondition,"preset",""] call BIS_fnc_returnConfigEntry; -private _presetParams = [_winCondition,"presetParams",[]] call BIS_fnc_returnConfigEntry; +private _presetParams = [_winCondition,"presetParams",[]] call BIS_fnc_returnConfigEntry;; private _winName = configName _winCondition; INFO_2("Initializing preset %1 (%2).",_preset,_winName); diff --git a/functions/waverespawn/cfgFunctions.hpp b/functions/waverespawn/cfgFunctions.hpp index 308fce3..36e9a99 100644 --- a/functions/waverespawn/cfgFunctions.hpp +++ b/functions/waverespawn/cfgFunctions.hpp @@ -1,7 +1,9 @@ class GRAD_waverespawn { class waverespawn { + class addToWaiting {}; class addToWave {}; class canRespawn {}; + class checkEnoughForWave {}; class getStatus {}; class init {postInit = 1;}; class onPlayerKilled {}; diff --git a/functions/waverespawn/fn_addToWaiting.sqf b/functions/waverespawn/fn_addToWaiting.sqf new file mode 100644 index 0000000..af93f77 --- /dev/null +++ b/functions/waverespawn/fn_addToWaiting.sqf @@ -0,0 +1,27 @@ +#include "component.hpp" + +params ["_deadPlayer",["_deadPlayerSide", sideUnknown],["_add",true]]; + +if (isNil "waitingPlayersBlu") then {waitingPlayersBlu = []}; +if (isNil "waitingPlayersOpf") then {waitingPlayersOpf = []}; +if (isNil "waitingPlayersInd") then {waitingPlayersInd = []}; + +//add player to array +private _array = switch (_deadPlayerSide) do { + case (WEST): {waitingPlayersBlu}; + case (EAST): {waitingPlayersOpf}; + case (INDEPENDENT): {waitingPlayersInd}; + default {[]}; +}; + +if (_add) then { + _array pushBackUnique _deadPlayer +} else { + _id = _array find _deadPlayer; + while {_id >= 0} do { + _array deleteAt _id; + _id = _array find _deadPlayer; + }; +}; + +[_deadPlayerSide] call grad_waverespawn_fnc_checkEnoughForWave; diff --git a/functions/waverespawn/fn_addToWave.sqf b/functions/waverespawn/fn_addToWave.sqf index ab06ae3..714a146 100644 --- a/functions/waverespawn/fn_addToWave.sqf +++ b/functions/waverespawn/fn_addToWave.sqf @@ -2,30 +2,30 @@ params ["_deadPlayerName", ["_deadPlayerSide", sideUnknown]]; -if (isNil "deadPlayersBlu") then {deadPlayersBlu = []}; -if (isNil "deadPlayersOpf") then {deadPlayersOpf = []}; -if (isNil "deadPlayersInd") then {deadPlayersInd = []}; +if (isNil "wavePlayernamesBlu") then {wavePlayernamesBlu = []}; +if (isNil "wavePlayernamesOpf") then {wavePlayernamesOpf = []}; +if (isNil "wavePlayernamesInd") then {wavePlayernamesInd = []}; _deadPlayerName = [_deadPlayerName] call BIS_fnc_filterString; //add player to array switch (_deadPlayerSide) do { case (WEST): { - deadPlayersBlu pushBackUnique _deadPlayerName; - INFO_2("Added player %1 to deadPlayersBlu. %2 dead blufor total.", _deadPlayerName, count deadPlayersBlu); - WAVERESPAWNPLAYERSLEFTBLU = BLUFORWAVESIZE - (count deadPlayersBlu); + wavePlayernamesBlu pushBackUnique _deadPlayerName; + INFO_2("Added player %1 to wavePlayernamesBlu. %2 dead blufor total.", _deadPlayerName, count wavePlayernamesBlu); + WAVERESPAWNPLAYERSLEFTBLU = BLUFORWAVESIZE - (count wavePlayernamesBlu); publicVariable "WAVERESPAWNPLAYERSLEFTBLU"; }; case (EAST): { - deadPlayersOpf pushBackUnique _deadPlayerName; - INFO_2("Added player %1 to deadPlayersOpf. %2 dead opfor total.", _deadPlayerName, count deadPlayersOpf); - WAVERESPAWNPLAYERSLEFTOPF = OPFORWAVESIZE - (count deadPlayersOpf); + wavePlayernamesOpf pushBackUnique _deadPlayerName; + INFO_2("Added player %1 to wavePlayernamesOpf. %2 dead opfor total.", _deadPlayerName, count wavePlayernamesOpf); + WAVERESPAWNPLAYERSLEFTOPF = OPFORWAVESIZE - (count wavePlayernamesOpf); publicVariable "WAVERESPAWNPLAYERSLEFTOPF"; }; case (INDEPENDENT): { - deadPlayersInd pushBackUnique _deadPlayerName; - INFO_2("Added player %1 to deadPlayersOpf. %2 dead opfor total.", _deadPlayerName, count deadPlayersInd); - WAVERESPAWNPLAYERSLEFTIND = INDEPWAVESIZE - (count deadPlayersInd); + wavePlayernamesInd pushBackUnique _deadPlayerName; + INFO_2("Added player %1 to wavePlayernamesOpf. %2 dead opfor total.", _deadPlayerName, count wavePlayernamesInd); + WAVERESPAWNPLAYERSLEFTIND = INDEPWAVESIZE - (count wavePlayernamesInd); publicVariable "WAVERESPAWNPLAYERSLEFTIND"; }; default { diff --git a/functions/waverespawn/fn_canRespawn.sqf b/functions/waverespawn/fn_canRespawn.sqf index d43e165..0995763 100644 --- a/functions/waverespawn/fn_canRespawn.sqf +++ b/functions/waverespawn/fn_canRespawn.sqf @@ -4,15 +4,15 @@ params ["_side"]; _canRespawn = switch (_side) do { case ("WEST"): { - count deadPlayersBlu >= BLUFORWAVESIZE && + count wavePlayernamesBlu >= BLUFORWAVESIZE && WAVERESPAWNTIMELEFTBLU <= 0 }; case ("EAST"): { - count deadPlayersOpf >= OPFORWAVESIZE && + count wavePlayernamesOpf >= OPFORWAVESIZE && WAVERESPAWNTIMELEFTOPF <= 0 }; case ("INDEPENDENT"): { - count deadPlayersInd >= INDEPWAVESIZE && + count wavePlayernamesInd >= INDEPWAVESIZE && WAVERESPAWNTIMELEFTIND <= 0 }; default { diff --git a/functions/waverespawn/fn_checkEnoughForWave.sqf b/functions/waverespawn/fn_checkEnoughForWave.sqf new file mode 100644 index 0000000..56daf44 --- /dev/null +++ b/functions/waverespawn/fn_checkEnoughForWave.sqf @@ -0,0 +1,35 @@ +/* sets respawn interrupted, if remaining players are not enough for a full wave +*/ + +#include "component.hpp" + +params ["_side",["_iteration",0]]; + +private _waitingPlayersArray = switch (_side) do { + case (WEST): {waitingPlayersBlu}; + case (EAST): {waitingPlayersOpf}; + case (INDEPENDENT): {waitingPlayersInd}; + default {[]}; +}; + + +// exit here if it's the second iteration (so players have either been dead or unconscious for 10s) +if (_iteration == 2) exitWith { + { + _x setVariable ["wr_interrupted",true,true]; + } forEach _waitingPlayersArray; +}; + + +private _waveSize = switch (_side) do { + case (WEST): {BLUFORWAVESIZE}; + case (EAST): {OPFORWAVESIZE}; + case (INDEPENDENT): {INDEPWAVESIZE}; + default {-1}; +}; +if (_waveSize < 0) exitWith {}; + + +if ((({side _x == _side} count playableUnits) + (count _waitingPlayersArray)) < _waveSize) then { + [grad_waverespawn_fnc_checkEnoughForWave,[_side,_iteration + 1],5] call CBA_fnc_waitAndExecute; +}; diff --git a/functions/waverespawn/fn_getStatus.sqf b/functions/waverespawn/fn_getStatus.sqf index 132616d..c357306 100644 --- a/functions/waverespawn/fn_getStatus.sqf +++ b/functions/waverespawn/fn_getStatus.sqf @@ -9,7 +9,7 @@ if (_side == WEST) then { case (WAVERESPAWNTIMELEFTBLU > 0): { "Waiting for wave-countdown."; }; - case (count deadPlayersBlu < BLUFORWAVESIZE): { + case (count wavePlayernamesBlu < BLUFORWAVESIZE): { "Waiting for more players."; }; default { @@ -23,7 +23,7 @@ if (_side == EAST) then { case (OPFORWAVESIZE > 0): { "Waiting for wave-countdown."; }; - case (count deadPlayersOpf < OPFORWAVESIZE): { + case (count wavePlayernamesOpf < OPFORWAVESIZE): { "Waiting for more players."; }; default { @@ -37,7 +37,7 @@ if (_side == INDEPENDENT) then { case (INDEPWAVESIZE > 0): { "Waiting for wave-countdown."; }; - case (count deadPlayersInd < INDEPWAVESIZE): { + case (count wavePlayernamesInd < INDEPWAVESIZE): { "Waiting for more players."; }; default { diff --git a/functions/waverespawn/fn_init.sqf b/functions/waverespawn/fn_init.sqf index 996ab85..4f8987b 100644 --- a/functions/waverespawn/fn_init.sqf +++ b/functions/waverespawn/fn_init.sqf @@ -2,9 +2,12 @@ if (([missionConfigFile >> "missionsettings","waveRespawnEnabled",0] call BIS_fnc_returnConfigEntry) == 0) exitWith {}; -deadPlayersBlu = []; -deadPlayersOpf = []; -deadPlayersInd = []; +wavePlayernamesBlu = []; +wavePlayernamesOpf = []; +wavePlayernamesInd = []; +waitingPlayersBlu = []; +waitingPlayersOpf = []; +waitingPlayersInd = []; newBluSpawns = []; newOpfSpawns = []; newIndSpawns = []; @@ -12,7 +15,11 @@ newIndSpawns = []; if (isServer) then { [] call grad_waverespawn_fnc_setWaveSize; [] call grad_waverespawn_fnc_startWaveLoops; - addMissionEventHandler ["HandleDisconnect", {[_this select 0,side (_this select 0)] call grad_waverespawn_fnc_removeFromWave}]; + addMissionEventHandler ["HandleDisconnect", { + params [["_unit",objNull],"","",["_name",""]]; + [_name,side _unit] call grad_waverespawn_fnc_removeFromWave; + [_unit,side _unit,false] call grad_waverespawn_fnc_addToWaiting; + }]; }; if (hasInterface) then { diff --git a/functions/waverespawn/fn_onPlayerKilled.sqf b/functions/waverespawn/fn_onPlayerKilled.sqf index 680866c..936be72 100644 --- a/functions/waverespawn/fn_onPlayerKilled.sqf +++ b/functions/waverespawn/fn_onPlayerKilled.sqf @@ -10,7 +10,7 @@ if (player getVariable ["wr_interrupted", false]) exitWith {}; [] call grad_waverespawn_fnc_resetPlayerVars; //check JIP player is spawning for the first time -_joinTime = player getVariable ["joinTime", 0]; +private _joinTime = player getVariable ["joinTime", 0]; if (serverTime - _joinTime < 30 && didJIP) exitWith {INFO("Player is JIP. Exiting onPlayerKilled.")}; ["Terminate"] call BIS_fnc_EGSpectator; @@ -22,7 +22,12 @@ private _maxRespawns = switch (playerSide) do { case (INDEPENDENT): {[missionConfigFile >> "missionsettings","indepWaveLifes",9999] call BIS_fnc_returnConfigEntry}; default {9999}; }; -if (player getVariable ["wr_respawnCount",0] >= _maxRespawns) then {player setVariable ["wr_interrupted",true]}; + +if (player getVariable ["wr_respawnCount",0] >= _maxRespawns) then { + player setVariable ["wr_interrupted",true,true] +} else { + [player,playerSide] remoteExec ["grad_waverespawn_fnc_addToWaiting",2,false]; +}; INFO("Starting waverespawn procedure..."); player setVariable ["wr_timeOfDeath",CBA_missionTime]; diff --git a/functions/waverespawn/fn_onPlayerRespawn.sqf b/functions/waverespawn/fn_onPlayerRespawn.sqf index 67a64f5..c21aee1 100644 --- a/functions/waverespawn/fn_onPlayerRespawn.sqf +++ b/functions/waverespawn/fn_onPlayerRespawn.sqf @@ -1,6 +1,9 @@ #include "component.hpp" +params ["",["_oldUnit",objNull]]; + [profileName,playerSide] remoteExec ["grad_waverespawn_fnc_removeFromWave",2,false]; +[_oldUnit,playerSide,false] remoteExec ["grad_waverespawn_fnc_addToWaiting",2,false]; setPlayerRespawnTime 99999; diff --git a/functions/waverespawn/fn_prepareRespawn.sqf b/functions/waverespawn/fn_prepareRespawn.sqf index 7a70e18..9d78f65 100644 --- a/functions/waverespawn/fn_prepareRespawn.sqf +++ b/functions/waverespawn/fn_prepareRespawn.sqf @@ -12,6 +12,7 @@ if (player getVariable ["wr_interrupted", false]) exitWith { ["Terminate"] call BIS_fnc_EGSpectator; ["Initialize", [player, [WEST,EAST,INDEPENDENT], true]] call BIS_fnc_EGSpectator; + [player,playerSide,false] remoteExec ["grad_waverespawn_fnc_addToWaiting",2,false]; _explanation = parseText format ["%1", "No respawn available."]; [playerSide, _explanation] call grad_waverespawn_fnc_respawnHint; diff --git a/functions/waverespawn/fn_removeFromWave.sqf b/functions/waverespawn/fn_removeFromWave.sqf index 68b6afd..526ac0c 100644 --- a/functions/waverespawn/fn_removeFromWave.sqf +++ b/functions/waverespawn/fn_removeFromWave.sqf @@ -6,29 +6,29 @@ _unitName = [_unitName] call BIS_fnc_filterString; switch (_side) do { case (WEST): { - if (_unitName in deadPlayersBlu) then { - deadPlayersBlu deleteAt (([deadPlayersBlu,_unitName] call BIS_fnc_arrayFindDeep) select 0); - INFO_1("Player %1 respawned and has been removed from deadPlayersBlu.", _unitName); + if (_unitName in wavePlayernamesBlu) then { + wavePlayernamesBlu deleteAt (([wavePlayernamesBlu,_unitName] call BIS_fnc_arrayFindDeep) select 0); + INFO_1("Player %1 respawned and has been removed from wavePlayernamesBlu.", _unitName); } else { - ERROR_1("Player %1 is not in deadPlayersBlu.", _unitName); + ERROR_1("Player %1 is not in wavePlayernamesBlu.", _unitName); }; }; case (EAST): { - if (_unitName in deadPlayersOpf) then { - deadPlayersOpf deleteAt (([deadPlayersOpf,_unitName] call BIS_fnc_arrayFindDeep) select 0); - INFO_1("Player %1 respawned and has been removed from deadPlayersOpf.", _unitName); + if (_unitName in wavePlayernamesOpf) then { + wavePlayernamesOpf deleteAt (([wavePlayernamesOpf,_unitName] call BIS_fnc_arrayFindDeep) select 0); + INFO_1("Player %1 respawned and has been removed from wavePlayernamesOpf.", _unitName); } else { - ERROR_1("Player %1 is not in deadPlayersOpf", _unitName); + ERROR_1("Player %1 is not in wavePlayernamesOpf", _unitName); }; }; case (INDEPENDENT): { - if (_unitName in deadPlayersInd) then { - deadPlayersInd deleteAt (([deadPlayersInd,_unitName] call BIS_fnc_arrayFindDeep) select 0); - INFO_1("Player %1 respawned and has been removed from deadPlayersInd.", _unitName); + if (_unitName in wavePlayernamesInd) then { + wavePlayernamesInd deleteAt (([wavePlayernamesInd,_unitName] call BIS_fnc_arrayFindDeep) select 0); + INFO_1("Player %1 respawned and has been removed from wavePlayernamesInd.", _unitName); } else { - ERROR_1("Player %1 is not in deadPlayersInd", _unitName); + ERROR_1("Player %1 is not in wavePlayernamesInd", _unitName); }; }; @@ -36,9 +36,9 @@ switch (_side) do { }; [{ - WAVERESPAWNPLAYERSLEFTBLU = BLUFORWAVESIZE - (count deadPlayersBlu); - WAVERESPAWNPLAYERSLEFTOPF = OPFORWAVESIZE - (count deadPlayersOpf); - WAVERESPAWNPLAYERSLEFTIND = INDEPWAVESIZE - (count deadPlayersInd); + WAVERESPAWNPLAYERSLEFTBLU = BLUFORWAVESIZE - (count wavePlayernamesBlu); + WAVERESPAWNPLAYERSLEFTOPF = OPFORWAVESIZE - (count wavePlayernamesOpf); + WAVERESPAWNPLAYERSLEFTIND = INDEPWAVESIZE - (count wavePlayernamesInd); publicVariable "WAVERESPAWNPLAYERSLEFTBLU"; publicVariable "WAVERESPAWNPLAYERSLEFTOPF"; publicVariable "WAVERESPAWNPLAYERSLEFTIND"; diff --git a/functions/waverespawn/fn_startWaveLoops.sqf b/functions/waverespawn/fn_startWaveLoops.sqf index 241bf80..febafba 100644 --- a/functions/waverespawn/fn_startWaveLoops.sqf +++ b/functions/waverespawn/fn_startWaveLoops.sqf @@ -8,7 +8,7 @@ if (WAVERESPAWNBLU) exitWith {}; //start countdown once first player is added to wave - if (count deadPlayersBlu > 0) then { + if (count wavePlayernamesBlu > 0) then { WAVERESPAWNTIMELEFTBLU = (WAVERESPAWNTIMELEFTBLU - 1) max 0; publicVariable "WAVERESPAWNTIMELEFTBLU"; } else { @@ -26,7 +26,7 @@ WAVERESPAWNBLU = false; publicVariable "WAVERESPAWNBLU"; WAVERESPAWNTIMELEFTBLU = WAVERESPAWNTIMEBLU; - publicVariable "WAVERESPAWNTIMELEFTBLU"; + publicVariable "WAVERESPAWNTIMELEFTBLU"; INFO("Respawning no longer possible for Blufor."); },[],(RESPAWNWAVEEXTRATIME max 7)] call CBA_fnc_waitAndExecute; }; @@ -41,7 +41,7 @@ if (WAVERESPAWNOPF) exitWith {}; //start countdown once first player is added to wave - if (count deadPlayersOpf > 0) then { + if (count wavePlayernamesOpf > 0) then { WAVERESPAWNTIMELEFTOPF = (WAVERESPAWNTIMELEFTOPF - 1) max 0; publicVariable "WAVERESPAWNTIMELEFTOPF"; } else { @@ -74,7 +74,7 @@ if (WAVERESPAWNIND) exitWith {}; //start countdown once first player is added to wave - if (count deadPlayersInd > 0) then { + if (count wavePlayernamesInd > 0) then { WAVERESPAWNTIMELEFTIND = (WAVERESPAWNTIMELEFTIND - 1) max 0; publicVariable "WAVERESPAWNTIMELEFTIND"; } else { diff --git a/onPlayerRespawn.sqf b/onPlayerRespawn.sqf index e0bcf30..0045711 100644 --- a/onPlayerRespawn.sqf +++ b/onPlayerRespawn.sqf @@ -1,5 +1,5 @@ ["Terminate"] call BIS_fnc_EGSpectator; if (([missionConfigFile >> "missionsettings","waveRespawnEnabled",0] call BIS_fnc_returnConfigEntry) == 1) then { - [] call grad_waverespawn_fnc_onPlayerRespawn; + _this call grad_waverespawn_fnc_onPlayerRespawn; }; From 961b8104d8a11b7a0cf2cf66bc6c29feb23df479 Mon Sep 17 00:00:00 2001 From: McDiod Date: Wed, 14 Nov 2018 19:39:23 +0100 Subject: [PATCH 02/10] remove unnecessary diag_log --- functions/endings/fn_presetElimination.sqf | 2 -- 1 file changed, 2 deletions(-) diff --git a/functions/endings/fn_presetElimination.sqf b/functions/endings/fn_presetElimination.sqf index 6a0842c..5f8aaa1 100644 --- a/functions/endings/fn_presetElimination.sqf +++ b/functions/endings/fn_presetElimination.sqf @@ -46,8 +46,6 @@ private _fnc_check = [ } ] select (([missionConfigFile >> "missionsettings","waveRespawnEnabled",0] call BIS_fnc_returnConfigEntry) == 1); -diag_log ["_fnc_check",_fnc_check]; - [{ params ["_args","_handle"]; _args params ["_winName","_sides","_taskID","_fnc_check","_respawningPlayersArrays"]; From 4a562731c79501b6d2284e74bcde72ff78a70ab1 Mon Sep 17 00:00:00 2001 From: McDiod Date: Tue, 20 Nov 2018 18:46:07 +0100 Subject: [PATCH 03/10] fix script error in fn_addPoints with sector control --- functions/points/fn_addPoints.sqf | 6 ++---- functions/sectors/fn_startPFH.sqf | 4 +--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/functions/points/fn_addPoints.sqf b/functions/points/fn_addPoints.sqf index 32eb5b7..b60056e 100644 --- a/functions/points/fn_addPoints.sqf +++ b/functions/points/fn_addPoints.sqf @@ -5,6 +5,8 @@ if (!isServer) exitWith {_this remoteExec ["grad_points_fnc_addPoints",2,false]} params ["_side","_points",["_category","Other"]]; private ["_newPoints","_categoriesVarName"]; +if (_side == sideUnknown) exitWith {}; + switch (_side) do { case (WEST): { _newPoints = (missionNamespace getVariable ["grad_common_points_west",0]) + _points; @@ -32,13 +34,9 @@ switch (_side) do { }; default { _newPoints = 0; - _categoriesVarName = "none"; }; }; -// fix for empty side -if (_categoriesVarName isEqualTo "none") exitWith { 0 }; - private _categories = missionNamespace getVariable _categoriesVarName; private _resultID = [_categories,_category] call BIS_fnc_findInPairs; diff --git a/functions/sectors/fn_startPFH.sqf b/functions/sectors/fn_startPFH.sqf index af2a826..e633910 100644 --- a/functions/sectors/fn_startPFH.sqf +++ b/functions/sectors/fn_startPFH.sqf @@ -3,8 +3,6 @@ params ["_trigger"]; INFO_1("PFH for %1 starting.",_trigger getVariable "grad_sectors_sectorName"); -[_trigger] call grad_sectors_fnc_updateMarker; - [{ params ["_trigger","_handle"]; if (isNull _trigger) exitWith { @@ -17,7 +15,7 @@ INFO_1("PFH for %1 starting.",_trigger getVariable "grad_sectors_sectorName"); _oldOwner = _trigger getVariable "grad_sectors_currentOwner"; _pps = _trigger getVariable "grad_sectors_pointsPerSecond"; - if (_pps > 0) then { + if (_pps > 0 && {_oldOwner != sideUnknown}) then { _categoryName = format ["Held %1",_trigger getVariable "grad_sectors_sectorName"]; [_oldOwner,_pps,_categoryName] call grad_points_fnc_addPoints; }; From 21eb964ada9b842bdbb03f649f2bbd38a11a34f9 Mon Sep 17 00:00:00 2001 From: McDiod Date: Tue, 20 Nov 2018 18:59:53 +0100 Subject: [PATCH 04/10] implement grad-replay --- description.ext | 13 + functions/endings/fn_endMissionServer.sqf | 38 +- functions/missionSetup/fn_initMission.sqf | 12 +- node_modules/@gruppe-adler/replay/LICENSE | 674 ++++++++++++++ node_modules/@gruppe-adler/replay/README.md | 61 ++ .../@gruppe-adler/replay/cfgFunctions.hpp | 47 + .../functions/player/fn_addReplayPart.sqf | 21 + .../functions/player/fn_animateShot.sqf | 94 ++ .../player/fn_assembleReplayData.sqf | 77 ++ .../functions/player/fn_createMapOverlay.sqf | 1 + .../replay/functions/player/fn_drawIcon.sqf | 35 + .../functions/player/fn_getColorFromID.sqf | 31 + .../functions/player/fn_getRecordEntry.sqf | 21 + .../replay/functions/player/fn_initReplay.sqf | 4 + .../player/fn_onPlaybackPosChanged.sqf | 16 + .../player/fn_preparePlaybackClient.sqf | 10 + .../functions/player/fn_receiveData.sqf | 26 + .../player/fn_removeDrawEventhandler.sqf | 10 + .../player/fn_setPlayPauseDisplay.sqf | 9 + .../functions/player/fn_setTimeDisplay.sqf | 8 + .../functions/player/fn_showHintPause.sqf | 14 + .../functions/player/fn_showHintPlay.sqf | 14 + .../player/fn_showHintReplayFinished.sqf | 17 + .../player/fn_showPlaybackControl.sqf | 20 + .../functions/player/fn_showProgressBar.sqf | 52 ++ .../player/fn_startPlaybackClient.sqf | 95 ++ .../player/fn_stopPlaybackClient.sqf | 9 + .../functions/player/fn_syncPlaybackPos.sqf | 3 + .../functions/player/script_component.hpp | 1 + .../replay/functions/script_component.hpp | 1 + .../functions/server/fn_canTrackUnit.sqf | 24 + .../functions/server/fn_getSideColorID.sqf | 9 + .../replay/functions/server/fn_init.sqf | 34 + .../replay/functions/server/fn_onFiredMan.sqf | 31 + .../functions/server/fn_pauseRecord.sqf | 3 + .../server/fn_preparePlaybackServer.sqf | 78 ++ .../functions/server/fn_setMeSpectator.sqf | 6 + .../functions/server/fn_startRecord.sqf | 115 +++ .../replay/functions/server/fn_stopRecord.sqf | 1 + .../replay/functions/server/fn_storeValue.sqf | 31 + .../functions/server/script_component.hpp | 1 + .../@gruppe-adler/replay/package.json | 87 ++ .../@gruppe-adler/replay/script_component.hpp | 4 + .../@gruppe-adler/replay/ui/defines.hpp | 819 ++++++++++++++++++ .../@gruppe-adler/replay/ui/dialog.hpp | 99 +++ .../@gruppe-adler/replay/ui/pause.paa | Bin 0 -> 24729 bytes node_modules/@gruppe-adler/replay/ui/play.paa | Bin 0 -> 25095 bytes node_modules/grad-factions-tvt/TEMPLATE.hpp | 2 +- .../grad-factions-tvt/factions/ger_heer_d.hpp | 2 +- .../grad-factions-tvt/factions/ger_heer_w.hpp | 19 +- .../factions/ind_eastern_nationalists.hpp | 11 +- .../factions/ind_me_terrorists.hpp | 4 +- .../factions/ind_pmc_special.hpp | 4 +- .../grad-factions-tvt/factions/rus_msv_w.hpp | 12 +- .../grad-factions-tvt/factions/us_army.hpp | 11 +- node_modules/grad-factions-tvt/package.json | 45 +- .../grad-fortifications/cfgFunctions.hpp | 1 + .../dialog/vehicle/dialog.hpp | 2 + .../functions/common/fn_addFort.sqf | 12 +- .../common/fn_addVehicleInteractions.sqf | 20 +- .../common/fn_getVehicleInventorySize.sqf | 15 +- .../functions/common/fn_initModule.sqf | 2 +- .../functions/common/fn_storageAction.sqf | 30 + .../functions/drop/fn_initDropCrate.sqf | 9 +- node_modules/grad-fortifications/package.json | 47 +- .../grad-listbuymenu/cfgFunctions.hpp | 2 + .../functions/buy/fn_vehicleMarker.sqf | 1 + .../functions/common/fn_addInteraction.sqf | 4 +- .../functions/common/fn_addStock.sqf | 12 + .../functions/common/fn_setStock.sqf | 11 + node_modules/grad-listbuymenu/package.json | 45 +- .../.idea/copyright/profiles_settings.xml | 3 - node_modules/grad-loadout/.idea/encodings.xml | 6 - .../grad-loadout/.idea/grad-loadout.iml | 8 - .../inspectionProfiles/Project_Default.xml | 11 - .../inspectionProfiles/profiles_settings.xml | 7 - .../grad-loadout/.idea/jsLibraryMappings.xml | 7 - node_modules/grad-loadout/.idea/misc.xml | 16 - node_modules/grad-loadout/.idea/modules.xml | 8 - .../.idea/typescript-compiler.xml | 7 - node_modules/grad-loadout/.idea/vcs.xml | 6 - node_modules/grad-loadout/.idea/workspace.xml | 799 ----------------- node_modules/grad-loadout/README.md | 50 +- node_modules/grad-loadout/cfgFunctions.hpp | 67 +- .../functions/api/fn_doLoadoutForUnit.sqf | 9 +- .../functions/api/fn_loadoutViewer.sqf | 504 +++++++++++ .../functions/api/fn_verifyLoadouts.sqf | 277 ++++++ .../fn_VanillaCivDefactionizer.sqf | 2 +- .../fn_vanillaMilitaryDefactionizer.sqf | 8 +- .../extract/fn_ExtractLoadoutFromConfig.sqf | 47 +- .../functions/extract/fn_GetPathExtractor.sqf | 8 +- .../functions/general/fn_DefactionizeType.sqf | 2 +- .../fn_NormalizeMagazinesInContent.sqf | 37 - .../functions/general/fn_addChatCommands.sqf | 17 + .../functions/general/fn_doLoadout.sqf | 4 +- .../general/fn_factionGetLoadout.sqf | 10 +- .../general/fn_factionSetLoadout.sqf | 9 +- .../general/fn_getApplicableUnits.sqf | 2 +- .../general/fn_getUnitLoadoutFromConfig.sqf | 3 +- .../general/fn_hashToUnitLoadout.sqf | 30 +- .../functions/general/fn_initGlobals.sqf | 4 +- .../general/fn_mergeLoadoutHierarchy.sqf | 2 +- .../functions/general/fn_normalizeContent.sqf | 55 ++ .../functions/general/fn_scheduleLoadout.sqf | 6 +- .../general/fn_weaponIsCompatibleMagazine.sqf | 3 +- .../functions/revivers/fn_addReviver.sqf | 13 +- .../functions/revivers/fn_applyRevivers.sqf | 23 +- .../functions/revivers/fn_getRevivers.sqf | 11 +- node_modules/grad-loadout/package.json | 49 +- package.json | 1 + 110 files changed, 4030 insertions(+), 1200 deletions(-) create mode 100644 node_modules/@gruppe-adler/replay/LICENSE create mode 100644 node_modules/@gruppe-adler/replay/README.md create mode 100644 node_modules/@gruppe-adler/replay/cfgFunctions.hpp create mode 100644 node_modules/@gruppe-adler/replay/functions/player/fn_addReplayPart.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/player/fn_animateShot.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/player/fn_assembleReplayData.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/player/fn_createMapOverlay.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/player/fn_drawIcon.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/player/fn_getColorFromID.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/player/fn_getRecordEntry.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/player/fn_initReplay.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/player/fn_onPlaybackPosChanged.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/player/fn_preparePlaybackClient.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/player/fn_receiveData.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/player/fn_removeDrawEventhandler.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/player/fn_setPlayPauseDisplay.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/player/fn_setTimeDisplay.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/player/fn_showHintPause.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/player/fn_showHintPlay.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/player/fn_showHintReplayFinished.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/player/fn_showPlaybackControl.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/player/fn_showProgressBar.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/player/fn_startPlaybackClient.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/player/fn_stopPlaybackClient.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/player/fn_syncPlaybackPos.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/player/script_component.hpp create mode 100644 node_modules/@gruppe-adler/replay/functions/script_component.hpp create mode 100644 node_modules/@gruppe-adler/replay/functions/server/fn_canTrackUnit.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/server/fn_getSideColorID.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/server/fn_init.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/server/fn_onFiredMan.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/server/fn_pauseRecord.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/server/fn_preparePlaybackServer.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/server/fn_setMeSpectator.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/server/fn_startRecord.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/server/fn_stopRecord.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/server/fn_storeValue.sqf create mode 100644 node_modules/@gruppe-adler/replay/functions/server/script_component.hpp create mode 100644 node_modules/@gruppe-adler/replay/package.json create mode 100644 node_modules/@gruppe-adler/replay/script_component.hpp create mode 100644 node_modules/@gruppe-adler/replay/ui/defines.hpp create mode 100644 node_modules/@gruppe-adler/replay/ui/dialog.hpp create mode 100644 node_modules/@gruppe-adler/replay/ui/pause.paa create mode 100644 node_modules/@gruppe-adler/replay/ui/play.paa create mode 100644 node_modules/grad-fortifications/functions/common/fn_storageAction.sqf create mode 100644 node_modules/grad-listbuymenu/functions/common/fn_addStock.sqf create mode 100644 node_modules/grad-listbuymenu/functions/common/fn_setStock.sqf delete mode 100644 node_modules/grad-loadout/.idea/copyright/profiles_settings.xml delete mode 100644 node_modules/grad-loadout/.idea/encodings.xml delete mode 100644 node_modules/grad-loadout/.idea/grad-loadout.iml delete mode 100644 node_modules/grad-loadout/.idea/inspectionProfiles/Project_Default.xml delete mode 100644 node_modules/grad-loadout/.idea/inspectionProfiles/profiles_settings.xml delete mode 100644 node_modules/grad-loadout/.idea/jsLibraryMappings.xml delete mode 100644 node_modules/grad-loadout/.idea/misc.xml delete mode 100644 node_modules/grad-loadout/.idea/modules.xml delete mode 100644 node_modules/grad-loadout/.idea/typescript-compiler.xml delete mode 100644 node_modules/grad-loadout/.idea/vcs.xml delete mode 100644 node_modules/grad-loadout/.idea/workspace.xml create mode 100644 node_modules/grad-loadout/functions/api/fn_loadoutViewer.sqf create mode 100644 node_modules/grad-loadout/functions/api/fn_verifyLoadouts.sqf delete mode 100644 node_modules/grad-loadout/functions/general/fn_NormalizeMagazinesInContent.sqf create mode 100644 node_modules/grad-loadout/functions/general/fn_addChatCommands.sqf create mode 100644 node_modules/grad-loadout/functions/general/fn_normalizeContent.sqf diff --git a/description.ext b/description.ext index 5e53bd6..feef120 100644 --- a/description.ext +++ b/description.ext @@ -68,10 +68,22 @@ class CfgGradCivs { debugMode = 0; }; +class GRAD_Replay { + precision = 3; // precision of replay, 5 means every 5 seconds one snapshot (number) + trackedSides[] = {"west","east","independent"}; // defines the sides that will be tracked (possible are "west", "east", "independant", "civilian") (array) + stepsPerTick = 1; // defines steps played back at once (number) + trackedVehicles = 1; // defines if empty and AI steered vehicles will be tracked (0/1) + trackedAI = 1; // defines if AI will be tracked (0/1) + sendingChunkSize = 10; // higher number means replay loading is faster, but might cause instability / lags during loading + trackShots = 1; // defines if shots will be tracked (0/1) +}; + //DIALOGS ====================================================================== #include "node_modules\grad-listBuymenu\grad_listBuymenu.hpp" #include "node_modules\grad-fortifications\grad_fortifications.hpp" +#include "node_modules\@gruppe-adler\replay\ui\defines.hpp" +#include "node_modules\@gruppe-adler\replay\ui\dialog.hpp" class RscTitles { #include "node_modules\grad-fortifications\dialog\hint\title.hpp" @@ -115,6 +127,7 @@ class CfgFunctions { #include "node_modules\grad-loadout\cfgFunctions.hpp" #include "node_modules\grad-listbuymenu\cfgFunctions.hpp" #include "node_modules\grad-fortifications\cfgFunctions.hpp" + #include "node_modules\@gruppe-adler\replay\cfgFunctions.hpp" #include "node_modules\grad-civs\cfgFunctions.hpp" }; diff --git a/functions/endings/fn_endMissionServer.sqf b/functions/endings/fn_endMissionServer.sqf index 3f428d8..17f7bc1 100644 --- a/functions/endings/fn_endMissionServer.sqf +++ b/functions/endings/fn_endMissionServer.sqf @@ -1,10 +1,38 @@ #include "component.hpp" -// do not add default values here - some params are nil by design and will be read from config in fnc_endMissionClient -params ["_configName","_winText","_winners","_winTextParams"]; - if (missionNamespace getVariable ["grad_endings_endingInProgress",false]) exitWith {}; missionNamespace setVariable ["grad_endings_endingInProgress",true]; -INFO_1("Ending %1 in progress.",_configName); -[_configName,_winText,_winners,_winTextParams] remoteExec ["grad_endings_fnc_endMissionClient",0,false]; +_this spawn { + params ["_configName","_winText","_winners","_winTextParams"]; + private ["_winText","_winners","_winTextParams"]; + + INFO_1("Ending %1 in progress.",_configName); + + if (isNil "_winText") then { + _winText = [missionConfigFile >> "CfgWinConditions" >> _configName,"winText",""] call BIS_fnc_returnConfigEntry; + }; + if (isNil "_winners") then { + _winners = ([missionConfigFile >> "CfgWinConditions" >> _configName,"winners",[]] call BIS_fnc_returnConfigEntry) apply {call compile _x}; + }; + _winTextParams = ([missionConfigFile >> "CfgWinConditions" >> _configName,"winTextParams",[]] call BIS_fnc_returnConfigEntry) apply {call compile _x}; + + _winText = "
" + _winText + ""; + + _text = format ([_winText] + _winTextParams); + + // show end title + [_text,0,0,4,2] remoteExec ["BIS_fnc_dynamicText",0,false]; + INFO_3("%1 %2 %3",_winText,_text,_winners); + sleep 5; + + // show points + if (({[_x] call grad_points_fnc_getPoints > 0} count [WEST,EAST,INDEPENDENT,CIVILIAN]) > 0) then { + [] remoteExecCall ["grad_points_fnc_displayPoints",0,false]; + sleep 16; + }; + + // show replay + [] call GRAD_replay_fnc_stopRecord; + [_winners] remoteExec ["grad_endings_fnc_endMissionClient",0,false]; +}; diff --git a/functions/missionSetup/fn_initMission.sqf b/functions/missionSetup/fn_initMission.sqf index 7a3fe08..47e07bb 100644 --- a/functions/missionSetup/fn_initMission.sqf +++ b/functions/missionSetup/fn_initMission.sqf @@ -8,16 +8,22 @@ grad_missionsettings_canUseScopes = ([missionConfigFile >> "missionsettings","ca [] call grad_missionSetup_fnc_intro; [] call grad_missionSetup_fnc_initCivs; [] call grad_groupsettings_fnc_setGroupSettings; - +if (!isServer) then {[] call GRAD_replay_fnc_init}; [{!isNull player || isDedicated},{ if (isServer) then { [["PREPARATION_TIME", 0] call BIS_fnc_getParamValue] call grad_missionSetup_fnc_startPreparationTime; - [{CBA_missionTime > 10 && {missionNamespace getVariable ["GRAD_MISSIONSTARTED",false]}}, {[] call grad_endings_fnc_init}, []] call CBA_fnc_waitUntilAndExecute; + [{CBA_missionTime > 10 && {missionNamespace getVariable ["GRAD_MISSIONSTARTED",false]}}, { + [] call grad_endings_fnc_init; + [] call GRAD_replay_fnc_init; + }, []] call CBA_fnc_waitUntilAndExecute; }; - if (hasInterface) then { + setViewDistance 3000; + setObjectViewDistance 2500; + if (hasInterface) then { + }; },[]] call CBA_fnc_waitUntilAndExecute; diff --git a/node_modules/@gruppe-adler/replay/LICENSE b/node_modules/@gruppe-adler/replay/LICENSE new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/node_modules/@gruppe-adler/replay/README.md b/node_modules/@gruppe-adler/replay/README.md new file mode 100644 index 0000000..1268c7b --- /dev/null +++ b/node_modules/@gruppe-adler/replay/README.md @@ -0,0 +1,61 @@ +[![Release](https://img.shields.io/github/release/gruppe-adler/grad-replay.svg)](https://github.com/gruppe-adler/grad-replay/release) +[![License](https://img.shields.io/github/license/gruppe-adler/grad-replay.svg)](https://github.com/gruppe-adler/grad-replay/license) + +# grad-replay +ARMA3 mission replay script (working but wip) +* Records player and AI movement and replays at end of mission. +* Meant for PvP but pimped to support AI as well +* Mission duration should be matched to replay precision (see below) - the longer the mission, the less precision is recommended. Better precision (smaller values) results in longer loading times. + +### Required Mods +CBA, ACE3 + +# How to install +### 1. Download Release +### 2. extract GRAD_replay folder into [mission folder]/node_modules +### 3. Add the following to the description.ext + +``` +#include "node_modules\@gruppe-adler\replay\ui\defines.hpp" +#include "node_modules\@gruppe-adler\replay\ui\dialog.hpp" +``` + +``` +// if CfgFunctions already exists, just put the #include part inside +class CfgFunctions { + #include "node_modules\@gruppe-adler\replay\cfgFunctions.hpp" +}; +``` + +``` +class GRAD_Replay { + precision = 5; // precision of replay, 5 means every 5 seconds one snapshot (number) + trackedSides[] = {"west", "east", "civilian"}; // defines the sides that will be tracked (possible are "west", "east", "independant", "civilian") (array) + stepsPerTick = 1; // defines steps played back at once (number) + trackedVehicles = 0; // defines if empty and AI steered vehicles will be tracked (0/1) + trackedAI = 0; // defines if AI will be tracked (0/1) + sendingChunkSize = 10; // higher number means replay loading is faster, but might cause instability / lags during loading +}; +``` +### 4. Initialize script in init.sqf +`[] call GRAD_replay_fnc_init;` + +### 5. Put this where you want the replay to start (recommended: end of mission) +Must be executed on server only! +``` +// stops record, sends data and starts replay +call GRAD_replay_fnc_stopRecord; + +// ends mission after replay is over +[{ + REPLAY_FINISHED +}, { + ["END1"] remoteExec ["endMission",0,false]; // your custom end mission call or whatever you want to do after replay +}, []] call CBA_fnc_waitUntilAndExecute; +``` + +### Important +Currently there is **no helper function to resume normal gameplay after replay has played**, this means all assets will be frozen and TFAR spectator channel will be set for all players, furthermore every wound will be healed and all spectator cams left. + +### Script commands +to pause recording, set `GRAD_REPLAY_RECORDING_PAUSED` to true on server / false to resume diff --git a/node_modules/@gruppe-adler/replay/cfgFunctions.hpp b/node_modules/@gruppe-adler/replay/cfgFunctions.hpp new file mode 100644 index 0000000..bb9bc6a --- /dev/null +++ b/node_modules/@gruppe-adler/replay/cfgFunctions.hpp @@ -0,0 +1,47 @@ +#ifndef MODULES_DIRECTORY + #define MODULES_DIRECTORY node_modules +#endif + +class GRAD_replay { + + class player { + file = MODULES_DIRECTORY\@gruppe-adler\replay\functions\player; + + class addReplayPart {}; + class animateShot {}; + class assembleReplayData {}; + class createMapOverlay {}; + class drawIcon {}; + class getColorFromID {}; + class getRecordEntry {}; + class initReplay {}; + class onPlaybackPosChanged {}; + class preparePlaybackClient {}; + class receiveData {} + class setPlayPauseDisplay {}; + class setTimeDisplay {}; + class showHintPause {}; + class showHintPlay {}; + class showHintReplayFinished {}; + class showPlaybackControl {}; + class showProgressBar {}; + class startPlaybackClient {}; + class stopPlaybackClient {}; + class syncPlaybackPos {}; + }; + + class server { + file = MODULES_DIRECTORY\@gruppe-adler\replay\functions\server; + + class canTrackUnit {}; + class getSideColorID {}; + class init {}; + class onFiredMan {}; + class pauseRecord {}; + class preparePlaybackServer {}; + class setMeSpectator {}; + class startRecord {}; + class stopRecord {}; + class storeValue {}; + }; +}; diff --git a/node_modules/@gruppe-adler/replay/functions/player/fn_addReplayPart.sqf b/node_modules/@gruppe-adler/replay/functions/player/fn_addReplayPart.sqf new file mode 100644 index 0000000..b0055af --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/player/fn_addReplayPart.sqf @@ -0,0 +1,21 @@ +#include "script_component.hpp" + +params ["_chunk", "_startIndex"]; + +// add all received parts to database +{ + GRAD_REPLAY_DATABASE_LOCAL set [_startIndex + _forEachIndex, _x]; +} forEach _chunk; + +// start assembling, if everything has been received +private _targetCount = missionNamespace getVariable ["GRAD_REPLAY_DATABASE_TARGET_COUNT_LOCAL",9999999]; +if ({!isNil "_x"} count GRAD_REPLAY_DATABASE_LOCAL >= _targetCount) then { + + // apparently function can run multiple times in parallel --> exit here if other instance was first + if (player getVariable ["grad_replay_playerReceiptComplete",false]) exitWith {}; + player setVariable ["grad_replay_playerReceiptComplete",true,true]; + + INFO_1("Client replay receipt completed at serverTime %1",serverTime); + + [{[] call grad_replay_fnc_assembleReplayData},[],1] call CBA_fnc_waitAndExecute; +}; diff --git a/node_modules/@gruppe-adler/replay/functions/player/fn_animateShot.sqf b/node_modules/@gruppe-adler/replay/functions/player/fn_animateShot.sqf new file mode 100644 index 0000000..e6cb952 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/player/fn_animateShot.sqf @@ -0,0 +1,94 @@ +params ["_map", "_index"]; + +private _positionData = GRAD_REPLAY_DATABASE_LOCAL_ASSEMBLED param [grad_replay_playbackPosition,[]]; +if !(_positionData isEqualType []) exitWith {}; + +private _iconData = _positionData param [_index,[]]; +if !(_iconData isEqualType []) exitWith {}; + +_iconData params [ + "", + ["_colorID", -1], + ["_pos", [0,0,0]], + "", + "", + "", + ["_firedTarget",[]] +]; + +// unit did not fire shot this tick +if (_firedTarget isEqualTo []) exitWith {}; + +private _color = [_colorID] call grad_replay_fnc_getColorFromID; +private _shotDir = _pos getDir _firedTarget; +private _shotDistance = _pos distance _firedTarget; +private _drawEH = -1; +private _shotAnimTicks = (floor (_shotDistance / GRAD_REPLAY_SHOTANIMSPEED)) min 30; +private _shotAnimCurrentTick = 1; + +// flying lines Star Wars style animation +[{ + params ["_args","_handle"]; + _args params ["_drawEH","_shotAnimCurrentTick","_shotAnimTicks","_map","_pos","_firedTarget","_color","_shotDir"]; + + _newShotEndPos = if (_shotAnimCurrentTick > _shotAnimTicks) then { + _firedTarget + } else { + _pos getPos [GRAD_REPLAY_SHOTANIMSPEED * _shotAnimCurrentTick,_shotDir] + }; + + _startPosTick = (_shotAnimCurrentTick - 2) max 0; + _newShotStartPos = if (_startPosTick > _shotAnimTicks) then { + _firedTarget + } else { + _pos getPos [GRAD_REPLAY_SHOTANIMSPEED * _startPosTick,_shotDir] + }; + + // remove previous draw EH + _map ctrlRemoveEventHandler ["Draw",_drawEH]; + + // create new draw EH and save ID in _drawEH (_args set [0,...]) + if (_startPosTick > _shotAnimTicks) then { + [_handle] call CBA_fnc_removePerFrameHandler; + } else { + _args set [0, + _map ctrlAddEventHandler ["Draw", + format ["(_this select 0) drawLine [%1,%2,%3]",_newShotStartPos,_newShotEndPos,_color] + ] + ]; + }; + + _args set [1,_shotAnimCurrentTick + 1]; + +},0.1,[_drawEH,_shotAnimCurrentTick,_shotAnimTicks,_map,_pos,_firedTarget,_color,_shotDir]] call CBA_fnc_addPerFrameHandler; + + +// continuous lines style animation +/* [{ + params ["_args","_handle"]; + _args params ["_drawEH","_shotAnimCurrentTick","_shotAnimTicks","_map","_pos","_firedTarget","_color","_shotDir"]; + + _newShotPos = if (_shotAnimCurrentTick > _shotAnimTicks) then { + _color set [3,(_color select 3) - 0.2]; + _firedTarget; + } else { + _pos getPos [GRAD_REPLAY_SHOTANIMSPEED * _shotAnimCurrentTick,_shotDir]; + }; + + // remove previous draw EH + _map ctrlRemoveEventHandler ["Draw",_drawEH]; + + // create new draw EH and save ID in _drawEH (_args set [0,...]) + if (_color select 3 <= 0) then { + [_handle] call CBA_fnc_removePerFrameHandler; + } else { + _args set [0, + _map ctrlAddEventHandler ["Draw", + format ["(_this select 0) drawLine [%1,%2,%3]",_pos,_newShotPos,_color] + ] + ]; + }; + + _args set [1,_shotAnimCurrentTick + 1]; + +},0.1,[_drawEH,_shotAnimCurrentTick,_shotAnimTicks,_map,_pos,_firedTarget,_color,_shotDir]] call CBA_fnc_addPerFrameHandler; */ diff --git a/node_modules/@gruppe-adler/replay/functions/player/fn_assembleReplayData.sqf b/node_modules/@gruppe-adler/replay/functions/player/fn_assembleReplayData.sqf new file mode 100644 index 0000000..9c84fba --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/player/fn_assembleReplayData.sqf @@ -0,0 +1,77 @@ +#include "script_component.hpp" + +params [["_part",0],["_startIndex",0],["_startTime",diag_tickTime],["_currentUnitsDataStates",[]]]; + +if (_part == 0) then { + INFO("Assembling replay data."); +} else { + INFO_2("Continuing assembly at index %1 (recursion %2).",_startIndex,_part); +}; + +if (isNil "GRAD_REPLAY_DATABASE_LOCAL_ASSEMBLED") then { + GRAD_REPLAY_DATABASE_LOCAL_ASSEMBLED = []; +}; + +private _typeDefaults = [ + "", // icon + -1, // color ID + [0,0], // pos2D + -1, // dir + "", // name + "", // group name + [] // fired target +]; + +private _interrupt = false; +private _startTimePart = diag_tickTime; +private _continueAt = 0; + +for [{_i=_startIndex},{_i< count GRAD_REPLAY_DATABASE_LOCAL},{_i=_i+1}] do { + + _compressedIntervalData = GRAD_REPLAY_DATABASE_LOCAL select _i; + _intervalData = []; + + { + // catch nil entries, not sure what's causing them + if (!isNil "_x") then { + + // timestamp + if (_x isEqualType 0) exitWith { + _intervalData pushBack _x; + }; + + // data array + if (_x isEqualType []) then { + _unitData = []; + _compressedUnitData = _x; + + if (_forEachIndex >= count _currentUnitsDataStates) then { + _currentUnitsDataStates pushBack []; + }; + _currentUnitDataState = _currentUnitsDataStates select _forEachIndex; + + { + if (isNil "_x") then { + _unitData pushBack (_currentUnitDataState param [_forEachIndex,_typeDefaults select _forEachIndex]); + } else { + _currentUnitDataState set [_forEachIndex,_x]; + _unitData pushBack _x; + }; + } forEach _compressedUnitData; + + _intervalData pushBack _unitData; + }; + }; + } forEach _compressedIntervalData; + + GRAD_REPLAY_DATABASE_LOCAL_ASSEMBLED pushBack _intervalData; + + if ((diag_tickTime - _startTimePart) > 0.2) exitWith {_interrupt = true; _continueAt = _i + 1}; +}; + +if (_interrupt) then { + [{_this call grad_replay_fnc_assembleReplayData},[_part + 1,_continueAt,_startTime,_currentUnitsDataStates]] call CBA_fnc_execNextFrame; +} else { + player setVariable ["grad_replay_playerAssemblyComplete",true,true]; + INFO_1("Assembling completed in %1s",diag_tickTime - _startTime); +}; diff --git a/node_modules/@gruppe-adler/replay/functions/player/fn_createMapOverlay.sqf b/node_modules/@gruppe-adler/replay/functions/player/fn_createMapOverlay.sqf new file mode 100644 index 0000000..725e924 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/player/fn_createMapOverlay.sqf @@ -0,0 +1 @@ +createDialog "playbackControl"; \ No newline at end of file diff --git a/node_modules/@gruppe-adler/replay/functions/player/fn_drawIcon.sqf b/node_modules/@gruppe-adler/replay/functions/player/fn_drawIcon.sqf new file mode 100644 index 0000000..1bebd41 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/player/fn_drawIcon.sqf @@ -0,0 +1,35 @@ +params ["_map", "_index"]; + +private _positionData = GRAD_REPLAY_DATABASE_LOCAL_ASSEMBLED param [grad_replay_playbackPosition,[]]; +if !(_positionData isEqualType []) exitWith {}; + +private _iconData = _positionData param [_index,[]]; +if !(_iconData isEqualType []) exitWith {}; + +_iconData params [ + ["_icon", ""], + ["_colorID", -1], + ["_pos", [0,0,0]], + ["_dir", 0], + ["_name", ""], + ["_groupname", ""], + "" +]; + +private _showName = (ctrlMapScale _map) < 0.03; +private _name = if (_showName) then { _name + " " + _groupname } else { "" }; +private _color = [_colorID] call grad_replay_fnc_getColorFromID; + +_map drawIcon [ + _icon, + _color, + _pos, + 24, + 24, + _dir, + _name, + 1, + 0.03, + 'TahomaB', + 'right' +]; diff --git a/node_modules/@gruppe-adler/replay/functions/player/fn_getColorFromID.sqf b/node_modules/@gruppe-adler/replay/functions/player/fn_getColorFromID.sqf new file mode 100644 index 0000000..9518d00 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/player/fn_getColorFromID.sqf @@ -0,0 +1,31 @@ +/* Color lookup table to reduce variable size when saving. + * + */ + + +#define DEFAULT_COLOR [0.7,0.6,0,1] + +params [["_colorID",-1]]; + +private _colors = [ + + // side color IDs + [0,0.3,0.6,1], // 0: WEST + [0.5,0,0,1], // 1: EAST + [0,0.5,0,1], // 2: INDEPENDENT + [0.4,0,0.5,1], // 3: CIVILIAN + [0.7,0.6,0,1], // 4: SIDEEMPTY + + // unconscious IDs are currently hardcoded to be exactly +5 in fn_startRecord! + [0,0.3,0.6,0.5], // 5: WEST unconscious + [0.5,0,0,0.5], // 6: EAST unconscious + [0,0.5,0,0.5], // 7: INDEPENDENT unconscious + [0.4,0,0.5,0.5], // 8: CIVILIAN unconscious + [0.7,0.6,0,0.5], // 9: SIDEEMPTY unconscious + + // other + [0.2,0.2,0.2,0.5], // 10: dead unit + [1,0,0,1] // 11: funkwagen-red when sending, speciality for mission "breaking contact" +]; + +_colors param [_colorID,DEFAULT_COLOR] diff --git a/node_modules/@gruppe-adler/replay/functions/player/fn_getRecordEntry.sqf b/node_modules/@gruppe-adler/replay/functions/player/fn_getRecordEntry.sqf new file mode 100644 index 0000000..aeea8e1 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/player/fn_getRecordEntry.sqf @@ -0,0 +1,21 @@ +params ["_database", "_cluster", "_iteration", "_index", "_defaultValue"]; + +private ["_return"]; + +_return = _database; +{ + + if (isNil "_x" || {count _return <= _x}) exitWith { + if (isNil "_x") then { diag_log format ["fucking nil detected"]; }; + if (isNil "_defaultValue") then {_return = nil} else {_return = _defaultValue}; + }; + _return = _return select _x; + + false +} count [_cluster,_iteration,_index]; + + + +/* diag_log format ["playback reading cluster %1 at iteration %2 at index %3", _cluster, _iteration, _index];*/ + +_return diff --git a/node_modules/@gruppe-adler/replay/functions/player/fn_initReplay.sqf b/node_modules/@gruppe-adler/replay/functions/player/fn_initReplay.sqf new file mode 100644 index 0000000..d4025c7 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/player/fn_initReplay.sqf @@ -0,0 +1,4 @@ +// heal everything +[player, player] call ace_medical_fnc_treatmentAdvanced_fullHealLocal; + +[] call GRAD_replay_fnc_preparePlaybackClient; \ No newline at end of file diff --git a/node_modules/@gruppe-adler/replay/functions/player/fn_onPlaybackPosChanged.sqf b/node_modules/@gruppe-adler/replay/functions/player/fn_onPlaybackPosChanged.sqf new file mode 100644 index 0000000..d1deade --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/player/fn_onPlaybackPosChanged.sqf @@ -0,0 +1,16 @@ +params ["_control"]; + +if (isMultiplayer && !(serverCommandAvailable "#kick")) exitWith {}; + +grad_replay_playbackPosition = + ceil ( + linearConversion [ + 0, + 10, + sliderPosition ctrlIDC (_control select 0), + 0, + count GRAD_REPLAY_DATABASE_LOCAL_ASSEMBLED, + true] + ); +(_control select 0) ctrlSetTooltip format ["%1 / %2", grad_replay_playbackPosition, count GRAD_REPLAY_DATABASE_LOCAL_ASSEMBLED]; +// systemchat format ['sliderPosition: %1 %', grad_replay_playbackPosition]; diff --git a/node_modules/@gruppe-adler/replay/functions/player/fn_preparePlaybackClient.sqf b/node_modules/@gruppe-adler/replay/functions/player/fn_preparePlaybackClient.sqf new file mode 100644 index 0000000..96b0b54 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/player/fn_preparePlaybackClient.sqf @@ -0,0 +1,10 @@ +{_x setMarkerAlphaLocal 0;} forEach allMapMarkers; // hide all markers for replay --> to be tested + +if (dialog) then {closeDialog 0;}; + +[ "TIMER", "onEachFrame" ] call BIS_fnc_removeStackedEventHandler; +ctrlDelete (uiNamespace getVariable "GRAD_replay_rsc_loadingBar"); +ctrlDelete (uiNamespace getVariable "GRAD_replay_txt_loading"); +ctrlDelete (uiNamespace getVariable "GRAD_replay_txt_loadingInfo"); + +[] spawn GRAD_replay_fnc_startPlaybackClient; diff --git a/node_modules/@gruppe-adler/replay/functions/player/fn_receiveData.sqf b/node_modules/@gruppe-adler/replay/functions/player/fn_receiveData.sqf new file mode 100644 index 0000000..8d2907a --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/player/fn_receiveData.sqf @@ -0,0 +1,26 @@ +params ["_replayLength", "_index", "_playerCount"]; + +// quit EG spec +if (["IsInitialized"] call BIS_fnc_EGSpectator) then { + ["Terminate"] call BIS_fnc_EGSpectator; +}; + + +// quit ACE spec +if (!isNil "ace_spectator_isSet") then { + [false] call ace_spectator_fnc_setSpectator; +}; + +GRAD_REPLAY_DATABASE_TARGET_COUNT_LOCAL = _replayLength; +[_replayLength, _index, _playerCount] spawn GRAD_replay_fnc_showProgressBar; + + +// quit grad cam +GRAD_CINEMACAM = objNull; + + +// quit gcam +GCamKill = true; + +// let players be able to talk already +[player, true] call TFAR_fnc_forceSpectator; diff --git a/node_modules/@gruppe-adler/replay/functions/player/fn_removeDrawEventhandler.sqf b/node_modules/@gruppe-adler/replay/functions/player/fn_removeDrawEventhandler.sqf new file mode 100644 index 0000000..2fa89d5 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/player/fn_removeDrawEventhandler.sqf @@ -0,0 +1,10 @@ +params ["_array"]; + +// diag_log "removing draw eh"; + +// delete icons frame before +if (count _array > 0) then { + { + ((findDisplay 12) displayCtrl 51) ctrlRemoveEventHandler ["Draw", _x]; + } forEach _array; +}; diff --git a/node_modules/@gruppe-adler/replay/functions/player/fn_setPlayPauseDisplay.sqf b/node_modules/@gruppe-adler/replay/functions/player/fn_setPlayPauseDisplay.sqf new file mode 100644 index 0000000..e2396c8 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/player/fn_setPlayPauseDisplay.sqf @@ -0,0 +1,9 @@ +params ["_isPlay"]; + +disableSerialization; + +if (_isPlay) then { + ((findDisplay 80000) displayCtrl 80005) ctrlSetText "node_modules\@gruppe-adler\replay\ui\play.paa"; +} else { + ((findDisplay 80000) displayCtrl 80005) ctrlSetText "node_modules\@gruppe-adler\replay\ui\pause.paa"; +}; diff --git a/node_modules/@gruppe-adler/replay/functions/player/fn_setTimeDisplay.sqf b/node_modules/@gruppe-adler/replay/functions/player/fn_setTimeDisplay.sqf new file mode 100644 index 0000000..d5585dd --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/player/fn_setTimeDisplay.sqf @@ -0,0 +1,8 @@ +params ["_position"]; + +disableSerialization; +private _time = GRAD_REPLAY_DATABASE_LOCAL_ASSEMBLED select _position select (count (GRAD_REPLAY_DATABASE_LOCAL_ASSEMBLED select _position) - 1); + +// if (_time find ".paa" > -1) exitWith { diag_log format ["grad-replay: catch unvalid time display: %1", _position]; }; + +((findDisplay 80000) displayCtrl 80004) ctrlSetText ([_time,"HH:MM:SS"] call BIS_fnc_timeToString); diff --git a/node_modules/@gruppe-adler/replay/functions/player/fn_showHintPause.sqf b/node_modules/@gruppe-adler/replay/functions/player/fn_showHintPause.sqf new file mode 100644 index 0000000..0e677e0 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/player/fn_showHintPause.sqf @@ -0,0 +1,14 @@ +[true] call GRAD_replay_fnc_setPlayPauseDisplay; + +disableSerialization; + +private _control = (findDisplay 80000) ctrlCreate ['grad_replay_RscPicture', -1]; +_control ctrlSetText 'node_modules\@gruppe-adler\replay\ui\pause.paa'; +_control ctrlSetPosition [0.45,0.45,(150 / 1920) * SafeZoneW,(150 / 1080) * SafeZoneH]; + +_control ctrlSetFade 0; +_control ctrlCommit 0; +_control ctrlSetFade 2; +_control ctrlCommit 2; +uiSleep 2; +ctrlDelete _control; diff --git a/node_modules/@gruppe-adler/replay/functions/player/fn_showHintPlay.sqf b/node_modules/@gruppe-adler/replay/functions/player/fn_showHintPlay.sqf new file mode 100644 index 0000000..93028cf --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/player/fn_showHintPlay.sqf @@ -0,0 +1,14 @@ +[false] call GRAD_replay_fnc_setPlayPauseDisplay; + +disableSerialization; + +private _control = (findDisplay 80000) ctrlCreate ['grad_replay_RscPicture', -1]; +_control ctrlSetText 'node_modules\@gruppe-adler\replay\ui\play.paa'; +_control ctrlSetPosition [0.45,0.45,(150 / 1920) * SafeZoneW,(150 / 1080) * SafeZoneH]; + +_control ctrlSetFade 0; +_control ctrlCommit 0; +_control ctrlSetFade 2; +_control ctrlCommit 2; +uiSleep 2; +ctrlDelete _control; \ No newline at end of file diff --git a/node_modules/@gruppe-adler/replay/functions/player/fn_showHintReplayFinished.sqf b/node_modules/@gruppe-adler/replay/functions/player/fn_showHintReplayFinished.sqf new file mode 100644 index 0000000..9a332c3 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/player/fn_showHintReplayFinished.sqf @@ -0,0 +1,17 @@ +private ["_xPos", "_yPos", "_width", "_height"]; + +with uiNamespace do { + disableSerialization; + + _xPos = SafeZoneX + (160 / 1920) * SafeZoneW; + _yPos = SafeZoneY + (910 / 1080) * SafeZoneH; + _width = (1600 / 1920) * SafeZoneW; + _height = (40 / 1080) * SafeZoneH; + + GRAD_replay_txt_finished = (findDisplay 80000) ctrlCreate ["grad_replay_RscStructuredText", -1]; + GRAD_replay_txt_finished ctrlSetPosition [ _xPos, _yPos, _width, _height]; + GRAD_replay_txt_finished ctrlSetBackgroundColor [0, 0, 0, 0.8]; + GRAD_replay_txt_finished ctrlSetFont "RobotoCondensed"; + GRAD_replay_txt_finished ctrlSetStructuredText parseText format["REPLAY FINISHED"]; + GRAD_replay_txt_finished ctrlCommit 0; +}; \ No newline at end of file diff --git a/node_modules/@gruppe-adler/replay/functions/player/fn_showPlaybackControl.sqf b/node_modules/@gruppe-adler/replay/functions/player/fn_showPlaybackControl.sqf new file mode 100644 index 0000000..84248f9 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/player/fn_showPlaybackControl.sqf @@ -0,0 +1,20 @@ +createDialog "playbackControl"; + +if (serverCommandAvailable "#kick" || !isMultiplayer) then { + + (findDisplay 80000) displayAddEventHandler [ + "KeyDown", + format ["if ((_this select 1) == 57) then { + GRAD_REPLAY_PLAYBACK_PAUSED = !GRAD_REPLAY_PLAYBACK_PAUSED; + + if (GRAD_REPLAY_PLAYBACK_PAUSED) then { + [] remoteExec ['GRAD_replay_fnc_showHintPause', [0,-2] select isDedicated, false]; + } else { + [] remoteExec ['GRAD_replay_fnc_showHintPlay', [0,-2] select isDedicated, false]; + }; + + publicVariable 'GRAD_REPLAY_PLAYBACK_PAUSED'; true + };"] + ]; + +}; diff --git a/node_modules/@gruppe-adler/replay/functions/player/fn_showProgressBar.sqf b/node_modules/@gruppe-adler/replay/functions/player/fn_showProgressBar.sqf new file mode 100644 index 0000000..ec6c4b4 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/player/fn_showProgressBar.sqf @@ -0,0 +1,52 @@ +params ["_count", "_index", "_playerCount"]; + +_xPos = SafeZoneX + (160 / 1920) * SafeZoneW; +_yPos = SafeZoneY + (910 / 1080) * SafeZoneH; +_width = (1600 / 1920) * SafeZoneW; +_height = (40 / 1080) * SafeZoneH; + +with uiNamespace do { + disableSerialization; + GRAD_replay_txt_loading = findDisplay 46 ctrlCreate ["grad_replay_RscStructuredText", -1]; + GRAD_replay_txt_loading ctrlSetPosition [ _xPos, 0.4, _width, 0.1]; + GRAD_replay_txt_loading ctrlSetBackgroundColor [0, 0, 0, 0.8]; + GRAD_replay_txt_loading ctrlSetFont "RobotoCondensed"; + GRAD_replay_txt_loading ctrlSetStructuredText parseText format["WAITING FOR REPLAY"]; + GRAD_replay_txt_loading ctrlCommit 0; + + GRAD_replay_txt_loadingInfo = findDisplay 46 ctrlCreate ["grad_replay_RscStructuredText", -1]; + GRAD_replay_txt_loadingInfo ctrlSetPosition [ _xPos, 0.475, _width, 0.1]; + GRAD_replay_txt_loadingInfo ctrlSetBackgroundColor [0, 0, 0, 0]; + GRAD_replay_txt_loadingInfo ctrlSetTextColor [1, 1, 1, 0.35]; + GRAD_replay_txt_loadingInfo ctrlSetFont "RobotoCondensed"; + GRAD_replay_txt_loadingInfo ctrlSetStructuredText parseText format["You are number %1 of %2 players receiving data", _index, _playerCount]; + GRAD_replay_txt_loadingInfo ctrlCommit 0; + + GRAD_replay_rsc_loadingBar = findDisplay 46 ctrlCreate ["grad_replay_RscProgress", -1]; + GRAD_replay_rsc_loadingBar ctrlSetPosition [ _xPos, 0.4, _width, 0.005]; + GRAD_replay_rsc_loadingBar ctrlSetTextColor [209/255, 141/255, 31/255, 1]; + GRAD_replay_rsc_loadingBar progressSetPosition 0; + GRAD_replay_rsc_loadingBar ctrlCommit 0; + + + +}; + +[ "TIMER", "onEachFrame", { + params[ "_start", "_end" ]; + _progress = linearConversion[ _start, _end, count GRAD_REPLAY_DATABASE_LOCAL, 0, 1 ]; + (uiNamespace getVariable "GRAD_replay_rsc_loadingBar") progressSetPosition _progress; + + if (_progress > 0 && _progress < 1) then { + (uiNamespace getVariable "GRAD_replay_txt_loading") ctrlSetStructuredText parseText format["LOADING REPLAY"]; + }; + + // hintsilent format ["showing progress bar %1", _progress]; + if (_progress >= 1) then { + (uiNamespace getVariable "GRAD_replay_txt_loading") ctrlSetStructuredText parseText format["WAITING FOR OTHERS"]; + }; + /* + // loading bar gets deleted in initreplay + */ + +}, [ 0, _count ] ] call BIS_fnc_addStackedEventHandler; \ No newline at end of file diff --git a/node_modules/@gruppe-adler/replay/functions/player/fn_startPlaybackClient.sqf b/node_modules/@gruppe-adler/replay/functions/player/fn_startPlaybackClient.sqf new file mode 100644 index 0000000..40ecff1 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/player/fn_startPlaybackClient.sqf @@ -0,0 +1,95 @@ +#include "script_component.hpp" + +grad_current_ehs = []; +grad_playback_finished = false; +grad_replay_playbackPosition = 0; +grad_current_playbackLoopPosition = 0; + +INFO_1("Playing replay at serverTime %1.", serverTime); + +// openMap [true, false]; + +[] call GRAD_replay_fnc_showPlaybackControl; + +[{ + params ["_args", "_handle"]; + + // delete icons frame before + if (count grad_current_ehs > 0) then { + { + ((findDisplay 80000) displayCtrl 1337) ctrlRemoveEventHandler ["Draw", _x]; + } forEach grad_current_ehs; + }; + + grad_current_ehs = []; // reset eventhandler draws + grad_current_playbackLoopPosition = 0; // reset loop + + // adjust progressbar + if (!isNull (findDisplay 80000)) then { + sliderSetPosition [80003, linearConversion [0,count GRAD_REPLAY_DATABASE_LOCAL_ASSEMBLED,grad_replay_playbackPosition,0,10]]; + ((findDisplay 80000) displayCtrl 80003) ctrlSetTooltip format ["%1 | %2", grad_replay_playbackPosition, count GRAD_REPLAY_DATABASE_LOCAL_ASSEMBLED - 1]; + }; + + { + private _fickediefackfack = grad_current_playbackLoopPosition; + private _map = ((findDisplay 80000) displayCtrl 1337); + + private _eh = _map ctrlAddEventHandler ["Draw", + format [ + "[ + _this select 0, + %1 + ] call GRAD_replay_fnc_drawIcon;", + _fickediefackfack] + ]; + + [_map,_fickediefackfack] call grad_replay_fnc_animateShot; + + grad_current_ehs pushBack _eh; + + if (grad_current_playbackLoopPosition < (count (GRAD_REPLAY_DATABASE_LOCAL_ASSEMBLED select (grad_replay_playbackPosition))) - 1) then { + grad_current_playbackLoopPosition = grad_current_playbackLoopPosition + 1; + }; + + } forEach (GRAD_REPLAY_DATABASE_LOCAL_ASSEMBLED select grad_replay_playbackPosition); + + // end playback + if ( + grad_replay_playbackPosition >= (count (GRAD_REPLAY_DATABASE_LOCAL_ASSEMBLED) - 1) && + count (GRAD_REPLAY_DATABASE_LOCAL_ASSEMBLED) >= GRAD_REPLAY_DATABASE_TARGET_COUNT_LOCAL && + !(grad_playback_finished) + ) exitWith { + INFO_3("playbackpos: %1, count: %2, count target: %3",grad_replay_playbackPosition,count (GRAD_REPLAY_DATABASE_LOCAL_ASSEMBLED),GRAD_REPLAY_DATABASE_TARGET_COUNT_LOCAL); + + if ((isMultiplayer && !(serverCommandAvailable "#kick")) || !isMultiplayer) then { + [] remoteExec ["GRAD_replay_fnc_showHintReplayFinished", [0,-2] select isDedicated]; + }; + + grad_playback_finished = true; + // grad_replay_playbackPosition = grad_replay_playbackPosition - 1; + [_handle] call CBA_fnc_removePerFrameHandler; + [] spawn GRAD_replay_fnc_stopPlaybackClient; + ((findDisplay 80000) displayCtrl 80003) ctrlEnable false; + + }; + + // counter + if (!grad_playback_finished && !GRAD_REPLAY_PLAYBACK_PAUSED) then { + grad_replay_playbackPosition = grad_replay_playbackPosition + 1; + [grad_replay_playbackPosition] call GRAD_replay_fnc_setTimeDisplay; + + if (!dialog) then { + [] call GRAD_replay_fnc_showPlaybackControl; + }; + }; + + + +},0.1,[]] call CBA_fnc_addPerFrameHandler; + +// admin client syncs his progress +if (isMultiplayer && !(serverCommandAvailable "#kick")) exitWith {}; + +[{ + [grad_replay_playbackPosition] remoteExec ["GRAD_replay_fnc_syncPlaybackPos", [0,-2] select isDedicated, false]; +},1,[]] call CBA_fnc_addPerFrameHandler; diff --git a/node_modules/@gruppe-adler/replay/functions/player/fn_stopPlaybackClient.sqf b/node_modules/@gruppe-adler/replay/functions/player/fn_stopPlaybackClient.sqf new file mode 100644 index 0000000..09cb9eb --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/player/fn_stopPlaybackClient.sqf @@ -0,0 +1,9 @@ +#include "\z\ace\addons\main\script_component.hpp" +// ["Replay finished."] call EFUNC(common,displayTextStructured); + +//disableSerialization; +uiSleep 5; +// openMap [false,false]; +if (dialog) then {closeDialog 2;}; +REPLAY_FINISHED = true; +publicVariable "REPLAY_FINISHED"; \ No newline at end of file diff --git a/node_modules/@gruppe-adler/replay/functions/player/fn_syncPlaybackPos.sqf b/node_modules/@gruppe-adler/replay/functions/player/fn_syncPlaybackPos.sqf new file mode 100644 index 0000000..e91d188 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/player/fn_syncPlaybackPos.sqf @@ -0,0 +1,3 @@ +params ["_pos"]; + +grad_replay_playbackPosition = _pos; \ No newline at end of file diff --git a/node_modules/@gruppe-adler/replay/functions/player/script_component.hpp b/node_modules/@gruppe-adler/replay/functions/player/script_component.hpp new file mode 100644 index 0000000..fcf9da9 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/player/script_component.hpp @@ -0,0 +1 @@ +#include "..\script_component.hpp" diff --git a/node_modules/@gruppe-adler/replay/functions/script_component.hpp b/node_modules/@gruppe-adler/replay/functions/script_component.hpp new file mode 100644 index 0000000..fcf9da9 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/script_component.hpp @@ -0,0 +1 @@ +#include "..\script_component.hpp" diff --git a/node_modules/@gruppe-adler/replay/functions/server/fn_canTrackUnit.sqf b/node_modules/@gruppe-adler/replay/functions/server/fn_canTrackUnit.sqf new file mode 100644 index 0000000..a740282 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/server/fn_canTrackUnit.sqf @@ -0,0 +1,24 @@ +params ["_unit","_veh","_isVehicle","_isEmptyVehicle","_isMan"]; + +// always track things +if (!_isVehicle && !_isMan) exitWith {true}; + +// always track empty vehicles +if (_isEmptyVehicle) exitWith {true}; + +// never track non empty vehicle objects (only effective commander has icon) +if (_isVehicle) exitWith {false}; + +// never track more than the effective commander in a vehicle to avoid duplicate icons +if (effectiveCommander _veh != _unit) exitWith {false}; + +// always track if explicitly set by user +if (_unit getVariable ["grad_replay_track",false]) exitWith {true}; + +// always track players +if (isPlayer _unit) exitWith {true}; + +// only track AI if in included sides +if ((side _unit) in GRAD_REPLAY_SIDES && (_unit getVariable ["grad_gcamspec_firstSpawn", true])) exitWith {true}; + +false diff --git a/node_modules/@gruppe-adler/replay/functions/server/fn_getSideColorID.sqf b/node_modules/@gruppe-adler/replay/functions/server/fn_getSideColorID.sqf new file mode 100644 index 0000000..09adbed --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/server/fn_getSideColorID.sqf @@ -0,0 +1,9 @@ +params [["_side",sideUnknown]]; + +[ + WEST, + EAST, + INDEPENDENT, + CIVILIAN, + sideEmpty +] find _side diff --git a/node_modules/@gruppe-adler/replay/functions/server/fn_init.sqf b/node_modules/@gruppe-adler/replay/functions/server/fn_init.sqf new file mode 100644 index 0000000..8cf4285 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/server/fn_init.sqf @@ -0,0 +1,34 @@ +// idea from a script by austin_medic +// completely reworked by nomisum for Gruppe Adler +GRAD_REPLAY_DATABASE_LOCAL = []; +GRAD_REPLAY_DATABASE_TARGET_COUNT_LOCAL = 999999; // something really high to prevent from finishing at once +GRAD_REPLAY_PLAYBACK_PAUSED = false; +GRAD_REPLAY_SHOTANIMSPEED = 60; // how fast projectiles move during replay in meters per 0.1s + +if (!isServer) exitWith {}; + +// constants +GRAD_REPLAY_RECORDING_PAUSED = false; +GRAD_REPLAY_RECORDING_STOPPED = false; +GRAD_REPLAY_SENDING_DELAY = 0.05; +GRAD_REPLAY_DATABASE = []; + +// vehicle setVariable ["GRAD_replay_track", true]; + +GRAD_REPLAY_SIDES = ([(missionConfigFile >> "GRAD_Replay"), "trackedSides", ["west", "east", "civilian"]] call BIS_fnc_returnConfigEntry) apply {call compile _x}; +GRAD_REPLAY_AI_VEHICLES_TRACKED = ([(missionConfigFile >> "GRAD_Replay"), "trackedVehicles", 0] call BIS_fnc_returnConfigEntry) == 1; +GRAD_REPLAY_AI_ONFOOT_TRACKED = ([(missionConfigFile >> "GRAD_Replay"), "trackedAI", 0] call BIS_fnc_returnConfigEntry) == 1; +REPLAY_STEPS_PER_TICK = [(missionConfigFile >> "GRAD_Replay"), "stepsPerTick", 1] call BIS_fnc_returnConfigEntry; +GRAD_REPLAY_SENDING_CHUNK_SIZE = [(missionConfigFile >> "GRAD_Replay"), "sendingChunkSize", 10] call BIS_fnc_returnConfigEntry; +GRAD_REPLAY_TRACKSHOTS = ([(missionConfigFile >> "GRAD_Replay"), "trackShots", 0] call BIS_fnc_returnConfigEntry) == 1; +private _precision = [(missionConfigFile >> "GRAD_Replay"), "precision", 1] call BIS_fnc_returnConfigEntry; + +if (GRAD_REPLAY_TRACKSHOTS) then { + ["CAManBase","firedMan",{_this call grad_replay_fnc_onFiredMan}] call CBA_fnc_addClassEventHandler; +}; + +[_precision] call GRAD_replay_fnc_startRecord; + +/* to start playback: +[] GRAD_replay_fnc_stopRecord; +*/ diff --git a/node_modules/@gruppe-adler/replay/functions/server/fn_onFiredMan.sqf b/node_modules/@gruppe-adler/replay/functions/server/fn_onFiredMan.sqf new file mode 100644 index 0000000..810fd59 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/server/fn_onFiredMan.sqf @@ -0,0 +1,31 @@ +#include "script_component.hpp" + +params ["_unit", "", "", "", "", "", "_projectile", "_vehicle"]; + +// only effective commander is tracked if unit is inside a vehicle --> proceed as if effective commander fired the shot +_unit = effectiveCommander vehicle _unit; + +// make sure unit is being tracked +private _unitID = _unit getVariable ["grad_replay_unitID",-1]; +if (_unitID < 0) exitWith {}; + +// a projectile is being tracked already +if (_unit getVariable ["grad_replay_projectileTrackingRunning",false]) exitWith {}; +_unit setVariable ["grad_replay_projectileTrackingRunning",true]; + +// track projectile +private _lastProjectilePos = [0,0,0]; +[{ + params ["_args","_handle"]; + _args params ["_projectile","_unit","_lastProjectilePos"]; + + if (!isNull _projectile) then { + _lastProjectilePos resize 0; + _lastProjectilePos append (getPos _projectile); + } else { + _lastProjectilePos resize 2; + _unit setVariable ["grad_replay_firedTarget",_lastProjectilePos]; + [_handle] call CBA_fnc_removePerFrameHandler; + _unit setVariable ["grad_replay_projectileTrackingRunning",false]; + }; +},0,[_projectile,_unit,_lastProjectilePos]] call CBA_fnc_addPerFrameHandler; diff --git a/node_modules/@gruppe-adler/replay/functions/server/fn_pauseRecord.sqf b/node_modules/@gruppe-adler/replay/functions/server/fn_pauseRecord.sqf new file mode 100644 index 0000000..09c04cd --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/server/fn_pauseRecord.sqf @@ -0,0 +1,3 @@ +params [["_set", true]]; + +GRAD_REPLAY_RECORDING_PAUSED = _set; \ No newline at end of file diff --git a/node_modules/@gruppe-adler/replay/functions/server/fn_preparePlaybackServer.sqf b/node_modules/@gruppe-adler/replay/functions/server/fn_preparePlaybackServer.sqf new file mode 100644 index 0000000..613ddf6 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/server/fn_preparePlaybackServer.sqf @@ -0,0 +1,78 @@ +#include "script_component.hpp" + +if (!isServer) exitWith {}; + +private _fnc_disableUnit = if (isMultiplayer) then { + { + _this enableSimulationGlobal false; + + // freeze vehicle + if (!(vehicle _this isEqualTo _this) && _this isEqualTo (driver vehicle _this)) then { + vehicle _this attachTo [_this]; + }; + } +} else { + {_this enableSimulation false} +}; + +{ + _x call _fnc_disableUnit; + _x setVariable ["ace_map_hideBlueForceMarker", true]; +} count allUnits; + +// remove ace blu force tracking marker + +ace_map_BFT_Enabled = false; +ace_map_mapShake = false; +// call ACE_map_fnc_blueForceTrackingUpdate; + +publicVariable "ace_map_BFT_Enabled"; +publicVariable "ace_map_mapShake"; + + +missionnamespace setVariable ["GRAD_replay_isRunning", true, true]; + +INFO("Sending database to clients."); +private _startTime = diag_tickTime; + +_replayLength = count GRAD_REPLAY_DATABASE; +INFO_1("Replay length is %1",_replayLength); + +private _allPlayers = allPlayers - entities "HeadlessClient_F"; + +// set every client to know whats his number in line and display progress bar +{ + [_replayLength, _forEachIndex + 1, count _allPlayers] remoteExec ["GRAD_replay_fnc_receiveData", _x]; +} forEach _allPlayers; + +// send to all clients at once, but one tidbit after another --> hopefully this works +for [{_i=0},{_i < ceil (_replayLength / GRAD_REPLAY_SENDING_CHUNK_SIZE)},{_i=_i+1}] do { + + _startIndex = _i * GRAD_REPLAY_SENDING_CHUNK_SIZE; + if (_startIndex >= _replayLength) exitWith {}; + + _endIndex = _startIndex + GRAD_REPLAY_SENDING_CHUNK_SIZE; + if (_endIndex >= _replayLength) then {_endIndex = _replayLength - 1}; + + _chunk = GRAD_REPLAY_DATABASE select [_startIndex, _endIndex - _startIndex + 1]; + + [_chunk,_startIndex] remoteExecCall ["GRAD_replay_fnc_addReplayPart", _allPlayers]; + sleep GRAD_REPLAY_SENDING_DELAY; // set to zero for debugging ordering +}; + +INFO_1("Database sending completed in %1s.",(diag_tickTime - _startTime)); + +// wait until all clients have received all the data and assembled it +private _waitCondition = {(_this select 0) findIf {!(_x getVariable ["grad_replay_playerAssemblyComplete",false])} < 0}; +private _onComplete = { + INFO_1("All players have received and assembled database. Total time since start of function: %1.",(diag_tickTime - (_this select 1))); + [] remoteExec ["GRAD_replay_fnc_initReplay", _this select 0, false]; +}; +private _onTimeout = { + [] remoteExec ["GRAD_replay_fnc_initReplay", _this select 0, false]; + _missingPlayers = (_this select 0) select {!(_x getVariable ["grad_replay_playerReceiptComplete",false])}; + INFO_1("Waiting for players timed out. Missing players: %1",_missingPlayers); +}; +[_waitCondition,_onComplete,[_allPlayers,_startTime],30,_onTimeout] call CBA_fnc_waitUntilAndExecute; + +// copyToClipboard str GRAD_REPLAY_DATABASE; diff --git a/node_modules/@gruppe-adler/replay/functions/server/fn_setMeSpectator.sqf b/node_modules/@gruppe-adler/replay/functions/server/fn_setMeSpectator.sqf new file mode 100644 index 0000000..c9bd956 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/server/fn_setMeSpectator.sqf @@ -0,0 +1,6 @@ +params ["_unit", "_deathPos"]; + +player setPos [_deathPos select 0, _deathPos select 1, 10]; + +_unit enableSimulationGlobal false; +_unit hideObjectGlobal true; \ No newline at end of file diff --git a/node_modules/@gruppe-adler/replay/functions/server/fn_startRecord.sqf b/node_modules/@gruppe-adler/replay/functions/server/fn_startRecord.sqf new file mode 100644 index 0000000..c09c147 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/server/fn_startRecord.sqf @@ -0,0 +1,115 @@ +#include "script_component.hpp" + +params ["_precision"]; + +INFO_1("Starting recording with precision %1",_precision); + +{ + _x setVariable ["GRAD_replay_track", true]; + _x setVariable ["asr_ai_exclude", true]; +} forEach playableUnits + switchableUnits + allPlayers; + +// currentSaveState array contains last relevant data +private _currentSaveState = []; + +[{ + params ["_args", "_handle"]; + _args params ["_currentSaveState"]; + + // end recording and start playback + if (GRAD_REPLAY_RECORDING_STOPPED) exitWith { + [_handle] call CBA_fnc_removePerFrameHandler; + [] spawn GRAD_replay_fnc_preparePlaybackServer; + }; + + // skip if currently paused + if (GRAD_REPLAY_RECORDING_PAUSED) exitWith {}; + + _players = playableUnits + switchableUnits + allDeadMen; + _trackedUnits = _players; + _terminals = allMissionObjects "Land_DataTerminal_01_F"; // speciality for mission "breaking contact" + _trackedUnits append _terminals; + + if (GRAD_REPLAY_AI_VEHICLES_TRACKED ) then { + // filter weapon holders + _vehicles = (vehicles + allDead - allDeadMen) select { + !(typeOf _x in ["WeaponHolder","WeaponHolder_Single_F","WeaponHolderSimulated","WeaponHolderSimulated_Scripted","GroundWeaponHolder","GroundWeaponHolder_Scripted"]) + }; + _trackedUnits append _vehicles; + }; + + if (GRAD_REPLAY_AI_ONFOOT_TRACKED) then { + _ai = allUnits - playableUnits - switchableUnits; + _trackedUnits append _ai; + }; + + /* diag_log ["_trackedUnits",_trackedUnits]; */ + + // _nextTickData contains all the data of the next timestamp that is then appended to GRAD_REPLAY_DATABASE + _nextTickData = []; + + { + _unit = _x; + _veh = vehicle _unit; + _isMan = _unit isKindOf "Man"; + _isVehicle = !_isMan && {_unit isKindOf "AllVehicles"}; + _isEmptyVehicle = _isVehicle && {{alive _x} count (crew _unit) == 0}; + + if ([_unit,_veh,_isVehicle,_isEmptyVehicle,_isMan] call grad_replay_fnc_canTrackUnit) then { + + // set tracking ID if unit doesn't have one + _unitID = _unit getVariable "grad_replay_unitID"; + if (isNil "_unitID") then { + _unitID = _currentSaveState pushBack []; + _unit setVariable ["grad_replay_unitID",_unitID]; + }; + _currentUnitData = _currentSaveState select _unitID; + + // use ACE_Name so it works with dead units + _name = _unit getVariable ["ACE_Name",""]; + + _pos = getpos _unit; + _pos resize 2; + + _groupname = if (_unit isEqualTo (leader group _unit)) then {" (" + groupId (group _unit) + ")"} else {""}; + _dir = round (getDir _veh); + _side = if (_isMan) then {side _unit} else {sideEmpty}; + _colorID = [_side] call GRAD_replay_fnc_getSideColorID; + _type = typeOf _veh; + _icon = getText (configfile >> "CfgVehicles" >> _type >> "icon"); + + // firedTarget is being set by fn_onFiredMan --> if it has a value, save and reset the variable + _firedTarget = _unit getVariable ["grad_replay_firedTarget",[]]; + _unit setVariable ["grad_replay_firedTarget",nil]; + + // mark funkwagen if he is sending in red // speciality for mission "breaking contact" + if (_type isEqualTo "rhs_gaz66_r142_vv" && {_veh getVariable ["tf_range",0] == 50000}) then { + _colorID = 11; + }; + + // speciality for mission "breaking contact" + if (_type isEqualTo "Land_DataTerminal_01_F" && !(isNil "GRAD_TERMINAL_ACTIVE") && {GRAD_TERMINAL_ACTIVE}) then { + _colorID = 11; + }; + + // set dead unit color to grey, independent of side + if (!alive _unit) then { + _colorID = 10; + } else { + + // colorID for unconscious is hardcoded to be +5 of side + if (_unit getVariable ["ACE_isUnconscious", false]) then { + _colorID = _colorID + 5; + _groupname = "unconscious"; + }; + }; + + [_currentUnitData,_nextTickData,_unitID,[_icon,_colorID,_pos,_dir,_name,_groupname,_firedTarget]] call GRAD_replay_fnc_storeValue; + }; + + } forEach _trackedUnits; + + _nextTickData pushBack dayTime; + GRAD_REPLAY_DATABASE pushBack _nextTickData; + +},_precision,[_currentSaveState]] call CBA_fnc_addPerFrameHandler; diff --git a/node_modules/@gruppe-adler/replay/functions/server/fn_stopRecord.sqf b/node_modules/@gruppe-adler/replay/functions/server/fn_stopRecord.sqf new file mode 100644 index 0000000..e1a8316 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/server/fn_stopRecord.sqf @@ -0,0 +1 @@ +GRAD_REPLAY_RECORDING_STOPPED = true; \ No newline at end of file diff --git a/node_modules/@gruppe-adler/replay/functions/server/fn_storeValue.sqf b/node_modules/@gruppe-adler/replay/functions/server/fn_storeValue.sqf new file mode 100644 index 0000000..26691d8 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/server/fn_storeValue.sqf @@ -0,0 +1,31 @@ +#include "script_component.hpp" + +params [["_currentUnitData",[]],["_nextTickData",[]],["_unitID",-1],["_newUnitData",[]]]; + +// _newUnitData contents: [_icon,_colorID,_pos,_dir,_name,_groupname] +if (count _newUnitData == 0) exitWith {}; + +private _newSaveData = []; +private _typeDefaults = [ + "", // icon + -1, // color ID + [0,0], // pos2D + -1, // dir + "", // name + "", // group name + [] // fired target +]; + +for [{_i=0},{_i<((count _currentUnitData) max (count _newUnitData))},{_i=_i+1}] do { + _typeDefault = _typeDefaults select _i; + _newUnitDataSelected = _newUnitData param [_i,_typeDefault]; + + if !((_currentUnitData param [_i,_typeDefault]) isEqualTo _newUnitDataSelected) then { + _currentUnitData set [_i,_newUnitDataSelected]; + _newSaveData set [_i,_newUnitDataSelected]; + } else { + _newSaveData set [_i,nil]; + }; +}; + +_nextTickData set [_unitID,_newSaveData]; diff --git a/node_modules/@gruppe-adler/replay/functions/server/script_component.hpp b/node_modules/@gruppe-adler/replay/functions/server/script_component.hpp new file mode 100644 index 0000000..fcf9da9 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/functions/server/script_component.hpp @@ -0,0 +1 @@ +#include "..\script_component.hpp" diff --git a/node_modules/@gruppe-adler/replay/package.json b/node_modules/@gruppe-adler/replay/package.json new file mode 100644 index 0000000..2185dad --- /dev/null +++ b/node_modules/@gruppe-adler/replay/package.json @@ -0,0 +1,87 @@ +{ + "_args": [ + [ + { + "raw": "@gruppe-adler/replay@1.2.0", + "scope": "@gruppe-adler", + "escapedName": "@gruppe-adler%2freplay", + "name": "@gruppe-adler/replay", + "rawSpec": "1.2.0", + "spec": "1.2.0", + "type": "version" + }, + "E:\\Dokumente\\Arma 3 - Other Profiles\\McDiod\\mpmissions\\TvT_Template.VR" + ] + ], + "_from": "@gruppe-adler/replay@1.2.0", + "_hasShrinkwrap": false, + "_id": "@gruppe-adler/replay@1.2.0", + "_inCache": true, + "_installable": true, + "_location": "/@gruppe-adler/replay", + "_nodeVersion": "4.4.7", + "_npmOperationalInternal": { + "host": "s3://npm-registry-packages", + "tmp": "tmp/replay_1.2.0_1541343872787_0.6585455370121378" + }, + "_npmUser": { + "name": "gruppe-adler-admin", + "email": "admin@gruppe-adler.de" + }, + "_npmVersion": "3.10.5", + "_phantomChildren": {}, + "_requested": { + "raw": "@gruppe-adler/replay@1.2.0", + "scope": "@gruppe-adler", + "escapedName": "@gruppe-adler%2freplay", + "name": "@gruppe-adler/replay", + "rawSpec": "1.2.0", + "spec": "1.2.0", + "type": "version" + }, + "_requiredBy": [ + "#USER", + "/" + ], + "_resolved": "https://registry.npmjs.org/@gruppe-adler/replay/-/replay-1.2.0.tgz", + "_shasum": "11f214573786d264e9875b605950e5a2af74a502", + "_shrinkwrap": null, + "_spec": "@gruppe-adler/replay@1.2.0", + "_where": "E:\\Dokumente\\Arma 3 - Other Profiles\\McDiod\\mpmissions\\TvT_Template.VR", + "dependencies": {}, + "description": "Arma3 mission replay script", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "11f214573786d264e9875b605950e5a2af74a502", + "tarball": "https://registry.npmjs.org/@gruppe-adler/replay/-/replay-1.2.0.tgz", + "integrity": "sha512-jvzb7UJ2jkN3OjvkWDiwvX8Ss2Ra5ZsRT8ffH9OpCxazpc2y3NESlGrjXKH2MhkRaEjTSnS7+xMxSTGZgUFlzw==", + "fileCount": 44, + "unpackedSize": 149623, + "npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb3wqBCRA9TVsSAnZWagAAkZwQAJ11rrzcoPZEZBW0HYNR\nGGTkyy3WQ3eAZhMYxbFhFf3SkB8R+R6/JwZv1BbRoEa/SlHv/F9y3q0a742f\nYm0Jfdy6JPHj9/wxFXcpPX7vecDy1MX/ptC9mqD80esDJd3otiODBgYQHrHo\n5lvU5DyA6BRY0BgbbsaARVUae6sJoUtM1zQpMWxvZbn2+QsIpk/4gZqR0ql7\n30wCwWGJG2S/HcAjq0sYR8Enq9ZArbuVA45tZ0liHDay1pCTyTkO112qbbaX\nqV4vJiJE02VQkWviU7+Q5ZEIBEyRhtAs5/g4SW4tpq+OfDGqAEDjpR8rmvx3\naq76hYdaM4WOF6JZ6Ci1R6ggNggjsOHq55tLQEVljG0gVBaQzYKdMTGckpn6\nqoXv8jTAumMO4k7Usm1tGQ1kj1ly+uWCC5IR7XZzwzpe74wvvRZgY4bEW1Do\npaqXIeZljCmCHrcWO3IceW/L9ZvPFrmkdAeQl1zCfFYX5AvLRhTrgI3QUo8O\nkawYpqTOTAF2C2hFzatMOoZ8RFXUGxjQi5za4L23QC7/y3YTKmawymZxxyYT\nLhyQRbn2UlD4u9kWJSDgXJzDJW7C5wZheBux+H4Ln7FG8P3HiXuWCvvu6POZ\nZBbRN+mylNsN5jIenqAQaMnF9e0iPZPGDaYxW5rurh47SS9dQHg8yy2kapY2\npqEe\r\n=bhCP\r\n-----END PGP SIGNATURE-----\r\n" + }, + "gitHead": "18a574f675f3f5ade22a39c60647df2b5f7e3f16", + "maintainers": [ + { + "name": "fusselwurm", + "email": "fusselwurm@gmail.com" + }, + { + "name": "gruppe-adler-admin", + "email": "admin@gruppe-adler.de" + }, + { + "name": "mcdiod", + "email": "mcdiod@gruppe-adler.de" + }, + { + "name": "nomisum", + "email": "nomisum@googlemail.com" + } + ], + "name": "@gruppe-adler/replay", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "scripts": {}, + "version": "1.2.0" +} diff --git a/node_modules/@gruppe-adler/replay/script_component.hpp b/node_modules/@gruppe-adler/replay/script_component.hpp new file mode 100644 index 0000000..55d2eba --- /dev/null +++ b/node_modules/@gruppe-adler/replay/script_component.hpp @@ -0,0 +1,4 @@ +#define PREFIX grad +#define COMPONENT replay + +#include "\x\cba\addons\main\script_macros.hpp" diff --git a/node_modules/@gruppe-adler/replay/ui/defines.hpp b/node_modules/@gruppe-adler/replay/ui/defines.hpp new file mode 100644 index 0000000..c4c960a --- /dev/null +++ b/node_modules/@gruppe-adler/replay/ui/defines.hpp @@ -0,0 +1,819 @@ +#define CT_STATIC 0 +#define CT_BUTTON 1 +#define CT_EDIT 2 +#define CT_SLIDER 3 +#define CT_COMBO 4 +#define CT_LISTBOX 5 +#define CT_TOOLBOX 6 +#define CT_CHECKBOXES 7 +#define CT_PROGRESS 8 +#define CT_HTML 9 +#define CT_STATIC_SKEW 10 +#define CT_ACTIVETEXT 11 +#define CT_TREE 12 +#define CT_STRUCTURED_TEXT 13 +#define CT_CONTEXT_MENU 14 +#define CT_CONTROLS_GROUP 15 +#define CT_SHORTCUTBUTTON 16 +#define CT_XKEYDESC 40 +#define CT_XBUTTON 41 +#define CT_XLISTBOX 42 +#define CT_XSLIDER 43 +#define CT_XCOMBO 44 +#define CT_ANIMATED_TEXTURE 45 +#define CT_OBJECT 80 +#define CT_OBJECT_ZOOM 81 +#define CT_OBJECT_CONTAINER 82 +#define CT_OBJECT_CONT_ANIM 83 +#define CT_LINEBREAK 98 +#define CT_USER 99 +#define CT_MAP 100 +#define CT_MAP_MAIN 101 +#define CT_LISTNBOX 102 + +#define ST_POS 0x0F +#define ST_HPOS 0x03 +#define ST_VPOS 0x0C +#define ST_LEFT 0x00 +#define ST_RIGHT 0x01 +#define ST_CENTER 0x02 +#define ST_DOWN 0x04 +#define ST_UP 0x08 +#define ST_VCENTER 0x0C + +#define ST_TYPE 0xF0 +#define ST_SINGLE 0x00 +#define ST_MULTI 0x10 +#define ST_TITLE_BAR 0x20 +#define ST_PICTURE 0x30 +#define ST_FRAME 0x40 +#define ST_BACKGROUND 0x50 +#define ST_GROUP_BOX 0x60 +#define ST_GROUP_BOX2 0x70 +#define ST_HUD_BACKGROUND 0x80 +#define ST_TILE_PICTURE 0x90 +#define ST_WITH_RECT 0xA0 +#define ST_LINE 0xB0 + +#define ST_SHADOW 0x100 +#define ST_NO_RECT 0x200 +#define ST_KEEP_ASPECT_RATIO 0x800 + +#define ST_TITLE ST_TITLE_BAR + ST_CENTER + +#define SL_DIR 0x400 +#define SL_VERT 0 +#define SL_HORZ 0x400 + +#define SL_TEXTURES 0x10 + +#define ST_VERTICAL 0x01 +#define ST_HORIZONTAL 0 + +#define LB_TEXTURES 0x10 +#define LB_MULTI 0x20 + +#define TR_SHOWROOT 1 +#define TR_AUTOCOLLAPSE 2 + +#define MB_BUTTON_OK 1 +#define MB_BUTTON_CANCEL 2 +#define MB_BUTTON_USER 4 + +#define GUI_GRID_X (0) +#define GUI_GRID_Y (0) +#define GUI_GRID_W (0.025) +#define GUI_GRID_H (0.04) +#define GUI_GRID_WAbs (1) +#define GUI_GRID_HAbs (1) + +class grad_replay_RscSlider +{ + style = "0x400 + 0x10"; + type = 43; // this is the more "modern" slider. Type = 3 is the old dull one. + shadow = 0; + colorActive[] = {1,1,1,1}; + colorDisabled[] = {0.5,0.5,0.5,0.2}; + + color[] = {1,1,1,0.4}; + + arrowEmpty = "\A3\ui_f\data\gui\cfg\slider\arrowEmpty_ca.paa"; + arrowFull = "\A3\ui_f\data\gui\cfg\slider\arrowFull_ca.paa"; + border = "\A3\ui_f\data\gui\cfg\slider\border_ca.paa"; + thumb = "\A3\ui_f\data\gui\cfg\slider\thumb_ca.paa"; +}; + +class grad_replay_RscProgress { + type = 8; + style = 0; + colorFrame[] = {0,0,0,0}; + colorBar[] = {1,1,1,1}; + texture = "#(argb,8,8,3)color(1,1,1,1)"; + x = 0; + y = 0; + w = 1; + h = 0.03; +}; + +class grad_replay_RscStructuredText +{ + access = 0; + idc = -1; + type = CT_STRUCTURED_TEXT; + style = ST_MULTI; + lineSpacing = 0.5; + colorBackground[] = {-1,-1,-1,0}; + colorText[] = {1,1,1,0.7}; + size = 0.038; + text = ""; + fixedWidth = 0; + x = 0; + y = 0; + h = 0; + w = 0; + shadow = 0; +}; + +class grad_replay_RscStructuredTextTooltip +{ + access = 0; + idc = -1; + type = CT_STRUCTURED_TEXT; + style = ST_MULTI; + lineSpacing = 0.5; + colorBackground[] = {-1,-1,-1,0}; + colorText[] = {1,1,1,0.7}; + size = 0.028; + text = ""; + fixedWidth = 0; + x = 0; + y = 0; + h = 0; + w = 0; + shadow = 0; +}; + +class grad_replay_RscStructuredTextHeadline +{ + access = 0; + idc = -1; + type = CT_STRUCTURED_TEXT; + style = ST_CENTER; + colorBackground[] = {-1,-1,-1,0}; + colorText[] = {0.5,0.5,0.5,1}; + size = 0.048; + text = ""; + fixedWidth = 0; + x = 0; + y = 0; + h = 0; + w = 0; + shadow = 0; + font = "puristaMedium"; +}; + + +class grad_replay_RscText +{ + access = 0; + idc = -1; + type = CT_STATIC; + style = ST_MULTI; + linespacing = 1; + colorBackground[] = {0,0,0,0}; + colorText[] = {1,1,1,0.5}; + text = ""; + shadow = 0; + font = "PuristaLight"; + SizeEx = 0.02300; + fixedWidth = 0; + x = 0; + y = 0; + h = 0; + w = 0; + +}; + +class grad_replay_RscPicture +{ + access = 0; + idc = -1; + type = CT_STATIC; + style = ST_PICTURE; + colorBackground[] = {0,0,0,0}; + colorText[] = {1,1,1,1}; + font = "PuristaLight"; + sizeEx = 0; + lineSpacing = 0; + text = ""; + fixedWidth = 0; + shadow = 0; + x = 0; + y = 0; + w = 0.2; + h = 0.15; +}; + +class grad_replay_RscButton +{ + + access = 0; + type = CT_BUTTON; + text = ""; + colorText[] = {1,1,1,.9}; + colorDisabled[] = {0.4,0.4,0.4,1}; + colorBackground[] = {0.75,0.75,0.75,0.8}; + colorBackgroundDisabled[] = {0,0.0,0}; + colorBackgroundActive[] = {0.75,0.75,0.75,1}; + colorFocused[] ={0.75,0.75,0.75,0.8}; + colorShadow[] = {0.023529,0,0.0313725,1}; + colorBorder[] = {0.023529,0,0.0313725,1}; + soundEnter[] = {"\ca\ui\data\sound\onover",0.09,1}; + soundPush[] = {"\ca\ui\data\sound\new1",0,0}; + soundClick[] = {"\ca\ui\data\sound\onclick",0.07,1}; + soundEscape[] = {"\ca\ui\data\sound\onescape",0.09,1}; + style = 2; //2 + x = 0; + y = 0; + w = 0.055589; + h = 0.039216; + shadow = 2; + font = "PuristaLight"; + sizeEx = 0.03921; + offsetX = 0.003; + offsetY = 0.003; + offsetPressedX = 0.002; + offsetPressedY = 0.002; + borderSize = 0; + period = 0; +}; + +class grad_replay_RscButtonSmall +{ + + access = 0; + type = CT_BUTTON; + text = ""; + colorText[] = {1,1,1,.9}; + colorDisabled[] = {0.4,0.4,0.4,1}; + colorBackground[] = {0.75,0.75,0.75,0.8}; + colorBackgroundDisabled[] = {0,0.0,0}; + colorBackgroundActive[] = {0.75,0.75,0.75,1}; + colorFocused[] = {0.75,0.75,0.75,0.8}; + colorShadow[] = {0.023529,0,0.0313725,1}; + colorBorder[] = {0.023529,0,0.0313725,1}; + soundEnter[] = {"\ca\ui\data\sound\onover",0.09,1}; + soundPush[] = {"\ca\ui\data\sound\new1",0,0}; + soundClick[] = {"\ca\ui\data\sound\onclick",0.07,1}; + soundEscape[] = {"\ca\ui\data\sound\onescape",0.09,1}; + style = 2; + x = 0; + y = 0; + w = 0.055589; + h = 0.039216; + shadow = 0; + font = "PuristaLight"; + size = 0.03921; + sizeEx = 0.02921; + offsetX = 0.003; + offsetY = 0.003; + offsetPressedX = 0.002; + offsetPressedY = 0.002; + borderSize = 0; +}; + +class grad_replay_RscFrame +{ + type = CT_STATIC; + idc = -1; + style = ST_FRAME; + shadow = 2; + colorBackground[] = {1,1,1,1}; + colorText[] = {1,1,1,0.9}; + font = "PuristaLight"; + sizeEx = 0.03; + text = ""; +}; + +class grad_replay_RscBackground +{ + type = CT_STATIC; + idc = -1; + style = ST_CENTER; + shadow = 2; + colorText[] = {1,1,1,1}; + font = "PuristaLight"; + sizeEx = 0.02; + colorBackground[] = { 0,0,0, 0.8 }; + text = ""; + +}; +class grad_replay_RscModel { + onObjectMoved = "systemChat str _this"; + idc = -1; + type = CT_OBJECT_CONTAINER; + model = "\A3\Structures_F\Items\Food\Can_V3_F.p3d"; + scale = 10; + direction[] = {0, -0.35, -0.65}; + up[] = {0, 0.65, -0.35}; + + position[] = {0,0,0.2}; + x = 0.5; y = 0.5; z = 0.2; + positionBack[] = {0,0,1.2}; + xBack = 0.5; yBack = 0.5; zBack = 1.2; + inBack = 1; + enableZoom = 1; + zoomDuration = 0.001; +}; +class grad_replay_RscCombo { + access = 0; + type = 4; + colorSelect[] = + { 0, 0, 0, 1 + }; + colorText[] = + { + 0.95, 0.95, 0.95, 1 + }; + colorBackground[] = + { + 0, 0, 0, 1 + }; + colograd_replay_rScrollbar[] = + { + 1, 0, 0, 1 + }; + soundSelect[] = + { + "\A3\ui_f\data\sound\grad_replay_RscCombo\soundSelect", + 0.1, + 1 + }; + soundExpand[] = + { + "\A3\ui_f\data\sound\grad_replay_RscCombo\soundExpand", + 0.1, + 1 + }; + soundCollapse[] = + { + "\A3\ui_f\data\sound\grad_replay_RscCombo\soundCollapse", + 0.1, + 1 + }; + maxHistoryDelay = 1; + class ScrollBar + { + color[] = + { + 1, 1, 1, 0.6 + }; + colorActive[] = + { + 1, 1, 1, 1 + }; + colorDisabled[] = + { + 1, 1, 1, 0.3 + }; + shadow = 0; + thumb = "\A3\ui_f\data\gui\cfg\scrollbar\thumb_ca.paa"; + arrowFull = "\A3\ui_f\data\gui\cfg\scrollbar\arrowFull_ca.paa"; + arrowEmpty = "\A3\ui_f\data\gui\cfg\scrollbar\arrowEmpty_ca.paa"; + border = "\A3\ui_f\data\gui\cfg\scrollbar\border_ca.paa"; + }; + style = 16; + x = 0; + y = 0; + w = 0.12; + h = 0.035; + shadow = 0; + colorSelectBackground[] = + { + 1, + 1, + 1, + 0.7 + }; + arrowEmpty = "\A3\ui_f\data\GUI\grad_replay_RscCommon\grad_replay_rsccombo\arrow_combo_ca.paa"; + arrowFull = "\A3\ui_f\data\GUI\grad_replay_RscCommon\grad_replay_rsccombo\arrow_combo_active_ca.paa"; + wholeHeight = 0.45; + color[] = + { + 1, + 1, + 1, + 1 + }; + colorActive[] = + { + 1, + 0, + 0, + 1 + }; + colorDisabled[] = + { + 1, + 1, + 1, + 0.25 + }; + font = "PuristaMedium"; + sizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1)"; + class ComboScrollBar : ScrollBar + { + color[] = {1,1,1,0.6}; + colorActive[] = {1,1,1,1}; + colorDisabled[] = {1,1,1,0.3}; + thumb = "#(argb,8,8,3)color(1,1,1,1)"; + arrowEmpty = "#(argb,8,8,3)color(1,1,1,1)"; + arrowFull = "#(argb,8,8,3)color(1,1,1,1)"; + border = "#(argb,8,8,3)color(1,1,1,1)"; + shadow = 0; + }; +}; + +class grad_replay_RscMapControl +{ + access = 0; + idc = -1; + type = CT_MAP_MAIN; + style = ST_PICTURE; + + x = 0.10; + y = 0.10; + w = 0.80; + h = 0.60; + + moveOnEdges = 0; + shadow = 1; + ptsPerSquareSea = 5; + ptsPerSquareTxt = 3; + ptsPerSquareCLn = 10; + ptsPerSquareExp = 10; + ptsPerSquareCost = 10; + ptsPerSquareFor = 9; + ptsPerSquareForEdge = 9; + ptsPerSquareRoad = 6; + ptsPerSquareObj = 9; + showCountourInterval = 1; + scaleMin = 0.001; + scaleMax = 1.0; + scaleDefault = 0.16; + maxSatelliteAlpha = 0.4; + alphaFadeStartScale = 1; + alphaFadeEndScale = 1; + colorBackground[] = {0.969,0.957,0.949,1.0}; + colorSea[] = {0.467,0.631,0.851,0.5}; + colorForest[] = {0.624,0.78,0.388,0.5}; + colorForestBorder[] = {0.0,0.0,0.0,0.0}; + colorRocks[] = {0.0,0.0,0.0,0.3}; + colorRocksBorder[] = {0.0,0.0,0.0,0.0}; + colorLevels[] = {0.286,0.177,0.094,0.5}; + colorMainCountlines[] = {0.572,0.354,0.188,0.5}; + colorCountlines[] = {0.572,0.354,0.188,0.25}; + colorMainCountlinesWater[] = {0.491,0.577,0.702,0.6}; + colorCountlinesWater[] = {0.491,0.577,0.702,0.3}; + colorPowerLines[] = {0.1,0.1,0.1,1.0}; + colorRailWay[] = {0.8,0.2,0.0,1.0}; + colorNames[] = {0.1,0.1,0.1,0.9}; + colorInactive[] = {1.0,1.0,1.0,0.5}; + colorOutside[] = {0.0,0.0,0.0,1.0}; + colorTracks[] = {0.84,0.76,0.65,0.15}; + colorTracksFill[] = {0.84,0.76,0.65,1.0}; + colorRoads[] = {0.7,0.7,0.7,1.0}; + colorRoadsFill[] = {1.0,1.0,1.0,1.0}; + colorMainRoads[] = {0.9,0.5,0.3,1.0}; + colorMainRoadsFill[] = {1.0,0.6,0.4,1.0}; + colorGrid[] = {0.1,0.1,0.1,0.6}; + colorGridMap[] = {0.1,0.1,0.1,0.6}; + fontLabel = "PuristaMedium"; + sizeExLabel = "( ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8)"; + fontGrid = "TahomaB"; + sizeExGrid = 0.02; + fontUnits = "TahomaB"; + sizeExUnits = "( ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8)"; + fontNames = "PuristaMedium"; + sizeExNames = "( ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8) * 2"; + fontInfo = "PuristaMedium"; + sizeExInfo = "( ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8)"; + fontLevel = "TahomaB"; + sizeExLevel = 0.02; + + colorText[] = {1,1,1,1.0}; + font = "PuristaMedium"; + text = "#(argb,8,8,3)color(1,1,1,1)"; + SizeEx = "( ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1)"; + //size = "( ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1)"; + + class Legend + { + x = "SafeZoneX + ( ((safezoneW / safezoneH) min 1.2) / 40)"; + y = "SafeZoneY + safezoneH - 4.5 * ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + w = "10 * ( ((safezoneW / safezoneH) min 1.2) / 40)"; + h = "3.5 * ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + font = "PuristaMedium"; + sizeEx = "( ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8)"; + colorBackground[] = {1,1,1,0.5}; + color[] = {0,0,0,1}; + }; + class Task + { + icon = "\A3\ui_f\data\map\mapcontrol\taskIcon_CA.paa"; + iconCreated = "\A3\ui_f\data\map\mapcontrol\taskIconCreated_CA.paa"; + iconCanceled = "\A3\ui_f\data\map\mapcontrol\taskIconCanceled_CA.paa"; + iconDone = "\A3\ui_f\data\map\mapcontrol\taskIconDone_CA.paa"; + iconFailed = "\A3\ui_f\data\map\mapcontrol\taskIconFailed_CA.paa"; + color[] = {"(profilenamespace getvariable ['IGUI_TEXT_RGB_R',0])","(profilenamespace getvariable ['IGUI_TEXT_RGB_G',1])","(profilenamespace getvariable ['IGUI_TEXT_RGB_B',1])","(profilenamespace getvariable ['IGUI_TEXT_RGB_A',0.8])"}; + colorCreated[] = {1,1,1,1}; + colorCanceled[] = {0.7,0.7,0.7,1}; + colorDone[] = {0.7,1,0.3,1}; + colorFailed[] = {1,0.3,0.2,1}; + size = 27; + importance = 1; + coefMin = 1; + coefMax = 1; + }; + class Waypoint + { + icon = "\A3\ui_f\data\map\mapcontrol\waypoint_ca.paa"; + color[] = {0,0,0,1}; + size = 27; + importance = 1; + coefMin = 1; + coefMax = 1; + }; + class WaypointCompleted + { + icon = "\A3\ui_f\data\map\mapcontrol\waypointCompleted_ca.paa"; + color[] = {0,0,0,1}; + size = 27; + importance = 1; + coefMin = 1; + coefMax = 1; + }; + class CustomMark + { + icon = "\A3\ui_f\data\map\mapcontrol\custommark_ca.paa"; + size = 24; + importance = 1; + coefMin = 1; + coefMax = 1; + color[] = {0,0,0,1}; + }; + class Command + { + icon = "\A3\ui_f\data\map\mapcontrol\waypoint_ca.paa"; + size = 18; + importance = 1; + coefMin = 1; + coefMax = 1; + color[] = {1,1,1,1}; + }; + class Bush + { + icon = "\A3\ui_f\data\map\mapcontrol\bush_ca.paa"; + color[] = {0.45,0.64,0.33,0.4}; + size = "14/2"; + importance = "0.2 * 14 * 0.05 * 0.05"; + coefMin = 0.25; + coefMax = 4; + }; + class Rock + { + icon = "\A3\ui_f\data\map\mapcontrol\rock_ca.paa"; + color[] = {0.1,0.1,0.1,0.8}; + size = 12; + importance = "0.5 * 12 * 0.05"; + coefMin = 0.25; + coefMax = 4; + }; + class SmallTree + { + icon = "\A3\ui_f\data\map\mapcontrol\bush_ca.paa"; + color[] = {0.45,0.64,0.33,0.4}; + size = 12; + importance = "0.6 * 12 * 0.05"; + coefMin = 0.25; + coefMax = 4; + }; + class Tree + { + icon = "\A3\ui_f\data\map\mapcontrol\bush_ca.paa"; + color[] = {0.45,0.64,0.33,0.4}; + size = 12; + importance = "0.9 * 16 * 0.05"; + coefMin = 0.25; + coefMax = 4; + }; + class busstop + { + icon = "\A3\ui_f\data\map\mapcontrol\busstop_CA.paa"; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1.0; + color[] = {1,1,1,1}; + }; + class fuelstation + { + icon = "\A3\ui_f\data\map\mapcontrol\fuelstation_CA.paa"; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1.0; + color[] = {1,1,1,1}; + }; + class hospital + { + icon = "\A3\ui_f\data\map\mapcontrol\hospital_CA.paa"; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1.0; + color[] = {1,1,1,1}; + }; + class church + { + icon = "\A3\ui_f\data\map\mapcontrol\church_CA.paa"; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1.0; + color[] = {1,1,1,1}; + }; + class lighthouse + { + icon = "\A3\ui_f\data\map\mapcontrol\lighthouse_CA.paa"; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1.0; + color[] = {1,1,1,1}; + }; + class power + { + icon = "\A3\ui_f\data\map\mapcontrol\power_CA.paa"; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1.0; + color[] = {1,1,1,1}; + }; + class powersolar + { + icon = "\A3\ui_f\data\map\mapcontrol\powersolar_CA.paa"; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1.0; + color[] = {1,1,1,1}; + }; + class powerwave + { + icon = "\A3\ui_f\data\map\mapcontrol\powerwave_CA.paa"; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1.0; + color[] = {1,1,1,1}; + }; + class powerwind + { + icon = "\A3\ui_f\data\map\mapcontrol\powerwind_CA.paa"; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1.0; + color[] = {1,1,1,1}; + }; + class quay + { + icon = "\A3\ui_f\data\map\mapcontrol\quay_CA.paa"; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1.0; + color[] = {1,1,1,1}; + }; + class shipwreck + { + icon = "\A3\ui_f\data\map\mapcontrol\shipwreck_CA.paa"; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1.0; + color[] = {1,1,1,1}; + }; + class transmitter + { + icon = "\A3\ui_f\data\map\mapcontrol\transmitter_CA.paa"; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1.0; + color[] = {1,1,1,1}; + }; + class watertower + { + icon = "\A3\ui_f\data\map\mapcontrol\watertower_CA.paa"; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1.0; + color[] = {1,1,1,1}; + }; + class Cross + { + icon = "\A3\ui_f\data\map\mapcontrol\Cross_CA.paa"; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1.0; + color[] = {0,0,0,1}; + }; + class Chapel + { + icon = "\A3\ui_f\data\map\mapcontrol\Chapel_CA.paa"; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1.0; + color[] = {0,0,0,1}; + }; + class Bunker + { + icon = "\A3\ui_f\data\map\mapcontrol\bunker_ca.paa"; + size = 14; + importance = "1.5 * 14 * 0.05"; + coefMin = 0.25; + coefMax = 4; + color[] = {0,0,0,1}; + }; + class Fortress + { + icon = "\A3\ui_f\data\map\mapcontrol\bunker_ca.paa"; + size = 16; + importance = "2 * 16 * 0.05"; + coefMin = 0.25; + coefMax = 4; + color[] = {0,0,0,1}; + }; + class Fountain + { + icon = "\A3\ui_f\data\map\mapcontrol\fountain_ca.paa"; + size = 11; + importance = "1 * 12 * 0.05"; + coefMin = 0.25; + coefMax = 4; + color[] = {0,0,0,1}; + }; + class Ruin + { + icon = "\A3\ui_f\data\map\mapcontrol\ruin_ca.paa"; + size = 16; + importance = "1.2 * 16 * 0.05"; + coefMin = 1; + coefMax = 4; + color[] = {0,0,0,1}; + }; + class Stack + { + icon = "\A3\ui_f\data\map\mapcontrol\stack_ca.paa"; + size = 20; + importance = "2 * 16 * 0.05"; + coefMin = 0.9; + coefMax = 4; + color[] = {0,0,0,1}; + }; + class Tourism + { + icon = "\A3\ui_f\data\map\mapcontrol\tourism_ca.paa"; + size = 16; + importance = "1 * 16 * 0.05"; + coefMin = 0.7; + coefMax = 4; + color[] = {0,0,0,1}; + }; + class ViewTower + { + icon = "\A3\ui_f\data\map\mapcontrol\viewtower_ca.paa"; + size = 16; + importance = "2.5 * 16 * 0.05"; + coefMin = 0.5; + coefMax = 4; + color[] = {0,0,0,1}; + }; + + class ActiveMarker + { + //icon = "\A3\ui_f\data\map\mapcontrol\custommark_ca.paa"; + size = 24; + importance = 1; + coefMin = 1; + coefMax = 1; + color[] = {0,0,0,1}; + }; + class LineMarker { lineDistanceMin = 3e-005; lineLengthMin = 5; lineWidthThick = 0.014; lineWidthThin = 0.008; textureComboBoxColor = "#(argb,8,8,3)color(1,1,1,1)"; }; +}; diff --git a/node_modules/@gruppe-adler/replay/ui/dialog.hpp b/node_modules/@gruppe-adler/replay/ui/dialog.hpp new file mode 100644 index 0000000..7412682 --- /dev/null +++ b/node_modules/@gruppe-adler/replay/ui/dialog.hpp @@ -0,0 +1,99 @@ +class playbackControl { + duration = 99999; + idd = 80000; + movingenable = 0; + showOverMap = 0; + enableSimulation = 0; + + class controlsBackground + { + class backgroundMap : grad_replay_RscMapControl { + idc = 1337; + x = safezoneXAbs; + y = safezoneY; + w = safezoneWAbs; + h = safezoneH; + }; + }; + + + class controls { + + // this can't be a controlsBackground class, or it will disappear while slider is unselected + class dlgBackground: grad_replay_RscBackground + { + idc = 1336; + x = "SafeZoneX + (160 / 1920) * SafeZoneW"; + y = "SafeZoneY + (910 / 1080) * SafeZoneH"; + w = "(1600 / 1920) * SafeZoneW"; + h = "(40 / 1080) * SafeZoneH"; + colorBackground[] = {0,0,0,0.8}; + }; + + // A slider to change the overcast value (look at grad_replay_RscXSlider - more pretty version of RscSlider) + class overcastSlider: grad_replay_RscSlider { + idc = 80003; + x = "SafeZoneX + (160 / 1920) * SafeZoneW"; + y = "SafeZoneY + (920 / 1080) * SafeZoneH"; + w = "(1600 / 1920) * SafeZoneW"; + h = "(20 / 1080) * SafeZoneH"; + // type = CT_XSLIDER; + // style = SL_HORZ; + color[] = {1,1,1,1}; + colorActive[] = {1,1,1,1}; // {0.8,0.5,0.1,1}; + colorDisabled[] = {0.5,0.5,0.5,0.2}; + + colorFocused[] = {1,1,1,0.4}; + colorBackground[] = {1,1,1,0.4}; + colorBackgroundDisabled[] = {1,1,1,0.4}; + thumb = "#(argb,8,8,3)color(0.8,0.5,0.1,1)"; + arrowEmpty = "#(argb,8,8,3)color(0,0,0,0)"; + arrowFull = "#(argb,8,8,3)color(0,0,0,0)"; + border = "#(argb,8,8,3)color(1,1,1,1)"; + shadow = 0; + vspacing = 0.5; + tooltip = "Set replay position"; + onSliderPosChanged = "[_this] call GRAD_replay_fnc_onPlaybackPosChanged"; // added onSliderPosChanged event handler + }; + + class timeDisplay: grad_replay_RscStructuredText { + + idc = 80004; + access = 0; + type = CT_STRUCTURED_TEXT; + style = ST_LEFT; + colorBackground[] = {0,0,0,0.85}; + + size = 0.1; + text = "00:00:00"; + class Attributes { + font = "RobotoCondensed"; + color = "#ffffff"; + align = "center"; + valign = "middle"; + shadow = false; + shadowColor = "#ff0000"; + size = "0.5"; + }; + + x = "SafeZoneX + (1760 / 1920) * SafeZoneW"; + y = "SafeZoneY + (910 / 1080) * SafeZoneH"; + w = "(120 / 1920) * SafeZoneW"; + h = "(40 / 1080) * SafeZoneH"; + }; + + class playPauseDisplay: grad_replay_RscPicture { + + idc = 80005; + access = 0; + colorBackground[] = {0,0,0,0.85}; + + text = "node_modules\@gruppe-adler\replay\ui\pause.paa"; + + x = "SafeZoneX + (120 / 1920) * SafeZoneW"; + y = "SafeZoneY + (910 / 1080) * SafeZoneH"; + w = "(40 / 1920) * SafeZoneW"; + h = "(40 / 1080) * SafeZoneH"; + }; + }; +}; diff --git a/node_modules/@gruppe-adler/replay/ui/pause.paa b/node_modules/@gruppe-adler/replay/ui/pause.paa new file mode 100644 index 0000000000000000000000000000000000000000..190dbbb32f72a1f53b31efb30786acbe37da0e5e GIT binary patch literal 24729 zcmeHP4OEn6zW=}PI|B>??~tOHBG1SS!@wYDNoq4NxQUEPQY#!fS`34g*1_0Y+qOE$ zfVO2@>p)>zpsU+GTb+A1wc?)LMj7dz!oANayLIlGn6_Q-?PIrc-MjX|40Hd_`_4Oz z;5Mj;wDJJM`ytsJ94;EJzs{mm2>eclUt|~5LIEaDa#l_1?80PSg z;UAWiEVtpa8~>(G03b^Nj4J_VRRhd*0J!jPn4t-{)_AxE4neROz=UOmGXAe+$fLmm zx4;U394l0?gv0{sOt81=?XA=OocgBL&br>tCua9^lj%n89esc^Y~r-<9z@tpY}mzHEM zoGxKg$7XY(3M=`tJ#H32!`c)An*w6j&fC`WS(_37W}Avcx=2Ur{7Iy`2o`~0{sDkC z-sIKpGL`YCks)gX;-sB_i_7fi^t7DI-Z%&;^43u3lZR+T;Z_}F# zHEBl)JcOy&H(Xa^JRmmR(V#CyIwp9(M02hsk1wQW zod!&1#$?EZLb{`)$7I!-Nr^X~C7NE{cf(!#F~Jh4oas6j;f`rKRuh=#7j@oBzUH-p zT7%KACXnxHK!qxVHz9Xp&EDH}4K+wsYC!a5SPjn@UH`(-G%g=YTIUsux_$(_!&C^@ zzOFl9dzt9GHu9!lRM}`jt$y7eOmvSckIBYHckBAgJ8mLh1;mLuS049lf%7_JKy`?G zzA^7zI<39;}(zx%QO`Tg4`k_A5d0LRa<^8Mc18&Z7jQ-ze%6Bp~&d}XY!?GxhnV>R}ZoE)y5zHD`$gwUU9A!{+e(y z&Ibv;VDPrLY(5_$-b7XK4CjCt$Epd!yf-*O5Qx^wf0mHJeF#Y(HcYkIfPCpKS9ihk zZhdKUCh75~3)ChU9L?lwR}mlloYO)naKYfVSIMM+csB8ABEjAhB;#OW@N9oFK25Un zpZ6zYic ziu!B6s4k$LYi}%Y=8>C90gb7)iA(U!FLS>zqA#!{&(%~qZt@ryhKd&?yGdvh>vO>-tbV?%PN z?sOh2CAU9aets;Fo~HBX=>p4NW8a$t=@04pm+#S&$Ncy4wa<3mJx%%=!M@vjUrr>C z`tQ?uoB7&l*coT}x8BODv@AhFK>XQ*5J!SsOy)ia9$!n^{4eoK_vlMMV$l=)T{{0u z!nT|2p7$UZ`{5n_w}rc$h7#uuESj-9m1;VAH0{U8uLI%@$xXk=(3RShxOsF(+R=Sw zy-XCz3kA<9t>Ne?1oRDO#0= z+C4|Mv};ps4sAD-^DQd-_EScy>dgm$d|F6?pCzAN9;?+}$CW1}L-`$bx4o6@UruxZ z@l5jHmd9*Np7%y_U^%DF=E{?jxpJZf0m^HDWLXmUHO=~EXSAtsNc*->Z=lPPitci< z_UsZ5 z{;H&%$-J;C*^IWUjfeX7mB&+5J{kyq6}$Cdvd@-~K~B12V+_>3U8U*p0ZGE~odfG5YBuAW49ryYGIv6uBjvw(HsOFqghab8D0v5-{wtt}Z<{yoj~V?bu05Z^?$ zPCiuN+|XHP+&GEOxCI2X5dSZ=umO$~LyXaz9&_#MP1au26)A`IOE|5XO)H((b>5rh z$|qlV%Tr;4t(fuA8?V|j{n)FCm=bGF4T2VJVyQFpLCGd?h)mNR{LPUUQg5^6r-H!c zd$Jog7mC%*`bsU#bho6!0?42G)%-2(?`IXpm$uIF{z4iCuq>Y2P~eX6+)nj0H5(~o8y)HEfM3=7&U+Gbvn_Q3*Ywkt*#tk|!w#Do*9+J$#Ctlnbk5+7`; zBR^zaM=ElLgPhz0`PZ`XCbOV+gE0_$7_|ug!*WZzHOqVRs$#x%(r#;SmN$+pvg8pc z^^1i9%%*E_+_}?? zsa>z_s7Q7j#)oJ1YYO(v^Ge|wp}ls8)A zafHirX>%JI42`*(;-guXm~xKn!NFO{(FI1&bJ_lR0=56AUMpnHhmwv>Jo&^W?$klP zsY})R-0ti`HJl{(TMBUoA=QI+cDNhlekZ{FjF8m4w=a%eGb*ZdfVUOdV|dE6m?ZmglAFLzMhxs%bf=yh?*5x0yeQ;FhiJ({FhqOI8 zvidMqGe0?9J4-!9LzVP|PXvu%cknwwVJ%=+UMPH-#htcfgYL5rE@Cn3(`N`dk z<0soxN1ghv{$aG_PvLNzc0Sw9liPEp<$Z**Co<6&1XU`OFZmiq<|keXBN< z-Vn;~4qNC^Q?sMk5qinB1YTu^a z;)$F7F`mq;)oMmJ3&G&YAdmmw>1+JUuHavbg29jHJKO-#UNR@@VCabbKxz;%tss4@vSkPk(T^j zA9eW;ZvO;yF?b)3X%%^(Sfp^df(?9?;v{RRpEZ>`|7! z+;5G<{!iq7D%<~~POcor(){i!mp^p^|I3K^VdQ@GNXQ@RA;t~y*ni6Vf1_^S(dH9Z zyZi_7C%c|G)TH%}RR7<&t+QqWI_8YaU+!DS+W0@%9vh!TKe~M*DF3$3+SkwrYFz%` z6ZyAEUTPy||JeWI_!8$Bm;d)e{@L{-D}S6%c-ZO4qsdQe-*^0bgJ^hQ8rS{c>wYZv7uw9$Ww8exv01uGEM7 zk*)e=S8hKjNOAL5)3Q3W{}=M}V)UP6dm;QgeQfjhn<;ERm-(+n)7N+UaP!x{wO>xp zYnUCe5Gv0dq`3L(*sl-m|E-Ev-blww{6@ETBDEs~6qJ)~e3%L2i_NP8cQuax|;SyCYQ$=XMLSK`d*tQpsb5I=_K{~&pj z-{D(Xdk5@CVkUl&Q2ycKu_FJ$?XAN%nx{qf4=llCkMz0{)0ZLq8EN~v(&aIF-H%%d z{$up6qdU$!e^cTynG^_qvh*^Ft`B2X{)5{;bpF8C^M{`f`xlrce;z(lp?|FFhuq#) z>6Kt6FH|?x=?w$^>)g^N_C7`A4Hyx4ys`$**{7Z=M@5p5!zAa5|?c z`cWX>U#h;y<+Ua$qs`fJ_#(UGsx9tefO__D~~t<=W)BJ{6& zaqQv9{c6@eQ(aXp(;ub14Q-A=*i;i4Z>sy$5s4%BQ^z8`iUbt;A~Ew{Q$pm}!M+>E zjAH{~oFC)-7|@2R$3ARe!@D!Wl#iRiU^770JYQ9%Fi47hvEtm}bVRtH(Kql~?nK&oXa16bX)bN!q%2DMOPz+%HjoB0rM!uB ze_FTwsqivEZqLwT5GB3T82n(=8ZZpt;n6RbKj8MhmEHA)C#_2PmrUO!E=#vcH;oOv zhAg%B@3@6u4E-oyr~a-z7ftV5(zLu4nz5@vbyv%{Ss%hHLh-5)PLVOM#9y$R^(5NT z;nU#FWRlDWWISB?GkaUvxi*8PXZnB1`rP;7R)5b{KPyjzZsjy!l-$Ur@|hcX07T}- zF0~Kc*lAzUUt$|i$1>~~hTHlO{TpO2NKbC>D``ii@`s`S^JO=Gqtw2tsue@ZzfgVc zL*hg9Gq-vgklpB6`H~xbKz8G2n7Q%OJ|sRw|8U&)qqT2=>?W_!pAyafr{OWTq0(t! z?OA~#TKQ4quQ2`7@tC-0OM4HaCj~=v`jPlbr!@ZjW6+PpZ)x`pm;MFxLCMWQl0UQm z3)T0*>94T-7tk#o%uPU|e;D?!?kaFT+j*z7Y?k{!rZJb`_9f9T;;}kjvdVE9+5YQ! zhSC13sBHhI8AkIrgzSGJ!)X6ekL`!Zr%lrEuv?V6tEsGazq}1_apT_-Ctd?5-9O0Y zKSSypEbl@1Evk`@N!j?O#sTmxD!XYhyh6hAF)G6;61GWhTnv{ZzR>z6QTtOzG}GTF z$OhJ4i5t@MMbCfEar>Zgc+5N1lc1D;q3s*-^l>;&`kKRTX~O;IKPF|IxET2>{8Q)^ z9yoVfaw4_w(Z|%TRN`^Iis2IMWsv^J-_>4&AzO()$2QoPk+yO*VZsg=Rg7XOFtIUjDGA_*j9;vXFPE2n3TC(U=nof# z;wvj8+{ioR__k1bdDsDnc3W8FZB??j$&3T%-X2m-OJ2W_w~ec*sXg*-SuF3ow`;KW zGH+R#zM2~uX5Mbq^sZ)o*>^1SzD4G2@TH#&5;Tj23n{}rkL;3hQ`6vX&Vg6Fs_@!u zBJmV&vtse2Ed<~m++b>N5K>Xj~|;P;YxhF9pJ1{!8ioP zm&?O~l3pqBe3+dUXz>R)h-+tNUL&o3+3puJ>!-1IVA-G&*$VdVLWq-bTSbMGes9Rk zad(M=rbRGmrP*B-TRoit*ldg2+;;-WU}|;-*e%*1VW#Hb;4L;GpOtUG)d>ZihoA4! zGK|@)=o!pxi<8o0_6m9iGbezAF*~*ggzJ4mCQFam4RP&w-EC;}sH%FNvBd^I-66B7 zqLN{7|5@IRtEgy0dYclJ(S?l;ark2cm_s{ju3y)D>NRY3`HHrbIe7P5w>_X@Se;V2 z0)64X$SkRy#&Am8it;&hx#vAoLNCKBDpS-d>`{@Q_Z^LSTvh7u{pfL|zPPwT7Q+7n D%P=aK literal 0 HcmV?d00001 diff --git a/node_modules/@gruppe-adler/replay/ui/play.paa b/node_modules/@gruppe-adler/replay/ui/play.paa new file mode 100644 index 0000000000000000000000000000000000000000..fc6197a995db064dd37857fb3f0c351db09bec92 GIT binary patch literal 25095 zcmeG^4R}*kmgl{fl%|xvAb%BFxS>hY^oJJ23YxU3Bc%Zf#UZ7B6q=@jAY06=4ziH6 zX~9uuRoZA3#zscg{buyrnL*U#Kh3DD{Q_?K#c|HZ#6Obu9RBHRXhAyNcj0wBEw|6so4 z(O`zfumm8>0(O>>m_eNmHlN<+O9^r6`+RM+U2V@y@8QPNI_^V#m^0LI-sg=LxZlG; zP66;u+3j#!qL5X{?e@Q#-NB_MWf$;`Mgke`5%*YN99H_zVR4BmB$AUH%>B*dVeZcQ zwfX<04{`OiPnG(NX5bR(cYal=HWmVX!h{u33S@a9JYf|w&A=zpF|Dtf0(|A|eCb}> z_w-qv!e;-L>;e@wa=JBs8h~fbI0Bo)V&}^bY~(XGBlD)43Pn0cM`}Y!q^c0+fROzS z0BwRPpxtRI<-3s~Yr^8#mp_kB@8R^cjLWQ>yq_a~a*Je2AshgnHLRyw{902$-8#L5 z#{#AvaeT1K)>fSx=B(n2D`ze+dBlALa#S;JtFt*sXfzb(@;D`G~a2M@57%DV#SkDc15(of57&F zKD$7ZdW66R%)QZbN42qCY*^vZmmnP@17d*%8Y&yOpsh)t)vno17Mr!?WLV73G3W9H z^qkXx*|ISkGNFL(@EWhY&P}+Z8vla?W`#supq#IM zH^0VU45*1+X7->Z*4y*LkXutmLp5OtToiXLSD?M^m{xtZ7|9EbROi@D5V} zOngt*Zhe#J0#>p=B&w`5zec}q7rEfc{pCwA^9Qr_?;JWr^*ytlT0gghfU8hzrLX9E z%KZ0{^I>s}&YjD>l<&O57*_2iVRx?T{mANF`gyz3>W*my06s#u3yxzs8@!|73wHy* zk)P!`UDvS0g*CZ%smIXWrCklFN6ATST2G6e=_M#&jd>9tIl^h71j|Qk^EfMKODi1kb3;$w920@Lp}d?xnYt4e?bDYu zrjrAqDFU?$21g@-+e7P!HY8fiprSpayAvZ9p6B>Vmlw`-HW(i`M4%XP0BUNA*EFlh zzlX(=G)vXXMz_GxIh>V1N+6!(A|7Tfe_>m9eWZeV zdrcOw)vsKH>i2_?sLrQtYwpQ+=3*DeDhfm5v;z2_FVc4B-3xO}Q(G6Sd#LTWel?%B zvtena1JwZWxQo7(+SPzvf>khquCLLTJJV5_B|e-)zRMzOn%k z2#+HRKo`ziiac|Vz+$iYgIik1mc@_w>}$Ed(Y93P}?ZU6Y~8tLcWM`TvPYcb6C#`1)?|c4*8OKmRd^PkMlt{# zMav`l4&Q8lTDz~3bO(Gw@e8{xU2l`ENO>x4TYFDiO&VGTY}EqCjUB$zo5%udETauaRC)qxn!xG?2Y8EZcN9VNNg6>b)&2yrDqELbQO1I!dsl+bB)CPkMK1wwLLV6z=iN5XGL!Awz4#{R}I06@?*5bSLexDyL^tF z9A~XP!oRV+>&;Q*sn8?3KqFr>2|ZOtXxsg~N=x8pA#v<$he(`ozI_E)BVumCtc{%) zye^c8n{~bKtcQ3K;o{QYfXHvwke1L-`1!l^CC3T89_mEFe7GJ|*>S?}ldYWELBoa3 z91m%AI~|o|pL-#h9{P#!!hN=;UqBAJw;iDmgjG&MvGXnhuZ2YSXwI8x`Q!yISe7I> zem*rc?b|{H`F)^3vd_s><3FHjJxYEM7VjF}@NAl{1pDIlut-P$gI3rX(Q?PmyX$yY zWjEcB)=_Z2oqUcZr=Vq@MR%kgd84$8ssHGEg{Bi)p)oWE#hz-mlDx3^#db~?D7fuF zna<-mqx-DZm{%p};=MX9_pqUE;qQ|PkB2KVh_} z_CJQ0B$x>idqmo^io1~5#(7<%8*oAt$la25?~uDvdt~Bne&khtMSC*QB+rnPhBN z?IS&AB8308Eu__?)z=E#k4ByOOlNs!tUgf7!*5sEKQ?p}B-RkPD^Q>{K~q*>ih3-4 zCH2T#qq>-lp9aif&O4r7?7V}(1A&BOuvtf=q4MG$8UOo^NLUW26zwNEOcJq_Ke>9pK=N88#AH@Y`5P?ikKtVN9Y zK!R#(%F(w+VODHAIRaWV3GzPSlLy}Zo$Bz%cmi&Ma`yM^Y6-HXL_pb0fxYg7tu5YL%-wcT8q>(oqWaYHy zO=SK(J-=p?F+AcRlktC>7q?n60t+jPc;DDpEM3e8%rWN@C_yVMz;wDA{rt*o^yf_+ z_J@G@@@&Y?2#nxtqmS+()i|hu)mXa#yPhSU1u*mO7l9O%{!Qd8xjHH(C;KJdx|x=6F1Y`W#KskqmQO z8Ao>EP)I4!3C5;ZGeffkYWulfD`d=uV*h5IoN|jV>mbk6sq(%0N@jr?J|T~q3nZ(I z?O^{n*qmt|$rmhfH5RynL#(}C;^=X(tq=0h~w__CD)AiR=7ESJS|0m;qOUZ zdbuQg`m0D9nd_0$rGxsX%rKfw zB)kCD-c0hmqYuCbHV?T4_jBMDKW^zmzczdw`v;@m>ri+gYs2gI;RcVC7bjE-ex_P! zh2l;HcDFEiRQ|=V|274d^ZSz&Sgx;8ufW5N-Y>_8*Yv-aDY$kR=PsC(@&q5EZQ}KU zbsL$yYT5WlYA=Dd)lRB-4wp1!IFGjJ(s4aXfoatr@ePj5@Q>k#i$zkpX1Jm%=h^m&4pw?^>;`85hxLW2ZrKaRu=)%e`ShTWt?(PE zlM=ztXnnX|@|Wi~)%PgvWz&*<7marZOW$D2e`-xSf&Ur(227Fjz%vF#BIc7;_DvV@ zMyudp?{O>Ddx)}NhDLp(mg$Rq$#Bnjp0V`42mHSwpJC9a8{^c zx-c~Ik6uq@>wnbAmBDZx-(6+@S2(8homlwLSq!^jFC)9O4&*WY8xF-rcZ zJI>?ya*4}(v-Kg<#iEH)yBOX>A^-Xp+Nw8URMIW^%bIYBJ|Lf2ir@&si{JFDs+%wT z%LtaQyuxwA=Nt9UVT|G%Ln!~2wwiY_Fd+C37+1{npIP@MxIlE%^*d(#JOkH*eu^=}B#H(`$Mur`NIdp% z*EwgJ(%x|62OX&YpJUu%{@TnuH}lu=Gym~3$-a5ffWO}>Z?+zY-Fw){JC@%g@f68X zjQl1@jH1K%c-`cW>y1(k{-~(%)!tG6hrn#~YjE8{&u75XY_iXwh;Vc^sb{jE<1ix-eWc?5&UHNWoTf17_Rb<#sAXr1MlJw zzStLEkS*=U^XUrx!(BgQe0_MvSe6&6m#TYHfBZT(zk!`+=(C5h{1__ut0Mn_=+$k^ zcSiFof!Z4HjPfUWOh25?Ndzlm{i8~b-?&qO2dgh~eZC~6KB+y8x=((Hk1r|8Uh6jA z82KvrAlXtP_!(^V)ihBde^p`>WtV87jh8OQq5Eq>hMN53|FefozLtaxokALX~YL2Nfb z*8H%dLSc~f_I3Nk$DS_(t2@!>v{g@6^3P_+-tgF}1V3!IPr_rPw%%n*7I%zrjwTA0 z^5d~mDgSGByHwxq)SoH!T`fKr<-UN(O=tOh<%A8GZf7a>vlN zm3i~}hq<(clZq($2RjU-Eg(5FrM@wAPwGC~^L^6<8J|nHL6rOwGWfx$Wntm{@RiXo z*WVxZzKz|ihC72w{ez}&kkim@(!Fl|$B-p_|4vx=wa}09b?R5`x@LOMO2cxWDg`&) zP~FGTzcLAEx#g!Nc*w(Q$I@nhP=mL=VJp!#?Mmg(`rER$HEAqA)BnNh^Euq6RpEcO z={OD(4S&$RlOcxnJG_V^;}2d?CiA1xHE4Z`=`To6PS;zhN3N9q*>ae_v6ucqAB%{k zpViBf%mIL-A-pV4N{gSi;_vh<`la0Nxhx;MGHFNKv=3_h&vZo1Xa!UQDxufYGQ zJM*0{wXKw<&9ePt^0@Y}uUPt7m`x#GAoq!62ZAp82RW>Y;Ws2junkV2Y8}4%!I+$BdlmFwLO1Wlk$;* zFQP3a#@}n9AIB3Hg?-R?+~&Q#DUo2UjK5dQk0H+=kDVsi*cX;2JbL+U(rcw(=3f7@ zyYSe>%aUWLZI?c-W?3IUB>lVg{&ER_V)Pl?^WCS*?puZw9=oz-$7`eihYI;9Yc^i% zU-$cau)1@+q%X?*yQO8@-eoxZ!!U`BcbXoQm*sFeCBZ&NAB_2ZNy@UF{WVZ`zLMCt zEO!O%D+nv?N5cj~rUFX3+XvtS)8(%tOxOmas*iG+30{ZtgABiJPbib8eG1HO>(L)9 zl+=R7%SmuO?~vcO^yZh{4!}USg+QX?=drq$V#HRq?^RJ=_+b! z-4c}_>$~jj8Vp|+Ei2PkeGh|K`&D#RqrUV@+B*T>(Wf@|u>AHlTQz@TYK^Cf-}#j^ zt*MN~&wF>1%IhMoTe%5BmZ7d9c)gK+Ak|Bi!FZ%{JR6&Lik@PAEAe(+hsmM zeDE-R?%$r4Cq#| zKHsZ&L#UCO_^x0~bY5(Q1OVAA64;r5iyPuw@v_@q?@>|lL&g>>{L>DZP4;pIgZEQe zZS3|Iq_<&|;$4_`h{u0cfEl!{dgi*u6D)SHY)Q+w8HaY`_5EQLLqk1oX(h(O|2e(5 zW)gcpu4PHtj6;i>eql=NVw3#JrQ_5pw5Z6>M~=ijttxQ@zx6Z=4.10.0" }, "description": "Various faction tvt loadouts for grad-loadout", "devDependencies": {}, "directories": {}, "dist": { - "shasum": "afcdb63d47ac7541c2de8c865eeb14c0dbab7a96", - "tarball": "https://registry.npmjs.org/grad-factions-tvt/-/grad-factions-tvt-0.2.0.tgz" + "shasum": "2c2a5db16d1280fc4b2e1c9c8d40bbcaa88f60fc", + "tarball": "https://registry.npmjs.org/grad-factions-tvt/-/grad-factions-tvt-0.3.1.tgz", + "integrity": "sha512-MyARV8Bsuc8PB+aYwG4uAI3bP4zgs2/4bPZSWNs+VDig2nXP8ZPcReRqqIJMaCS9/wV2ledm/frMXJ3SYDueoQ==", + "fileCount": 15, + "unpackedSize": 37712, + "npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb6aJmCRA9TVsSAnZWagAANJoP/3MCkvj1dDxUS5++bOJW\ncC2ortrNPHdehR+kSloh7LRVCMCQg7jFdB5p87cneEIkJst3ZCyhEWYcz38n\nT/WwLEjvG/4eAkywS4n2POQJFt6K7xATGwjiHexw/vvOd5xlBId7N1XRUz6t\nQZM1qkquK4eRlXbqsBQkQ5TGekitbprVBsdoc5K5QTaiTBe7Md24Cw+6mYhj\nbWtxG0Xfb1GZ3jEZgdpZGkLceqzZb7GH7R7Bh+1OB5gJYWJqWwuTFEe5P4pj\ndihn9Y17u6IYGkf/Mu45pDvdbDGTnPjx+5Zxuyj5wZOhlSoNPnsKIoYn36Y6\nuZzftpYjrr0l3lDI9Eoy+6IvqU5yBK6w9UGwp+gLEfHD2GVA1icbiLn8eFjM\nmr783pQo+8f0KMH0kBzlsEslmnCXdNDwMuzuyy6ZLpWi8w4UuXBI6uhn+pL0\nXWevYHH5I9XR7iOjKPwlymbJPbpV17C3WtWCNxxU3KEjy1+ZWD+8+4eovC5W\n4xW717d8W4Upkr9oTA8p9saRcRyW4dEs5Ns+K/ja2LaFy9OgFDZnvvSXNS97\nLkWOnNbb4vXteta82nK/5mrXkwwZ9oFJVYhlXVdnUvvpPjN2rEwkJ7lfzt9C\nAw0kO6f1IOnLRRjb3sfQ63h4dVSGKPSptdxY59o9k14cJJ6/17cehEKCRNcp\nddd4\r\n=+ymT\r\n-----END PGP SIGNATURE-----\r\n" }, - "gitHead": "dfe123c721bcba1f722cc35134975f80c8ed5c3d", + "gitHead": "b6937088ddcb810b6947d54fcc71ea716d017ec0", "maintainers": [ { - "name": "gruppe-adler", - "email": "kontakt@gruppe-adler.de" + "name": "gruppe-adler-admin", + "email": "admin@gruppe-adler.de" } ], "name": "grad-factions-tvt", "optionalDependencies": {}, "readme": "ERROR: No README data found!", "scripts": {}, - "version": "0.2.0" + "version": "0.3.1" } diff --git a/node_modules/grad-fortifications/cfgFunctions.hpp b/node_modules/grad-fortifications/cfgFunctions.hpp index ea13867..5fa5d0d 100644 --- a/node_modules/grad-fortifications/cfgFunctions.hpp +++ b/node_modules/grad-fortifications/cfgFunctions.hpp @@ -38,6 +38,7 @@ class GRAD_fortifications { class setDemolishTimeFactor {}; class setPackUpTimeFactor {}; class stopAnimation {}; + class storageAction {}; }; class drop { diff --git a/node_modules/grad-fortifications/dialog/vehicle/dialog.hpp b/node_modules/grad-fortifications/dialog/vehicle/dialog.hpp index 9cfa374..d9e1e67 100644 --- a/node_modules/grad-fortifications/dialog/vehicle/dialog.hpp +++ b/node_modules/grad-fortifications/dialog/vehicle/dialog.hpp @@ -83,6 +83,7 @@ class grad_fortifications_vehicle: grad_fortifications { w = grad_fortifications_Item_W; h = grad_fortifications_Item_H; + colorBackground[] = {0,0.8,0,0.8}; text = "<"; action = "['STORE'] call grad_fortifications_fnc_requestStoreTake"; }; @@ -96,6 +97,7 @@ class grad_fortifications_vehicle: grad_fortifications { w = grad_fortifications_Item_W; h = grad_fortifications_Item_H; + colorBackground[] = {0,0.8,0,0.8}; text = ">"; action = "['TAKE'] call grad_fortifications_fnc_requestStoreTake"; }; diff --git a/node_modules/grad-fortifications/functions/common/fn_addFort.sqf b/node_modules/grad-fortifications/functions/common/fn_addFort.sqf index 3b78d17..e563974 100644 --- a/node_modules/grad-fortifications/functions/common/fn_addFort.sqf +++ b/node_modules/grad-fortifications/functions/common/fn_addFort.sqf @@ -6,22 +6,22 @@ if (!local _unit) exitWith { }; _amount = round _amount; -_myForts = _unit getVariable ["grad_fortifications_myFortsHash",[[],0] call CBA_fnc_hashCreate]; +private _myForts = _unit getVariable ["grad_fortifications_myFortsHash",[[],0] call CBA_fnc_hashCreate]; -_stock = [_myForts,_type] call CBA_fnc_hashGet; -if (_stock+_amount <= 0) then { +private _stock = [_myForts,_type] call CBA_fnc_hashGet; +if (_stock + _amount <= 0) then { [_myForts,_type] call CBA_fnc_hashRem; } else { [_myForts,_type,_stock+_amount] call CBA_fnc_hashSet; }; -_size = [_type] call grad_fortifications_fnc_getObjectSize; +private _size = [(missionConfigFile >> "CfgGradFortifications" >> "Fortifications" >> _type >> "size"),"number",[_type] call grad_fortifications_fnc_getObjectSize] call CBA_fnc_getConfigEntry; if (_amount < 0) then {_size = -_size}; -if (_stock+_amount >= 0) then { +if (_stock + _amount >= 0) then { _unit setVariable ["grad_fortifications_inventoryCargo",(_unit getVariable ["grad_fortifications_inventoryCargo",0]) + _size, true]; }; -_isPublic = !(_unit isKindOf "Man"); +private _isPublic = !(_unit isKindOf "Man"); _unit setVariable ["grad_fortifications_myFortsHash",_myForts,_isPublic]; if (_isPublic) then { [_unit,_myForts] remoteExec ["grad_fortifications_fnc_updateItemList",0,false]; diff --git a/node_modules/grad-fortifications/functions/common/fn_addVehicleInteractions.sqf b/node_modules/grad-fortifications/functions/common/fn_addVehicleInteractions.sqf index 372633a..cdf03f8 100644 --- a/node_modules/grad-fortifications/functions/common/fn_addVehicleInteractions.sqf +++ b/node_modules/grad-fortifications/functions/common/fn_addVehicleInteractions.sqf @@ -1,19 +1,4 @@ -_moduleRoot = [] call grad_fortifications_fnc_getModuleRoot; - -_condition = { - !(locked (_this select 0) in [2,3]) && - vehicle player == player && - !(player getVariable ["grad_fortifications_isPlacing", false]) && - {([(missionConfigFile >> "CfgGradFortifications" >> "Vehicles" >> typeOf (_this select 0) >> "isStorage"),"number",1] call CBA_fnc_getConfigEntry) == 1} && - { - (count (((_this select 0) getVariable ["grad_fortifications_myFortsHash",[[],0] call CBA_fnc_hashCreate]) select 1) > 0) || - (count (((_this select 1) getVariable ["grad_fortifications_myFortsHash",[[],0] call CBA_fnc_hashCreate]) select 1) > 0) - } -}; -_onActivate = { - [grad_fortifications_fnc_loadVehicleDialog,[_this select 0, _this select 1]] call CBA_fnc_execNextFrame; -}; -_action = ["grad_fortifications_containerBuildAction", "Fortifications", _moduleRoot + "\data\sandbags.paa",_onActivate,_condition] call ace_interact_menu_fnc_createAction; +private _action = [] call grad_fortifications_fnc_storageAction; if (([(missionConfigFile >> "CfgGradFortifications" >> "canStoreInLandVehicles"),"number",1] call CBA_fnc_getConfigEntry) == 1) then { ["LandVehicle",0,["ACE_MainActions"],_action,true] call ace_interact_menu_fnc_addActionToClass; @@ -27,3 +12,6 @@ if (([(missionConfigFile >> "CfgGradFortifications" >> "canStoreInHelicopters"), if (([(missionConfigFile >> "CfgGradFortifications" >> "canStoreInPlanes"),"number",1] call CBA_fnc_getConfigEntry) == 1) then { ["Plane",0,["ACE_MainActions"],_action,true] call ace_interact_menu_fnc_addActionToClass; }; +if (([(missionConfigFile >> "CfgGradFortifications" >> "canStoreInContainers"),"number",1] call CBA_fnc_getConfigEntry) == 1) then { + ["ThingX",0,["ACE_MainActions"],_action,true] call ace_interact_menu_fnc_addActionToClass; +}; diff --git a/node_modules/grad-fortifications/functions/common/fn_getVehicleInventorySize.sqf b/node_modules/grad-fortifications/functions/common/fn_getVehicleInventorySize.sqf index daff501..3c3adf3 100644 --- a/node_modules/grad-fortifications/functions/common/fn_getVehicleInventorySize.sqf +++ b/node_modules/grad-fortifications/functions/common/fn_getVehicleInventorySize.sqf @@ -1,8 +1,19 @@ params ["_unit"]; -_size = [(missionConfigFile >> "CfgGradFortifications" >> "Vehicles" >> typeOf _unit >> "vehicleInventorySize"),"number",-1] call CBA_fnc_getConfigEntry; + + +private _size = [missionConfigFile >> "CfgGradFortifications" >> "Vehicles" >> typeOf _unit,"vehicleInventorySize",-1] call BIS_fnc_returnConfigEntry; + +if (_size < 0) then { + _size = grad_fortifications_vehicleInventorySizeFactor * 15 * ([configFile >> "CfgVehicles" >> typeOf _unit,"ace_cargo_space",-1] call BIS_fnc_returnConfigEntry); +}; + +if (_size < 0) then { + _size = grad_fortifications_vehicleInventorySizeFactor * 15 * ([configFile >> "CfgVehicles" >> typeOf _unit,"ace_cargo_size",-1] call BIS_fnc_returnConfigEntry); +}; + if (_size < 0) then { - _size = grad_fortifications_vehicleInventorySizeFactor * 15 * ([(configFile >> "CfgVehicles" >> typeOf _unit >> "ace_cargo_space"),"number",0] call CBA_fnc_getConfigEntry); + _size = grad_fortifications_vehicleInventorySizeFactor * 0.015 * ([configFile >> "CfgVehicles" >> typeOf _unit,"maximumLoad",0] call BIS_fnc_returnConfigEntry); }; _size diff --git a/node_modules/grad-fortifications/functions/common/fn_initModule.sqf b/node_modules/grad-fortifications/functions/common/fn_initModule.sqf index 9c9faf8..4aaaed4 100644 --- a/node_modules/grad-fortifications/functions/common/fn_initModule.sqf +++ b/node_modules/grad-fortifications/functions/common/fn_initModule.sqf @@ -5,7 +5,7 @@ grad_fortifications_demolishTimeFactor = [(missionConfigFile >> "CfgGradFortific grad_fortifications_packUpTimeFactor = [(missionConfigFile >> "CfgGradFortifications" >> "packUpTimeFactor"),"number",1] call CBA_fnc_getConfigEntry; grad_fortifications_playerInventorySize = [(missionConfigFile >> "CfgGradFortifications" >> "playerInventorySize"),"number",70] call CBA_fnc_getConfigEntry; grad_fortifications_boundingBoxSizeFactor = [(missionConfigFile >> "CfgGradFortifications" >> "boundingBoxSizeFactor"),"number",1] call CBA_fnc_getConfigEntry; -grad_fortifications_vehicleInventorySizeFactor = [(missionConfigFile >> "CfgGradFortifications" >> "vehicleInventorySizeFactor"),"number",1] call CBA_fnc_getConfigEntry; +grad_fortifications_vehicleInventorySizeFactor = ([(missionConfigFile >> "CfgGradFortifications" >> "vehicleInventorySizeFactor"),"number",1] call CBA_fnc_getConfigEntry) max 0; grad_fortifications_fortificationOwnerType = [(missionConfigFile >> "CfgGradFortifications" >> "fortificationOwner"),"text","BUILDER"] call CBA_fnc_getConfigEntry; if (hasInterface) then { diff --git a/node_modules/grad-fortifications/functions/common/fn_storageAction.sqf b/node_modules/grad-fortifications/functions/common/fn_storageAction.sqf new file mode 100644 index 0000000..aae439b --- /dev/null +++ b/node_modules/grad-fortifications/functions/common/fn_storageAction.sqf @@ -0,0 +1,30 @@ +private _moduleRoot = [] call grad_fortifications_fnc_getModuleRoot; + +private _condition = { + params [["_vehicle",objNull]]; + + alive _vehicle && + {!(locked _vehicle in [2,3])} && + {vehicle player == player} && + {!(_vehicle getVariable ["ace_cookoff_isCookingOff",false])} && + {!(player getVariable ["grad_fortifications_isPlacing", false])} && + { + [ + missionConfigFile >> "CfgGradFortifications" >> "Vehicles" >> typeOf _vehicle, + "isStorage", + [0,1] select ([configFile >> "CfgVehicles" >> typeOf (_vehicle),"maximumLoad",-1] call BIS_fnc_returnConfigEntry > 0) + ] call BIS_fnc_returnConfigEntry > 0 + } && + { + (count (((_this select 0) getVariable ["grad_fortifications_myFortsHash",[[],0] call CBA_fnc_hashCreate]) select 1) > 0) || + (count (((_this select 1) getVariable ["grad_fortifications_myFortsHash",[[],0] call CBA_fnc_hashCreate]) select 1) > 0) + } +}; + +private _onActivate = { + [grad_fortifications_fnc_loadVehicleDialog,[_this select 0, _this select 1]] call CBA_fnc_execNextFrame; +}; + +_action = ["grad_fortifications_containerBuildAction", "Fortifications", _moduleRoot + "\data\sandbags.paa",_onActivate,_condition] call ace_interact_menu_fnc_createAction; + +_action diff --git a/node_modules/grad-fortifications/functions/drop/fn_initDropCrate.sqf b/node_modules/grad-fortifications/functions/drop/fn_initDropCrate.sqf index 79b23b1..110ab22 100644 --- a/node_modules/grad-fortifications/functions/drop/fn_initDropCrate.sqf +++ b/node_modules/grad-fortifications/functions/drop/fn_initDropCrate.sqf @@ -6,9 +6,12 @@ if (isNull _crate) exitWith {}; _crate setVariable ["grad_fortifications_dropCrate_type", _type]; if (isClass (configfile >> "CfgPatches" >> "CUP_Core")) then { - [_crate,true] call ace_dragging_fnc_setDraggable; - [_crate,true] call ace_dragging_fnc_setCarryable; - [_crate,true] call ace_cargo_fnc_makeLoadable; + [_crate,true,[0,2,0]] call ace_dragging_fnc_setDraggable; + [_crate,true,[0,1.5,0.8]] call ace_dragging_fnc_setCarryable; + + if (isServer) then { + [cursorTarget, 1] call ace_cargo_fnc_setSize; + }; }; _moduleRoot = [] call grad_fortifications_fnc_getModuleRoot; diff --git a/node_modules/grad-fortifications/package.json b/node_modules/grad-fortifications/package.json index b2e9422..0e1672e 100644 --- a/node_modules/grad-fortifications/package.json +++ b/node_modules/grad-fortifications/package.json @@ -2,50 +2,51 @@ "_args": [ [ { - "raw": "grad-fortifications@0.6.1", + "raw": "grad-fortifications@0.7.1", "scope": null, "escapedName": "grad-fortifications", "name": "grad-fortifications", - "rawSpec": "0.6.1", - "spec": "0.6.1", + "rawSpec": "0.7.1", + "spec": "0.7.1", "type": "version" }, "E:\\Dokumente\\Arma 3 - Other Profiles\\McDiod\\mpmissions\\TvT_Template.VR" ] ], - "_from": "grad-fortifications@0.6.1", - "_id": "grad-fortifications@0.6.1", + "_from": "grad-fortifications@0.7.1", + "_hasShrinkwrap": false, + "_id": "grad-fortifications@0.7.1", "_inCache": true, "_installable": true, "_location": "/grad-fortifications", "_nodeVersion": "4.4.7", "_npmOperationalInternal": { - "host": "packages-12-west.internal.npmjs.com", - "tmp": "tmp/grad-fortifications-0.6.1.tgz_1490799318488_0.46003740769810975" + "host": "s3://npm-registry-packages", + "tmp": "tmp/grad-fortifications_0.7.1_1541962683999_0.6687044061406351" }, "_npmUser": { - "name": "gruppe-adler", - "email": "kontakt@gruppe-adler.de" + "name": "gruppe-adler-admin", + "email": "admin@gruppe-adler.de" }, "_npmVersion": "3.10.5", "_phantomChildren": {}, "_requested": { - "raw": "grad-fortifications@0.6.1", + "raw": "grad-fortifications@0.7.1", "scope": null, "escapedName": "grad-fortifications", "name": "grad-fortifications", - "rawSpec": "0.6.1", - "spec": "0.6.1", + "rawSpec": "0.7.1", + "spec": "0.7.1", "type": "version" }, "_requiredBy": [ "#USER", "/" ], - "_resolved": "https://registry.npmjs.org/grad-fortifications/-/grad-fortifications-0.6.1.tgz", - "_shasum": "066c9e1386322424a94cc237954a90e0c1237069", + "_resolved": "https://registry.npmjs.org/grad-fortifications/-/grad-fortifications-0.7.1.tgz", + "_shasum": "1d3e7cfe4478bed391ca0e3859523a005a8dd931", "_shrinkwrap": null, - "_spec": "grad-fortifications@0.6.1", + "_spec": "grad-fortifications@0.7.1", "_where": "E:\\Dokumente\\Arma 3 - Other Profiles\\McDiod\\mpmissions\\TvT_Template.VR", "author": { "name": "McDiod" @@ -55,19 +56,23 @@ "devDependencies": {}, "directories": {}, "dist": { - "shasum": "066c9e1386322424a94cc237954a90e0c1237069", - "tarball": "https://registry.npmjs.org/grad-fortifications/-/grad-fortifications-0.6.1.tgz" + "shasum": "1d3e7cfe4478bed391ca0e3859523a005a8dd931", + "tarball": "https://registry.npmjs.org/grad-fortifications/-/grad-fortifications-0.7.1.tgz", + "integrity": "sha512-IkiglcKbykv68BURzBKqO5V1DyUtg7waoBqk+cipqJbdZ0OIyMlT6X6+96FFjyRjjw3m6MOvZVmd+LCeEnlqhg==", + "fileCount": 84, + "unpackedSize": 292665, + "npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb6Hu8CRA9TVsSAnZWagAAvagP/1YZPSkKDsIfUNS11nKy\nI1J3tnNDsjr9vj/s/M9kWIqBJVnLsurMyY6NXUwLvOJ9RAWy8axwNNB9xxr7\n0kjzlsVTmeuSF7czQhZTpygU9EGdCM6pieceoPy+rZB28yoXesTtfaNMBaCW\ntGZQvMpvF4Lm9BnDB4JFq8KnC75+JyXpoJFNGPbIHJq88PecPg21srfuu+yn\n3wz45iepYlRs6G5+5PtFG4F6c/S7w8JJ9gFCn+1405rfYQK8D4pPTVpahkwX\nB0lvQ+pPVcFVkiUDfuk/2Ac8Xk1mABTMea2zr8StU1unrFZfBrC5woPj+Oqy\npBQUscnQiknkpmk+qIZDAm1UnqXvty/91U4O5wcdjyKQcHiR9Kq9dfdfm3pZ\niNql4ubVH683tYh/vbfs8QnVak+sRnWuNI7Z+MGJxR+5V7eb1sbzaJ8Vg/Ym\nOKXmZSdS2J4at467l9uWB33KLrleV12W0B1mPX8NtBoHEFgVVIojeXmyib6g\n2ixDoNYVrcPmub3Fj/SISzKN4VmBgDb+PCIITZMtkR4Il5L3zqNNq6h1jaRh\n/YZP2GXZ5dPhZT82RoDR1TsvpLXYR2GCy1l6kD5xxXV4lWeZngy8JCLsrBoZ\nNl5+6dHQzZGgitpWJ54PVOlMmQD9lE6G3atDX8E1k/LdxZMXrTNSzaHdyDN3\ny3u9\r\n=frio\r\n-----END PGP SIGNATURE-----\r\n" }, - "gitHead": "2475f60ff174c5599beaa72acbf73d361f90f980", + "gitHead": "8c10b2bcd73c684cef3bef4034e6d5b33d6f5e79", "maintainers": [ { - "name": "gruppe-adler", - "email": "kontakt@gruppe-adler.de" + "name": "gruppe-adler-admin", + "email": "admin@gruppe-adler.de" } ], "name": "grad-fortifications", "optionalDependencies": {}, "readme": "ERROR: No README data found!", "scripts": {}, - "version": "0.6.1" + "version": "0.7.1" } diff --git a/node_modules/grad-listbuymenu/cfgFunctions.hpp b/node_modules/grad-listbuymenu/cfgFunctions.hpp index a57fb80..2d4f7d6 100644 --- a/node_modules/grad-listbuymenu/cfgFunctions.hpp +++ b/node_modules/grad-listbuymenu/cfgFunctions.hpp @@ -33,6 +33,7 @@ class GRAD_lbm { file = MODULES_DIRECTORY\grad-listBuymenu\functions\common; class addFunds {}; class addInteraction {}; + class addStock {}; class checkCargoSpace {}; class getCurrentFunds {}; class getDescription {}; @@ -48,6 +49,7 @@ class GRAD_lbm { class rotateModel {}; class setFunds {}; class setPermissionLevel {}; + class setStock {}; }; class buy { diff --git a/node_modules/grad-listbuymenu/functions/buy/fn_vehicleMarker.sqf b/node_modules/grad-listbuymenu/functions/buy/fn_vehicleMarker.sqf index 5a65a49..7b38c5e 100644 --- a/node_modules/grad-listbuymenu/functions/buy/fn_vehicleMarker.sqf +++ b/node_modules/grad-listbuymenu/functions/buy/fn_vehicleMarker.sqf @@ -15,6 +15,7 @@ _function = { params ["_args", "_handle"]; _args params ["_vehicle", "_displayName"]; + if (isNull _vehicle) exitWith {}; drawIcon3D ["a3\ui_f\data\gui\Rsc\RscDisplayIntel\azimuth_ca.paa", [1,1,1,1], (getPosATL _vehicle) vectorAdd [0,0,1], 1, 1, 45, format ["%1 (%2m)", _displayName, round (player distance _vehicle)], 1, 0.04, "PuristaMedium", "center", true]; }; _handle = [_function, 0, [_vehicle, _displayName]] call CBA_fnc_addPerFrameHandler; diff --git a/node_modules/grad-listbuymenu/functions/common/fn_addInteraction.sqf b/node_modules/grad-listbuymenu/functions/common/fn_addInteraction.sqf index a93b59e..7dafcec 100644 --- a/node_modules/grad-listbuymenu/functions/common/fn_addInteraction.sqf +++ b/node_modules/grad-listbuymenu/functions/common/fn_addInteraction.sqf @@ -2,7 +2,7 @@ * */ -params ["_object", "_baseConfigName", ["_cargospace", objNull], ["_vehiclespawn", objNull], ["_shopName", ""], ["_actionDescription", "Buy Gear"], ["_condition", {true}], ["_position",[0,0,0]], ["_distance",3], "_rootAction", ["_account",player]]; +params ["_object", "_baseConfigName", ["_cargospace", objNull], ["_vehiclespawn", objNull], ["_shopName", ""], ["_actionDescription", "Buy Gear"], ["_condition", {true}], ["_position",[0,0,0]], ["_distance",3], "_rootAction", ["_account",objNull]]; _actionName = format ["grad_lbm_interaction_%1_%2", str _object, _baseConfigName]; _icon = (missionNamespace getVariable ["grad_lbm_moduleRoot", [] call grad_lbm_fnc_getModuleRoot]) + "\data\moneyIcon.paa"; @@ -15,6 +15,8 @@ _action = [_actionName,_actionDescription,_icon,{ _args = _this select 2; _args params ["_object","_cargospace","_vehiclespawn","_baseConfigName","_shopName","_account"]; + + if (_account isEqualType objNull && {isNull _account}) then {_account = player}; [_object,_cargospace,_vehiclespawn,_baseConfigName,_shopName,_account] call grad_lbm_fnc_loadBuymenu; },_condition,{},[_object,_cargospace,_vehiclespawn,_baseConfigName,_shopName,_account],_position,_distance] call ace_interact_menu_fnc_createAction; diff --git a/node_modules/grad-listbuymenu/functions/common/fn_addStock.sqf b/node_modules/grad-listbuymenu/functions/common/fn_addStock.sqf new file mode 100644 index 0000000..a9b77fb --- /dev/null +++ b/node_modules/grad-listbuymenu/functions/common/fn_addStock.sqf @@ -0,0 +1,12 @@ +params ["_baseConfigName", "_categoryConfigName", "_itemConfigName", ["_add",0]]; + +private _currentStock = _this call grad_lbm_fnc_getStock; +if (_currentStock < 0) exitWith {systemChat "Stock could not be added."; -1}; + +private _hashKey = format ["%1_%2_%3", _baseConfigName, _categoryConfigName, _itemConfigName]; +private _newStock = (_currentStock + _add) max 0; +[GRAD_LBM_ITEMSTOCKS,_hashKey,_newStock] call CBA_fnc_hashSet; + +publicVariable "GRAD_LBM_ITEMSTOCKS"; + +_newStock diff --git a/node_modules/grad-listbuymenu/functions/common/fn_setStock.sqf b/node_modules/grad-listbuymenu/functions/common/fn_setStock.sqf new file mode 100644 index 0000000..73e5f75 --- /dev/null +++ b/node_modules/grad-listbuymenu/functions/common/fn_setStock.sqf @@ -0,0 +1,11 @@ +params ["_baseConfigName", "_categoryConfigName", "_itemConfigName", ["_newStock",0]]; + +private _currentStock = _this call grad_lbm_fnc_getStock; +if (_currentStock < 0) exitWith {systemChat "Stock could not be set."; -1}; + +private _hashKey = format ["%1_%2_%3", _baseConfigName, _categoryConfigName, _itemConfigName]; +[GRAD_LBM_ITEMSTOCKS,_hashKey,_newStock] call CBA_fnc_hashSet; + +publicVariable "GRAD_LBM_ITEMSTOCKS"; + +_newStock diff --git a/node_modules/grad-listbuymenu/package.json b/node_modules/grad-listbuymenu/package.json index 10d2be4..491e4c5 100644 --- a/node_modules/grad-listbuymenu/package.json +++ b/node_modules/grad-listbuymenu/package.json @@ -2,69 +2,74 @@ "_args": [ [ { - "raw": "grad-listbuymenu@0.6.5", + "raw": "grad-listbuymenu@0.7.1", "scope": null, "escapedName": "grad-listbuymenu", "name": "grad-listbuymenu", - "rawSpec": "0.6.5", - "spec": "0.6.5", + "rawSpec": "0.7.1", + "spec": "0.7.1", "type": "version" }, "E:\\Dokumente\\Arma 3 - Other Profiles\\McDiod\\mpmissions\\TvT_Template.VR" ] ], - "_from": "grad-listbuymenu@0.6.5", - "_id": "grad-listbuymenu@0.6.5", + "_from": "grad-listbuymenu@0.7.1", + "_hasShrinkwrap": false, + "_id": "grad-listbuymenu@0.7.1", "_inCache": true, "_installable": true, "_location": "/grad-listbuymenu", "_nodeVersion": "4.4.7", "_npmOperationalInternal": { "host": "s3://npm-registry-packages", - "tmp": "tmp/grad-listbuymenu-0.6.5.tgz_1500209125354_0.18287534709088504" + "tmp": "tmp/grad-listbuymenu_0.7.1_1540738285908_0.49315632642348706" }, "_npmUser": { - "name": "gruppe-adler", - "email": "kontakt@gruppe-adler.de" + "name": "gruppe-adler-admin", + "email": "admin@gruppe-adler.de" }, "_npmVersion": "3.10.5", "_phantomChildren": {}, "_requested": { - "raw": "grad-listbuymenu@0.6.5", + "raw": "grad-listbuymenu@0.7.1", "scope": null, "escapedName": "grad-listbuymenu", "name": "grad-listbuymenu", - "rawSpec": "0.6.5", - "spec": "0.6.5", + "rawSpec": "0.7.1", + "spec": "0.7.1", "type": "version" }, "_requiredBy": [ "#USER", "/" ], - "_resolved": "https://registry.npmjs.org/grad-listbuymenu/-/grad-listbuymenu-0.6.5.tgz", - "_shasum": "3d86d698af12859b597683ad9366ee2df782d43c", + "_resolved": "https://registry.npmjs.org/grad-listbuymenu/-/grad-listbuymenu-0.7.1.tgz", + "_shasum": "064be20a619546c1da5d5a5b9f1513c99f13d94a", "_shrinkwrap": null, - "_spec": "grad-listbuymenu@0.6.5", + "_spec": "grad-listbuymenu@0.7.1", "_where": "E:\\Dokumente\\Arma 3 - Other Profiles\\McDiod\\mpmissions\\TvT_Template.VR", "dependencies": {}, "description": "a simple interface to buy stuff", "devDependencies": {}, "directories": {}, "dist": { - "shasum": "3d86d698af12859b597683ad9366ee2df782d43c", - "tarball": "https://registry.npmjs.org/grad-listbuymenu/-/grad-listbuymenu-0.6.5.tgz" + "shasum": "064be20a619546c1da5d5a5b9f1513c99f13d94a", + "tarball": "https://registry.npmjs.org/grad-listbuymenu/-/grad-listbuymenu-0.7.1.tgz", + "integrity": "sha512-PmHxgf1d4X+xo+WhXqa/N4ZTABrjvz22GFuOb4tzxoU7CUkq9BVJISjRu0G8dbNEWgL0SP6QMnb5RmfzjVmstA==", + "fileCount": 74, + "unpackedSize": 132317, + "npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb1czvCRA9TVsSAnZWagAA6VgP/3B0fSxfNDa4Nlz38u/M\nU27x5cb4lV9qNbwtQEURHR/QhflR4Ud0fZ4nZakLjfaLUow/rnx/9/6bzmJn\nxxMM9NmyIB5wTgU1b4/q4qyGWfXjiOF0NXTXC+Wxj9k2DNTJaF1ltJEXPGjA\nmxNqTnBHjkVQeztv1UVfY/5GKyOhCfESAczSNQmtRTHupACehtZlcxJ13wqs\nO7u2Rys3aFFBo//77pikw+8td4EZVFiInAbWIwV1EMBg37F0l1vXnx3i263S\nVMD5Zp3glgGQMyxKeNZGzalAsbxF5x7hwfMvjvKeIcZbNW60u1dN4TqffCcs\nqY7V9Vyion89YK6pmF1Q0/o54R5Gyz85PgxDJ+OvvVuML+JRjSObCjZIHufg\nL+OQ8ihiIcB8W9VmoB7qZIr31CV69lnJmu1efwA9eplih6ApqBg9YDMjA/ws\nL/Wl8Hk/Tiuf6PucuX7se/mAstF4GryLjZJcNFvulWEShQZK9j3AC034VqDu\nDDOwM8/Qo9jQGCgo2kR9Qix6a0zOriPL/tXiXdj6OPWnExUgFl4EKI4Af5R9\n2G4V4vFpr/IhPYrclyuKoN/JU0Dn2QaaeQQ/gSgZtcu+FRKS0otI9vaB/z5a\nEOX+lArNrYYaLCWIP0Jl72WpFNs7WuEaq8IaxR3Y25nLjJ/LifQLMyRphOyR\nX6ee\r\n=8VWY\r\n-----END PGP SIGNATURE-----\r\n" }, - "gitHead": "4e7d4b75bcf547675f214965f8ae4906c7df35e2", + "gitHead": "634d3af7b7f4c4496016b095bd217f7e2be1fc82", "maintainers": [ { - "name": "gruppe-adler", - "email": "kontakt@gruppe-adler.de" + "name": "gruppe-adler-admin", + "email": "admin@gruppe-adler.de" } ], "name": "grad-listbuymenu", "optionalDependencies": {}, "readme": "ERROR: No README data found!", "scripts": {}, - "version": "0.6.5" + "version": "0.7.1" } diff --git a/node_modules/grad-loadout/.idea/copyright/profiles_settings.xml b/node_modules/grad-loadout/.idea/copyright/profiles_settings.xml deleted file mode 100644 index e7bedf3..0000000 --- a/node_modules/grad-loadout/.idea/copyright/profiles_settings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/node_modules/grad-loadout/.idea/encodings.xml b/node_modules/grad-loadout/.idea/encodings.xml deleted file mode 100644 index 97626ba..0000000 --- a/node_modules/grad-loadout/.idea/encodings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/node_modules/grad-loadout/.idea/grad-loadout.iml b/node_modules/grad-loadout/.idea/grad-loadout.iml deleted file mode 100644 index c956989..0000000 --- a/node_modules/grad-loadout/.idea/grad-loadout.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/node_modules/grad-loadout/.idea/inspectionProfiles/Project_Default.xml b/node_modules/grad-loadout/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 99b1a92..0000000 --- a/node_modules/grad-loadout/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - \ No newline at end of file diff --git a/node_modules/grad-loadout/.idea/inspectionProfiles/profiles_settings.xml b/node_modules/grad-loadout/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 3b31283..0000000 --- a/node_modules/grad-loadout/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - \ No newline at end of file diff --git a/node_modules/grad-loadout/.idea/jsLibraryMappings.xml b/node_modules/grad-loadout/.idea/jsLibraryMappings.xml deleted file mode 100644 index f3e502d..0000000 --- a/node_modules/grad-loadout/.idea/jsLibraryMappings.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/node_modules/grad-loadout/.idea/misc.xml b/node_modules/grad-loadout/.idea/misc.xml deleted file mode 100644 index eabe228..0000000 --- a/node_modules/grad-loadout/.idea/misc.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/node_modules/grad-loadout/.idea/modules.xml b/node_modules/grad-loadout/.idea/modules.xml deleted file mode 100644 index a276d6d..0000000 --- a/node_modules/grad-loadout/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/node_modules/grad-loadout/.idea/typescript-compiler.xml b/node_modules/grad-loadout/.idea/typescript-compiler.xml deleted file mode 100644 index df9714f..0000000 --- a/node_modules/grad-loadout/.idea/typescript-compiler.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - \ No newline at end of file diff --git a/node_modules/grad-loadout/.idea/vcs.xml b/node_modules/grad-loadout/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/node_modules/grad-loadout/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/node_modules/grad-loadout/.idea/workspace.xml b/node_modules/grad-loadout/.idea/workspace.xml deleted file mode 100644 index 9b7731d..0000000 --- a/node_modules/grad-loadout/.idea/workspace.xml +++ /dev/null @@ -1,799 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - DEFINITION_ORDER - - - - - - - - - - - - - - - - AnnotationPHP - - - Bitwise operation issuesJavaScript - - - CSS - - - Code style issuesJavaScript - - - DOM issuesJavaScript - - - GeneralJavaScript - - - Invalid elementsCSS - - - JavaScript - - - PHP - - - Potentially confusing code constructsJavaScript - - - Probable bugsJavaScript - - - Spelling - - - TypeScript - - - UnusedPHP - - - XPath - - - - - SpellCheckingInspection - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - project - - - - - - - - - - - - - - - - project - - - true - - bdd - - DIRECTORY - - false - - - - - - - - - - - - 1476902973226 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/node_modules/grad-loadout/README.md b/node_modules/grad-loadout/README.md index d4e625d..2c3161f 100644 --- a/node_modules/grad-loadout/README.md +++ b/node_modules/grad-loadout/README.md @@ -74,9 +74,9 @@ class Loadouts { ### GRAD_Loadout_fnc_FactionSetLoadout -You can dynamically alias a faction name: +You can dynamically alias a faction name and optionally broadcast it over network (parameter 2, bool): -`["BLU_F", "USMC"] call GRAD_Loadout_fnc_FactionSetLoadout;` – thus, you can change loadout presets for your factions. In this example, this would work now: +`["BLU_F", "USMC", true] call GRAD_Loadout_fnc_FactionSetLoadout;` – thus, you can change loadout presets for your factions. In this example, this would work now: ``` class Loadouts { @@ -92,21 +92,27 @@ class Loadouts { ### GRAD_Loadout_fnc_AddReviver -dynamically adjust loadout values. This example adds a bit of randomization to Russian helmets: +dynamically adjust loadout values. This example adds a bit of randomization to Russian helmets and broadcasts the reviver over network (parameter 2, bool): ``` [ { - _value = param [0]; + params ["_value"]; if (_value == "rhs_6b27m_digi") then { _value = selectRandom ["rhs_6b27m_digi", "rhs_6b27m_digi_bala"]; }; _value }, - "headgear" + "headgear", + true ] call GRAD_Loadout_fnc_addReviver; ``` +## Debugging +To see if your loadouts were applied correctly, you can use the chat command `#grad-loadout viewer` to open the loadoutViewer and inspect all units. + +To check all currently loaded loadouts, you can use the chat command `#grad-loadout verify`. This will test the loadouts of all units currently in the game and output errors and warning to your rpt file. + ## Loadouts Loadouts are defined directly inside the `description.ext`. They are applied on mission start and when you respawn. This is an example on how a loadout looks like with this system: @@ -145,6 +151,40 @@ class Loadouts { This simple block of code changes and applies the loadout of 18 units at once, based on a few key instructions. Since the `AllPlayers` class is done first ( the actual order inside the block plays no role, the loadout for `AllPlayers` is always applied first ), followed by the class based loadouts and finally the individual loadouts, you can combine the different priority layers for some extremely tight loadout descriptions. We don't have to redefine a different primary weapon for the individual soldiers because the `AllPlayers` class already gives them each one. Note that the marksman class `AV_IndUs_Marksman_M14_Des` gets a different primary weapon, which is why we redefine it in his loadout, which overwrites the generic behavior of `AllPlayers`. +### Random selection +To use a random selection of Uniforms, Vests, etc. it is possible to define them as an array. Example: +```sqf +class AllUnits { + uniform[] = {"U_C_man_sport_1_F", "U_BG_Guerilla2_1"}; +}; +``` +### Weapons in backpacks +If you want to add a weapon to a backpack, simply add the weapon's classname to `addItemsToBackpack` like you would with any other item. However, if you want the weapon to have attachments and/or loaded magazines, the config has to look like the following examples. Note that the weapon class has to be inside the same parent class as the `addItemsToBackpack` property where it is used. +```sqf +addItemsToBackpack[] = {"arifle_Mk20C_F", ...}; +class arifle_Mk20C_F { + muzzle = ""; + pointer = ""; + optics = ""; + magazine = "30Rnd_556x45_Stanag"; + underBarrelMagazine = ""; + underBarrel = ""; +}; +``` +or +```sqf +addItemsToBackpack[] = {"FancySchmazyWeapon", ...}; +class FancySchmazyWeapon { + weapon = "arifle_Mk20C_F"; + muzzle = ""; + pointer = ""; + optics = ""; + magazine = "30Rnd_556x45_Stanag"; + underBarrelMagazine = ""; + underBarrel = ""; +}; +``` + ### Notes - Unique loadouts ( targeting a specific unit ) overwrite class loadouts ( targeting all units of the same class ), which in turn overwrite `generic` loadouts ( targeting multiple units ). - All loadouts are case _insensitive_, meaning `person`, `Person` and `perSon` all refer to the same unit, likewise, class definition and the `AllPlayers` class are also case insensitive. This is because Bohemia Interactive doesn't know how string comparisons should work. diff --git a/node_modules/grad-loadout/cfgFunctions.hpp b/node_modules/grad-loadout/cfgFunctions.hpp index a6b62bd..9eb5180 100644 --- a/node_modules/grad-loadout/cfgFunctions.hpp +++ b/node_modules/grad-loadout/cfgFunctions.hpp @@ -5,50 +5,45 @@ class GRAD_Loadout { class Api { file = MODULES_DIRECTORY\grad-loadout\functions\api; - class DoLoadoutForUnit {}; + class doLoadoutForUnit {}; + class loadoutViewer {}; + class verifyLoadouts {}; + }; + class Defactionizers { + file = MODULES_DIRECTORY\grad-loadout\functions\defactionizers; + class vanillaCivDefactionizer {}; + class vanillaMilitaryDefactionizer {}; }; class Extract { file = MODULES_DIRECTORY\grad-loadout\functions\extract; - class GetPathExtractor {}; - class ExtractLoadoutFromConfig {}; + class getPathExtractor {}; + class extractLoadoutFromConfig {}; }; class General { file = MODULES_DIRECTORY\grad-loadout\functions\general; - class ApplyLoadout {}; - class AssignRespawn { - postInit = 1; - }; - class DefactionizeType {}; - class DoLoadout {}; - class FactionGetLoadout {}; - class FactionSetLoadout {}; - class GetApplicableUnits {}; - class GetLoadoutConfigPath {}; - class GetUnusedConfigs {}; - class GetUnitLoadoutFromConfig {}; - class HashToUnitLoadout {}; - class InitGlobals { - preinit = 1; - }; - class MergeLoadoutHierarchy {}; - class NormalizeMagazinesInContent {}; - class RemoveRadios { - preinit = 1; - }; - class ScheduleLoadout { - postInit = 1; - }; - class WeaponIsCompatibleMagazine {}; + class addChatCommands {postInit = 1;}; + class applyLoadout {}; + class assignRespawn {postInit = 1;}; + class defactionizeType {}; + class doLoadout {}; + class factionGetLoadout {}; + class factionSetLoadout {}; + class getApplicableUnits {}; + class getLoadoutConfigPath {}; + class getUnusedConfigs {}; + class getUnitLoadoutFromConfig {}; + class hashToUnitLoadout {}; + class initGlobals {preinit = 1;}; + class mergeLoadoutHierarchy {}; + class normalizeContent {}; + class removeRadios {preinit = 1;}; + class scheduleLoadout {postInit = 1;}; + class weaponIsCompatibleMagazine {}; }; class Revivers { file = MODULES_DIRECTORY\grad-loadout\functions\revivers; - class GetRevivers {}; - class AddReviver {}; - class ApplyRevivers {}; - }; - class Defactionizers { - file = MODULES_DIRECTORY\grad-loadout\functions\defactionizers; - class VanillaCivDefactionizer {}; - class VanillaMilitaryDefactionizer {}; + class getRevivers {}; + class addReviver {}; + class applyRevivers {}; }; }; diff --git a/node_modules/grad-loadout/functions/api/fn_doLoadoutForUnit.sqf b/node_modules/grad-loadout/functions/api/fn_doLoadoutForUnit.sqf index 20d4cc8..ed49b23 100644 --- a/node_modules/grad-loadout/functions/api/fn_doLoadoutForUnit.sqf +++ b/node_modules/grad-loadout/functions/api/fn_doLoadoutForUnit.sqf @@ -3,7 +3,7 @@ #define COMPONENT loadout #include "\x\cba\addons\main\script_macros_mission.hpp" -private _unit = param [0, objNull]; +params [["_unit", objNull]]; private _configPath = missionConfigFile >> "Loadouts"; @@ -15,4 +15,9 @@ TRACE_1("applying loadout from mission config file %1 to %2 ...", _configPath, _ private _loadoutHash = [_unit, _configPath] call FUNC(GetUnitLoadoutFromConfig); _loadoutHash = [_loadoutHash, _unit] call FUNC(ApplyRevivers); -[_loadoutHash, _unit] call FUNC(DoLoadout); + +if (([_loadoutHash] call CBA_fnc_hashSize) > 0) then { + [_loadoutHash, _unit] call FUNC(DoLoadout); +} else { + TRACE_1("no loadout entries found for %1, skipping unit", _unit); +}; diff --git a/node_modules/grad-loadout/functions/api/fn_loadoutViewer.sqf b/node_modules/grad-loadout/functions/api/fn_loadoutViewer.sqf new file mode 100644 index 0000000..5719d9f --- /dev/null +++ b/node_modules/grad-loadout/functions/api/fn_loadoutViewer.sqf @@ -0,0 +1,504 @@ +#define PREFIX grad +#define COMPONENT loadout +#include "\x\cba\addons\main\script_macros_mission.hpp" + + +// DIALOG DEFINES ============================================================== +#define SZ_SCALE (safezoneW min safezoneH) +#define X_SCALE (SZ_SCALE * 0.75) +#define Y_SCALE (SZ_SCALE * 1.0) + +#define PADDING_X (0.025 * X_SCALE) +#define PADDING_Y (0.025 * Y_SCALE) + +#define CAMERA_W (0.75 * X_SCALE) +#define COLUMN_Y (safeZoneY + PADDING_Y) +#define COLUMN_W ((safeZoneW - 4 * PADDING_X - CAMERA_W) / 2) +#define CAMERA_X (safeZoneX + 2 * PADDING_X + COLUMN_W) +#define COLUMN_H (safeZoneH - 2 * PADDING_Y) + +#define COLUMN1_X (safeZoneX + PADDING_X) +#define COLUMN2_X (safeZoneX + safeZoneW - PADDING_X - COLUMN_W) + +#define TREE_H (COLUMN_H - 2 * PADDING_Y) +#define CHECKBOX_Y (COLUMN_Y + COLUMN_H - PADDING_Y) + +#define INFOPIC_W (COLUMN_W - 8 * PADDING_X) +#define INFOPIC_H (COLUMN_H/2 - 8 * PADDING_Y) +#define INFOPIC_X (COLUMN2_X + 4 * PADDING_X) +#define INFOPIC_Y (COLUMN_Y + 8 * PADDING_Y) + +#define INFOTEXT_W ((COLUMN_W - 3 * PADDING_X)/2) +#define INFOTEXTL_X (COLUMN2_X + 2 * PADDING_X) +#define INFOTEXTR_X (INFOTEXTL_X + INFOTEXT_W - PADDING_X) +#define INFOTEXT_Y (INFOPIC_Y + INFOPIC_H + PADDING_Y) +#define INFOTEXT_H (5.000 * Y_SCALE) + +#define SWITCHBUTTON_H (0.025 * Y_SCALE) +#define SWITCHBUTTON_W (COLUMN_W - 6 * PADDING_X) +#define SWITCHBUTTON_X (COLUMN2_X + (COLUMN_W - SWITCHBUTTON_W) / 2) +#define SWITCHBUTTON_Y (safeZoneY + safeZoneH - PADDING_Y - SWITCHBUTTON_H) + + +// OTHER DEFINES =============================================================== +#define DEFAULT_CAMPROPS [7,45,20,[0,0,0.9],objNull] +#define BACKGROUND_COLOR [0.1,0.1,0.1,1] +#define QUADS(var1,var2,var3,var4) ##var1##_##var2##_##var3##_##var4 +#define DISPLAYFUNC(var) (_display getVariable [QUOTE(QUADS(PREFIX,COMPONENT,fnc,var)),{}]) +#define DISPLAYCONTROL(var) (_display getVariable [QUOTE(TRIPLES(PREFIX,COMPONENT,var)),controlNull]) +#define DISPLAYVAR(var1,var2) (_display getVariable [QGVAR(var1),var2]) +#define CONVERTTOKG(var) (round ((0.1 * var) * (1/2.2046) * 100)) / 100 + +// CREATE DIALOG =============================================================== +private _display = (findDisplay 46) createDisplay "RscDisplayEmpty"; +if (isNull _display) exitWith {systemChat "[GRAD] (loadout) ERROR: Display is null."}; +_display setVariable [QGVAR(sides),_this]; + +{ + _bgCtrl = _display ctrlCreate ["RscBackground",-1]; + _bgCtrl ctrlSetPosition _x; + _bgCtrl ctrlSetBackgroundColor BACKGROUND_COLOR; + _bgCtrl ctrlCommit 0; +} forEach [ + [safeZoneX,safeZoneY,safeZoneW,PADDING_Y], + [safeZoneX,safeZoneY + safeZoneH - PADDING_Y,safeZoneW,PADDING_Y], + [safeZoneX,safeZoneY + PADDING_Y,2 * PADDING_X + COLUMN_W,safeZoneH - 2 * PADDING_Y], + [safeZoneX + safeZoneW - 2 * PADDING_X - COLUMN_W,safeZoneY + PADDING_Y,2 * PADDING_X + COLUMN_W,safeZoneH - 2 * PADDING_Y] +]; + +private _camInteractionCtrl = _display ctrlCreate ["RscTextMulti",-1]; +_camInteractionCtrl ctrlSetPosition [CAMERA_X,COLUMN_Y,CAMERA_W,COLUMN_H]; +_camInteractionCtrl ctrlSetBackgroundColor BACKGROUND_COLOR; +_camInteractionCtrl ctrlCommit 0; +_display setVariable [QGVAR(camInteractionCtrl),_camInteractionCtrl]; + +private _tvCtrl = _display ctrlCreate ["RscTree",-1]; +_tvCtrl ctrlSetPosition [COLUMN1_X,COLUMN_Y,COLUMN_W,TREE_H]; +_tvCtrl ctrlCommit 0; +_display setVariable [QGVAR(tvCtrl),_tvCtrl]; + +private _checkboxCtrl = _display ctrlCreate ["RscCheckBox",-1]; +_checkboxCtrl ctrlSetPosition [COLUMN1_X,CHECKBOX_Y,PADDING_X,PADDING_Y]; +_checkboxCtrl ctrlCommit 0; +_checkboxCtrl cbSetChecked (missionNamespace getVariable [QGVAR(loadoutViewer_onlyPlayable),false]); +_display setVariable [QGVAR(checkboxCtrl),_checkboxCtrl]; + +private _checkboxTextCtrl = _display ctrlCreate ["RscText",-1]; +_checkboxTextCtrl ctrlSetPosition [COLUMN1_X + PADDING_X,CHECKBOX_Y,COLUMN_W,PADDING_Y]; +_checkboxTextCtrl ctrlSetText (["Hide Non-Playable (only in works in multiplayer)","Hide Non-Playable"] select isMultiplayer); +_checkboxTextCtrl ctrlCommit 0; + +private _infoPicCtrl = _display ctrlCreate ["RscPictureKeepAspect",-1]; +_infoPicCtrl ctrlSetPosition [INFOPIC_X,INFOPIC_Y,INFOPIC_W,INFOPIC_H]; +_infoPicCtrl ctrlCommit 0; +_display setVariable [QGVAR(infoPicCtrl),_infoPicCtrl]; + +private _infoTextCtrlL = _display ctrlCreate ["RscStructuredText",-1]; +_infoTextCtrlL ctrlSetPosition [INFOTEXTL_X,INFOTEXT_Y,2 * X_SCALE,5 * X_SCALE]; +_infoTextCtrlL ctrlCommit 0; +_display setVariable [QGVAR(infoTextCtrlL),_infoTextCtrlL]; + +private _infoTextCtrlR = _display ctrlCreate ["RscStructuredText",-1]; +_infoTextCtrlR ctrlSetPosition [INFOTEXTR_X,INFOTEXT_Y,INFOTEXT_W,INFOTEXT_H]; +_infoTextCtrlR ctrlCommit 0; +_display setVariable [QGVAR(infoTextCtrlR),_infoTextCtrlR]; + +private _switchUnitCtrl = _display ctrlCreate ["RscButtonMenu",-1]; +_switchUnitCtrl ctrlSetPosition [SWITCHBUTTON_X,SWITCHBUTTON_Y,SWITCHBUTTON_W,SWITCHBUTTON_H]; +_switchUnitCtrl ctrlSetBackgroundColor [profilenamespace getvariable ['GUI_BCG_RGB_R',0.13],profilenamespace getvariable ['GUI_BCG_RGB_G',0.54],profilenamespace getvariable ['GUI_BCG_RGB_B',0.21],profilenamespace getvariable ['GUI_BCG_RGB_A',0.8]]; +_switchUnitCtrl ctrlSetText "Switch to Unit"; +_switchUnitCtrl ctrlEnable false; +_switchUnitCtrl ctrlCommit 0; +_display setVariable [QGVAR(switchUnitCtrl),_switchUnitCtrl]; + + +// SUBFUNCTIONS ================================================================ +_display setVariable [QGVAR(fnc_getParentClass),{ + params ["_thisItemClassname"]; + private _parentClass = ""; + { + if (isClass (configFile >> _x >> _thisItemClassname)) exitWith {_parentClass = _x}; + false + } count ["CfgWeapons","CfgMagazines","CfgVehicles"]; + _parentClass +}]; + +_display setVariable [QGVAR(fnc_fillDialog),{ + params ["_display","_sides","_onlyPlayable"]; + + tvClear DISPLAYCONTROL(tvCtrl); + + if (count _sides == 0) then {_sides = [WEST,EAST,INDEPENDENT,CIVILIAN]}; + + private _unitsCache = []; + { + [_display,_x,_onlyPlayable] call DISPLAYFUNC(addSide); + } forEach _sides; + _display setVariable [QGVAR(unitsCache),_unitsCache]; +}]; + +_display setVariable [QGVAR(fnc_addSide),{ + params ["_display","_side","_onlyPlayable"]; + + _sideUnitsCache = _unitsCache select (_unitsCache pushBack []); + _sideGroups = allGroups select {side _x == _side && {count units _x > 0}}; + _filteredGroups = _sideGroups select {!_onlyPlayable || {{_x in playableUnits} count (units _x) > 0}}; + + _sidePath = [DISPLAYCONTROL(tvCtrl) tvAdd [[],str _side]]; + {[_display,_sidePath,_x,_onlyPlayable] call DISPLAYFUNC(addGroup)} forEach _filteredGroups; +}]; + +_display setVariable [QGVAR(fnc_addGroup),{ + params ["_display","_sidePath","_group","_onlyPlayable"]; + + _groupUnitsCache = _sideUnitsCache select (_sideUnitsCache pushBack []); + _groupPath = _sidePath + [DISPLAYCONTROL(tvCtrl) tvAdd [_sidePath,str _group]]; + _filteredUnits = (units _group) select {!_onlyPlayable || {_x in playableUnits}}; + {[_display,_groupPath,_x] call DISPLAYFUNC(addUnit)} forEach _filteredUnits; +}]; + +_display setVariable [QGVAR(fnc_addUnit),{ + params ["_display","_groupPath","_unit"]; + + _groupUnitsCache pushBack _unit; + _unitDisplayName = roleDescription _unit; + if (_unitDisplayName == "") then { + _unitDisplayName = [configfile >> "CfgVehicles" >> typeOf _unit,"displayName","ERROR: NO DISPLAYNAME"] call BIS_fnc_returnConfigEntry; + }; + _unitPath = _groupPath + [DISPLAYCONTROL(tvCtrl) tvAdd [_groupPath,_unitDisplayName]]; + DISPLAYCONTROL(tvCtrl) tvSetTooltip [_unitPath,typeOf _unit]; + + { + [_display,_unitPath,_x,_forEachIndex] call DISPLAYFUNC(addAnItem); + } forEach [ + (assignedItems _unit) + [headgear _unit,goggles _unit,hmd _unit], + uniformItems _unit, + vestItems _unit, + backpackItems _unit, + (primaryWeaponItems _unit) + (primaryWeaponMagazine _unit), + (secondaryWeaponItems _unit) + (secondaryWeaponMagazine _unit), + (handgunItems _unit) + (handgunMagazine _unit) + ]; +}]; + +_display setVariable [QGVAR(fnc_addAnItem),{ + params ["_display","_unitPath","_itemsList","_containerType"]; + + _sanitizedItemsList = _itemsList select {_x != ""}; + _uniqueItemsList = _sanitizedItemsList arrayIntersect _sanitizedItemsList; + _containerClassName = [QGVAR(STR_ASSIGNED_ITEMS),uniform _unit,vest _unit,backpack _unit,primaryWeapon _unit,secondaryWeapon _unit,handgunWeapon _unit] select _containerType; + _containerParentClass = [_containerClassName] call DISPLAYFUNC(getParentClass); + _containerDisplayName = [[configFile >> _containerParentClass >> _containerClassName,"displayName","ERROR: NO DISPLAY NAME"] call BIS_fnc_returnConfigEntry,"Assigned Items"] select (_containerType == 0); + + _tvCtrl = DISPLAYCONTROL(tvCtrl); + + if (_containerClassName != "") then { + _containerContentMass = 0; + _containerPath = _unitPath + [_tvCtrl tvAdd [_unitPath,_containerDisplayName]]; + _tvCtrl tvSetTooltip [_containerPath,_containerClassName]; + _tvCtrl tvSetData [_containerPath,_containerClassName]; + _tvCtrl tvSetPicture [_containerPath,[configFile >> _containerParentClass >> _containerClassName,"picture",""] call BIS_fnc_returnConfigEntry]; + + { + _itemClassname = _x; + _itemCount = {_x == _itemClassname} count _sanitizedItemsList; + _itemParentClass = [_itemClassname] call DISPLAYFUNC(getParentClass); + _itemPic = [_itemClassname,_itemParentClass] call DISPLAYFUNC(getItemPic); + + _itemPath = _containerPath + [_tvCtrl tvAdd [_containerPath,format ["%1x %2",_itemCount,[configFile >> _itemParentClass >> _itemClassname,"displayName","ERROR: NO DISPLAY NAME"] call BIS_fnc_returnConfigEntry]]]; + _tvCtrl tvSetTooltip [_itemPath,_itemClassname]; + _tvCtrl tvSetValue [_itemPath,_itemCount]; + _tvCtrl tvSetData [_itemPath,_itemClassname]; + _tvCtrl tvSetPicture [_itemPath,[configFile >> _itemParentClass >> _itemClassname,"picture",""] call BIS_fnc_returnConfigEntry]; + + _containerContentMass = _containerContentMass + _itemCount * ([_itemClassname] call DISPLAYFUNC(getItemMass)); + } forEach _uniqueItemsList; + _tvCtrl tvSetValue [_containerPath,_containerContentMass * 100]; + }; +}]; + +_display setVariable [QGVAR(fnc_updateCamera),{ + params [["_display",displayNull]]; + + if (isNull _display) exitWith {}; + + private _cam = DISPLAYVAR(cam,objNull); + private _camProperties = _display getVariable [QGVAR(camProperties),DEFAULT_CAMPROPS]; + _camProperties params ["_dis","_dirH","_dirV","_targetHelperOffset",["_targetUnit",objNull]]; + + private _targetHelper = _targetUnit getVariable [QGVAR(targetHelper),objNull]; + if (isNull _targetHelper) exitWith {ERROR("_targetHelper is null")}; + + [_targetHelper,[_dirH + 180,-_dirV,0]] call bis_fnc_setobjectrotation; + _targetHelper attachto [_targetUnit,_targetHelperOffset,""]; + + _cam setpos (_targetHelper modeltoworld [0,-_dis,0]); + _cam setvectordirandup [vectordir _targetHelper,vectorup _targetHelper]; + + //--- Make sure the camera is not underground + if ((getposasl _cam select 2) < (getposasl _cam select 2)) then { + _disCoef = ((getposasl _targetHelper select 2) - (getposasl _cam select 2)) / ((getposasl _targetHelper select 2) - (getposasl _cam select 2) + 0.001); + _cam setpos (_targetHelper modeltoworldvisual [0,-_dis * _disCoef,0]); + }; + + _cam camCommit 0; +}]; + +_display setVariable [QGVAR(fnc_getItemMass),{ + params ["_className"]; + + private _mass = [configFile >> "CfgWeapons" >> _className >> "ItemInfo","mass",0] call BIS_fnc_returnConfigEntry; + if (_mass isEqualTo 0) then { + _mass = [configFile >> "CfgWeapons" >> _className >> "WeaponSlotsInfo","mass",0] call BIS_fnc_returnConfigEntry; + }; + if (_mass isEqualTo 0) then { + _mass = [configFile >> "CfgMagazines" >> _className,"mass",0] call BIS_fnc_returnConfigEntry; + }; + if (_mass isEqualTo 0) then { + _mass = [configFile >> "CfgVehicles" >> _className,"mass",0] call BIS_fnc_returnConfigEntry; + }; + if !(_mass isEqualType 0) then { + _mass = 0; + }; + CONVERTTOKG(_mass) +}]; + + +// CREATE CAMERA =============================================================== +private _cam = "camera" camcreate (getPos player); +_cam cameraeffect ["External","back"]; + +showCinemaBorder false; +if (sunOrMoon < 0.35) then {camUseNVG true}; + +_display setVariable [QGVAR(camProperties),DEFAULT_CAMPROPS]; +_display setVariable [QGVAR(cam),_cam]; + + +// DIALOG FUNCTIONALITY ======================================================== +_tvCtrl ctrlAddEventHandler ["treeSelChanged",{ + params ["_tvCtrl","_selPath"]; + _selPath params [["_sideIndex",999999],["_groupIndex",999999],["_unitIndex",999999],["_containerIndex",999999],["_itemIndex",999999]]; + + _display = ctrlParent _tvCtrl; + _switchUnitCtrl = _display getVariable [QGVAR(switchUnitCtrl),controlNull]; + + // center cam on selected unit/group + _unitsCache = DISPLAYVAR(unitsCache,[]); + _unit = if (count _selPath > 1) then { + if (count _selPath > 2) then { + _unitsCache select _sideIndex select _groupIndex select _unitIndex + } else { + leader (_unitsCache select _sideIndex select _groupIndex select 0) + }; + } else {objNull}; + + _camProperties = _display getVariable [QGVAR(camProperties),DEFAULT_CAMPROPS]; + _camProperties params ["_dis","_dirH","_dirV","_targetHelperOffset",["_targetUnit",objNull]]; + + if (count _selPath > 2 && {!isNull _unit} && {!isPlayer _unit}) then { + _switchUnitCtrl ctrlEnable true; + } else { + _switchUnitCtrl ctrlEnable false; + }; + + if (!isNull _unit) then { + if (isNull _targetUnit) then { + DISPLAYCONTROL(camInteractionCtrl) ctrlSetBackgroundColor [0,0,0,0]; + }; + + if (_targetUnit != _unit) then { + deleteVehicle (_targetUnit getVariable [QGVAR(targetHelper),objNull]); + _camProperties set [4,_unit]; + + _targetHelper = createagent ["Logic",getPos _unit,[],0,"NONE"]; + _targetHelper attachto [_unit,_targetHelperOffset,""]; + _unit setVariable [QGVAR(targetHelper),_targetHelper]; + }; + + [_display] call DISPLAYFUNC(updateCamera); + } else { + if (!isNull _targetUnit) then { + DISPLAYCONTROL(camInteractionCtrl) ctrlSetBackgroundColor BACKGROUND_COLOR; + _camProperties set [4,_unit]; + }; + }; + + // display info + _infoPicCtrl = DISPLAYCONTROL(infoPicCtrl); + _infoTextCtrlL = DISPLAYCONTROL(infoTextCtrlL); + _infoTextCtrlR = DISPLAYCONTROL(infoTextCtrlR); + + if (count _selPath > 2) then { + // _infoTextArrayR needs
instead of lineBreak because it's converted to structured text differently in order for to work + _infoTextArrayL = [(_tvCtrl tvText _selPath),lineBreak,lineBreak]; + _infoTextArrayR = ["
","
"]; + + if (count _selPath == 3) then { + _infoTextArrayL pushBack "Total Load:"; + _infoTextArrayR pushBack format ["%1 kg",CONVERTTOKG(loadAbs _unit)]; + }; + + if (count _selPath in [4,5]) then { + _infoPicCtrl ctrlSetText (_tvCtrl tvPicture _selPath); + + _itemWeight = [_tvCtrl tvData _selPath] call DISPLAYFUNC(getItemMass); + + // assigned items container has no weight + if (_selPath select 3 > 0 || count _selPath == 5) then { + _infoTextArrayL pushBack "Item Weight:"; + _infoTextArrayR pushBack format ["%1 kg",_itemWeight]; + _infoTextArrayL pushBack lineBreak; + _infoTextArrayR pushBack "
"; + }; + + if (count _selPath == 4) then { + _containerClassName = (_tvCtrl tvData _selPath); + _infoTextArrayL pushBack "Content Weight:"; + _infoTextArrayR pushBack format ["%1 kg",(_tvCtrl tvValue _selPath)/100]; + + + if ((isClass (configFile >> "CfgWeapons" >> _containerClassName) || (isClass (configFile >> "CfgVehicles" >> _containerClassName))) && {getContainerMaxLoad _containerClassName > -1}) then { + _infoTextArrayL pushBack lineBreak; + _infoTextArrayR pushBack "
"; + + _maxLoad = CONVERTTOKG(getContainerMaxLoad _containerClassName); + _currentLoad = ((_tvCtrl tvValue _selPath)/100); + _spaceleft = _maxLoad - _currentLoad; + + _infoTextArrayL pushBack "Space Left:"; + _infoTextArrayR pushBack ([ + format ["%1 kg (%2%3)",_spaceleft,(round ((_spaceleft/(_maxLoad max 0.0001))*100)),"%"], + "Beyond max. capacity!" + ] select (_spaceleft < 0)); + }; + }; + + if (count _selPath == 5 && {(_tvCtrl tvValue _selPath) > 1}) then { + _infoTextArrayL pushBack "Total Weight:"; + _infoTextArrayR pushBack format ["%1 kg",_itemWeight * (_tvCtrl tvValue _selPath)]; + }; + } else { + _infoPicCtrl ctrlSetText ""; + }; + + _infoTextCtrlL ctrlSetStructuredText composeText _infoTextArrayL; + _infoTextCtrlR ctrlSetStructuredText parseText call {_t = ""; {_t=_t+_x} forEach _infoTextArrayR;_t + ""}; + } else { + _infoTextCtrlL ctrlSetStructuredText parseText ""; + _infoTextCtrlR ctrlSetStructuredText parseText ""; + _infoPicCtrl ctrlSetText ""; + }; +}]; + +_switchUnitCtrl ctrlAddEventHandler ["buttonClick",{ + params [["_switchUnitCtrl",controlNull]]; + + + _display = ctrlParent _switchUnitCtrl; + _tvCtrl = _display getVariable [QGVAR(tvCtrl),controlNull]; + _selPath = tvCurSel _tvCtrl; + + _selPath params [["_sideIndex",999999],["_groupIndex",999999],["_unitIndex",999999],["_containerIndex",999999],["_itemIndex",999999]]; + _unitsCache = DISPLAYVAR(unitsCache,[]); + + _unit = if (count _selPath > 1) then { + if (count _selPath > 2) then { + _unitsCache select _sideIndex select _groupIndex select _unitIndex + } else { + leader (_unitsCache select _sideIndex select _groupIndex select 0) + }; + } else {objNull}; + + if (!isNull _unit) then { + _display closeDisplay 1; + selectPlayer _unit; + player action ["Gear",player]; + } else { + _switchUnitCtrl ctrlEnable false; + playSound "taskFailed"; + }; +}]; + +_camInteractionCtrl ctrlAddEventHandler ["mouseMoving",{ + params ["_camInteractionCtrl","_mouseX","_mouseY","_mouseOver"]; + + _display = ctrlParent _camInteractionCtrl; + _display setVariable [QGVAR(mouseOver),_mouseOver]; + + if !(DISPLAYVAR(rMouseDown,false)) exitWith { + _display setVariable [QGVAR(oldMouseCoords),[_mouseX,_mouseY]]; + }; + + if (isNil {DISPLAYVAR(oldMouseCoords,nil)}) exitWith { + _display setVariable [QGVAR(oldMouseCoords),[_mouseX,_mouseY]]; + }; + + (_display getVariable [QGVAR(oldMouseCoords),[0,0]]) params ["_mouseXOld","_mouseYOld"]; + + _camProperties = _display getVariable [QGVAR(camProperties),DEFAULT_CAMPROPS]; + _camProperties params ["_dis","_dirH","_dirV","_targetHelperOffset",["_targetUnit",objNull]];; + + _dX = (_mouseXOld - _mouseX) * 0.75; + _dY = (_mouseYOld - _mouseY) * 0.75; + _targetHelperOffset = [ + [0,0,_targetHelperOffset select 2], + [[0,0,0],_targetHelperOffset] call bis_fnc_distance2D, + ([[0,0,0],_targetHelperOffset] call bis_fnc_dirto) - _dX * 180 + ] call bis_fnc_relpos; + + _camProperties set [1,(_dirH - _dX * 180) % 360]; + _camProperties set [2,(_dirV - _dY * 100) max -89 min 89]; + _camProperties set [3,_targetHelperOffset]; + + _display setVariable [QGVAR(oldMouseCoords),[_mouseX,_mouseY]]; + + [_display] call DISPLAYFUNC(updateCamera); +}]; + +_camInteractionCtrl ctrlAddEventHandler ["mouseZChanged",{ + params ["_camInteractionCtrl","_mouseZ"]; + + _display = ctrlParent _camInteractionCtrl; + if !(DISPLAYVAR(mouseOver,false)) exitWith {}; + + _camProperties = _display getVariable [QGVAR(camProperties),DEFAULT_CAMPROPS]; + + _camProperties params ["_dis"]; + _camProperties set [0,((_dis - _mouseZ/2) max 2) min 20]; + + [_display] call DISPLAYFUNC(updateCamera); +}]; + +_checkboxCtrl ctrlAddEventHandler ["checkedChanged",{ + params ["_checkboxCtrl","_checkedID"]; + + missionNamespace setVariable [QGVAR(loadoutViewer_onlyPlayable),_checkedID == 1]; + _display = ctrlParent _checkboxCtrl; + [_display,DISPLAYVAR(sides,[]),_checkedID == 1] call DISPLAYFUNC(fillDialog); +}]; + +_display displayAddEventHandler ["unload",{ + params ["_display","_exitCode"]; + + _cam = DISPLAYVAR(cam,objNull); + _cam cameraeffect ["terminate", "back"]; + camDestroy _cam; +}]; + +_display displayaddeventhandler ["mousebuttondown",{ + params ["_display","_button"]; + if (_button == 1) then { + _display setVariable [QGVAR(rMouseDown),true]; + }; +}]; + +_display displayaddeventhandler ["mousebuttonup",{ + params ["_display","_button"]; + if (_button == 1) then { + _display setVariable [QGVAR(rMouseDown),false]; + }; +}]; + +// FILL DIALOG ================================================================= +[_display,_this,missionNamespace getVariable [QGVAR(loadoutViewer_onlyPlayable),false]] call DISPLAYFUNC(fillDialog); diff --git a/node_modules/grad-loadout/functions/api/fn_verifyLoadouts.sqf b/node_modules/grad-loadout/functions/api/fn_verifyLoadouts.sqf new file mode 100644 index 0000000..0ce87c9 --- /dev/null +++ b/node_modules/grad-loadout/functions/api/fn_verifyLoadouts.sqf @@ -0,0 +1,277 @@ +#define PREFIX grad +#define COMPONENT loadout +#include "\x\cba\addons\main\script_macros_mission.hpp" + +#define CENTER(PARENT_SIZE, CHILD_SIZE) ((PARENT_SIZE / 2) - (CHILD_SIZE / 2)) +#define SZ_SCALE (safezoneW min safezoneH) +#define X_SCALE (SZ_SCALE * 0.75) +#define Y_SCALE (SZ_SCALE * 1.0) + +#define PADDING_X (0.025 * X_SCALE) +#define PADDING_Y (0.025 * Y_SCALE) +#define SPACER_Y (0.000 * Y_SCALE) + +#define TOTAL_W (safeZoneW) +#define TOTAL_H (safeZoneH) +#define TOTAL_X (CENTER(1,TOTAL_W)) +#define TOTAL_Y (CENTER(1,TOTAL_H)) + +#define TITLE_H (0.025 * Y_SCALE) +#define BACKGROUND_H (TOTAL_H - SPACER_Y - TITLE_H) +#define BACKGROUND_Y (TOTAL_Y + SPACER_Y + TITLE_H) + +#define BACKGROUND_COLOR [0.1,0.1,0.1,1] + +// SUBFUNCTIONS ================================================================ +private _fnc_verify = { + params ["_loadoutHash","_unit"]; + + _this call _fnc_checkContainers; + _this call _fnc_checkWeapons; + _this call _fnc_checkOther; +}; + +private _fnc_getMass = { + params ["_className"]; + private _mass = [configFile >> "CfgWeapons" >> _className >> "ItemInfo","mass",0] call BIS_fnc_returnConfigEntry; + if (_mass isEqualTo 0) then { + _mass = [configFile >> "CfgWeapons" >> _className >> "WeaponSlotsInfo","mass",0] call BIS_fnc_returnConfigEntry; + }; + if (_mass isEqualTo 0) then { + _mass = [configFile >> "CfgMagazines" >> _className,"mass",0] call BIS_fnc_returnConfigEntry; + }; + if (_mass isEqualTo 0) then { + _mass = [configFile >> "CfgVehicles" >> _className,"mass",0] call BIS_fnc_returnConfigEntry; + }; + if !(_mass isEqualType 0) then { + _mass = 0; + }; + _mass +}; + +private _fnc_getLoad = { + params ["_container","_itemsList"]; + _load = 0; + { + _load = _load + ([_x] call _fnc_getMass); + false + } count _itemsList; + _maxLoad = getContainerMaxLoad _container; + + _loadRatio = if (_maxLoad <= 0) then {-1} else {_load/_maxLoad}; + _loadRatio +}; + +private _fnc_checkClassExists = { + params ["_className",["_allowedConfigs",["cfgVehicles","cfgWeapons","cfgMagazines","cfgGlasses"]]]; + + _classExists = false; + { + if (isClass (configFile >> _x >> _className)) exitWith {_classExists = true}; + } forEach _allowedConfigs; + _classExists +}; + +private _fnc_getRoleDescription = { + params ["_unit"]; + _roleDescription = roleDescription _unit; + if (_roleDescription == "") then { + _roleDescription = [configfile >> "CfgVehicles" >> typeOf _unit,"displayName",""] call BIS_fnc_returnConfigEntry; + }; + _roleDescription +}; + +private _fnc_checkContainers = { + params ["_loadoutHash","_unit"]; + { + _x params ["_containerKey","_itemsKey"]; + _container = [_loadoutHash,_containerKey] call CBA_fnc_hashGet; + _itemsList = [_loadoutHash,_itemsKey] call CBA_fnc_hashGet; + + if (!isNil "_itemsList" && (isNil "_container" || {_container == ""}) && {count _itemsList > 0}) then { + _errorLog pushBack [format ["no %1 for %2",_containerKey,_itemsKey],_unit]; + }; + + if (!isNil "_container" && {_container != ""}) then { + _containerExists = [_container,["cfgVehicles","cfgWeapons"]] call _fnc_checkClassExists; + if (!_containerExists) then { + _errorLog pushBack [format ["%1 %2 does not exist",_containerKey,_container],_unit]; + }; + }; + + if (!isNil "_itemsList" && !isNil "_container" && {count _itemsList > 0} && {_container != ""}) then { + if (count _itemsList == 0) then { + _warningLog pushBack [format ["no items in %1",_containerKey],_unit]; + } else { + _load = [_container,_itemsList] call _fnc_getLoad; + if (_load > 1) then { + _errorLog pushBack [format ["%1 %2 loaded beyond capacity (%3%4)",_containerKey,_container,round (_load*100),"%"],_unit]; + }; + if (_load < 0) then { + _errorLog pushBack [format ["%1 %2 can not hold any items",_containerKey,_container],_unit]; + }; + }; + }; + + } forEach [ + ["uniform","addItemsToUniform"], + ["vest","addItemsToVest"], + ["backpack","addItemsToBackpack"] + ]; +}; + +private _fnc_checkWeapons = { + params ["_loadoutHash","_unit"]; + + { + _x params ["_weaponKey","_weaponAccessoryKeys","_magazineKeys"]; + _weaponClassname = [_loadoutHash,_weaponKey] call CBA_fnc_hashGet; + if (!isNil "_weaponClassname" && {_weaponClassname != ""}) then { + if !([_weaponClassname,["cfgWeapons"]] call _fnc_checkClassExists) then { + _errorLog pushBack [format ["%1 %2 does not exist",_x,_weaponClassname]]; + } else { + { + _accessoryClassname = [_loadoutHash,_x] call CBA_fnc_hashGet; + if (!isNil "_accessoryClassname" && {_accessoryClassname != ""}) then { + if !([_weaponClassname,_accessoryClassname,_forEachIndex] call _fnc_checkAccessoryFits) then { + _errorLog pushBack [format ["%1 %2 is not compatible with weapon %3",_x,_accessoryClassname,_weaponClassname],_unit]; + }; + }; + } forEach _weaponAccessoryKeys; + + { + _magazineClassname = [_loadoutHash,_x] call CBA_fnc_hashGet; + if (!isNil "_magazineClassname" && {_magazineClassname != ""}) then { + if !([_weaponClassname,_magazineClassname,_forEachIndex] call _fnc_magazineFits) then { + _errorLog pushBack [format ["%1 %2 is not compatible with weapon %3",_x,_magazineClassname,_weaponClassname],_unit]; + }; + }; + } forEach _magazineKeys; + }; + }; + } forEach [ + ["primaryWeapon",["primaryWeaponMuzzle","primaryWeaponPointer","primaryWeaponOptics","primaryWeaponUnderbarrel"],["primaryWeaponMagazine","primaryWeaponUnderbarrelMagazine"]], + ["secondaryWeapon",["secondaryWeaponMuzzle","secondaryWeaponPointer","secondaryWeaponOptics","secondaryWeaponUnderbarrel"],["secondaryWeaponMagazine","secondaryWeaponUnderbarrelMagazine"]], + ["handgunWeapon",["handgunWeaponMuzzle","handgunWeaponPointer","handgunWeaponOptics","handgunWeaponUnderbarrel"],["handgunWeaponMagazine","handungWeaponUnderbarrelMagazine"]] + ]; +}; + +private _fnc_checkAccessoryFits = { + params ["_weaponClassname","_accessoryClassname","_accessoryTypeID"]; + _accessorySlots = [["MuzzleSlot"],["PointerSlot"],["CowsSlot"],["UnderBarrelSlot","GripodSlot"]] select _accessoryTypeID; + + _accessoryFits = false; + { + // check if class exists first, because Arma throws some bullshit error message when nonexistant class is accessed + private _configPath = (configFile >> "CfgWeapons" >> _weaponClassname >> "WeaponSlotsInfo" >> _x); + if (isClass _configPath) then { + if (([_configPath >> "compatibleItems",_accessoryClassname,0] call BIS_fnc_returnConfigEntry) == 1) exitWith { + _accessoryFits = true; + }; + }; + } forEach _accessorySlots; + _accessoryFits +}; + +private _fnc_magazineFits = { + params ["_weaponClassname","_magazineClassname","_magazineTypeID"]; + + _magazineFits = false; + if (_magazineTypeID == 0) then { + _magazineFits = _magazineClassname in ([configfile >> "CfgWeapons" >> _weaponClassname,"magazines",[]] call BIS_fnc_returnConfigEntry); + }; + if (_magazineTypeID == 1) then { + _muzzles = [configfile >> "CfgWeapons" >> _weaponClassname,"muzzles",[]] call BIS_fnc_returnConfigEntry; + { + if (_magazineClassname in ([configfile >> "CfgWeapons" >> _weaponClassname >> _x,"magazines",[]] call BIS_fnc_returnConfigEntry)) exitWith { + _magazineFits = true; + }; + } forEach _muzzles; + }; + _magazineFits +}; + +private _fnc_checkOther = { + params ["_loadoutHash","_unit"]; + + { + _otherClassname = [_loadoutHash,_x] call CBA_fnc_hashGet; + if (!isNil "_otherClassname" && {_otherClassname != ""}) then { + if !([_otherClassname] call _fnc_checkClassExists) then { + _errorLog pushBack [format ["%1 %2 does not exist",_x,_otherClassname],_unit]; + }; + }; + } forEach ["headgear","goggles","nvgoggles","binoculars","map","gps","compass","watch","radio"]; +}; + +private _fnc_errorDisplay = { + params ["_textArray",["_title",""]]; + + private _display = (findDisplay 46) createDisplay "RscDisplayEmpty"; + if (isNull _display) exitWith {systemChat "[GRAD] (loadout) ERROR: Display is null."}; + + private _titleCtrl = _display ctrlCreate ["RscTitle",-1]; + _titleCtrl ctrlSetPosition [TOTAL_X,TOTAL_Y,TOTAL_W,TITLE_H]; + _titleCtrl ctrlSetBackgroundColor [profilenamespace getvariable ['GUI_BCG_RGB_R',0.13],profilenamespace getvariable ['GUI_BCG_RGB_G',0.54],profilenamespace getvariable ['GUI_BCG_RGB_B',0.21],profilenamespace getvariable ['GUI_BCG_RGB_A',0.8]]; + _titleCtrl ctrlSetText _title; + _titleCtrl ctrlCommit 0; + + private _bgCtrl = _display ctrlCreate ["RscBackground",-1]; + _bgCtrl ctrlSetPosition [TOTAL_X,BACKGROUND_Y,TOTAL_W,BACKGROUND_H]; + _bgCtrl ctrlSetBackgroundColor BACKGROUND_COLOR; + _bgCtrl ctrlCommit 0; + + _cgCtrl = _display ctrlCreate ["RscControlsGroupNoHScrollbars",-1]; + _cgCtrl ctrlSetPosition [TOTAL_X,BACKGROUND_Y,TOTAL_W,BACKGROUND_H]; + _cgCtrl ctrlCommit 0; + + _textCtrl = _display ctrlCreate ["RscStructuredText",-1,_cgCtrl]; + _textCtrl ctrlSetStructuredText parseText (_textArray joinString "
"); + _textCtrl ctrlSetPosition [0,0,TOTAL_W,(ctrlTextHeight _textCtrl) * 0.10]; + _textCtrl ctrlCommit 0; +}; + +// MAIN ======================================================================== +systemChat "grad-loadout verifier: checking loadouts"; + +private _configPath = missionConfigFile >> "Loadouts"; + +if ((missionNamespace getVariable [QGVAR(Chosen_Prefix),""]) != "") then { + _configPath = _configPath >> GVAR(Chosen_Prefix); +}; + +private _errorLog = []; +private _warningLog = []; +private _verifiedLoadoutCount = 0; + +{ + _loadoutHash = [_x,_configPath] call FUNC(GetUnitLoadoutFromConfig); + _loadoutHash = [_loadoutHash,_x] call FUNC(ApplyRevivers); + + if (([_loadoutHash] call CBA_fnc_hashSize) > 0) then { + [_loadoutHash,_x] call _fnc_verify; + _verifiedLoadoutCount = _verifiedLoadoutCount + 1; + }; +} forEach allUnits; + +private _displayText = []; + +diag_log "GRAD-LOADOUT VERIFICATION REPORT ====================================="; +diag_log format ["%1 loadouts checked",_verifiedLoadoutCount]; +diag_log format ["%1 errors, %2 warnings",count _errorLog,count _warningLog]; +{ + _logType = ["ERROR","WARNING"] select _forEachIndex; + { + _x params ["_message","_unit"]; + _log = format ["%1: %2 - %3 (%4)",_logType,_message,_unit,[_unit] call _fnc_getRoleDescription]; + diag_log _log; + _displayText pushBack _log; + } forEach _x; +} forEach [_errorLog,_warningLog]; +diag_log "======================================================================"; + +systemChat format ["grad-loadout verifier: %1 loadouts checked",_verifiedLoadoutCount]; +systemChat format ["grad-loadout verifier: %1 errors, %2 warnings",count _errorLog,count _warningLog]; +if (count _errorLog > 0 || count _warningLog > 0) then {systemChat "grad-loadout verifier: see rpt file for results"}; + +[_displayText,format ["GRAD-LOADOUT VERIFIER - %1 ERRORS, %2 WARNINGS",count _errorLog,count _warningLog]] call _fnc_errorDisplay; diff --git a/node_modules/grad-loadout/functions/defactionizers/fn_VanillaCivDefactionizer.sqf b/node_modules/grad-loadout/functions/defactionizers/fn_VanillaCivDefactionizer.sqf index 42cd95c..d330e55 100644 --- a/node_modules/grad-loadout/functions/defactionizers/fn_VanillaCivDefactionizer.sqf +++ b/node_modules/grad-loadout/functions/defactionizers/fn_VanillaCivDefactionizer.sqf @@ -2,7 +2,7 @@ #define COMPONENT loadout #include "\x\cba\addons\main\script_macros_mission.hpp" -private _unit = param [0]; +params ["_unit"]; private _faction = faction _unit; private _type = typeOf _unit; diff --git a/node_modules/grad-loadout/functions/defactionizers/fn_vanillaMilitaryDefactionizer.sqf b/node_modules/grad-loadout/functions/defactionizers/fn_vanillaMilitaryDefactionizer.sqf index af6b62b..44927cb 100644 --- a/node_modules/grad-loadout/functions/defactionizers/fn_vanillaMilitaryDefactionizer.sqf +++ b/node_modules/grad-loadout/functions/defactionizers/fn_vanillaMilitaryDefactionizer.sqf @@ -2,7 +2,7 @@ #define COMPONENT loadout #include "\x\cba\addons\main\script_macros_mission.hpp" -private _unit = param [0]; +params ["_unit"]; private _faction = faction _unit; private _type = typeOf _unit; @@ -11,10 +11,10 @@ private _result = ""; if (side _unit == civilian) exitWith {""}; private _getTypePrefix = { - _faction = param [0]; + params ["_faction"]; - _prefix = _faction select [0, (count _faction) - 1]; // cut suffix F - _initial = _prefix select [0, 1]; + private _prefix = _faction select [0, (count _faction) - 1]; // cut suffix F + private _initial = _prefix select [0, 1]; (_initial + (_prefix select [3])); // cut middle part & return }; diff --git a/node_modules/grad-loadout/functions/extract/fn_ExtractLoadoutFromConfig.sqf b/node_modules/grad-loadout/functions/extract/fn_ExtractLoadoutFromConfig.sqf index f46fdd3..9214274 100644 --- a/node_modules/grad-loadout/functions/extract/fn_ExtractLoadoutFromConfig.sqf +++ b/node_modules/grad-loadout/functions/extract/fn_ExtractLoadoutFromConfig.sqf @@ -2,12 +2,12 @@ #define COMPONENT loadout #include "\x\cba\addons\main\script_macros_mission.hpp" -private _configPath = param [0]; +params ["_configPath"]; GVAR(usedConfigs) pushBack _configPath; { - _value = [_configPath >> _x, "array", false] call CBA_fnc_getConfigEntry; + private _value = [_configPath >> _x, "array", false] call CBA_fnc_getConfigEntry; if (_value isEqualTo false) then { _value = [_configPath >> _x, "text", false] call CBA_fnc_getConfigEntry; }; @@ -34,6 +34,10 @@ private _configValues = [] call CBA_fnc_hashCreate; if (!(_value isEqualTo false)) then { [_configValues, _x, _value] call CBA_fnc_hashSet; }; + _value = [_configPath >> _x, "array", false] call CBA_fnc_getConfigEntry; + if (!(_value isEqualTo false)) then { + [_configValues, _x, (selectRandom _value)] call CBA_fnc_hashSet; + }; } forEach [ "uniform", "vest", @@ -77,8 +81,43 @@ private _configValues = [] call CBA_fnc_hashCreate; }; } forEach [ "addItemsToUniform", - "addItemsToVest", - "addItemsToBackpack" + "addItemsToVest" ]; +private _value = [_configPath >> "addItemsToBackpack", "array", false] call CBA_fnc_getConfigEntry; +if (!(_value isEqualTo false)) then { + { + if (isClass (configFile >> "CfgWeapons" >> _x)) then { + private _muzzle = [_configPath >> _x >> "muzzle", "text", ""] call CBA_fnc_getConfigEntry; + private _pointer = [_configPath >> _x >> "pointer", "text", ""] call CBA_fnc_getConfigEntry; + private _scope = [_configPath >> _x >> "optics", "text", ""] call CBA_fnc_getConfigEntry; + private _magazine = [_configPath >> _x >> "magazine", "text", ""] call CBA_fnc_getConfigEntry; + private _underBarrelMagazine = [_configPath >> _x >> "underBarrelMagazine", "text", ""] call CBA_fnc_getConfigEntry; + private _underBarrel = [_configPath >> _x >> "underBarrel", "text", ""] call CBA_fnc_getConfigEntry; + _value set [_forEachIndex, [_x, _muzzle, _pointer, _scope, _magazine, _underBarrelMagazine, _underBarrel]]; + }; + + private _check = true; + private _type = _x; + + { + if (isClass (configFile >> _x >> _type)) exitWith {_check = false;} + } forEach ["CfgWeapons", "CfgAmmo", "CfgVehicles", "CfgMagazines", "CfgItems"]; + + if (_check) then { + private _weapon = [_configPath >> _x >> "weapon", "text", ""] call CBA_fnc_getConfigEntry; + if (!(_weapon isEqualTo "") && (isClass (configFile >> "CfgWeapons" >> _weapon))) then { + private _muzzle = [_configPath >> _x >> "muzzle", "text", ""] call CBA_fnc_getConfigEntry; + private _pointer = [_configPath >> _x >> "pointer", "text", ""] call CBA_fnc_getConfigEntry; + private _scope = [_configPath >> _x >> "optics", "text", ""] call CBA_fnc_getConfigEntry; + private _magazine = [_configPath >> _x >> "magazine", "text", ""] call CBA_fnc_getConfigEntry; + private _underBarrelMagazine = [_configPath >> _x >> "underBarrelMagazine", "text", ""] call CBA_fnc_getConfigEntry; + private _underBarrel = [_configPath >> _x >> "underBarrel", "text", ""] call CBA_fnc_getConfigEntry; + _value set [_forEachIndex, [_weapon, _muzzle, _pointer, _scope, _magazine, _underBarrelMagazine, _underBarrel]]; + }; + }; + } forEach _value; + [_configValues, "addItemsToBackpack", _value] call CBA_fnc_hashSet; +}; + _configValues diff --git a/node_modules/grad-loadout/functions/extract/fn_GetPathExtractor.sqf b/node_modules/grad-loadout/functions/extract/fn_GetPathExtractor.sqf index 0d639fc..c5fad25 100644 --- a/node_modules/grad-loadout/functions/extract/fn_GetPathExtractor.sqf +++ b/node_modules/grad-loadout/functions/extract/fn_GetPathExtractor.sqf @@ -3,9 +3,7 @@ #define COMPONENT loadout #include "\x\cba\addons\main\script_macros_mission.hpp" -private _unit = param [0]; -private _loadoutHierarchy = param [1]; - +params ["_unit", "_loadoutHierarchy"]; #ifdef DEBUG_MODE_FULL assert (_unit in allUnits); @@ -13,8 +11,8 @@ private _loadoutHierarchy = param [1]; #endif { - private _path = param [0]; - private _discriminator = param [1]; + params ["_path", "_discriminator"]; + if (isClass(_path) && ([_unit] call _discriminator)) then { TRACE_2("adding values from %1 to %2", _path, _unit); _loadoutHierarchy pushBack ([_path] call FUNC(ExtractLoadoutFromConfig)); diff --git a/node_modules/grad-loadout/functions/general/fn_DefactionizeType.sqf b/node_modules/grad-loadout/functions/general/fn_DefactionizeType.sqf index bf20aca..29eee59 100644 --- a/node_modules/grad-loadout/functions/general/fn_DefactionizeType.sqf +++ b/node_modules/grad-loadout/functions/general/fn_DefactionizeType.sqf @@ -3,7 +3,7 @@ #define COMPONENT loadout #include "\x\cba\addons\main\script_macros_mission.hpp" -private _unit = param [0]; +params ["_unit"]; private _defactionedClassname = ""; { diff --git a/node_modules/grad-loadout/functions/general/fn_NormalizeMagazinesInContent.sqf b/node_modules/grad-loadout/functions/general/fn_NormalizeMagazinesInContent.sqf deleted file mode 100644 index f6b9d21..0000000 --- a/node_modules/grad-loadout/functions/general/fn_NormalizeMagazinesInContent.sqf +++ /dev/null @@ -1,37 +0,0 @@ -// normalize magazines in content. -// input: ["stanag_foo", "stanag_blub", "handgrenade", "something_else"] -// output: [["stanag_foo", 2], ["handgrenade", 1], "something_else"] - -private _contentFromConfig = param [0]; - -private _CBA_fnc_hashIncr = { - private _hash = param [0]; - private _key = param [1]; - _value = 1; - if ([_hash, _key] call CBA_fnc_hashHasKey) then { - _value = _value + ([_hash, _key] call CBA_fnc_hashGet); - }; - [_hash, _key, _value] call CBA_fnc_hashSet; -}; - -private _magazines = [] call CBA_fnc_hashCreate; -private _contentForLoadout = []; - -{ - [_magazines, _x] call _CBA_fnc_hashIncr; -} forEach _contentFromConfig; - -[ - _magazines, - { - _className = _key; - - if (_className isKindOf ["CA_Magazine", configFile >> "CfgMagazines"]) then { - _contentForLoadout pushBack [_key, _value, 1]; - } else { - _contentForLoadout pushBack [_key, _value]; - }; - } -] call CBA_fnc_hashEachPair; - -_contentForLoadout diff --git a/node_modules/grad-loadout/functions/general/fn_addChatCommands.sqf b/node_modules/grad-loadout/functions/general/fn_addChatCommands.sqf new file mode 100644 index 0000000..a1435df --- /dev/null +++ b/node_modules/grad-loadout/functions/general/fn_addChatCommands.sqf @@ -0,0 +1,17 @@ + +#define PREFIX grad +#define COMPONENT loadout +#include "\x\cba\addons\main\script_macros_mission.hpp" + +["grad-loadout", { + params ["_command"]; + + switch (_command) do { + case ("viewer"): { + [] call FUNC(loadoutViewer); + }; + case ("verify"): { + [] spawn FUNC(verifyLoadouts); + }; + }; +},"admin"] call CBA_fnc_registerChatCommand; diff --git a/node_modules/grad-loadout/functions/general/fn_doLoadout.sqf b/node_modules/grad-loadout/functions/general/fn_doLoadout.sqf index 165deab..254392c 100644 --- a/node_modules/grad-loadout/functions/general/fn_doLoadout.sqf +++ b/node_modules/grad-loadout/functions/general/fn_doLoadout.sqf @@ -3,8 +3,7 @@ #define COMPONENT loadout #include "\x\cba\addons\main\script_macros_mission.hpp" -private _loadoutHash = param [0]; -private _loadoutTarget = param [1]; +params ["_loadoutHash", "_loadoutTarget"]; if (typeName _loadoutHash != "ARRAY") then { throw "loadoutHash is not of type array (and thus, no cba hash) :((" @@ -31,5 +30,6 @@ if (_loadoutTarget == player) then { }; [_loadoutTarget, [_unitLoadout, true]] remoteExec ["setUnitLoadout", _loadoutTarget, false]; +[QGVAR(loadoutApplied), [_loadoutTarget, _unitLoadout], _loadoutTarget] call CBA_fnc_targetEvent; _loadoutTarget setVariable [QGVAR(applicationCount), (_loadoutTarget getVariable [QGVAR(applicationCount), 0]) + 1, true]; diff --git a/node_modules/grad-loadout/functions/general/fn_factionGetLoadout.sqf b/node_modules/grad-loadout/functions/general/fn_factionGetLoadout.sqf index a73a9cb..075cd7c 100644 --- a/node_modules/grad-loadout/functions/general/fn_factionGetLoadout.sqf +++ b/node_modules/grad-loadout/functions/general/fn_factionGetLoadout.sqf @@ -3,11 +3,7 @@ #define COMPONENT loadout #include "\x\cba\addons\main\script_macros_mission.hpp" -private _faction = param [0]; +params [["_faction",""]]; -private _path = _faction; -if ([GRAD_Loadout_factionPathMap, _faction] call CBA_fnc_hashHasKey) then { - _path = [GRAD_Loadout_factionPathMap, _faction] call CBA_fnc_hashGet; -}; - -_path +// return faction as path if no value exists +GVAR(factionPathMap) getVariable [_faction,_faction] diff --git a/node_modules/grad-loadout/functions/general/fn_factionSetLoadout.sqf b/node_modules/grad-loadout/functions/general/fn_factionSetLoadout.sqf index 31b9e7e..1a0a9f4 100644 --- a/node_modules/grad-loadout/functions/general/fn_factionSetLoadout.sqf +++ b/node_modules/grad-loadout/functions/general/fn_factionSetLoadout.sqf @@ -1,6 +1,9 @@ // usage: ["BLU_T", "BwFleck"] call GRAD_Loadout_FactionSetLoadout; -private _faction = param [0]; -private _loadoutClass = param [1]; +#define PREFIX grad +#define COMPONENT loadout +#include "\x\cba\addons\main\script_macros_mission.hpp" -[GRAD_Loadout_factionPathMap, _faction, _loadoutClass] call CBA_fnc_hashSet; +params [["_faction",""],["_loadoutClass",""],["_global",false]]; + +GVAR(factionPathMap) setVariable [_faction,_loadoutClass,_global]; diff --git a/node_modules/grad-loadout/functions/general/fn_getApplicableUnits.sqf b/node_modules/grad-loadout/functions/general/fn_getApplicableUnits.sqf index a1618d1..62f9ead 100644 --- a/node_modules/grad-loadout/functions/general/fn_getApplicableUnits.sqf +++ b/node_modules/grad-loadout/functions/general/fn_getApplicableUnits.sqf @@ -1,4 +1,4 @@ -private _isMissionStart = param [0]; +params ["_isMissionStart"]; // Make sure that only local player is considered as target on respawn. // This is because AI don't respawn, and we especially don't want to have local AI go through an entire loadout loop again, everytime the player respawns that the AI belongs to. diff --git a/node_modules/grad-loadout/functions/general/fn_getUnitLoadoutFromConfig.sqf b/node_modules/grad-loadout/functions/general/fn_getUnitLoadoutFromConfig.sqf index d7eb6d2..a9d9cd2 100644 --- a/node_modules/grad-loadout/functions/general/fn_getUnitLoadoutFromConfig.sqf +++ b/node_modules/grad-loadout/functions/general/fn_getUnitLoadoutFromConfig.sqf @@ -3,8 +3,7 @@ #define COMPONENT loadout #include "\x\cba\addons\main\script_macros_mission.hpp" -private _unit = param [0]; -private _configPath = param [1]; +params ["_unit", "_configPath"]; private _getSidePath = { _configPath >> "Side" >> _this; diff --git a/node_modules/grad-loadout/functions/general/fn_hashToUnitLoadout.sqf b/node_modules/grad-loadout/functions/general/fn_hashToUnitLoadout.sqf index 7b68194..9820fc3 100644 --- a/node_modules/grad-loadout/functions/general/fn_hashToUnitLoadout.sqf +++ b/node_modules/grad-loadout/functions/general/fn_hashToUnitLoadout.sqf @@ -3,10 +3,7 @@ #define COMPONENT loadout #include "\x\cba\addons\main\script_macros_mission.hpp" - -private _loadoutHash = param [0]; -private _unitLoadout = param [1]; - +params ["_loadoutHash", "_unitLoadout"]; if (typeName _loadoutHash != "ARRAY") then { throw "loadoutHash is not of type array (and thus, no cba hash) :((" @@ -18,8 +15,7 @@ if (typeName _unitLoadout != "ARRAY") then { // CBA_fnc_findTypeName ? CBA_fnc_findTypeOf ? private _getFirstOfType = { - private _array = param [0]; - private _classPath = param [1]; + params ["_array","_classPath"]; private _className = configName _classPath; private _hierarchy = (configHierarchy _classPath); @@ -35,8 +31,7 @@ private _getFirstOfType = { }; private _walkIntoArray = { - private _array = param [0, []]; - private _indices = param [1, []]; + params [["_array",[]],["_indices",[]]]; { _array = _array select _x; } forEach _indices; @@ -45,9 +40,7 @@ private _walkIntoArray = { }; private _assignFromLoadoutHash = { - private _indices = param [0, []]; - private _entryName = param [1, ""]; - private _classNameToPickOrMapper = param [2]; + params [["_indices",[]],["_entryName",""],"_classNameToPickOrMapper"]; if ( [_loadoutHash, _entryName] call CBA_fnc_hashHasKey ) then { private _value = [_loadoutHash, _entryName] call CBA_fnc_hashGet; @@ -69,8 +62,8 @@ private _assignFromLoadoutHash = { }; private _assignValue = { - private _indices = param [0, []]; - private _value = param [1]; + params [["_indices",[]], "_value"]; + if (!(isNil "_value")) then { _index = _indices call BIS_fnc_arrayPop; _targetArray = [_unitLoadout, _indices] call _walkIntoArray; @@ -114,7 +107,7 @@ private _normalizeWeaponArray = { _weaponArray set [_forEachIndex, [_x, 1]]; } else { _weaponArray set [_forEachIndex, _defaultValue]; - }; + }; }; // doesnt work for UGL values. no idea where to get those, btw // if (!([_weaponValue, _x select 0] call FUNC(WeaponIsCompatibleMagazine))) then { @@ -130,10 +123,9 @@ private _normalizeWeaponArray = { _weaponArray }; - private _defaultValueForItemCarriers = { private _targetArray = _unitLoadout select _this; - _carrierClassName = _targetArray select 0; + private _carrierClassName = _targetArray select 0; if (!(isNil "_carrierClassName")) then { _val = _targetArray select 1; if (isNil "_val") then { @@ -172,17 +164,17 @@ private _defaultValueForItemCarriers = { (_unitLoadout select 2) call _normalizeWeaponArray; [[3, 0], "uniform"] call _assignFromLoadoutHash; -[[3, 1], "addItemsToUniform", FUNC(NormalizeMagazinesInContent)] call _assignFromLoadoutHash; +[[3, 1], "addItemsToUniform", FUNC(normalizeContent)] call _assignFromLoadoutHash; 3 call _defaultValueForItemCarriers; [3, 0] call _setEmptyParentArrayIfEmptyString; [[4, 0], "vest"] call _assignFromLoadoutHash; -[[4, 1], "addItemsToVest", FUNC(NormalizeMagazinesInContent)] call _assignFromLoadoutHash; +[[4, 1], "addItemsToVest", FUNC(normalizeContent)] call _assignFromLoadoutHash; 4 call _defaultValueForItemCarriers; [4, 0] call _setEmptyParentArrayIfEmptyString; [[5, 0], "backpack"] call _assignFromLoadoutHash; -[[5, 1], "addItemsToBackpack", FUNC(NormalizeMagazinesInContent)] call _assignFromLoadoutHash; +[[5, 1], "addItemsToBackpack", FUNC(normalizeContent)] call _assignFromLoadoutHash; 5 call _defaultValueForItemCarriers; [5, 0] call _setEmptyParentArrayIfEmptyString; diff --git a/node_modules/grad-loadout/functions/general/fn_initGlobals.sqf b/node_modules/grad-loadout/functions/general/fn_initGlobals.sqf index 2aa21e1..cba3244 100644 --- a/node_modules/grad-loadout/functions/general/fn_initGlobals.sqf +++ b/node_modules/grad-loadout/functions/general/fn_initGlobals.sqf @@ -8,5 +8,5 @@ GVAR(Chosen_Prefix) = ""; // note: units get property GRAD_Loadout_applicationCount -GVAR(factionPathMap) = [] call CBA_fnc_hashCreate; -GVAR(revivers) = [] call CBA_fnc_hashCreate; +GVAR(factionPathMap) = [true] call CBA_fnc_createNamespace; +GVAR(revivers) = [true] call CBA_fnc_createNamespace; diff --git a/node_modules/grad-loadout/functions/general/fn_mergeLoadoutHierarchy.sqf b/node_modules/grad-loadout/functions/general/fn_mergeLoadoutHierarchy.sqf index ad1e6f2..19013e5 100644 --- a/node_modules/grad-loadout/functions/general/fn_mergeLoadoutHierarchy.sqf +++ b/node_modules/grad-loadout/functions/general/fn_mergeLoadoutHierarchy.sqf @@ -1,4 +1,4 @@ -private _loadoutHierarchy = param [0]; +params ["_loadoutHierarchy"]; private _mergedLoadout = [] call CBA_fnc_hashCreate; diff --git a/node_modules/grad-loadout/functions/general/fn_normalizeContent.sqf b/node_modules/grad-loadout/functions/general/fn_normalizeContent.sqf new file mode 100644 index 0000000..5a23b34 --- /dev/null +++ b/node_modules/grad-loadout/functions/general/fn_normalizeContent.sqf @@ -0,0 +1,55 @@ +#define PREFIX grad +#define COMPONENT loadout +#include "\x\cba\addons\main\script_macros_mission.hpp" + +// normalize magazines in content. +// input: ["stanag_foo", "stanag_blub", "handgrenade", "something_else"] +// output: [["stanag_foo", 2], ["handgrenade", 1], "something_else"] + +params ["_contentFromConfig"]; + +private _CBA_fnc_hashIncr = { + params ["_hash","_key"]; + + _value = 1; + if ([_hash, _key] call CBA_fnc_hashHasKey) then { + _value = _value + ([_hash, _key] call CBA_fnc_hashGet); + }; + [_hash, _key, _value] call CBA_fnc_hashSet; +}; + +private _magazines = [] call CBA_fnc_hashCreate; +private _contentForLoadout = []; + +{ + if ((typeName _x) == "ARRAY") then { + if (isClass (configFile >> "CfgWeapons" >> (_x select 0))) then { + _x params ["_weapon", "_muzzle", "_pointer", "_optics", "_magazine", "_underbarrelMagazine", "_underbarrel"]; + + if (!(_magazine isEqualTo "") && isNumber (configFile >> "CfgMagazines" >> _magazine >> "count")) then { + _magazine = [_magazine, (getNumber (configFile >> "CfgMagazines" >> _magazine >> "count"))]; + }; + if (!(_underbarrelMagazine isEqualTo "") && isNumber (configFile >> "CfgMagazines" >> _underbarrelMagazine >> "count")) then { + _underbarrelMagazine = [_underbarrelMagazine, (getNumber (configFile >> "CfgMagazines" >> _underbarrelMagazine >> "count"))]; + }; + _contentForLoadout pushBack [[_weapon, _muzzle, _pointer, _optics, _magazine, _underbarrelMagazine, _underbarrel],1]; + }; + } else { + [_magazines, _x] call _CBA_fnc_hashIncr; + }; +} forEach _contentFromConfig; + +[ + _magazines, + { + _className = _key; + + if (_className isKindOf ["CA_Magazine", configFile >> "CfgMagazines"]) then { + _contentForLoadout pushBack [_key, _value, 1]; + } else { + _contentForLoadout pushBack [_key, _value]; + }; + } +] call CBA_fnc_hashEachPair; + +_contentForLoadout diff --git a/node_modules/grad-loadout/functions/general/fn_scheduleLoadout.sqf b/node_modules/grad-loadout/functions/general/fn_scheduleLoadout.sqf index fb547f1..1e0bc23 100644 --- a/node_modules/grad-loadout/functions/general/fn_scheduleLoadout.sqf +++ b/node_modules/grad-loadout/functions/general/fn_scheduleLoadout.sqf @@ -4,8 +4,8 @@ #include "\x\cba\addons\main\script_macros_mission.hpp" private _getDelay = { - _baseDelay = [(missionConfigFile >> "Loadouts"), "baseDelay", 10] call BIS_fnc_returnConfigEntry; - _perPlayerDelay = [(missionConfigFile >> "Loadouts"), "perPlayerDelay", 1] call BIS_fnc_returnConfigEntry; + private _baseDelay = [(missionConfigFile >> "Loadouts"), "baseDelay", 10] call BIS_fnc_returnConfigEntry; + private _perPlayerDelay = [(missionConfigFile >> "Loadouts"), "perPlayerDelay", 1] call BIS_fnc_returnConfigEntry; _baseDelay + floor(_perPlayerDelay * random (count allPlayers)); }; @@ -17,7 +17,7 @@ systemChat format ["grad-loadout: waiting %1 s for loadout...", _delay]; [ { - _msg = "triggering loadout..."; + private _msg = "triggering loadout..."; INFO(_msg); systemChat ("grad-loadout: " + _msg); [_this select 0] call FUNC(ApplyLoadout); diff --git a/node_modules/grad-loadout/functions/general/fn_weaponIsCompatibleMagazine.sqf b/node_modules/grad-loadout/functions/general/fn_weaponIsCompatibleMagazine.sqf index b20f85c..cc48913 100644 --- a/node_modules/grad-loadout/functions/general/fn_weaponIsCompatibleMagazine.sqf +++ b/node_modules/grad-loadout/functions/general/fn_weaponIsCompatibleMagazine.sqf @@ -1,5 +1,4 @@ -private _weaponClassName = param [0]; -private _magazineClassName = param[1]; +params ["_weaponClassName", "_magazineClassName"]; private _compatibleMagazines = (configFile >> "CfgWeapons" >> _weaponClassName >> "magazines") call BIS_fnc_getCfgData; diff --git a/node_modules/grad-loadout/functions/revivers/fn_addReviver.sqf b/node_modules/grad-loadout/functions/revivers/fn_addReviver.sqf index be9d27f..b3b58e6 100644 --- a/node_modules/grad-loadout/functions/revivers/fn_addReviver.sqf +++ b/node_modules/grad-loadout/functions/revivers/fn_addReviver.sqf @@ -3,16 +3,9 @@ #define COMPONENT loadout #include "\x\cba\addons\main\script_macros_mission.hpp" -private _callback = param [0]; -private _propertyName = param [1]; +params [["_callBack",{}],["_propertyName",""],["_global",false]]; -private _revivers = GVAR(revivers); -private _pRevivers = []; - -if ([_revivers, _propertyName] call CBA_fnc_hashHasKey) then { - _pRevivers = [_revivers, _propertyName] call CBA_fnc_hashGet; -}; +private _pRevivers = GVAR(revivers) getVariable [_propertyName,[]]; _pRevivers pushBack _callback; - -[_revivers, _propertyName, _pRevivers] call CBA_fnc_hashSet; +GVAR(revivers) setVariable [_propertyName,_pRevivers,_global]; diff --git a/node_modules/grad-loadout/functions/revivers/fn_applyRevivers.sqf b/node_modules/grad-loadout/functions/revivers/fn_applyRevivers.sqf index 331c7d5..a530035 100644 --- a/node_modules/grad-loadout/functions/revivers/fn_applyRevivers.sqf +++ b/node_modules/grad-loadout/functions/revivers/fn_applyRevivers.sqf @@ -3,22 +3,21 @@ #define COMPONENT loadout #include "\x\cba\addons\main\script_macros_mission.hpp" -private _loadoutHash = param [0, []]; -private _unit = param [1, objNull]; +params [["_loadoutHash", []], ["_unit", objNull]]; [ - _loadoutHash, - { - _oldValue = _value; - _revivers = [_key] call FUNC(GetRevivers); - { - _value = [_value, _unit] call _x; - } forEach _revivers; + _loadoutHash, + { + _oldValue = _value; + _revivers = [_key] call FUNC(GetRevivers); + { + _value = [_value, _unit] call _x; + } forEach _revivers; - TRACE_2("revivers: replaced %1 with %2", _oldValue, _value); + TRACE_2("revivers: replaced %1 with %2", _oldValue, _value); - [_loadoutHash, _key, _value] call CBA_fnc_hashSet; - } + [_loadoutHash, _key, _value] call CBA_fnc_hashSet; + } ] call CBA_fnc_hashEachPair; _loadoutHash diff --git a/node_modules/grad-loadout/functions/revivers/fn_getRevivers.sqf b/node_modules/grad-loadout/functions/revivers/fn_getRevivers.sqf index 7e7722b..e36accc 100644 --- a/node_modules/grad-loadout/functions/revivers/fn_getRevivers.sqf +++ b/node_modules/grad-loadout/functions/revivers/fn_getRevivers.sqf @@ -3,13 +3,6 @@ #define COMPONENT loadout #include "\x\cba\addons\main\script_macros_mission.hpp" -private _propertyName = param [0]; +params [["_propertyName",""]]; -private _revivers = GVAR(revivers); -private _pRevivers = []; - -if ([_revivers, _propertyName] call CBA_fnc_hashHasKey) then { - _pRevivers = [_revivers, _propertyName] call CBA_fnc_hashGet; -}; - -_pRevivers +GVAR(revivers) getVariable [_propertyName,[]] diff --git a/node_modules/grad-loadout/package.json b/node_modules/grad-loadout/package.json index bf9eca1..0f28922 100644 --- a/node_modules/grad-loadout/package.json +++ b/node_modules/grad-loadout/package.json @@ -2,40 +2,41 @@ "_args": [ [ { - "raw": "grad-loadout@4.7.1", + "raw": "grad-loadout@4.10.0", "scope": null, "escapedName": "grad-loadout", "name": "grad-loadout", - "rawSpec": "4.7.1", - "spec": "4.7.1", + "rawSpec": "4.10.0", + "spec": "4.10.0", "type": "version" }, "E:\\Dokumente\\Arma 3 - Other Profiles\\McDiod\\mpmissions\\TvT_Template.VR" ] ], - "_from": "grad-loadout@4.7.1", - "_id": "grad-loadout@4.7.1", + "_from": "grad-loadout@4.10.0", + "_hasShrinkwrap": false, + "_id": "grad-loadout@4.10.0", "_inCache": true, "_installable": true, "_location": "/grad-loadout", - "_nodeVersion": "8.5.0", + "_nodeVersion": "4.4.7", "_npmOperationalInternal": { "host": "s3://npm-registry-packages", - "tmp": "tmp/grad-loadout-4.7.1.tgz_1509899774690_0.048366304486989975" + "tmp": "tmp/grad-loadout_4.10.0_1541331261748_0.8083629912901567" }, "_npmUser": { - "name": "gruppe-adler", + "name": "gruppe-adler-admin", "email": "admin@gruppe-adler.de" }, - "_npmVersion": "5.3.0", + "_npmVersion": "3.10.5", "_phantomChildren": {}, "_requested": { - "raw": "grad-loadout@4.7.1", + "raw": "grad-loadout@4.10.0", "scope": null, "escapedName": "grad-loadout", "name": "grad-loadout", - "rawSpec": "4.7.1", - "spec": "4.7.1", + "rawSpec": "4.10.0", + "spec": "4.10.0", "type": "version" }, "_requiredBy": [ @@ -43,10 +44,10 @@ "/", "/grad-factions-tvt" ], - "_resolved": "https://registry.npmjs.org/grad-loadout/-/grad-loadout-4.7.1.tgz", - "_shasum": "ef20a1a8d1ffaf65dcdbd2a95ddd8681b2a8816c", + "_resolved": "https://registry.npmjs.org/grad-loadout/-/grad-loadout-4.10.0.tgz", + "_shasum": "2010bc7639fcace5c5064c66a59209d52d7449cd", "_shrinkwrap": null, - "_spec": "grad-loadout@4.7.1", + "_spec": "grad-loadout@4.10.0", "_where": "E:\\Dokumente\\Arma 3 - Other Profiles\\McDiod\\mpmissions\\TvT_Template.VR", "contributors": [ { @@ -68,19 +69,23 @@ "devDependencies": {}, "directories": {}, "dist": { - "integrity": "sha512-eVMRs+6lNI7YRVa7FqyzQFEG/IUb+7BpNUqsz3aaWLka7J2xG85WiQLwR7PuUVZVZbgsWwtFerkbQCq1SXtkBw==", - "shasum": "ef20a1a8d1ffaf65dcdbd2a95ddd8681b2a8816c", - "tarball": "https://registry.npmjs.org/grad-loadout/-/grad-loadout-4.7.1.tgz" + "shasum": "2010bc7639fcace5c5064c66a59209d52d7449cd", + "tarball": "https://registry.npmjs.org/grad-loadout/-/grad-loadout-4.10.0.tgz", + "integrity": "sha512-o2dxT2CBHr3qHjpLyqEhpMVVr8SObSyRMhxjQvHDVtchjZzReXKaDluMH6SV5+1pR83sahnd3FMxbCKSMbeaPg==", + "fileCount": 36, + "unpackedSize": 93733, + "npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb3tk+CRA9TVsSAnZWagAAP0MP/0Y98h+jTp3tZRc9trO9\nVLFtMeZfvZ4I/f1+OZfY5PVhcDQef2OlkDuuvmdYTjNQpMppG8QqTdErBZHs\nAU3EvIJPGd8dkDmsuLQO9pxALD0WLFolPA+2BbimfenLvL3NHLA7oCiU5iEv\nqAEqHE35MGPNreJQ+Pk+YQ/IFVITFMyxDyq8rcZmrfEW+WAgSxifkWJUStJw\nnn6YH1wNbnyMB9CHfikaOgjwUiUiQPnq36gpY879LT/mZr9Y8LB+k0Ihe09o\n7m6CwlYd4Ml5HTFzowTrvBmo7VXbX8+RPh909U1fOhJ5Pz6yAFivurNS3h+Y\nrcelSOgQRvwQuHryh6tcFDuRxV/lehT4v6NJ2m9p/u21FmsOAg3aKpsl4GmE\nZAvXLIY/THYaW/1Djk9pdgzn/XmC0MITsDtICJam0/OyPDdz+1s8dDudN2bp\n3H7dkZVkszv+1tAbjS+tfrZxnstXcDSPgs7y4sIbeFQtH52JxHfOolr+QYJw\nGcDkkmK+NhwfvxURAvGg7THao79KUKV7WWnexKmdWdoDzmFFaRRtgYRj+v30\nGt9OCXqrrVzSW5pHS3y9X3O7jufZnzxNF8cbaMm76kXOEZEs7gILBoyq5fu6\nakKM/T554VpkDjPkEkpOw8VD91GkZ3MQczCMo8cbYahTaCBbrKhNcIvFGoA6\nMZSc\r\n=srXE\r\n-----END PGP SIGNATURE-----\r\n" }, - "gitHead": "7aac9a71dddbdc33d1cad33aa9ef25e6ebb722b6", + "gitHead": "8d2ecc7ec9bd3ee5ced9246f7afd1011d732b2d3", "maintainers": [ { - "name": "gruppe-adler", - "email": "kontakt@gruppe-adler.de" + "name": "gruppe-adler-admin", + "email": "admin@gruppe-adler.de" } ], "name": "grad-loadout", "optionalDependencies": {}, "readme": "ERROR: No README data found!", - "version": "4.7.1" + "scripts": {}, + "version": "4.10.0" } diff --git a/package.json b/package.json index aa7f535..3edb653 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ ], "dependencies": { + "@gruppe-adler/replay": ">=0.0.1", "grad-listbuymenu": ">=0.0.1", "grad-fortifications": ">=0.0.1", "grad-loadout": ">=0.0.1", From e1395112629335f7b00b9385e5bfd21ea53e2e84 Mon Sep 17 00:00:00 2001 From: McDiod Date: Tue, 20 Nov 2018 19:02:26 +0100 Subject: [PATCH 05/10] add virtual spectator slots --- mission.sqm | 686 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 680 insertions(+), 6 deletions(-) diff --git a/mission.sqm b/mission.sqm index b86ee8f..7186ff4 100644 --- a/mission.sqm +++ b/mission.sqm @@ -8,7 +8,7 @@ class EditorData toggles=1; class ItemIDProvider { - nextID=421; + nextID=428; }; class MarkerIDProvider { @@ -16,7 +16,7 @@ class EditorData }; class LayerIndexProvider { - nextID=72; + nextID=77; }; class Camera { @@ -37,13 +37,14 @@ addons[]= "A3_Characters_F_Mark", "ace_explosives", "A3_Characters_F_Jets", - "ace_nouniformrestrictions" + "ace_nouniformrestrictions", + "A3_Data_F_Exp_A_Virtual" }; class AddonsMetaData { class List { - items=9; + items=10; class Item0 { className="A3_Modules_F_Curator"; @@ -105,6 +106,13 @@ class AddonsMetaData author="ACE-Team"; url="http://ace3mod.com/"; }; + class Item9 + { + className="A3_Data_F_Exp_A"; + name="Arma 3 Nexus Update - Main Configuration"; + author="Bohemia Interactive"; + url="https://www.arma3.com"; + }; }; }; randomSeed=7199820; @@ -1782,7 +1790,7 @@ class Mission }; class Entities { - items=3; + items=4; class Item0 { dataType="Layer"; @@ -2033,7 +2041,7 @@ class Mission }; }; id=127; - atlOffset=49.115803; + atlOffset=11.59075; }; class Item1 { @@ -14377,6 +14385,672 @@ class Mission }; id=205; }; + class Item3 + { + dataType="Layer"; + name="Template: Spielereinheiten_1"; + class Entities + { + items=6; + class Item0 + { + dataType="Logic"; + class PositionInfo + { + position[]={1900.5229,5,2000.0884}; + }; + isPlayer=1; + isPlayable=1; + id=422; + type="VirtualSpectator_F"; + class CustomAttributes + { + class Attribute0 + { + property="AllowFreeCamera"; + expression="_this setVariable ['AllowFreeCamera', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=1; + }; + }; + }; + class Attribute1 + { + property="WhitelistedSides"; + expression="_this setVariable ['WhitelistedSides', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "ARRAY" + }; + }; + }; + }; + }; + class Attribute2 + { + property="ShowFocusInfo"; + expression="_this setVariable ['ShowFocusInfo', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=1; + }; + }; + }; + class Attribute3 + { + property="AllowAi"; + expression="_this setVariable ['AllowAi', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=0; + }; + }; + }; + class Attribute4 + { + property="Allow3PPCamera"; + expression="_this setVariable ['Allow3PPCamera', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=1; + }; + }; + }; + nAttributes=5; + }; + }; + class Item1 + { + dataType="Logic"; + class PositionInfo + { + position[]={1900.5229,5,1900.4424}; + }; + isPlayable=1; + id=423; + type="VirtualSpectator_F"; + class CustomAttributes + { + class Attribute0 + { + property="AllowFreeCamera"; + expression="_this setVariable ['AllowFreeCamera', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=1; + }; + }; + }; + class Attribute1 + { + property="WhitelistedSides"; + expression="_this setVariable ['WhitelistedSides', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "ARRAY" + }; + }; + }; + }; + }; + class Attribute2 + { + property="ShowFocusInfo"; + expression="_this setVariable ['ShowFocusInfo', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=1; + }; + }; + }; + class Attribute3 + { + property="AllowAi"; + expression="_this setVariable ['AllowAi', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=0; + }; + }; + }; + class Attribute4 + { + property="Allow3PPCamera"; + expression="_this setVariable ['Allow3PPCamera', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=1; + }; + }; + }; + nAttributes=5; + }; + }; + class Item2 + { + dataType="Logic"; + class PositionInfo + { + position[]={1901.0767,5,1799.1353}; + }; + isPlayable=1; + id=424; + type="VirtualSpectator_F"; + class CustomAttributes + { + class Attribute0 + { + property="AllowFreeCamera"; + expression="_this setVariable ['AllowFreeCamera', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=1; + }; + }; + }; + class Attribute1 + { + property="WhitelistedSides"; + expression="_this setVariable ['WhitelistedSides', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "ARRAY" + }; + }; + }; + }; + }; + class Attribute2 + { + property="ShowFocusInfo"; + expression="_this setVariable ['ShowFocusInfo', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=1; + }; + }; + }; + class Attribute3 + { + property="AllowAi"; + expression="_this setVariable ['AllowAi', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=0; + }; + }; + }; + class Attribute4 + { + property="Allow3PPCamera"; + expression="_this setVariable ['Allow3PPCamera', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=1; + }; + }; + }; + nAttributes=5; + }; + }; + class Item3 + { + dataType="Logic"; + class PositionInfo + { + position[]={1799.5546,5,1999.6997}; + }; + isPlayer=1; + isPlayable=1; + id=425; + type="VirtualSpectator_F"; + class CustomAttributes + { + class Attribute0 + { + property="AllowFreeCamera"; + expression="_this setVariable ['AllowFreeCamera', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=1; + }; + }; + }; + class Attribute1 + { + property="WhitelistedSides"; + expression="_this setVariable ['WhitelistedSides', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "ARRAY" + }; + }; + }; + }; + }; + class Attribute2 + { + property="ShowFocusInfo"; + expression="_this setVariable ['ShowFocusInfo', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=1; + }; + }; + }; + class Attribute3 + { + property="AllowAi"; + expression="_this setVariable ['AllowAi', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=0; + }; + }; + }; + class Attribute4 + { + property="Allow3PPCamera"; + expression="_this setVariable ['Allow3PPCamera', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=1; + }; + }; + }; + nAttributes=5; + }; + }; + class Item4 + { + dataType="Logic"; + class PositionInfo + { + position[]={1799.5546,5,1900.0537}; + }; + isPlayable=1; + id=426; + type="VirtualSpectator_F"; + class CustomAttributes + { + class Attribute0 + { + property="AllowFreeCamera"; + expression="_this setVariable ['AllowFreeCamera', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=1; + }; + }; + }; + class Attribute1 + { + property="WhitelistedSides"; + expression="_this setVariable ['WhitelistedSides', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "ARRAY" + }; + }; + }; + }; + }; + class Attribute2 + { + property="ShowFocusInfo"; + expression="_this setVariable ['ShowFocusInfo', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=1; + }; + }; + }; + class Attribute3 + { + property="AllowAi"; + expression="_this setVariable ['AllowAi', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=0; + }; + }; + }; + class Attribute4 + { + property="Allow3PPCamera"; + expression="_this setVariable ['Allow3PPCamera', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=1; + }; + }; + }; + nAttributes=5; + }; + }; + class Item5 + { + dataType="Logic"; + class PositionInfo + { + position[]={1800.1083,5,1798.7466}; + }; + isPlayable=1; + id=427; + type="VirtualSpectator_F"; + class CustomAttributes + { + class Attribute0 + { + property="AllowFreeCamera"; + expression="_this setVariable ['AllowFreeCamera', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=1; + }; + }; + }; + class Attribute1 + { + property="WhitelistedSides"; + expression="_this setVariable ['WhitelistedSides', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "ARRAY" + }; + }; + }; + }; + }; + class Attribute2 + { + property="ShowFocusInfo"; + expression="_this setVariable ['ShowFocusInfo', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=1; + }; + }; + }; + class Attribute3 + { + property="AllowAi"; + expression="_this setVariable ['AllowAi', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=0; + }; + }; + }; + class Attribute4 + { + property="Allow3PPCamera"; + expression="_this setVariable ['Allow3PPCamera', _value];"; + class Value + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=1; + }; + }; + }; + nAttributes=5; + }; + }; + }; + id=421; + }; }; class Connections { From b6766e6ad3fc06f11b2c8d5c382ae56362eea93d Mon Sep 17 00:00:00 2001 From: McDiod Date: Tue, 20 Nov 2018 19:14:10 +0100 Subject: [PATCH 06/10] close #19 force basic medical --- mission.sqm | 1255 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 1247 insertions(+), 8 deletions(-) diff --git a/mission.sqm b/mission.sqm index 7186ff4..af57e62 100644 --- a/mission.sqm +++ b/mission.sqm @@ -16,14 +16,14 @@ class EditorData }; class LayerIndexProvider { - nextID=77; + nextID=82; }; class Camera { - pos[]={4923.6338,30,1529.8053}; - dir[]={0.90338212,-0.28735021,0.31835207}; - up[]={0.27102202,0.9578225,0.095508225}; - aside[]={0.33236971,-2.2002496e-007,-0.94316244}; + pos[]={5356.1299,151.47934,1589.2156}; + dir[]={0.57903713,-0.53247643,0.61742061}; + up[]={0.36425498,0.84644032,0.38840109}; + aside[]={0.72942597,-9.0803951e-008,-0.68408108}; }; }; binarizationWanted=0; @@ -170,7 +170,7 @@ class CustomAttributes }; class value { - items=26; + items=47; class Item0 { class data @@ -535,6 +535,300 @@ class CustomAttributes value="ace_weather_windsimulation"; }; }; + class Item26 + { + class data + { + class type + { + type[]= + { + "STRING" + }; + }; + value="ace_medical_level"; + }; + }; + class Item27 + { + class data + { + class type + { + type[]= + { + "STRING" + }; + }; + value="ace_medical_medicsetting"; + }; + }; + class Item28 + { + class data + { + class type + { + type[]= + { + "STRING" + }; + }; + value="ace_medical_enablefor"; + }; + }; + class Item29 + { + class data + { + class type + { + type[]= + { + "STRING" + }; + }; + value="ace_medical_enableoverdosing"; + }; + }; + class Item30 + { + class data + { + class type + { + type[]= + { + "STRING" + }; + }; + value="ace_medical_paincoefficient"; + }; + }; + class Item31 + { + class data + { + class type + { + type[]= + { + "STRING" + }; + }; + value="ace_medical_enableadvancedwounds"; + }; + }; + class Item32 + { + class data + { + class type + { + type[]= + { + "STRING" + }; + }; + value="ace_medical_enablevehiclecrashes"; + }; + }; + class Item33 + { + class data + { + class type + { + type[]= + { + "STRING" + }; + }; + value="ace_medical_enablescreams"; + }; + }; + class Item34 + { + class data + { + class type + { + type[]= + { + "STRING" + }; + }; + value="ace_medical_enableunconsciousnessai"; + }; + }; + class Item35 + { + class data + { + class type + { + type[]= + { + "STRING" + }; + }; + value="ace_medical_remotecontrolledai"; + }; + }; + class Item36 + { + class data + { + class type + { + type[]= + { + "STRING" + }; + }; + value="ace_medical_preventinstadeath"; + }; + }; + class Item37 + { + class data + { + class type + { + type[]= + { + "STRING" + }; + }; + value="ace_medical_enablerevive"; + }; + }; + class Item38 + { + class data + { + class type + { + type[]= + { + "STRING" + }; + }; + value="ace_medical_maxrevivetime"; + }; + }; + class Item39 + { + class data + { + class type + { + type[]= + { + "STRING" + }; + }; + value="ace_medical_amountofrevivelives"; + }; + }; + class Item40 + { + class data + { + class type + { + type[]= + { + "STRING" + }; + }; + value="ace_medical_allowlittercreation"; + }; + }; + class Item41 + { + class data + { + class type + { + type[]= + { + "STRING" + }; + }; + value="ace_medical_medicsetting_basicepi"; + }; + }; + class Item42 + { + class data + { + class type + { + type[]= + { + "STRING" + }; + }; + value="ace_medical_medicsetting_pak"; + }; + }; + class Item43 + { + class data + { + class type + { + type[]= + { + "STRING" + }; + }; + value="ace_medical_medicsetting_surgicalkit"; + }; + }; + class Item44 + { + class data + { + class type + { + type[]= + { + "STRING" + }; + }; + value="ace_medical_consumeitem_pak"; + }; + }; + class Item45 + { + class data + { + class type + { + type[]= + { + "STRING" + }; + }; + value="ace_medical_consumeitem_surgicalkit"; + }; + }; + class Item46 + { + class data + { + class type + { + type[]= + { + "STRING" + }; + }; + value="ace_medical_uselocation_basicepi"; + }; + }; }; }; }; @@ -551,7 +845,7 @@ class CustomAttributes }; class value { - items=26; + items=47; class Item0 { class data @@ -1342,7 +1636,7 @@ class CustomAttributes "SCALAR" }; }; - value=1.2; + value=1.3; }; }; class Item1 @@ -1722,6 +2016,951 @@ class CustomAttributes }; }; }; + class Item26 + { + class data + { + class type + { + type[]= + { + "ARRAY" + }; + }; + class value + { + items=2; + class Item0 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=1; + }; + }; + class Item1 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=1; + }; + }; + }; + }; + }; + class Item27 + { + class data + { + class type + { + type[]= + { + "ARRAY" + }; + }; + class value + { + items=2; + class Item0 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=1; + }; + }; + class Item1 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=1; + }; + }; + }; + }; + }; + class Item28 + { + class data + { + class type + { + type[]= + { + "ARRAY" + }; + }; + class value + { + items=2; + class Item0 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=0; + }; + }; + class Item1 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=1; + }; + }; + }; + }; + }; + class Item29 + { + class data + { + class type + { + type[]= + { + "ARRAY" + }; + }; + class value + { + items=2; + class Item0 + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=1; + }; + }; + class Item1 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=1; + }; + }; + }; + }; + }; + class Item30 + { + class data + { + class type + { + type[]= + { + "ARRAY" + }; + }; + class value + { + items=2; + class Item0 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=1; + }; + }; + class Item1 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=1; + }; + }; + }; + }; + }; + class Item31 + { + class data + { + class type + { + type[]= + { + "ARRAY" + }; + }; + class value + { + items=2; + class Item0 + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=0; + }; + }; + class Item1 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=1; + }; + }; + }; + }; + }; + class Item32 + { + class data + { + class type + { + type[]= + { + "ARRAY" + }; + }; + class value + { + items=2; + class Item0 + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=1; + }; + }; + class Item1 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=1; + }; + }; + }; + }; + }; + class Item33 + { + class data + { + class type + { + type[]= + { + "ARRAY" + }; + }; + class value + { + items=2; + class Item0 + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=1; + }; + }; + class Item1 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=1; + }; + }; + }; + }; + }; + class Item34 + { + class data + { + class type + { + type[]= + { + "ARRAY" + }; + }; + class value + { + items=2; + class Item0 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=1; + }; + }; + class Item1 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=1; + }; + }; + }; + }; + }; + class Item35 + { + class data + { + class type + { + type[]= + { + "ARRAY" + }; + }; + class value + { + items=2; + class Item0 + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=1; + }; + }; + class Item1 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=1; + }; + }; + }; + }; + }; + class Item36 + { + class data + { + class type + { + type[]= + { + "ARRAY" + }; + }; + class value + { + items=2; + class Item0 + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=0; + }; + }; + class Item1 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=1; + }; + }; + }; + }; + }; + class Item37 + { + class data + { + class type + { + type[]= + { + "ARRAY" + }; + }; + class value + { + items=2; + class Item0 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=0; + }; + }; + class Item1 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=1; + }; + }; + }; + }; + }; + class Item38 + { + class data + { + class type + { + type[]= + { + "ARRAY" + }; + }; + class value + { + items=2; + class Item0 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=120; + }; + }; + class Item1 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=1; + }; + }; + }; + }; + }; + class Item39 + { + class data + { + class type + { + type[]= + { + "ARRAY" + }; + }; + class value + { + items=2; + class Item0 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=-1; + }; + }; + class Item1 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=1; + }; + }; + }; + }; + }; + class Item40 + { + class data + { + class type + { + type[]= + { + "ARRAY" + }; + }; + class value + { + items=2; + class Item0 + { + class data + { + class type + { + type[]= + { + "BOOL" + }; + }; + value=1; + }; + }; + class Item1 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=1; + }; + }; + }; + }; + }; + class Item41 + { + class data + { + class type + { + type[]= + { + "ARRAY" + }; + }; + class value + { + items=2; + class Item0 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=0; + }; + }; + class Item1 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=1; + }; + }; + }; + }; + }; + class Item42 + { + class data + { + class type + { + type[]= + { + "ARRAY" + }; + }; + class value + { + items=2; + class Item0 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=1; + }; + }; + class Item1 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=1; + }; + }; + }; + }; + }; + class Item43 + { + class data + { + class type + { + type[]= + { + "ARRAY" + }; + }; + class value + { + items=2; + class Item0 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=1; + }; + }; + class Item1 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=1; + }; + }; + }; + }; + }; + class Item44 + { + class data + { + class type + { + type[]= + { + "ARRAY" + }; + }; + class value + { + items=2; + class Item0 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=0; + }; + }; + class Item1 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=1; + }; + }; + }; + }; + }; + class Item45 + { + class data + { + class type + { + type[]= + { + "ARRAY" + }; + }; + class value + { + items=2; + class Item0 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=0; + }; + }; + class Item1 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=1; + }; + }; + }; + }; + }; + class Item46 + { + class data + { + class type + { + type[]= + { + "ARRAY" + }; + }; + class value + { + items=2; + class Item0 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=0; + }; + }; + class Item1 + { + class data + { + class type + { + type[]= + { + "SCALAR" + }; + }; + value=1; + }; + }; + }; + }; + }; }; }; }; From afe7823dd9091c64a4a7b6b5b7f8bf7157d36011 Mon Sep 17 00:00:00 2001 From: McDiod Date: Tue, 20 Nov 2018 19:19:49 +0100 Subject: [PATCH 07/10] close #18 round points --- functions/points/fn_displayPoints.sqf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/functions/points/fn_displayPoints.sqf b/functions/points/fn_displayPoints.sqf index dca4487..74f4541 100644 --- a/functions/points/fn_displayPoints.sqf +++ b/functions/points/fn_displayPoints.sqf @@ -18,7 +18,7 @@ if (!isServer && !isRemoteExecuted) exitWith {[] remoteExec ["grad_points_fnc_displayPoints",2,false]}; -if (isServer && count _this == 0) then { +if (isServer && count _this == 0) exitWith { [ [([WEST] call grad_points_fnc_getPointsCategorized),[],{_x select 1},"DESCEND"] call BIS_fnc_sortBy, [([EAST] call grad_points_fnc_getPointsCategorized),[],{_x select 1},"DESCEND"] call BIS_fnc_sortBy, @@ -64,7 +64,7 @@ if (hasInterface && count _this > 0) then { _text = [parseText format ["Points for %2:",[_side,"HTML"] call grad_common_fnc_getSideColor,[_side] call grad_common_fnc_getSideDisplayName],lineBreak,lineBreak]; { _x params ["_category","_points"]; - _text pushBack (parseText format ["%1: %3",_category,if (_points > 0) then {"#00ff00"} else {"#ff0000"},_points]); + _text pushBack (parseText format ["%1: %3",_category,if (_points > 0) then {"#00ff00"} else {"#ff0000"},round _points]); _text pushBack lineBreak; false } count _x; @@ -72,7 +72,7 @@ if (hasInterface && count _this > 0) then { _sumCtrl = _display ctrlCreate ["RscStructuredText",-1]; _sumCtrl ctrlSetPosition [(0.5-_backgroundW/2) + PADDINGW + _columnCount * (PADDINGW + COLUMNW),BACKGROUNDY + PADDINGH + COLUMNH,COLUMNW,SUMH]; - _sumCtrl ctrlSetStructuredText (parseText format ["Total: %1",[_side] call grad_points_fnc_getPoints]); + _sumCtrl ctrlSetStructuredText (parseText format ["Total: %1",round ([_side] call grad_points_fnc_getPoints)]); _sumCtrl ctrlCommit 0; if (_columnCount > 0) then { From 3491f58af216475db860aa63ac0d7e75f0dd684f Mon Sep 17 00:00:00 2001 From: McDiod Date: Tue, 20 Nov 2018 19:29:03 +0100 Subject: [PATCH 08/10] close #8 grad-replay --- functions/endings/fn_endMissionClient.sqf | 30 +++-------------------- 1 file changed, 3 insertions(+), 27 deletions(-) diff --git a/functions/endings/fn_endMissionClient.sqf b/functions/endings/fn_endMissionClient.sqf index 6bbdccb..d5c0ec7 100644 --- a/functions/endings/fn_endMissionClient.sqf +++ b/functions/endings/fn_endMissionClient.sqf @@ -1,30 +1,6 @@ #include "component.hpp" -_this spawn { - params ["_configName","_winText","_winners","_winTextParams"]; - private ["_winText","_winners","_winTextParams"]; +params [["_winners",[]]]; - if (isNil "_winText") then { - _winText = [missionConfigFile >> "CfgWinConditions" >> _configName,"winText",""] call BIS_fnc_returnConfigEntry; - }; - if (isNil "_winners") then { - _winners = ([missionConfigFile >> "CfgWinConditions" >> _configName,"winners",[]] call BIS_fnc_returnConfigEntry) apply {call compile _x}; - }; - private _winTextParams = ([missionConfigFile >> "CfgWinConditions" >> _configName,"winTextParams",[]] call BIS_fnc_returnConfigEntry) apply {call compile _x}; - - _winText = "
" + _winText + ""; - - _text = format ([_winText] + _winTextParams); - [_text,0,0,4,2] spawn BIS_fnc_dynamicText; - - INFO_3("%1 %2 %3",_winText,_text,_winners); - - sleep 5; - - if (({[_x] call grad_points_fnc_getPoints > 0} count [WEST,EAST,INDEPENDENT,CIVILIAN]) > 0) then { - [] call grad_points_fnc_displayPoints; - sleep 16; - }; - - ["end1",playerSide in _winners,true,true,true] spawn BIS_fnc_endMission; -}; +waitUntil {missionNamespace getVariable ["REPLAY_FINISHED",false]}; +["end1",playerSide in _winners,true,true,true] spawn BIS_fnc_endMission; From 7aa0d02acc136315e1df6ecf2882ed26fc358428 Mon Sep 17 00:00:00 2001 From: McDiod Date: Tue, 20 Nov 2018 20:09:31 +0100 Subject: [PATCH 09/10] move waverespawn from saving names to saving units --- functions/waverespawn/fn_addToWave.sqf | 30 ++++++++-------- functions/waverespawn/fn_canRespawn.sqf | 6 ++-- functions/waverespawn/fn_getStatus.sqf | 6 ++-- functions/waverespawn/fn_init.sqf | 10 +++--- functions/waverespawn/fn_onPlayerRespawn.sqf | 2 +- functions/waverespawn/fn_removeFromWave.sqf | 36 +++++++++----------- functions/waverespawn/fn_startWaveLoops.sqf | 6 ++-- functions/waverespawn/fn_waveCountdown.sqf | 2 +- 8 files changed, 47 insertions(+), 51 deletions(-) diff --git a/functions/waverespawn/fn_addToWave.sqf b/functions/waverespawn/fn_addToWave.sqf index 714a146..ba79ef8 100644 --- a/functions/waverespawn/fn_addToWave.sqf +++ b/functions/waverespawn/fn_addToWave.sqf @@ -1,34 +1,32 @@ #include "component.hpp" -params ["_deadPlayerName", ["_deadPlayerSide", sideUnknown]]; +params ["_deadPlayer", ["_deadPlayerSide", sideUnknown]]; -if (isNil "wavePlayernamesBlu") then {wavePlayernamesBlu = []}; -if (isNil "wavePlayernamesOpf") then {wavePlayernamesOpf = []}; -if (isNil "wavePlayernamesInd") then {wavePlayernamesInd = []}; - -_deadPlayerName = [_deadPlayerName] call BIS_fnc_filterString; +if (isNil "wavePlayersBlu") then {wavePlayersBlu = []}; +if (isNil "wavePlayersOpf") then {wavePlayersOpf = []}; +if (isNil "wavePlayersInd") then {wavePlayersInd = []}; //add player to array switch (_deadPlayerSide) do { case (WEST): { - wavePlayernamesBlu pushBackUnique _deadPlayerName; - INFO_2("Added player %1 to wavePlayernamesBlu. %2 dead blufor total.", _deadPlayerName, count wavePlayernamesBlu); - WAVERESPAWNPLAYERSLEFTBLU = BLUFORWAVESIZE - (count wavePlayernamesBlu); + wavePlayersBlu pushBackUnique _deadPlayer; + INFO_2("Added player %1 to wavePlayersBlu. %2 dead blufor total.", _deadPlayer, count wavePlayersBlu); + WAVERESPAWNPLAYERSLEFTBLU = BLUFORWAVESIZE - (count wavePlayersBlu); publicVariable "WAVERESPAWNPLAYERSLEFTBLU"; }; case (EAST): { - wavePlayernamesOpf pushBackUnique _deadPlayerName; - INFO_2("Added player %1 to wavePlayernamesOpf. %2 dead opfor total.", _deadPlayerName, count wavePlayernamesOpf); - WAVERESPAWNPLAYERSLEFTOPF = OPFORWAVESIZE - (count wavePlayernamesOpf); + wavePlayersOpf pushBackUnique _deadPlayer; + INFO_2("Added player %1 to wavePlayersOpf. %2 dead opfor total.", _deadPlayer, count wavePlayersOpf); + WAVERESPAWNPLAYERSLEFTOPF = OPFORWAVESIZE - (count wavePlayersOpf); publicVariable "WAVERESPAWNPLAYERSLEFTOPF"; }; case (INDEPENDENT): { - wavePlayernamesInd pushBackUnique _deadPlayerName; - INFO_2("Added player %1 to wavePlayernamesOpf. %2 dead opfor total.", _deadPlayerName, count wavePlayernamesInd); - WAVERESPAWNPLAYERSLEFTIND = INDEPWAVESIZE - (count wavePlayernamesInd); + wavePlayersInd pushBackUnique _deadPlayer; + INFO_2("Added player %1 to wavePlayersOpf. %2 dead opfor total.", _deadPlayer, count wavePlayersInd); + WAVERESPAWNPLAYERSLEFTIND = INDEPWAVESIZE - (count wavePlayersInd); publicVariable "WAVERESPAWNPLAYERSLEFTIND"; }; default { - ERROR_1("Unknown side for player %1", _deadPlayerName); + ERROR_1("Unknown side for player %1", _deadPlayer); }; }; diff --git a/functions/waverespawn/fn_canRespawn.sqf b/functions/waverespawn/fn_canRespawn.sqf index 0995763..b36f145 100644 --- a/functions/waverespawn/fn_canRespawn.sqf +++ b/functions/waverespawn/fn_canRespawn.sqf @@ -4,15 +4,15 @@ params ["_side"]; _canRespawn = switch (_side) do { case ("WEST"): { - count wavePlayernamesBlu >= BLUFORWAVESIZE && + count wavePlayersBlu >= BLUFORWAVESIZE && WAVERESPAWNTIMELEFTBLU <= 0 }; case ("EAST"): { - count wavePlayernamesOpf >= OPFORWAVESIZE && + count wavePlayersOpf >= OPFORWAVESIZE && WAVERESPAWNTIMELEFTOPF <= 0 }; case ("INDEPENDENT"): { - count wavePlayernamesInd >= INDEPWAVESIZE && + count wavePlayersInd >= INDEPWAVESIZE && WAVERESPAWNTIMELEFTIND <= 0 }; default { diff --git a/functions/waverespawn/fn_getStatus.sqf b/functions/waverespawn/fn_getStatus.sqf index c357306..abd30cf 100644 --- a/functions/waverespawn/fn_getStatus.sqf +++ b/functions/waverespawn/fn_getStatus.sqf @@ -9,7 +9,7 @@ if (_side == WEST) then { case (WAVERESPAWNTIMELEFTBLU > 0): { "Waiting for wave-countdown."; }; - case (count wavePlayernamesBlu < BLUFORWAVESIZE): { + case (count wavePlayersBlu < BLUFORWAVESIZE): { "Waiting for more players."; }; default { @@ -23,7 +23,7 @@ if (_side == EAST) then { case (OPFORWAVESIZE > 0): { "Waiting for wave-countdown."; }; - case (count wavePlayernamesOpf < OPFORWAVESIZE): { + case (count wavePlayersOpf < OPFORWAVESIZE): { "Waiting for more players."; }; default { @@ -37,7 +37,7 @@ if (_side == INDEPENDENT) then { case (INDEPWAVESIZE > 0): { "Waiting for wave-countdown."; }; - case (count wavePlayernamesInd < INDEPWAVESIZE): { + case (count wavePlayersInd < INDEPWAVESIZE): { "Waiting for more players."; }; default { diff --git a/functions/waverespawn/fn_init.sqf b/functions/waverespawn/fn_init.sqf index 4f8987b..d70f747 100644 --- a/functions/waverespawn/fn_init.sqf +++ b/functions/waverespawn/fn_init.sqf @@ -2,9 +2,9 @@ if (([missionConfigFile >> "missionsettings","waveRespawnEnabled",0] call BIS_fnc_returnConfigEntry) == 0) exitWith {}; -wavePlayernamesBlu = []; -wavePlayernamesOpf = []; -wavePlayernamesInd = []; +wavePlayersBlu = []; +wavePlayersOpf = []; +wavePlayersInd = []; waitingPlayersBlu = []; waitingPlayersOpf = []; waitingPlayersInd = []; @@ -16,8 +16,8 @@ if (isServer) then { [] call grad_waverespawn_fnc_setWaveSize; [] call grad_waverespawn_fnc_startWaveLoops; addMissionEventHandler ["HandleDisconnect", { - params [["_unit",objNull],"","",["_name",""]]; - [_name,side _unit] call grad_waverespawn_fnc_removeFromWave; + params [["_unit",objNull]]; + [_unit,side _unit] call grad_waverespawn_fnc_removeFromWave; [_unit,side _unit,false] call grad_waverespawn_fnc_addToWaiting; }]; }; diff --git a/functions/waverespawn/fn_onPlayerRespawn.sqf b/functions/waverespawn/fn_onPlayerRespawn.sqf index c21aee1..31abc21 100644 --- a/functions/waverespawn/fn_onPlayerRespawn.sqf +++ b/functions/waverespawn/fn_onPlayerRespawn.sqf @@ -2,7 +2,7 @@ params ["",["_oldUnit",objNull]]; -[profileName,playerSide] remoteExec ["grad_waverespawn_fnc_removeFromWave",2,false]; +[_oldUnit,playerSide] remoteExec ["grad_waverespawn_fnc_removeFromWave",2,false]; [_oldUnit,playerSide,false] remoteExec ["grad_waverespawn_fnc_addToWaiting",2,false]; setPlayerRespawnTime 99999; diff --git a/functions/waverespawn/fn_removeFromWave.sqf b/functions/waverespawn/fn_removeFromWave.sqf index 526ac0c..e97110c 100644 --- a/functions/waverespawn/fn_removeFromWave.sqf +++ b/functions/waverespawn/fn_removeFromWave.sqf @@ -1,44 +1,42 @@ #include "component.hpp" -params ["_unitName","_side"]; - -_unitName = [_unitName] call BIS_fnc_filterString; +params ["_unit","_side"]; switch (_side) do { case (WEST): { - if (_unitName in wavePlayernamesBlu) then { - wavePlayernamesBlu deleteAt (([wavePlayernamesBlu,_unitName] call BIS_fnc_arrayFindDeep) select 0); - INFO_1("Player %1 respawned and has been removed from wavePlayernamesBlu.", _unitName); + if (_unit in wavePlayersBlu) then { + wavePlayersBlu deleteAt (wavePlayersBlu find _unit); + INFO_1("Player %1 respawned and has been removed from wavePlayersBlu.", _unit); } else { - ERROR_1("Player %1 is not in wavePlayernamesBlu.", _unitName); + ERROR_1("Player %1 is not in wavePlayersBlu.", _unit); }; }; case (EAST): { - if (_unitName in wavePlayernamesOpf) then { - wavePlayernamesOpf deleteAt (([wavePlayernamesOpf,_unitName] call BIS_fnc_arrayFindDeep) select 0); - INFO_1("Player %1 respawned and has been removed from wavePlayernamesOpf.", _unitName); + if (_unit in wavePlayersOpf) then { + wavePlayersOpf deleteAt (wavePlayersOpf find _unit); + INFO_1("Player %1 respawned and has been removed from wavePlayersOpf.", _unit); } else { - ERROR_1("Player %1 is not in wavePlayernamesOpf", _unitName); + ERROR_1("Player %1 is not in wavePlayersOpf", _unit); }; }; case (INDEPENDENT): { - if (_unitName in wavePlayernamesInd) then { - wavePlayernamesInd deleteAt (([wavePlayernamesInd,_unitName] call BIS_fnc_arrayFindDeep) select 0); - INFO_1("Player %1 respawned and has been removed from wavePlayernamesInd.", _unitName); + if (_unit in wavePlayersInd) then { + wavePlayersInd deleteAt (wavePlayersInd find _unit); + INFO_1("Player %1 respawned and has been removed from wavePlayersInd.", _unit); } else { - ERROR_1("Player %1 is not in wavePlayernamesInd", _unitName); + ERROR_1("Player %1 is not in wavePlayersInd", _unit); }; }; - default {ERROR_1("Player %1 is neither WEST nor EAST nor INDEPENDENT.", _unitName)}; + default {ERROR_1("Player %1 is neither WEST nor EAST nor INDEPENDENT.", _unit)}; }; [{ - WAVERESPAWNPLAYERSLEFTBLU = BLUFORWAVESIZE - (count wavePlayernamesBlu); - WAVERESPAWNPLAYERSLEFTOPF = OPFORWAVESIZE - (count wavePlayernamesOpf); - WAVERESPAWNPLAYERSLEFTIND = INDEPWAVESIZE - (count wavePlayernamesInd); + WAVERESPAWNPLAYERSLEFTBLU = BLUFORWAVESIZE - (count wavePlayersBlu); + WAVERESPAWNPLAYERSLEFTOPF = OPFORWAVESIZE - (count wavePlayersOpf); + WAVERESPAWNPLAYERSLEFTIND = INDEPWAVESIZE - (count wavePlayersInd); publicVariable "WAVERESPAWNPLAYERSLEFTBLU"; publicVariable "WAVERESPAWNPLAYERSLEFTOPF"; publicVariable "WAVERESPAWNPLAYERSLEFTIND"; diff --git a/functions/waverespawn/fn_startWaveLoops.sqf b/functions/waverespawn/fn_startWaveLoops.sqf index febafba..9cb84fe 100644 --- a/functions/waverespawn/fn_startWaveLoops.sqf +++ b/functions/waverespawn/fn_startWaveLoops.sqf @@ -8,7 +8,7 @@ if (WAVERESPAWNBLU) exitWith {}; //start countdown once first player is added to wave - if (count wavePlayernamesBlu > 0) then { + if (count wavePlayersBlu > 0) then { WAVERESPAWNTIMELEFTBLU = (WAVERESPAWNTIMELEFTBLU - 1) max 0; publicVariable "WAVERESPAWNTIMELEFTBLU"; } else { @@ -41,7 +41,7 @@ if (WAVERESPAWNOPF) exitWith {}; //start countdown once first player is added to wave - if (count wavePlayernamesOpf > 0) then { + if (count wavePlayersOpf > 0) then { WAVERESPAWNTIMELEFTOPF = (WAVERESPAWNTIMELEFTOPF - 1) max 0; publicVariable "WAVERESPAWNTIMELEFTOPF"; } else { @@ -74,7 +74,7 @@ if (WAVERESPAWNIND) exitWith {}; //start countdown once first player is added to wave - if (count wavePlayernamesInd > 0) then { + if (count wavePlayersInd > 0) then { WAVERESPAWNTIMELEFTIND = (WAVERESPAWNTIMELEFTIND - 1) max 0; publicVariable "WAVERESPAWNTIMELEFTIND"; } else { diff --git a/functions/waverespawn/fn_waveCountdown.sqf b/functions/waverespawn/fn_waveCountdown.sqf index c1de153..5e5a520 100644 --- a/functions/waverespawn/fn_waveCountdown.sqf +++ b/functions/waverespawn/fn_waveCountdown.sqf @@ -5,7 +5,7 @@ if (player getVariable "wr_isFreeRespawn") exitWith {player setVariable ["wr_wav INFO("Player countdown done. Starting wave countdown..."); -[profileName, playerSide] remoteExec ["grad_waverespawn_fnc_addToWave",2,false]; +[player,playerSide] remoteExec ["grad_waverespawn_fnc_addToWave",2,false]; [{ From b8c1143db042f1218026431801e01306e8e78411 Mon Sep 17 00:00:00 2001 From: McDiod Date: Tue, 20 Nov 2018 20:32:31 +0100 Subject: [PATCH 10/10] add prefixes to global vars in waverespawn component --- functions/waverespawn/fn_addToWaiting.sqf | 14 ++-- functions/waverespawn/fn_addToWave.sqf | 30 +++---- functions/waverespawn/fn_canRespawn.sqf | 12 +-- .../waverespawn/fn_checkEnoughForWave.sqf | 14 ++-- functions/waverespawn/fn_getStatus.sqf | 12 +-- functions/waverespawn/fn_init.sqf | 28 +++---- functions/waverespawn/fn_onPlayerKilled.sqf | 10 +-- functions/waverespawn/fn_onPlayerRespawn.sqf | 6 +- functions/waverespawn/fn_playerCountdown.sqf | 4 +- functions/waverespawn/fn_prepareRespawn.sqf | 4 +- functions/waverespawn/fn_pubVars.sqf | 60 ++++++------- functions/waverespawn/fn_removeFromWave.sqf | 26 +++--- functions/waverespawn/fn_resetPlayerVars.sqf | 26 +++--- functions/waverespawn/fn_respawnHint.sqf | 8 +- functions/waverespawn/fn_setWaveSize.sqf | 42 +++++----- functions/waverespawn/fn_startWaveLoops.sqf | 84 +++++++++---------- functions/waverespawn/fn_waveCountdown.sqf | 6 +- 17 files changed, 193 insertions(+), 193 deletions(-) diff --git a/functions/waverespawn/fn_addToWaiting.sqf b/functions/waverespawn/fn_addToWaiting.sqf index af93f77..3b77b26 100644 --- a/functions/waverespawn/fn_addToWaiting.sqf +++ b/functions/waverespawn/fn_addToWaiting.sqf @@ -2,15 +2,15 @@ params ["_deadPlayer",["_deadPlayerSide", sideUnknown],["_add",true]]; -if (isNil "waitingPlayersBlu") then {waitingPlayersBlu = []}; -if (isNil "waitingPlayersOpf") then {waitingPlayersOpf = []}; -if (isNil "waitingPlayersInd") then {waitingPlayersInd = []}; +if (isNil QGVAR(waitingPlayersBlu)) then {GVAR(waitingPlayersBlu) = []}; +if (isNil QGVAR(waitingPlayersOpf)) then {GVAR(waitingPlayersOpf) = []}; +if (isNil QGVAR(waitingPlayersInd)) then {GVAR(waitingPlayersInd) = []}; //add player to array private _array = switch (_deadPlayerSide) do { - case (WEST): {waitingPlayersBlu}; - case (EAST): {waitingPlayersOpf}; - case (INDEPENDENT): {waitingPlayersInd}; + case (WEST): {GVAR(waitingPlayersBlu)}; + case (EAST): {GVAR(waitingPlayersOpf)}; + case (INDEPENDENT): {GVAR(waitingPlayersInd)}; default {[]}; }; @@ -24,4 +24,4 @@ if (_add) then { }; }; -[_deadPlayerSide] call grad_waverespawn_fnc_checkEnoughForWave; +[_deadPlayerSide] call FUNC(checkEnoughForWave); diff --git a/functions/waverespawn/fn_addToWave.sqf b/functions/waverespawn/fn_addToWave.sqf index ba79ef8..3b04353 100644 --- a/functions/waverespawn/fn_addToWave.sqf +++ b/functions/waverespawn/fn_addToWave.sqf @@ -2,29 +2,29 @@ params ["_deadPlayer", ["_deadPlayerSide", sideUnknown]]; -if (isNil "wavePlayersBlu") then {wavePlayersBlu = []}; -if (isNil "wavePlayersOpf") then {wavePlayersOpf = []}; -if (isNil "wavePlayersInd") then {wavePlayersInd = []}; +if (isNil QGVAR(wavePlayersBlu)) then {GVAR(wavePlayersBlu) = []}; +if (isNil QGVAR(wavePlayersOpf)) then {GVAR(wavePlayersOpf) = []}; +if (isNil QGVAR(wavePlayersInd)) then {GVAR(wavePlayersInd) = []}; //add player to array switch (_deadPlayerSide) do { case (WEST): { - wavePlayersBlu pushBackUnique _deadPlayer; - INFO_2("Added player %1 to wavePlayersBlu. %2 dead blufor total.", _deadPlayer, count wavePlayersBlu); - WAVERESPAWNPLAYERSLEFTBLU = BLUFORWAVESIZE - (count wavePlayersBlu); - publicVariable "WAVERESPAWNPLAYERSLEFTBLU"; + GVAR(wavePlayersBlu) pushBackUnique _deadPlayer; + INFO_2("Added player %1 to wavePlayersBlu. %2 dead blufor total.", _deadPlayer, count GVAR(wavePlayersBlu)); + GVAR(WAVERESPAWNPLAYERSLEFTBLU) = GVAR(BLUFORWAVESIZE) - (count GVAR(wavePlayersBlu)); + publicVariable QGVAR(WAVERESPAWNPLAYERSLEFTBLU); }; case (EAST): { - wavePlayersOpf pushBackUnique _deadPlayer; - INFO_2("Added player %1 to wavePlayersOpf. %2 dead opfor total.", _deadPlayer, count wavePlayersOpf); - WAVERESPAWNPLAYERSLEFTOPF = OPFORWAVESIZE - (count wavePlayersOpf); - publicVariable "WAVERESPAWNPLAYERSLEFTOPF"; + GVAR(wavePlayersOpf) pushBackUnique _deadPlayer; + INFO_2("Added player %1 to wavePlayersOpf. %2 dead opfor total.", _deadPlayer, count GVAR(wavePlayersOpf)); + GVAR(WAVERESPAWNPLAYERSLEFTOPF) = GVAR(OPFORWAVESIZE) - (count GVAR(wavePlayersOpf)); + publicVariable QGVAR(WAVERESPAWNPLAYERSLEFTOPF); }; case (INDEPENDENT): { - wavePlayersInd pushBackUnique _deadPlayer; - INFO_2("Added player %1 to wavePlayersOpf. %2 dead opfor total.", _deadPlayer, count wavePlayersInd); - WAVERESPAWNPLAYERSLEFTIND = INDEPWAVESIZE - (count wavePlayersInd); - publicVariable "WAVERESPAWNPLAYERSLEFTIND"; + GVAR(wavePlayersInd) pushBackUnique _deadPlayer; + INFO_2("Added player %1 to wavePlayersOpf. %2 dead opfor total.", _deadPlayer, count GVAR(wavePlayersInd)); + GVAR(WAVERESPAWNPLAYERSLEFTIND) = GVAR(INDEPWAVESIZE) - (count GVAR(wavePlayersInd)); + publicVariable QGVAR(WAVERESPAWNPLAYERSLEFTIND); }; default { ERROR_1("Unknown side for player %1", _deadPlayer); diff --git a/functions/waverespawn/fn_canRespawn.sqf b/functions/waverespawn/fn_canRespawn.sqf index b36f145..e4a542a 100644 --- a/functions/waverespawn/fn_canRespawn.sqf +++ b/functions/waverespawn/fn_canRespawn.sqf @@ -4,16 +4,16 @@ params ["_side"]; _canRespawn = switch (_side) do { case ("WEST"): { - count wavePlayersBlu >= BLUFORWAVESIZE && - WAVERESPAWNTIMELEFTBLU <= 0 + count GVAR(wavePlayersBlu) >= GVAR(BLUFORWAVESIZE) && + GVAR(WAVERESPAWNTIMELEFTBLU) <= 0 }; case ("EAST"): { - count wavePlayersOpf >= OPFORWAVESIZE && - WAVERESPAWNTIMELEFTOPF <= 0 + count GVAR(wavePlayersOpf) >= GVAR(OPFORWAVESIZE) && + GVAR(WAVERESPAWNTIMELEFTOPF) <= 0 }; case ("INDEPENDENT"): { - count wavePlayersInd >= INDEPWAVESIZE && - WAVERESPAWNTIMELEFTIND <= 0 + count GVAR(wavePlayersInd) >= GVAR(INDEPWAVESIZE) && + GVAR(WAVERESPAWNTIMELEFTIND) <= 0 }; default { false diff --git a/functions/waverespawn/fn_checkEnoughForWave.sqf b/functions/waverespawn/fn_checkEnoughForWave.sqf index 56daf44..35383d7 100644 --- a/functions/waverespawn/fn_checkEnoughForWave.sqf +++ b/functions/waverespawn/fn_checkEnoughForWave.sqf @@ -6,9 +6,9 @@ params ["_side",["_iteration",0]]; private _waitingPlayersArray = switch (_side) do { - case (WEST): {waitingPlayersBlu}; - case (EAST): {waitingPlayersOpf}; - case (INDEPENDENT): {waitingPlayersInd}; + case (WEST): {GVAR(waitingPlayersBlu)}; + case (EAST): {GVAR(waitingPlayersOpf)}; + case (INDEPENDENT): {GVAR(waitingPlayersInd)}; default {[]}; }; @@ -22,14 +22,14 @@ if (_iteration == 2) exitWith { private _waveSize = switch (_side) do { - case (WEST): {BLUFORWAVESIZE}; - case (EAST): {OPFORWAVESIZE}; - case (INDEPENDENT): {INDEPWAVESIZE}; + case (WEST): {GVAR(BLUFORWAVESIZE)}; + case (EAST): {GVAR(OPFORWAVESIZE)}; + case (INDEPENDENT): {GVAR(INDEPWAVESIZE)}; default {-1}; }; if (_waveSize < 0) exitWith {}; if ((({side _x == _side} count playableUnits) + (count _waitingPlayersArray)) < _waveSize) then { - [grad_waverespawn_fnc_checkEnoughForWave,[_side,_iteration + 1],5] call CBA_fnc_waitAndExecute; + [FUNC(checkEnoughForWave),[_side,_iteration + 1],5] call CBA_fnc_waitAndExecute; }; diff --git a/functions/waverespawn/fn_getStatus.sqf b/functions/waverespawn/fn_getStatus.sqf index abd30cf..0d923d3 100644 --- a/functions/waverespawn/fn_getStatus.sqf +++ b/functions/waverespawn/fn_getStatus.sqf @@ -6,10 +6,10 @@ _status = ""; if (_side == WEST) then { _status = switch (true) do { - case (WAVERESPAWNTIMELEFTBLU > 0): { + case (GVAR(WAVERESPAWNTIMELEFTBLU) > 0): { "Waiting for wave-countdown."; }; - case (count wavePlayersBlu < BLUFORWAVESIZE): { + case (count GVAR(wavePlayersBlu) < GVAR(BLUFORWAVESIZE)): { "Waiting for more players."; }; default { @@ -20,10 +20,10 @@ if (_side == WEST) then { if (_side == EAST) then { _status = switch (true) do { - case (OPFORWAVESIZE > 0): { + case (GVAR(OPFORWAVESIZE) > 0): { "Waiting for wave-countdown."; }; - case (count wavePlayersOpf < OPFORWAVESIZE): { + case (count GVAR(wavePlayersOpf) < GVAR(OPFORWAVESIZE)): { "Waiting for more players."; }; default { @@ -34,10 +34,10 @@ if (_side == EAST) then { if (_side == INDEPENDENT) then { _status = switch (true) do { - case (INDEPWAVESIZE > 0): { + case (GVAR(INDEPWAVESIZE) > 0): { "Waiting for wave-countdown."; }; - case (count wavePlayersInd < INDEPWAVESIZE): { + case (count GVAR(wavePlayersInd) < GVAR(INDEPWAVESIZE)): { "Waiting for more players."; }; default { diff --git a/functions/waverespawn/fn_init.sqf b/functions/waverespawn/fn_init.sqf index d70f747..e99b1a8 100644 --- a/functions/waverespawn/fn_init.sqf +++ b/functions/waverespawn/fn_init.sqf @@ -2,28 +2,28 @@ if (([missionConfigFile >> "missionsettings","waveRespawnEnabled",0] call BIS_fnc_returnConfigEntry) == 0) exitWith {}; -wavePlayersBlu = []; -wavePlayersOpf = []; -wavePlayersInd = []; -waitingPlayersBlu = []; -waitingPlayersOpf = []; -waitingPlayersInd = []; -newBluSpawns = []; -newOpfSpawns = []; -newIndSpawns = []; +GVAR(wavePlayersBlu) = []; +GVAR(wavePlayersOpf) = []; +GVAR(wavePlayersInd) = []; +GVAR(waitingPlayersBlu) = []; +GVAR(waitingPlayersOpf) = []; +GVAR(waitingPlayersInd) = []; +GVAR(newBluSpawns) = []; +GVAR(newOpfSpawns) = []; +GVAR(newIndSpawns) = []; if (isServer) then { - [] call grad_waverespawn_fnc_setWaveSize; - [] call grad_waverespawn_fnc_startWaveLoops; + [] call FUNC(setWaveSize); + [] call FUNC(startWaveLoops); addMissionEventHandler ["HandleDisconnect", { params [["_unit",objNull]]; - [_unit,side _unit] call grad_waverespawn_fnc_removeFromWave; - [_unit,side _unit,false] call grad_waverespawn_fnc_addToWaiting; + [_unit,side _unit] call FUNC(removeFromWave); + [_unit,side _unit,false] call FUNC(addToWaiting); }]; }; if (hasInterface) then { player setVariable ["joinTime", serverTime]; player setVariable ["wr_respawnCount",0]; - [] call grad_waverespawn_fnc_resetPlayerVars; + [] call FUNC(resetPlayerVars); }; diff --git a/functions/waverespawn/fn_onPlayerKilled.sqf b/functions/waverespawn/fn_onPlayerKilled.sqf index 936be72..9a09f97 100644 --- a/functions/waverespawn/fn_onPlayerKilled.sqf +++ b/functions/waverespawn/fn_onPlayerKilled.sqf @@ -7,7 +7,7 @@ if (player getVariable ["wr_interrupted", false]) exitWith {}; -[] call grad_waverespawn_fnc_resetPlayerVars; +[] call FUNC(resetPlayerVars); //check JIP player is spawning for the first time private _joinTime = player getVariable ["joinTime", 0]; @@ -26,7 +26,7 @@ private _maxRespawns = switch (playerSide) do { if (player getVariable ["wr_respawnCount",0] >= _maxRespawns) then { player setVariable ["wr_interrupted",true,true] } else { - [player,playerSide] remoteExec ["grad_waverespawn_fnc_addToWaiting",2,false]; + [player,playerSide] remoteExec [QFUNC(addToWaiting),2,false]; }; INFO("Starting waverespawn procedure..."); @@ -36,6 +36,6 @@ player setVariable ["wr_respawnCount",(player getVariable ["wr_respawnCount",0]) setPlayerRespawnTime 99999; //do the steps -[CBA_missionTime] call grad_waverespawn_fnc_playerCountdown; -[{player getVariable "wr_playerCountdownDone"}, {_this call grad_waverespawn_fnc_waveCountdown}, [CBA_missionTime]] call CBA_fnc_waitUntilAndExecute; -[{player getVariable "wr_waveCountdownDone"}, {[] call grad_waverespawn_fnc_prepareRespawn}, []] call CBA_fnc_waitUntilAndExecute; +[CBA_missionTime] call FUNC(playerCountdown); +[{player getVariable "wr_playerCountdownDone"}, {_this call FUNC(waveCountdown)}, [CBA_missionTime]] call CBA_fnc_waitUntilAndExecute; +[{player getVariable "wr_waveCountdownDone"}, {[] call FUNC(prepareRespawn)}, []] call CBA_fnc_waitUntilAndExecute; diff --git a/functions/waverespawn/fn_onPlayerRespawn.sqf b/functions/waverespawn/fn_onPlayerRespawn.sqf index 31abc21..6594e05 100644 --- a/functions/waverespawn/fn_onPlayerRespawn.sqf +++ b/functions/waverespawn/fn_onPlayerRespawn.sqf @@ -2,11 +2,11 @@ params ["",["_oldUnit",objNull]]; -[_oldUnit,playerSide] remoteExec ["grad_waverespawn_fnc_removeFromWave",2,false]; -[_oldUnit,playerSide,false] remoteExec ["grad_waverespawn_fnc_addToWaiting",2,false]; +[_oldUnit,playerSide] remoteExec [QFUNC(removeFromWave),2,false]; +[_oldUnit,playerSide,false] remoteExec [QFUNC(addToWaiting),2,false]; setPlayerRespawnTime 99999; hint ""; -[] call grad_waverespawn_fnc_resetPlayerVars; +[] call FUNC(resetPlayerVars); diff --git a/functions/waverespawn/fn_playerCountdown.sqf b/functions/waverespawn/fn_playerCountdown.sqf index 250a9fb..7074c60 100644 --- a/functions/waverespawn/fn_playerCountdown.sqf +++ b/functions/waverespawn/fn_playerCountdown.sqf @@ -20,7 +20,7 @@ INFO("Starting player countdown..."); INFO("Respawn interrupted."); }; - if (CBA_missionTime - _timeOfDeath > MAXRESPAWNTIME) then { + if (CBA_missionTime - _timeOfDeath > GVAR(MAXRESPAWNTIME)) then { [_this select 1] call CBA_fnc_removePerFrameHandler; player setVariable ["wr_isFreeRespawn", true]; player setVariable ["wr_playerCountdownDone", true]; @@ -29,7 +29,7 @@ INFO("Starting player countdown..."); _playerTimeLeft = (player getVariable "wr_playerRespawnTimeLeft") - 1; player setVariable ["wr_playerRespawnTimeLeft", _playerTimeLeft]; - [playerSide,"Waiting for player-countdown."] call grad_waverespawn_fnc_respawnHint; + [playerSide,"Waiting for player-countdown."] call FUNC(respawnHint); if (_playerTimeLeft <= 0) exitWith { [_this select 1] call CBA_fnc_removePerFrameHandler; diff --git a/functions/waverespawn/fn_prepareRespawn.sqf b/functions/waverespawn/fn_prepareRespawn.sqf index 9d78f65..1b7b651 100644 --- a/functions/waverespawn/fn_prepareRespawn.sqf +++ b/functions/waverespawn/fn_prepareRespawn.sqf @@ -12,10 +12,10 @@ if (player getVariable ["wr_interrupted", false]) exitWith { ["Terminate"] call BIS_fnc_EGSpectator; ["Initialize", [player, [WEST,EAST,INDEPENDENT], true]] call BIS_fnc_EGSpectator; - [player,playerSide,false] remoteExec ["grad_waverespawn_fnc_addToWaiting",2,false]; + [player,playerSide,false] remoteExec [QFUNC(addToWaiting),2,false]; _explanation = parseText format ["%1", "No respawn available."]; - [playerSide, _explanation] call grad_waverespawn_fnc_respawnHint; + [playerSide, _explanation] call FUNC(respawnHint); [{hint ""}, [], 3] call CBA_fnc_waitAndExecute; }; diff --git a/functions/waverespawn/fn_pubVars.sqf b/functions/waverespawn/fn_pubVars.sqf index d801700..e48e5de 100644 --- a/functions/waverespawn/fn_pubVars.sqf +++ b/functions/waverespawn/fn_pubVars.sqf @@ -2,36 +2,36 @@ if (([missionConfigFile >> "missionsettings","waveRespawnEnabled",0] call BIS_fnc_returnConfigEntry) == 0) exitWith {}; -WAVERESPAWNTIMEPLAYER = [missionConfigFile >> "missionsettings","waverespawntimePlayer",30] call BIS_fnc_returnConfigEntry; -WAVERESPAWNTIMEBLU = [missionConfigFile >> "missionsettings","waverespawntimeBlu",30] call BIS_fnc_returnConfigEntry; -WAVERESPAWNTIMEOPF = [missionConfigFile >> "missionsettings","waverespawntimeOpf",30] call BIS_fnc_returnConfigEntry; -WAVERESPAWNTIMEIND = [missionConfigFile >> "missionsettings","waverespawntimeInd",30] call BIS_fnc_returnConfigEntry; +GVAR(WAVERESPAWNTIMEPLAYER) = [missionConfigFile >> "missionsettings","waverespawntimePlayer",30] call BIS_fnc_returnConfigEntry; +GVAR(WAVERESPAWNTIMEBLU) = [missionConfigFile >> "missionsettings","waverespawntimeBlu",30] call BIS_fnc_returnConfigEntry; +GVAR(WAVERESPAWNTIMEOPF) = [missionConfigFile >> "missionsettings","waverespawntimeOpf",30] call BIS_fnc_returnConfigEntry; +GVAR(WAVERESPAWNTIMEIND) = [missionConfigFile >> "missionsettings","waverespawntimeInd",30] call BIS_fnc_returnConfigEntry; -WAVERESPAWNBLU = false; -WAVERESPAWNOPF = false; -WAVERESPAWNIND = false; -WAVERESPAWNTIMELEFTBLU = WAVERESPAWNTIMEBLU; -WAVERESPAWNTIMELEFTOPF = WAVERESPAWNTIMEOPF; -WAVERESPAWNTIMELEFTIND = WAVERESPAWNTIMEIND; -MAXRESPAWNTIME = 1200; -RESPAWNWAVEEXTRATIME = 30; -WAVERESPAWNSTATUSBLU = ""; -WAVERESPAWNSTATUSOPF = ""; -WAVERESPAWNSTATUSIND = ""; +GVAR(WAVERESPAWNBLU) = false; +GVAR(WAVERESPAWNOPF) = false; +GVAR(WAVERESPAWNIND) = false; +GVAR(WAVERESPAWNTIMELEFTBLU) = GVAR(WAVERESPAWNTIMEBLU); +GVAR(WAVERESPAWNTIMELEFTOPF) = GVAR(WAVERESPAWNTIMEOPF); +GVAR(WAVERESPAWNTIMELEFTIND) = GVAR(WAVERESPAWNTIMEIND); +GVAR(MAXRESPAWNTIME) = 1200; +GVAR(RESPAWNWAVEEXTRATIME) = 30; +GVAR(WAVERESPAWNSTATUSBLU) = ""; +GVAR(WAVERESPAWNSTATUSOPF) = ""; +GVAR(WAVERESPAWNSTATUSIND) = ""; -publicVariable "WAVERESPAWNTIMEPLAYER"; -publicVariable "WAVERESPAWNTIMEBLU"; -publicVariable "WAVERESPAWNTIMEOPF"; -publicVariable "WAVERESPAWNTIMEIND"; +publicVariable QGVAR(WAVERESPAWNTIMEPLAYER); +publicVariable QGVAR(WAVERESPAWNTIMEBLU); +publicVariable QGVAR(WAVERESPAWNTIMEOPF); +publicVariable QGVAR(WAVERESPAWNTIMEIND); -publicVariable "WAVERESPAWNBLU"; -publicVariable "WAVERESPAWNOPF"; -publicVariable "WAVERESPAWNIND"; -publicVariable "WAVERESPAWNTIMELEFTBLU"; -publicVariable "WAVERESPAWNTIMELEFTOPF"; -publicVariable "WAVERESPAWNTIMELEFTIND"; -publicVariable "MAXRESPAWNTIME"; -publicVariable "RESPAWNWAVEEXTRATIME"; -publicVariable "WAVERESPAWNSTATUSBLU"; -publicVariable "WAVERESPAWNSTATUSOPF"; -publicVariable "WAVERESPAWNSTATUSIND"; +publicVariable QGVAR(WAVERESPAWNBLU); +publicVariable QGVAR(WAVERESPAWNOPF); +publicVariable QGVAR(WAVERESPAWNIND); +publicVariable QGVAR(WAVERESPAWNTIMELEFTBLU); +publicVariable QGVAR(WAVERESPAWNTIMELEFTOPF); +publicVariable QGVAR(WAVERESPAWNTIMELEFTIND); +publicVariable QGVAR(MAXRESPAWNTIME); +publicVariable QGVAR(RESPAWNWAVEEXTRATIME); +publicVariable QGVAR(WAVERESPAWNSTATUSBLU); +publicVariable QGVAR(WAVERESPAWNSTATUSOPF); +publicVariable QGVAR(WAVERESPAWNSTATUSIND); diff --git a/functions/waverespawn/fn_removeFromWave.sqf b/functions/waverespawn/fn_removeFromWave.sqf index e97110c..4566d7e 100644 --- a/functions/waverespawn/fn_removeFromWave.sqf +++ b/functions/waverespawn/fn_removeFromWave.sqf @@ -4,8 +4,8 @@ params ["_unit","_side"]; switch (_side) do { case (WEST): { - if (_unit in wavePlayersBlu) then { - wavePlayersBlu deleteAt (wavePlayersBlu find _unit); + if (_unit in GVAR(wavePlayersBlu)) then { + GVAR(wavePlayersBlu) deleteAt (GVAR(wavePlayersBlu) find _unit); INFO_1("Player %1 respawned and has been removed from wavePlayersBlu.", _unit); } else { ERROR_1("Player %1 is not in wavePlayersBlu.", _unit); @@ -13,8 +13,8 @@ switch (_side) do { }; case (EAST): { - if (_unit in wavePlayersOpf) then { - wavePlayersOpf deleteAt (wavePlayersOpf find _unit); + if (_unit in GVAR(wavePlayersOpf)) then { + GVAR(wavePlayersOpf) deleteAt (GVAR(wavePlayersOpf) find _unit); INFO_1("Player %1 respawned and has been removed from wavePlayersOpf.", _unit); } else { ERROR_1("Player %1 is not in wavePlayersOpf", _unit); @@ -22,8 +22,8 @@ switch (_side) do { }; case (INDEPENDENT): { - if (_unit in wavePlayersInd) then { - wavePlayersInd deleteAt (wavePlayersInd find _unit); + if (_unit in GVAR(wavePlayersInd)) then { + GVAR(wavePlayersInd) deleteAt (GVAR(wavePlayersInd) find _unit); INFO_1("Player %1 respawned and has been removed from wavePlayersInd.", _unit); } else { ERROR_1("Player %1 is not in wavePlayersInd", _unit); @@ -34,10 +34,10 @@ switch (_side) do { }; [{ - WAVERESPAWNPLAYERSLEFTBLU = BLUFORWAVESIZE - (count wavePlayersBlu); - WAVERESPAWNPLAYERSLEFTOPF = OPFORWAVESIZE - (count wavePlayersOpf); - WAVERESPAWNPLAYERSLEFTIND = INDEPWAVESIZE - (count wavePlayersInd); - publicVariable "WAVERESPAWNPLAYERSLEFTBLU"; - publicVariable "WAVERESPAWNPLAYERSLEFTOPF"; - publicVariable "WAVERESPAWNPLAYERSLEFTIND"; -}, [], (RESPAWNWAVEEXTRATIME max 7)] call CBA_fnc_waitAndExecute; + GVAR(WAVERESPAWNPLAYERSLEFTBLU) = GVAR(BLUFORWAVESIZE) - (count GVAR(wavePlayersBlu)); + GVAR(WAVERESPAWNPLAYERSLEFTOPF) = GVAR(OPFORWAVESIZE) - (count GVAR(wavePlayersOpf)); + GVAR(WAVERESPAWNPLAYERSLEFTIND) = GVAR(INDEPWAVESIZE) - (count GVAR(wavePlayersInd)); + publicVariable QGVAR(WAVERESPAWNPLAYERSLEFTBLU); + publicVariable QGVAR(WAVERESPAWNPLAYERSLEFTOPF); + publicVariable QGVAR(WAVERESPAWNPLAYERSLEFTIND); +}, [], (GVAR(RESPAWNWAVEEXTRATIME) max 7)] call CBA_fnc_waitAndExecute; diff --git a/functions/waverespawn/fn_resetPlayerVars.sqf b/functions/waverespawn/fn_resetPlayerVars.sqf index 0ad6a8d..de78df1 100644 --- a/functions/waverespawn/fn_resetPlayerVars.sqf +++ b/functions/waverespawn/fn_resetPlayerVars.sqf @@ -2,32 +2,32 @@ switch (playerSide) do { case (WEST): { - player setVariable ["wr_waitCondition", {!WAVERESPAWNBLU}]; + player setVariable ["wr_waitCondition", {!GVAR(WAVERESPAWNBLU)}]; player setVariable ["wr_interruptCondition", compile ([missionConfigFile >> "missionsettings","bluforInterruptCondition","false"] call BIS_fnc_returnConfigEntry)]; - player setVariable ["wr_playersLeft", {WAVERESPAWNPLAYERSLEFTBLU}]; - player setVariable ["wr_waveTimeLeft", {WAVERESPAWNTIMELEFTBLU}]; - player setVariable ["wr_waveSize", {BLUFORWAVESIZE}]; + player setVariable ["wr_playersLeft", {GVAR(WAVERESPAWNPLAYERSLEFTBLU)}]; + player setVariable ["wr_waveTimeLeft", {GVAR(WAVERESPAWNTIMELEFTBLU)}]; + player setVariable ["wr_waveSize", {GVAR(BLUFORWAVESIZE)}]; }; case (EAST): { - player setVariable ["wr_waitCondition", {!WAVERESPAWNOPF}]; + player setVariable ["wr_waitCondition", {!GVAR(WAVERESPAWNOPF)}]; player setVariable ["wr_interruptCondition", compile ([missionConfigFile >> "missionsettings","opforInterruptCondition","false"] call BIS_fnc_returnConfigEntry)]; - player setVariable ["wr_playersLeft", {WAVERESPAWNPLAYERSLEFTOPF}]; - player setVariable ["wr_waveTimeLeft", {WAVERESPAWNTIMELEFTOPF}]; - player setVariable ["wr_waveSize", {OPFORWAVESIZE}]; + player setVariable ["wr_playersLeft", {GVAR(WAVERESPAWNPLAYERSLEFTOPF)}]; + player setVariable ["wr_waveTimeLeft", {GVAR(WAVERESPAWNTIMELEFTOPF)}]; + player setVariable ["wr_waveSize", {GVAR(OPFORWAVESIZE)}]; }; case (INDEPENDENT): { - player setVariable ["wr_waitCondition", {!WAVERESPAWNIND}]; + player setVariable ["wr_waitCondition", {!GVAR(WAVERESPAWNIND)}]; player setVariable ["wr_interruptCondition", compile ([missionConfigFile >> "missionsettings","indepInterruptCondition","false"] call BIS_fnc_returnConfigEntry)]; - player setVariable ["wr_playersLeft", {WAVERESPAWNPLAYERSLEFTIND}]; - player setVariable ["wr_waveTimeLeft", {WAVERESPAWNTIMELEFTIND}]; - player setVariable ["wr_waveSize", {INDEPWAVESIZE}]; + player setVariable ["wr_playersLeft", {GVAR(WAVERESPAWNPLAYERSLEFTIND)}]; + player setVariable ["wr_waveTimeLeft", {GVAR(WAVERESPAWNTIMELEFTIND)}]; + player setVariable ["wr_waveSize", {GVAR(INDEPWAVESIZE)}]; }; default { ERROR_1("Playerside is %1",playerSide); }; }; -player setVariable ["wr_playerRespawnTimeLeft", WAVERESPAWNTIMEPLAYER]; +player setVariable ["wr_playerRespawnTimeLeft", GVAR(WAVERESPAWNTIMEPLAYER)]; player setVariable ["wr_interrupted", false]; player setVariable ["wr_isFreeRespawn", false]; player setVariable ["wr_playerCountdownDone", false]; diff --git a/functions/waverespawn/fn_respawnHint.sqf b/functions/waverespawn/fn_respawnHint.sqf index 4b25654..fbf2625 100644 --- a/functions/waverespawn/fn_respawnHint.sqf +++ b/functions/waverespawn/fn_respawnHint.sqf @@ -11,9 +11,9 @@ _lineBreak = parseText "
"; if (isNil "_status") then { _status = switch (_side) do { - case (WEST): {WAVERESPAWNSTATUSBLU}; - case (EAST): {WAVERESPAWNSTATUSOPF}; - case (INDEPENDENT): {WAVERESPAWNSTATUSIND}; + case (WEST): {GVAR(WAVERESPAWNSTATUSBLU)}; + case (EAST): {GVAR(WAVERESPAWNSTATUSOPF)}; + case (INDEPENDENT): {GVAR(WAVERESPAWNSTATUSIND)}; default {"ERROR - UNKOWN SIDE"}; }; }; @@ -29,7 +29,7 @@ _playersLeft = call (player getVariable "wr_playersLeft"); _waveSize = call (player getVariable "wr_waveSize"); _waveLeftStr = parseText format ["Wave: %1/%2 - %5", _waveSize - _playersLeft, _waveSize, if (_playersLeft > 0) then {'#ffff00'} else {'#00ff00'},if (_waveTimeLeft > 0) then {'#ffff00'} else {'#00ff00'}, _timeLeftStr]; -_maxTime = parseText format ["Skipping waiting time in: %1.", [MAXRESPAWNTIME - (time - (player getVariable ["wr_timeOfDeath",time])),"MM:SS"] call BIS_fnc_secondsToString]; +_maxTime = parseText format ["Skipping waiting time in: %1.", [GVAR(MAXRESPAWNTIME) - (time - (player getVariable ["wr_timeOfDeath",time])),"MM:SS"] call BIS_fnc_secondsToString]; _hintArray = [ diff --git a/functions/waverespawn/fn_setWaveSize.sqf b/functions/waverespawn/fn_setWaveSize.sqf index f117bdc..c07c284 100644 --- a/functions/waverespawn/fn_setWaveSize.sqf +++ b/functions/waverespawn/fn_setWaveSize.sqf @@ -4,35 +4,35 @@ #include "component.hpp" -BLUFORWAVESIZE = [missionConfigFile >> "missionsettings","bluforWaveSize",1] call BIS_fnc_returnConfigEntry; -OPFORWAVESIZE = [missionConfigFile >> "missionsettings","opforWaveSize",1] call BIS_fnc_returnConfigEntry; -INDEPWAVESIZE = [missionConfigFile >> "missionsettings","indepWaveSize",1] call BIS_fnc_returnConfigEntry; +GVAR(BLUFORWAVESIZE) = [missionConfigFile >> "missionsettings","bluforWaveSize",1] call BIS_fnc_returnConfigEntry; +GVAR(OPFORWAVESIZE) = [missionConfigFile >> "missionsettings","opforWaveSize",1] call BIS_fnc_returnConfigEntry; +GVAR(INDEPWAVESIZE) = [missionConfigFile >> "missionsettings","indepWaveSize",1] call BIS_fnc_returnConfigEntry; _allPlayers = [] call BIS_fnc_listPlayers; -if (BLUFORWAVESIZE < 0) then { +if (GVAR(BLUFORWAVESIZE) < 0) then { _teamSize = west countside _allPlayers; - BLUFORWAVESIZE = (ceil ((_teamSize / 3) - 0.5)) max 1; + GVAR(BLUFORWAVESIZE) = (ceil ((_teamSize / 3) - 0.5)) max 1; }; -if (INDEPWAVESIZE < 0) then { +if (GVAR(INDEPWAVESIZE) < 0) then { _teamSize = independent countside _allPlayers; - INDEPWAVESIZE = (ceil ((_teamSize / 3) - 0.5)) max 1; + GVAR(INDEPWAVESIZE) = (ceil ((_teamSize / 3) - 0.5)) max 1; }; -if (OPFORWAVESIZE < 0) then { +if (GVAR(OPFORWAVESIZE) < 0) then { _teamSize = east countside _allPlayers; - OPFORWAVESIZE = (ceil ((_teamSize / 3) - 0.5)) max 1; + GVAR(OPFORWAVESIZE) = (ceil ((_teamSize / 3) - 0.5)) max 1; }; -WAVERESPAWNPLAYERSLEFTBLU = BLUFORWAVESIZE; -WAVERESPAWNPLAYERSLEFTOPF = OPFORWAVESIZE; -WAVERESPAWNPLAYERSLEFTIND = INDEPWAVESIZE; +GVAR(WAVERESPAWNPLAYERSLEFTBLU) = GVAR(BLUFORWAVESIZE); +GVAR(WAVERESPAWNPLAYERSLEFTOPF) = GVAR(OPFORWAVESIZE); +GVAR(WAVERESPAWNPLAYERSLEFTIND) = GVAR(INDEPWAVESIZE); -publicVariable "BLUFORWAVESIZE"; -publicVariable "OPFORWAVESIZE"; -publicVariable "INDEPWAVESIZE"; -publicVariable "WAVERESPAWNPLAYERSLEFTBLU"; -publicVariable "WAVERESPAWNPLAYERSLEFTOPF"; -publicVariable "WAVERESPAWNPLAYERSLEFTIND"; +publicVariable QGVAR(BLUFORWAVESIZE); +publicVariable QGVAR(OPFORWAVESIZE); +publicVariable QGVAR(INDEPWAVESIZE); +publicVariable QGVAR(WAVERESPAWNPLAYERSLEFTBLU); +publicVariable QGVAR(WAVERESPAWNPLAYERSLEFTOPF); +publicVariable QGVAR(WAVERESPAWNPLAYERSLEFTIND); -INFO_1("Blufor wave size is %1", BLUFORWAVESIZE); -INFO_1("Independent wave size is %1", INDEPWAVESIZE); -INFO_1("Opfor wave size is %1", OPFORWAVESIZE); +INFO_1("Blufor wave size is %1", GVAR(BLUFORWAVESIZE)); +INFO_1("Independent wave size is %1", GVAR(INDEPWAVESIZE)); +INFO_1("Opfor wave size is %1", GVAR(OPFORWAVESIZE)); diff --git a/functions/waverespawn/fn_startWaveLoops.sqf b/functions/waverespawn/fn_startWaveLoops.sqf index 9cb84fe..857a018 100644 --- a/functions/waverespawn/fn_startWaveLoops.sqf +++ b/functions/waverespawn/fn_startWaveLoops.sqf @@ -2,98 +2,98 @@ //BLUFOR ======================================================================= [{ - ["WAVERESPAWNSTATUSBLU",[WEST] call grad_waverespawn_fnc_getStatus] call CBA_fnc_publicVariable; + [QGVAR(WAVERESPAWNSTATUSBLU),[WEST] call FUNC(getStatus)] call CBA_fnc_publicVariable; //dont execute while respawning is possible - if (WAVERESPAWNBLU) exitWith {}; + if (GVAR(WAVERESPAWNBLU)) exitWith {}; //start countdown once first player is added to wave - if (count wavePlayersBlu > 0) then { - WAVERESPAWNTIMELEFTBLU = (WAVERESPAWNTIMELEFTBLU - 1) max 0; - publicVariable "WAVERESPAWNTIMELEFTBLU"; + if (count GVAR(wavePlayersBlu) > 0) then { + GVAR(WAVERESPAWNTIMELEFTBLU) = (GVAR(WAVERESPAWNTIMELEFTBLU) - 1) max 0; + publicVariable QGVAR(WAVERESPAWNTIMELEFTBLU); } else { - ["WAVERESPAWNTIMELEFTBLU",WAVERESPAWNTIMEBLU] call CBA_fnc_publicVariable; + [QGVAR(WAVERESPAWNTIMELEFTBLU),GVAR(WAVERESPAWNTIMEBLU)] call CBA_fnc_publicVariable; }; //enable respawning when wave is full - if (["WEST"] call grad_waverespawn_fnc_canRespawn) then { + if (["WEST"] call FUNC(canRespawn)) then { - WAVERESPAWNBLU = true; - publicVariable "WAVERESPAWNBLU"; + GVAR(WAVERESPAWNBLU) = true; + publicVariable QGVAR(WAVERESPAWNBLU); INFO("Respawning now possible for Blufor."); [{ - WAVERESPAWNBLU = false; - publicVariable "WAVERESPAWNBLU"; - WAVERESPAWNTIMELEFTBLU = WAVERESPAWNTIMEBLU; - publicVariable "WAVERESPAWNTIMELEFTBLU"; + GVAR(WAVERESPAWNBLU) = false; + publicVariable QGVAR(WAVERESPAWNBLU); + GVAR(WAVERESPAWNTIMELEFTBLU) = GVAR(WAVERESPAWNTIMEBLU); + publicVariable QGVAR(WAVERESPAWNTIMELEFTBLU); INFO("Respawning no longer possible for Blufor."); - },[],(RESPAWNWAVEEXTRATIME max 7)] call CBA_fnc_waitAndExecute; + },[],(GVAR(RESPAWNWAVEEXTRATIME) max 7)] call CBA_fnc_waitAndExecute; }; }, 1, []] call CBA_fnc_addPerFrameHandler; //OPFOR ======================================================================== [{ - ["WAVERESPAWNSTATUSOPF",[EAST] call grad_waverespawn_fnc_getStatus] call CBA_fnc_publicVariable; + [QGVAR(WAVERESPAWNSTATUSOPF),[EAST] call FUNC(getStatus)] call CBA_fnc_publicVariable; //dont execute while respawning is possible - if (WAVERESPAWNOPF) exitWith {}; + if (GVAR(WAVERESPAWNOPF)) exitWith {}; //start countdown once first player is added to wave - if (count wavePlayersOpf > 0) then { - WAVERESPAWNTIMELEFTOPF = (WAVERESPAWNTIMELEFTOPF - 1) max 0; - publicVariable "WAVERESPAWNTIMELEFTOPF"; + if (count GVAR(wavePlayersOpf) > 0) then { + GVAR(WAVERESPAWNTIMELEFTOPF) = (GVAR(WAVERESPAWNTIMELEFTOPF) - 1) max 0; + publicVariable QGVAR(WAVERESPAWNTIMELEFTOPF); } else { - ["WAVERESPAWNTIMELEFTOPF",WAVERESPAWNTIMEOPF] call CBA_fnc_publicVariable; + [QGVAR(WAVERESPAWNTIMELEFTOPF),GVAR(WAVERESPAWNTIMEOPF)] call CBA_fnc_publicVariable; }; //enable respawning when wave is full - if (["EAST"] call grad_waverespawn_fnc_canRespawn) then { + if (["EAST"] call FUNC(canRespawn)) then { - WAVERESPAWNOPF = true; - publicVariable "WAVERESPAWNOPF"; + GVAR(WAVERESPAWNOPF) = true; + publicVariable QGVAR(WAVERESPAWNOPF); INFO("Respawning now possible for Opfor."); [{ - WAVERESPAWNOPF = false; - publicVariable "WAVERESPAWNOPF"; - WAVERESPAWNTIMELEFTOPF = WAVERESPAWNTIMEOPF; - publicVariable "WAVERESPAWNTIMELEFTOPF"; + GVAR(WAVERESPAWNOPF) = false; + publicVariable QGVAR(WAVERESPAWNOPF); + GVAR(WAVERESPAWNTIMELEFTOPF) = GVAR(WAVERESPAWNTIMEOPF); + publicVariable QGVAR(WAVERESPAWNTIMELEFTOPF); INFO("Respawning no longer possible for Opfor."); - },[],(RESPAWNWAVEEXTRATIME max 7)] call CBA_fnc_waitAndExecute; + },[],(GVAR(RESPAWNWAVEEXTRATIME) max 7)] call CBA_fnc_waitAndExecute; }; }, 1, []] call CBA_fnc_addPerFrameHandler; //INDEP ======================================================================== [{ - ["WAVERESPAWNSTATUSIND",[INDEPENDENT] call grad_waverespawn_fnc_getStatus] call CBA_fnc_publicVariable; + [QGVAR(WAVERESPAWNSTATUSIND),[INDEPENDENT] call FUNC(getStatus)] call CBA_fnc_publicVariable; //dont execute while respawning is possible - if (WAVERESPAWNIND) exitWith {}; + if (GVAR(WAVERESPAWNIND)) exitWith {}; //start countdown once first player is added to wave - if (count wavePlayersInd > 0) then { - WAVERESPAWNTIMELEFTIND = (WAVERESPAWNTIMELEFTIND - 1) max 0; - publicVariable "WAVERESPAWNTIMELEFTIND"; + if (count GVAR(wavePlayersInd) > 0) then { + GVAR(WAVERESPAWNTIMELEFTIND) = (GVAR(WAVERESPAWNTIMELEFTIND) - 1) max 0; + publicVariable QGVAR(WAVERESPAWNTIMELEFTIND); } else { - ["WAVERESPAWNTIMELEFTIND",WAVERESPAWNTIMEIND] call CBA_fnc_publicVariable; + [QGVAR(WAVERESPAWNTIMELEFTIND),GVAR(WAVERESPAWNTIMEIND)] call CBA_fnc_publicVariable; }; //enable respawning when wave is full - if (["INDEPENDENT"] call grad_waverespawn_fnc_canRespawn) then { + if (["INDEPENDENT"] call FUNC(canRespawn)) then { - WAVERESPAWNIND = true; - publicVariable "WAVERESPAWNIND"; + GVAR(WAVERESPAWNIND) = true; + publicVariable QGVAR(WAVERESPAWNIND); INFO("Respawning now possible for Independent."); [{ - WAVERESPAWNIND = false; - publicVariable "WAVERESPAWNIND"; - WAVERESPAWNTIMELEFTIND = WAVERESPAWNTIMEIND; - publicVariable "WAVERESPAWNTIMELEFTIND"; + GVAR(WAVERESPAWNIND) = false; + publicVariable QGVAR(WAVERESPAWNIND); + GVAR(WAVERESPAWNTIMELEFTIND) = GVAR(WAVERESPAWNTIMEIND); + publicVariable QGVAR(WAVERESPAWNTIMELEFTIND); INFO("Respawning no longer possible for Independent."); - },[],(RESPAWNWAVEEXTRATIME max 7)] call CBA_fnc_waitAndExecute; + },[],(GVAR(RESPAWNWAVEEXTRATIME) max 7)] call CBA_fnc_waitAndExecute; }; }, 1, []] call CBA_fnc_addPerFrameHandler; diff --git a/functions/waverespawn/fn_waveCountdown.sqf b/functions/waverespawn/fn_waveCountdown.sqf index 5e5a520..c22be3c 100644 --- a/functions/waverespawn/fn_waveCountdown.sqf +++ b/functions/waverespawn/fn_waveCountdown.sqf @@ -5,7 +5,7 @@ if (player getVariable "wr_isFreeRespawn") exitWith {player setVariable ["wr_wav INFO("Player countdown done. Starting wave countdown..."); -[player,playerSide] remoteExec ["grad_waverespawn_fnc_addToWave",2,false]; +[player,playerSide] remoteExec [QFUNC(addToWave),2,false]; [{ @@ -20,7 +20,7 @@ INFO("Player countdown done. Starting wave countdown..."); }; //check max respawn time - if ((time - _timeOfDeath) > MAXRESPAWNTIME) then { + if ((time - _timeOfDeath) > GVAR(MAXRESPAWNTIME)) then { [_this select 1] call CBA_fnc_removePerFrameHandler; player setVariable ["wr_isFreeRespawn", true]; player setVariable ["wr_waveCountdownDone", true]; @@ -32,6 +32,6 @@ INFO("Player countdown done. Starting wave countdown..."); player setVariable ["wr_waveCountdownDone", true]; }; - [playerSide] call grad_waverespawn_fnc_respawnHint; + [playerSide] call FUNC(respawnHint); }, 1, _this] call CBA_fnc_addPerFrameHandler;