diff --git a/functions/CfgFunctions.hpp b/functions/CfgFunctions.hpp
index 04aa8f0..cd622c8 100644
--- a/functions/CfgFunctions.hpp
+++ b/functions/CfgFunctions.hpp
@@ -45,9 +45,14 @@ class milsim
};
class resupply {
+ class crateDefinitions {};
class createAmmoBox {};
- class createWeaponsBox {};
+ class createBox {};
+ class createCSWBox {};
+ class createLaunchersBox {};
class createMedicalBox {};
+ class createMortarBox {};
+ class createWeaponsBox {};
}
class ambience {
@@ -64,4 +69,35 @@ class milsim
class mapMarkerToString {}; //needs refactor
class stringToMapMarker {}; //needs refactor
};
+
+ class util
+ {
+ class getPlayerLogString {};
+ class addPlayerInfoToArray {};
+ class log {};
+ };
+};
+
+class milsim_reinsert {
+ class functions {
+ file = "functions\reinsert";
+ class getBaseName {};
+ class getNearestBase {};
+ };
+ class server {
+ file = "functions\reinsert\server";
+ class initServer { postInit = 1; };
+ class addToQueue {};
+ class globalShowQueue {};
+ class removeFromQueue {};
+ class returnReinsertQueueNotification {};
+ class validateQueue {};
+ };
+ class client {
+ file = "functions\reinsert\client";
+ class initClient { postInit = 1; };
+ class addAceSelfActions {};
+ class addCheckQueueSelfAction {};
+ class requestShowQueue {};
+ };
};
\ No newline at end of file
diff --git a/functions/client/fn_addZenModules.sqf b/functions/client/fn_addZenModules.sqf
index 72e5e2b..ec7ca94 100644
--- a/functions/client/fn_addZenModules.sqf
+++ b/functions/client/fn_addZenModules.sqf
@@ -5,35 +5,42 @@ if ( !hasInterface ) exitWith {};
"Create Resupply Box",
{
params [["_pos", [0,0,0], [[]], 3], ["_target", objNull, [objNull]]];
-
+ _keysSorted = keys milsim_resupply_crateDefinitions;
+ _keysSorted sort true;
+ _comboOptions = [];
+ _comboOptions resize (count _keysSorted);
+ for "_i" from 0 to (count _keysSorted) - 1 do {
+ private _definition = milsim_resupply_crateDefinitions get (_keysSorted select _i);
+ _comboOptions set [_i, [
+ _definition getOrDefault ["displayName", "ERROR"], // display name
+ _definition getOrDefault ["description", "No description"], // tooltip
+ _definition getOrDefault ["icon", "No icon"] // icon
+ ]];
+ };
+
[
"Resupply Box Options",
[
- [ "COMBO", "Box Type", [[1,2,3], [["Ammo"],["Weapons"],["Medical"]],0] ]
+ // [ "COMBO", "Box Type", [[1,2,3], [["Ammo"],["Weapons"],["Medical"]],0] ]
+ ["COMBO", "Box Type", [_keysSorted, _comboOptions, 0]]
],
{
params ["_dialog", "_args"];
- _dialog params ["_type"];
- _args params ["_pos", "_target"];
-
- switch (_type) do {
- case 1: {
- [_target, _pos] call milsim_fnc_createAmmoBox;
- };
- case 2: {
- [_target, _pos] call milsim_fnc_createWeaponsBox;
- };
- case 3: {
- [_target, _pos] call milsim_fnc_createMedicalBox;
- };
+ _dialog params ["_typeOptionSelected"];
+ _args params ["_pos", "_target", "_keysSorted"];
+
+
+ private _box = [_target, _typeOptionSelected, _pos] call milsim_fnc_createBox;
+ if (isNull _box) exitWith {
+ ["Resupply Box", "WARNING: Failed to locate or create box!"] call BIS_fnc_curatorHint;
};
+ ["Resupply Box", format["Created a %1 box", _typeOptionSelected]] call BIS_fnc_curatorHint;
},
{},
- [_pos, _target]
+ [_pos, _target, _options]
] call zen_dialog_fnc_create;
-
}
] call zen_custom_modules_fnc_register;
diff --git a/functions/client/fn_bindEventHandlers.sqf b/functions/client/fn_bindEventHandlers.sqf
index f04d505..075a86d 100644
--- a/functions/client/fn_bindEventHandlers.sqf
+++ b/functions/client/fn_bindEventHandlers.sqf
@@ -3,9 +3,12 @@ if ( !hasInterface ) exitWith {};
player addEventHandler["Respawn",
{
params ["_unit", "_corpse"];
- _killer = _corpse getVariable ["ace_medical_causeOfDeath", "#scripted"];
+ private _killer = _corpse getVariable ["ace_medical_causeOfDeath", "#scripted"];
if (_killer == "respawn_button") then {
- format["[MILSIM] (client) %1 was unconscious then clicked the respawn button", name _unit] remoteExec["diag_log", 0];
+ format[
+ "[MILSIM] (client) RESPAWNED WHILE UNCONSCIOUS %1",
+ [_unit] call milsim_fnc_getPlayerLogString
+ ] remoteExec["diag_log", 0];
// format["%1 was unconscious then clicked the respawn button", name _unit] remoteExec["systemChat", 0];
};
}
diff --git a/functions/fbcb2/fn_messageFBCB2AssetStatus.sqf b/functions/fbcb2/fn_messageFBCB2AssetStatus.sqf
index abfc739..6571a0b 100644
--- a/functions/fbcb2/fn_messageFBCB2AssetStatus.sqf
+++ b/functions/fbcb2/fn_messageFBCB2AssetStatus.sqf
@@ -11,7 +11,7 @@ _text = composeText [_text, parseText "Asset 60*5 && // only allow after 15 minutes
+ missionNamespace getVariable ["milsim_reinsert_setting_reinsertion_enabled", true] &&
+ (_baseDistance < _maxRangeToReady) &&
+ not (_player in (_existingQueue apply {_x#0}))
+ }
+] call ace_interact_menu_fnc_createAction;
+[_type, 1, ["ACE_SelfActions"], _fileForReinsertAction, true] call ace_interact_menu_fnc_addActionToClass;
+
+private _removeFileForReinsertAction = [
+ "milsim_reinsert_removeReinsertRequest",
+ "Remove Re-insert Request",
+ "\A3\ui_f\data\igui\cfg\simpleTasks\types\land_ca.paa",
+ { // statement
+ params ["_target", "_player", "_params"];
+ // send event to server
+ ["milsim_reinsert_removeReinsertRequest", [_player]] call CBA_fnc_serverEvent;
+ // notify player their request was rescinded
+ "Re-insert Request Rescinded" call CBA_fnc_notify;
+ },
+ { // condition
+ params ["_target", "_player", "_params"];
+ private _existingQueue = missionNamespace getVariable ["milsim_reinsert_reinsertionQueue", []];
+
+ // check if module is enabled, player is in the queue
+ // (serverTime - milsim_reinsert_missionStartServerTime) > 60*5 && // only allow after 15 minutes
+ missionNamespace getVariable ["milsim_reinsert_setting_reinsertion_enabled", true] &&
+ (_player in (_existingQueue apply {_x#0}))
+ }
+] call ace_interact_menu_fnc_createAction;
+[_type, 1, ["ACE_SelfActions"], _removeFileForReinsertAction, true] call ace_interact_menu_fnc_addActionToClass;
+
+private _classesActionsAddedTo = (localNamespace getVariable ["milsim_reinsert_fileForReinsertClassesAdded", []]);
+_classesActionsAddedTo pushBackUnique _type;
+localNamespace setVariable ["milsim_reinsert_fileForReinsertClassesAdded", _classesActionsAddedTo];
+
diff --git a/functions/reinsert/client/fn_addCheckQueueSelfAction.sqf b/functions/reinsert/client/fn_addCheckQueueSelfAction.sqf
new file mode 100644
index 0000000..5897b53
--- /dev/null
+++ b/functions/reinsert/client/fn_addCheckQueueSelfAction.sqf
@@ -0,0 +1,28 @@
+params ["_type"]; // string of the object's classname
+if (!(_type isKindOf "CAManBase")) exitWith {};
+
+if (
+ (localNamespace getVariable ["milsim_reinsert_checkReinsertQueueClassesAdded", []])
+ find _type != -1
+) exitWith {};
+
+private _checkReinsertQueueAction = [
+ "milsim_reinsert_checkReinsertQueue",
+ "[PILOT] Check Re-insert Queue",
+ "\A3\ui_f\data\igui\cfg\simpleTasks\types\land_ca.paa",
+ {
+ params ["_target", "_player", "_params"];
+ // request notification from the server
+ call milsim_reinsert_fnc_requestShowQueue;
+ // reset last check time
+ localNamespace setVariable ["milsim_reinsert_lastReinsertQueueCheck", diag_tickTime];
+ },
+ {
+ missionNamespace getVariable ["milsim_reinsert_setting_reinsertion_enabled", true]
+ } // always allow
+] call ace_interact_menu_fnc_createAction;
+[_type, 1, ["ACE_SelfActions"], _checkReinsertQueueAction, true] call ace_interact_menu_fnc_addActionToClass;
+
+private _classesActionsAddedTo = (localNamespace getVariable ["milsim_reinsert_checkReinsertQueueClassesAdded", []]);
+_classesActionsAddedTo pushBackUnique _type;
+localNamespace setVariable ["milsim_reinsert_checkReinsertQueueClassesAdded", _classesActionsAddedTo];
\ No newline at end of file
diff --git a/functions/reinsert/client/fn_initClient.sqf b/functions/reinsert/client/fn_initClient.sqf
new file mode 100644
index 0000000..cdee922
--- /dev/null
+++ b/functions/reinsert/client/fn_initClient.sqf
@@ -0,0 +1,53 @@
+if (!hasInterface) exitWith {};
+
+// ACE SELF-INTERACTIONS FOR FILING AND RESCINDING REINSERT REQUESTS NEAR BASE - ALL PLAYERS
+localNamespace setVariable ["milsim_reinsert_fileForReinsertClassesAdded", []];
+// add actions to current class
+[typeOf player] call milsim_reinsert_fnc_addAceSelfActions;
+// add actions to future classes
+["ace_interact_menu_newControllableObject", {
+ _this call milsim_reinsert_fnc_addAceSelfActions;
+}] call CBA_fnc_addEventHandler;
+
+/////////////////////////////////////////////////////
+// PILOTS ONLY
+// ACE SELF-INTERACTIONS FOR CHECKING REINSERT QUEUE - ONLY FOR PILOTS
+if ((typeOf player) in ["B_Helipilot_F", "B_helicrew_F"]) then {
+ localNamespace setVariable ["milsim_reinsert_checkReinsertQueueClassesAdded", []];
+ localNamespace setVariable ["milsim_reinsert_lastReinsertQueueCheck", diag_tickTime];
+
+ // add actions to current class
+ [typeOf player] call milsim_reinsert_fnc_addCheckQueueSelfAction;
+ // add actions to future classes
+ ["ace_interact_menu_newControllableObject", {
+ _this call milsim_reinsert_fnc_addCheckQueueSelfAction;
+ }] call CBA_fnc_addEventHandler;
+};
+/////////////////////////////////////////////////////
+
+
+// ADD TIMER FOR PILOTS - IF REINSERT LIST NOT CHECKED FOR 20 MINUTES, SHOW NOTIFICATION AUTOMATICALLY
+if ((typeOf player) in ["B_Helipilot_F", "B_helicrew_F"]) then {
+ [{
+ // if module not enabled and pilot forced check not enabled, exit
+ if (not (
+ missionNamespace getVariable ["milsim_reinsert_setting_reinsertion_enabled", true] &&
+ missionNamespace getVariable ["milsim_reinsert_setting_reinsertion_pilotForcedCheckEnabled", true]
+ )) exitWith {};
+
+ // if last check was less than X minutes ago, skip
+ private _lastCheck = localNamespace getVariable ["milsim_reinsert_lastReinsertQueueCheck", diag_tickTime];
+ private _requiredCheckInterval = missionNamespace getVariable ["milsim_reinsert_setting_reinsertion_pilotForcedCheckInterval", 60*20];
+ if (
+ diag_tickTime - _lastCheck <
+ _requiredCheckInterval
+ ) exitWith {}; // if last check was less than X minutes ago, skip
+
+ // last check was greater than X minutes ago
+ // reset last check time
+ localNamespace setVariable ["milsim_reinsert_lastReinsertQueueCheck", diag_tickTime];
+ // request notification from the server
+ call milsim_reinsert_fnc_requestShowQueue;
+ }, 30] call CBA_fnc_addPerFrameHandler;
+};
+/////////////////////////////////////////////////////
\ No newline at end of file
diff --git a/functions/reinsert/client/fn_requestShowQueue.sqf b/functions/reinsert/client/fn_requestShowQueue.sqf
new file mode 100644
index 0000000..1afed4e
--- /dev/null
+++ b/functions/reinsert/client/fn_requestShowQueue.sqf
@@ -0,0 +1,3 @@
+if (!hasInterface) exitWith {};
+
+[] remoteExec ["milsim_reinsert_fnc_returnReinsertQueueNotification", 2];
\ No newline at end of file
diff --git a/functions/reinsert/fn_getBaseName.sqf b/functions/reinsert/fn_getBaseName.sqf
new file mode 100644
index 0000000..ab2cbf8
--- /dev/null
+++ b/functions/reinsert/fn_getBaseName.sqf
@@ -0,0 +1,8 @@
+params [["_base", objNull, [objNull]]];
+if (_base == objNull) exitWith {""};
+
+// get base name
+private _baseName = _base getVariable ["name", ""];
+if (_baseName == "") then {_baseName = format["near %1", text (nearestLocation [_base, ["NameCity", "NameLocal"]])]};
+
+_baseName;
\ No newline at end of file
diff --git a/functions/reinsert/fn_getNearestBase.sqf b/functions/reinsert/fn_getNearestBase.sqf
new file mode 100644
index 0000000..049cc04
--- /dev/null
+++ b/functions/reinsert/fn_getNearestBase.sqf
@@ -0,0 +1,10 @@
+params [["_player", objNull, [objNull]]];
+if (isNull _player) exitWith {objNull};
+
+private _bases = missionNamespace getVariable ["milsim_reinsert_bases", []];
+if (count _bases == 0) exitWith {objNull};
+
+// get nearest base (Module_Respawn_F)
+private _closestBase = [_bases, _player] call BIS_fnc_nearestPosition;
+if (isNull _closestBase) exitWith {objNull};
+_closestBase;
\ No newline at end of file
diff --git a/functions/reinsert/server/fn_addToQueue.sqf b/functions/reinsert/server/fn_addToQueue.sqf
new file mode 100644
index 0000000..ce662d1
--- /dev/null
+++ b/functions/reinsert/server/fn_addToQueue.sqf
@@ -0,0 +1,56 @@
+params [
+ ["_player", objNull, [objNull]],
+ ["_base", objNull, [objNull]],
+ ["_timeFiled", diag_tickTime, [25]]
+];
+
+if (!isServer) exitWith {
+ [
+ "respawn_reinsertion",
+ "ATTEMPTED RUN ON CLIENT",
+ [
+ ["player", _player],
+ ["base", _base]
+ ]
+ ] call milsim_fnc_log;
+};
+if (
+ isNull _player ||
+ isNull _base
+) exitWith {
+ [
+ "respawn_reinsertion",
+ "NULL PARAMETERS",
+ [
+ ["player", _player],
+ ["base", _base]
+ ]
+ ] call milsim_fnc_log;
+};
+
+
+private _maxRangeToReady = missionNamespace getVariable ["milsim_reinsert_setting_reinsertion_maxRangeToReady", 400];
+// nearest base here is the same as the base sent
+private _nearestBase = _base;
+
+milsim_reinsert_reinsertionQueue pushBackUnique [
+ _player, _base, _timeFiled
+];
+// broadcast new list to all machines
+publicVariable "milsim_reinsert_reinsertionQueue";
+
+// log to rpt
+private _logParams = [
+ ["filedAtBase", [_base] call milsim_reinsert_fnc_getBaseName],
+ ["filedAtBaseDistance", _player distance _base],
+ ["closestBase", [_nearestBase] call milsim_reinsert_fnc_getBaseName],
+ ["closestBaseDistance", _player distance _nearestBase],
+ ["maxDistanceSetting", _maxRangeToReady],
+ ["inQueueDuration", diag_tickTime - _timeFiled]
+];
+_logParams = [_player, _logParams] call milsim_fnc_addPlayerInfoToArray;
+[
+ "respawn_reinsertion",
+ "PLAYER FILED REQUEST",
+ _logParams
+] call milsim_fnc_log;
\ No newline at end of file
diff --git a/functions/reinsert/server/fn_globalShowQueue.sqf b/functions/reinsert/server/fn_globalShowQueue.sqf
new file mode 100644
index 0000000..a85462e
--- /dev/null
+++ b/functions/reinsert/server/fn_globalShowQueue.sqf
@@ -0,0 +1,70 @@
+if (!isServer) exitWith {};
+
+// if at least 1 player in the queue has been waiting longer than the configured timeout, notify all players
+private _timeout = missionNamespace getVariable ["milsim_reinsert_setting_reinsertion_max_wait", 60*20]; // default 20 minutes
+private _timeoutPlayers = milsim_reinsert_reinsertionQueue select {
+ _x params ["_player", "_base", "_timeFiled"];
+ alive (_player) &&
+ (diag_tickTime - (_timeFiled)) > _timeout
+};
+if (count _timeoutPlayers > 0) then {
+ // GLOBAL CBA NOTIFY
+ private _playerLines = [["Players are still waiting for Re-insert!", 1.2, [1, 0.64, 0, 1]]];
+ private _maxRangeToReady = missionNamespace getVariable ["milsim_reinsert_setting_reinsertion_maxRangeToReady", 400];
+
+ // get base objects from queue
+ private _basesWithPeople = (missionNamespace getVariable ["milsim_reinsert_reinsertionQueue", []]) apply {_x#1};
+ // get unique base objects
+ private _basesWithPeople = _basesWithPeople arrayIntersect _basesWithPeople;
+
+ {
+ private _thisBase = _x;
+
+ // Add line for base name
+ _playerLines pushBack ([[_thisBase] call milsim_reinsert_fnc_getBaseName, 1, [0,1,0,1]]);
+
+ // Get players under this base
+ private _thisBasePlayers = _timeoutPlayers select {_x#1 isEqualTo _thisBase};
+ // sort _timeoutPlayers by time in queue, descending
+ _thisBasePlayers = [_thisBasePlayers, [], {
+ _x params ["_player", "_base", "_timeFiled"];
+ _timeFiled;
+ }, "DESCEND"] call BIS_fnc_sortBy;
+
+
+ { // for each player under this base, add a line
+ _x params ["_player", "_base", "_timeFiled"];
+ // get the closest base to the player
+ private _nearestBase = [_player] call milsim_reinsert_fnc_getNearestBase;
+
+ // add player to array of players under bases
+ _playerLines pushBack ([format [
+ "%1: %2 [%3]",
+ groupID (group (_player)),
+ name (_player),
+ [diag_tickTime - (_timeFiled), "MM:SS"] call BIS_fnc_secondsToString
+ ], 0.8, [0.8, 0.8, 0.8, 1]]);
+
+ // log to rpt
+ private _logParams = [
+ ["filedAtBase", [_base] call milsim_reinsert_fnc_getBaseName],
+ ["filedAtBaseDistance", _player distance _base],
+ ["closestBase", [_nearestBase] call milsim_reinsert_fnc_getBaseName],
+ ["closestBaseDistance", _player distance _nearestBase],
+ ["maxDistanceSetting", _maxRangeToReady],
+ ["inQueueDuration", diag_tickTime - _timeFiled]
+ ];
+ _logParams = [_player, _logParams] call milsim_fnc_addPlayerInfoToArray;
+ [
+ "respawn_reinsertion",
+ "PLAYER WAITING OVER TIMEOUT",
+ _logParams
+ ] call milsim_fnc_log;
+ } forEach _thisBasePlayers;
+ } forEach _basesWithPeople;
+
+ // SEND NOTIFY
+ _playerLines remoteExec ["CBA_fnc_notify", [0, -2] select isDedicated];
+ // RESET NOTIFICATION TIMER
+ milsim_reinsert_reinsertionOverTimeoutLastNotificationTime = diag_tickTime;
+};
\ No newline at end of file
diff --git a/functions/reinsert/server/fn_initServer.sqf b/functions/reinsert/server/fn_initServer.sqf
new file mode 100644
index 0000000..9dd329f
--- /dev/null
+++ b/functions/reinsert/server/fn_initServer.sqf
@@ -0,0 +1,50 @@
+// if a player files for reinsert using self-interaction
+// they're added to the queue along with their nearest base location and the time they filed
+// if a player's time in the queue exceeds the configured timeout, a message will be posted every 5 minutes on a cycle based around
+// the player's time in the queue stating how long they have been waiting, their name, and their group's name
+
+if (!isServer) exitWith {};
+
+// array of all respawn modules in the mission, used as 'base' locations for reinsertion
+milsim_reinsert_bases = allMissionObjects "ModuleRespawnPosition_F";
+publicVariable "milsim_reinsert_bases";
+
+// register queue
+milsim_reinsert_reinsertionQueue = [];
+publicVariable "milsim_reinsert_reinsertionQueue";
+
+
+// server mission start time
+milsim_reinsert_missionStartServerTime = serverTime;
+
+// FILE REQUEST CBA HANDLER
+["milsim_reinsert_fileReinsertRequest", {
+ params ["_player", "_base"];
+ [_player, _base] call milsim_reinsert_fnc_addToQueue;
+}] call CBA_fnc_addEventHandler;
+
+// REMOVE REQUEST CBA HANDLER
+["milsim_reinsert_removeReinsertRequest", {
+ params ["_player"];
+ [_player] call milsim_reinsert_fnc_removeFromQueue;
+}] call CBA_fnc_addEventHandler;
+
+
+// automated wait threshold timer
+milsim_reinsert_reinsertionOverTimeoutLastNotificationTime = 0;
+
+[{ // every 60 seconds
+
+ // validate queue
+ call milsim_reinsert_fnc_validateQueue;
+
+ // check if last overTimeout notification was sent more than X minutes ago
+ if (
+ diag_tickTime - milsim_reinsert_reinsertionOverTimeoutLastNotificationTime > 60*5
+ ) then {
+ // show global queue notification with any players that are over timeout
+ call milsim_reinsert_fnc_globalShowQueue;
+ };
+
+}, 60] call CBA_fnc_addPerFrameHandler;
+
diff --git a/functions/reinsert/server/fn_removeFromQueue.sqf b/functions/reinsert/server/fn_removeFromQueue.sqf
new file mode 100644
index 0000000..0e24679
--- /dev/null
+++ b/functions/reinsert/server/fn_removeFromQueue.sqf
@@ -0,0 +1,57 @@
+params [["_player", objNull, [objNull]]];
+
+if (!isServer) exitWith {
+ [
+ "respawn_reinsertion",
+ "ATTEMPTED RUN ON CLIENT",
+ [
+ ["player", _player]
+ ]
+ ] call milsim_fnc_log;
+};
+if (isNull _player) exitWith {
+ [
+ "respawn_reinsertion",
+ "NULL PARAMETERS",
+ [
+ ["player", _player]
+ ]
+ ] call milsim_fnc_log;
+};
+
+// get entries for this player from queue
+private _unitArrs = milsim_reinsert_reinsertionQueue select {_x#0 isEqualTo _player};
+// if player not in queue, skip
+if (count _unitArrs isEqualTo 0) exitWith {};
+
+private _maxRangeToReady = missionNamespace getVariable ["milsim_reinsert_setting_reinsertion_maxRangeToReady", 400];
+
+// remove player from queue
+milsim_reinsert_reinsertionQueue = milsim_reinsert_reinsertionQueue - _unitArrs;
+// broadcast new list to all machines
+publicVariable "milsim_reinsert_reinsertionQueue";
+
+// sort _unitArrs by time in queue, descending, to get longest wait (if for some reason there's a duplicate)
+[_unitArrs, [], {
+ _x#2
+}, "DESCEND"] call BIS_fnc_sortBy;
+
+// get first entry (longest wait)
+(_unitArrs#0) params ["_player", "_base", "_timeFiled"]; // _unitArr = [unit, base, timeInQueue]
+// get the closest base to the player
+private _nearestBase = [_player] call milsim_reinsert_fnc_getNearestBase;
+// log to rpt
+private _logParams = [
+ ["filedAtBase", [_base] call milsim_reinsert_fnc_getBaseName],
+ ["filedAtBaseDistance", _player distance _base],
+ ["closestBase", [_nearestBase] call milsim_reinsert_fnc_getBaseName],
+ ["closestBaseDistance", _player distance _nearestBase],
+ ["maxDistanceSetting", _maxRangeToReady],
+ ["inQueueDuration", diag_tickTime - _timeFiled]
+];
+_logParams = [_player, _logParams] call milsim_fnc_addPlayerInfoToArray;
+[
+ "respawn_reinsertion",
+ "PLAYER RESCINDED REQUEST",
+ _logParams
+] call milsim_fnc_log;
\ No newline at end of file
diff --git a/functions/reinsert/server/fn_returnReinsertQueueNotification.sqf b/functions/reinsert/server/fn_returnReinsertQueueNotification.sqf
new file mode 100644
index 0000000..d114ad2
--- /dev/null
+++ b/functions/reinsert/server/fn_returnReinsertQueueNotification.sqf
@@ -0,0 +1,109 @@
+/*
+ Function: milsim_reinsert_fnc_showReinsertQueueNotification
+
+ Description:
+ Designed to be remoteExecuted on the server. Will show a CBA notification on the remoteExecutedOwner's screen with the current reinsertion queue and log this occurrence in the server RPT.
+
+ Author: IndigoFox
+*/
+
+if (not isRemoteExecuted) exitWith {
+ diag_log text format ["[milsim] (respawn_reinsertion) SHOW QUEUE NOT REMOTE EXECUTED"];
+};
+if (not isServer) exitWith {
+ diag_log text format ["[milsim] (respawn_reinsertion) SHOW QUEUE NOT RUN ON SERVER"];
+};
+
+private _users = allUsers apply {getUserInfo _x} select {count _x > 0};
+private _userIndex = _users findIf {_x#1 isEqualTo remoteExecutedOwner};
+if (_userIndex isEqualTo -1) exitWith {
+ diag_log text format ["[milsim] (respawn_reinsertion) SHOW QUEUE USER NOT FOUND"];
+};
+private _userObject = _users select _userIndex select 10;
+if (isNull _userObject) exitWith {
+ diag_log text format ["[milsim] (respawn_reinsertion) SHOW QUEUE USER OBJECT NOT FOUND"];
+};
+
+// log to rpt
+private _logParams = [_userObject, []] call milsim_fnc_addPlayerInfoToArray;
+[
+ "respawn_reinsertion",
+ "SHOW QUEUE REQUESTED",
+ _logParams
+] call milsim_fnc_log;
+
+private _queue = missionNamespace getVariable ["milsim_reinsert_reinsertionQueue", []];
+// get base objects from queue
+private _basesWithPeople = (missionNamespace getVariable ["milsim_reinsert_reinsertionQueue", []]) apply {_x#1};
+// get unique base objects
+private _basesWithPeople = _basesWithPeople arrayIntersect _basesWithPeople;
+
+// text array to use in notification
+private _par = [["Players Awaiting Reinsert", 1.2, [1,0.64,0,1]]];
+
+if (count _basesWithPeople isEqualTo 0) then {
+ _par pushBack ["[QUEUE EMPTY]", 1, [1,1,1,1]];
+};
+
+// forEach _basesWithPeople
+{
+ private _thisBase = _x;
+ private _baseName = [_thisBase] call milsim_reinsert_fnc_getBaseName;
+
+ // generate player lines for this base
+ private _playerLines = _queue select {
+ _x#1 isEqualTo _thisBase
+ } apply {
+ _x params ["_player", "_base", "_timeFiled"];
+ [
+ format [
+ "%1: %2 [%3]",
+ groupId (group _player),
+ name _player,
+ [diag_tickTime - _timeFiled, "MM:SS"] call BIS_fnc_secondsToString
+ ],
+ 0.8,
+ [1,1,1,1]
+ ];
+ };
+
+ // determine suffix for player count based on count
+ private _playerCountText = "";
+ switch (count _playerLines) do {
+ case 0: {
+ _playerCountText = "No players";
+ };
+ case 1: {
+ _playerCountText = "1 player";
+ };
+ default {
+ _playerCountText = format ["%1 players", count _playerLines];
+ };
+ };
+
+ // add base name and player count to notification lines
+ _par pushBack [
+ format ["Location: %1 (%2)",
+ _baseName,
+ _playerCountText
+ ],
+ 1,
+ [0,1,0,1]
+ ];
+
+ // sort by text (first piece of text is group name)
+ _playerLines = [
+ _playerLines,
+ [],
+ {_x#0}
+ ] call BIS_fnc_sortBy;
+
+ // add to notification lines
+ {
+ _par pushBack _x;
+ } forEach _playerLines;
+} forEach _basesWithPeople;
+
+_par remoteExec ["CBA_fnc_notify", remoteExecutedOwner];
+
+true;
\ No newline at end of file
diff --git a/functions/reinsert/server/fn_validateQueue.sqf b/functions/reinsert/server/fn_validateQueue.sqf
new file mode 100644
index 0000000..9c59209
--- /dev/null
+++ b/functions/reinsert/server/fn_validateQueue.sqf
@@ -0,0 +1,57 @@
+// revalidate any players in the queue
+// compare their distance to the nearest base, and remove them if they're too far away (or dead)
+private _stillValid = [];
+private _maxRangeToReady = missionNamespace getVariable ["milsim_reinsert_setting_reinsertion_maxRangeToReady", 400];
+{
+ _x params ["_player", "_base", "_timeFiled"]; // _unitArr = [unit, baseName, timeInQueue]
+
+ private _distanceToOriginalBase = _player distance _base;
+ // get the closest base to the player
+ private _nearestBase = [_player] call milsim_reinsert_fnc_getNearestBase;
+ private _isCloseEnoughToAnyBase = (_player distance _nearestBase) < _maxRangeToReady;
+
+ if (not _isCloseEnoughToAnyBase || not (alive _player)) then {
+ // don't include player in updated queue
+ // log to rpt
+ private _logParams = [
+ ["filedAtBase", [_base] call milsim_reinsert_fnc_getBaseName],
+ ["filedAtBaseDistance", _player distance _base],
+ ["closestBase", [_nearestBase] call milsim_reinsert_fnc_getBaseName],
+ ["closestBaseDistance", _player distance _nearestBase],
+ ["maxDistanceSetting", _maxRangeToReady],
+ ["inQueueDuration", diag_tickTime - _timeFiled]
+ ];
+ _logParams = [_player, _logParams] call milsim_fnc_addPlayerInfoToArray;
+ [
+ "respawn_reinsertion",
+ "PLAYER DEQUEUED AUTOMATICALLY",
+ _logParams
+ ] call milsim_fnc_log;
+ // continue loop
+ continue
+ };
+
+ // include player in updated queue, and update their location to nearest base
+ _stillValid pushBackUnique [_player, _nearestBase, _timeFiled];
+ // if player's base has changed, log to rpt
+ if (_base != _nearestBase) then {
+ private _logParams = [
+ ["filedAtBase", [_base] call milsim_reinsert_fnc_getBaseName],
+ ["filedAtBaseDistance", _player distance _base],
+ ["closestBase", [_nearestBase] call milsim_reinsert_fnc_getBaseName],
+ ["closestBaseDistance", _player distance _nearestBase],
+ ["maxDistanceSetting", _maxRangeToReady],
+ ["inQueueDuration", diag_tickTime - _timeFiled]
+ ];
+ _logParams = [_player, _logParams] call milsim_fnc_addPlayerInfoToArray;
+ [
+ "respawn_reinsertion",
+ "PLAYER BASE WAS UPDATED",
+ _logParams
+ ] call milsim_fnc_log;
+ };
+} forEach milsim_reinsert_reinsertionQueue;
+
+// broadcast new list to all machines
+milsim_reinsert_reinsertionQueue = _stillValid;
+publicVariable "milsim_reinsert_reinsertionQueue";
\ No newline at end of file
diff --git a/functions/resupply/fn_crateDefinitions.sqf b/functions/resupply/fn_crateDefinitions.sqf
new file mode 100644
index 0000000..17bb3e8
--- /dev/null
+++ b/functions/resupply/fn_crateDefinitions.sqf
@@ -0,0 +1,201 @@
+milsim_resupply_crateDefinitions = createHashMapFromArray [
+ ["AMMO LIGHT", createHashMapFromArray [
+ ["className", "Box_Syndicate_Ammo_F"],
+ ["displayName", "Ammo Crate"],
+ ["description", "A crate containing general ammunition and equipment for an infantry squad."],
+ ["icon", "\A3\ui_f\data\igui\cfg\simpleTasks\types\rifle_ca.paa"],
+ ["items", createHashMapFromArray [
+ ["backpacks", []],
+ ["weapons", [
+ ["rhs_weap_M136",4],
+ ["rhs_weap_M136_hp",4],
+ ["rhs_weap_m72a7",2]
+ ]],
+ ["magazines", [
+ ["1Rnd_SmokePurple_Grenade_shell",12],
+ ["1Rnd_SmokeBlue_Grenade_shell",24],
+ ["1Rnd_SmokeOrange_Grenade_shell",12],
+ ["rhs_mag_M441_HE",25],
+ ["rhs_mag_M433_HEDP",15],
+ ["ACE_40mm_Flare_ir",12],
+ ["rhsusf_200Rnd_556x45_mixed_soft_pouch_coyote",25],
+ ["rhsusf_20Rnd_762x51_m993_Mag",25],
+ ["SmokeShell",12],
+ ["rhs_mag_m67",12],
+ ["1Rnd_Smoke_Grenade_shell",24],
+ ["1Rnd_SmokeRed_Grenade_shell",24],
+ ["1Rnd_SmokeGreen_Grenade_shell",24],
+ ["1Rnd_SmokeYellow_Grenade_shell",12],
+ ["Tier1_30Rnd_556x45_M856A1_EMag",25],
+ ["Tier1_30Rnd_556x45_Mk318Mod0_EMag",75],
+ ["ACE_30Rnd_65_Creedmor_mag",25],
+ ["SMA_30Rnd_762x35_BLK_EPR",25],
+ ["Tier1_30Rnd_762x35_300BLK_SMK_PMAG",25],
+ ["SMA_30Rnd_68x43_SPC_FMJ",25],
+ ["SMA_30Rnd_68x43_SPC_FMJ_Tracer",25],
+ ["SMA_20Rnd_762x51mm_M80A1_EPR",25],
+ ["SMA_20Rnd_762x51mm_M80A1_EPR_Tracer",25],
+ ["SMA_20Rnd_762x51mm_Mk316_Mod_0_Special_Long_Range",25],
+ ["SMA_20Rnd_762x51mm_Mk316_Mod_0_Special_Long_Range_Tracer",25],
+ ["Tier1_250Rnd_762x51_Belt_M993_AP",15],
+ ["ACE_20Rnd_762x51_Mag_Tracer",25],
+ ["ACE_20Rnd_762x51_M993_AP_Mag",25],
+ ["rhsusf_20Rnd_762x51_SR25_m993_Mag",25],
+ ["Tier1_20Rnd_762x51_M993_SR25_Mag",25],
+ ["Tier1_20Rnd_65x48_Creedmoor_SR25_Mag",25],
+ ["rhssaf_30rnd_556x45_EPR_G36", 25],
+ ["DemoCharge_Remote_Mag",16]
+ ]],
+ ["items", []]
+ ]
+ ]]],
+ ["AMMO HEAVY", createHashMapFromArray [
+ ["className", "Box_NATO_Wps_F"],
+ ["displayName", "Heavy Ammo Crate"],
+ ["description", "A crate containing mixed ammo for rifles, ARs, MAT, and HAT."],
+ ["icon", "\A3\ui_f\data\igui\cfg\simpleTasks\types\heli_ca.paa"],
+ ["items", createHashMapFromArray [
+ ["backpacks", []],
+ ["weapons", []],
+ ["magazines", [
+ ["MRAWS_HEAT_F",35],
+ ["MRAWS_HE_F",15],
+ ["Tier1_250Rnd_762x51_Belt_M993_AP",50],
+ ["Tier1_30Rnd_556x45_M856A1_EMag",25],
+ ["Tier1_30Rnd_556x45_Mk318Mod0_EMag",50],
+ ["Titan_AA",10],
+ ["Titan_AT",10],
+ ["200Rnd_65x39_cased_Box_Tracer_Red",50]
+ ]],
+ ["items", []]
+ ]
+ ]]],
+ ["AMMO MORTAR", createHashMapFromArray [
+ ["className", "Box_Syndicate_Wps_F"],
+ ["displayName", "Mortar Ammo Crate"],
+ ["description", "A crate containing mortar ammunition."],
+ ["icon", "\A3\ui_f\data\igui\cfg\simpleTasks\types\scout_ca.paa"],
+ ["items", createHashMapFromArray [
+ ["backpacks", []],
+ ["weapons", []],
+ ["magazines", [
+ ["ACE_1Rnd_82mm_Mo_HE",24],
+ ["ACE_1Rnd_82mm_Mo_Smoke",12],
+ ["ACE_1Rnd_82mm_Mo_Illum",12]
+ ]],
+ ["items", []]
+ ]
+ ]]],
+ ["MEDICAL", createHashMapFromArray [
+ ["className", "ACE_medicalSupplyCrate_advanced"],
+ ["displayName", "Medical Crate"],
+ ["description", "A crate containing medical supplies."],
+ ["icon", "\A3\ui_f\data\igui\cfg\simpleTasks\types\heal_ca.paa"],
+ ["items", createHashMapFromArray [
+ ["backpacks", []],
+ ["weapons", []],
+ ["magazines", []],
+ ["items", [
+ ["ACE_packingBandage",100],
+ ["ACE_elasticBandage",100],
+ ["ACE_tourniquet",48],
+ ["ACE_splint",48],
+ ["ACE_morphine",50],
+ ["ACE_epinephrine",50],
+ ["ACE_bloodIV",75],
+ ["ACE_bloodIV_500",50],
+ ["ACE_bloodIV_250",25],
+ ["ACE_quikclot",75],
+ ["ACE_personalAidKit", 5],
+ ["ACE_surgicalKit", 5]
+ ]]
+ ]
+ ]]],
+ ["LAUNCHERS", createHashMapFromArray [
+ ["className", "Box_NATO_WpsLaunch_F"],
+ ["displayName", "Launcher Crate"],
+ ["description", "A crate containing missile launchers and ammunition."],
+ ["icon", "\A3\ui_f\data\igui\cfg\simpleTasks\types\heli_ca.paa"],
+ ["items", createHashMapFromArray [
+ ["backpacks", [
+
+ ]],
+ ["weapons", [
+ ["launch_B_Titan_short_F",2],
+ ["launch_NLAW_F",2],
+ ["rhs_weap_fim92",2]
+ ]],
+ ["magazines", [
+ ["Titan_AA",6],
+ ["Titan_AT",6]
+ ]],
+ ["items", [
+
+ ]]
+ ]
+ ]]],
+ ["CSW", createHashMapFromArray [
+ ["className", "Box_NATO_Equip_F"],
+ ["displayName", "CSW Crate"],
+ ["description", "A crate containing backpacks that assemble into static weapons."],
+ ["icon", "\A3\ui_f\data\igui\cfg\simpleTasks\types\defend_ca.paa"],
+ ["items", createHashMapFromArray [
+ ["backpacks", [
+ ["RHS_M2_Gun_Bag",2],
+ ["RHS_M2_Tripod_Bag",2],
+ ["RHS_M2_MiniTripod_Bag",2],
+ ["rhs_Tow_Gun_Bag",2],
+ ["rhs_TOW_Tripod_Bag",2],
+ ["UK3CB_Static_M240_Elcan_Gun_Bag",2],
+ ["UK3CB_B_Static_M240_Elcan_Tripod_Low_Bag_US_D",2],
+ ["RHS_Mk19_Gun_Bag",2],
+ ["RHS_Mk19_Tripod_Bag",2]
+ ]],
+ ["weapons", []],
+ ["magazines", []],
+ ["items", []]
+ ]
+ ]]],
+ ["MORTAR MK6", createHashMapFromArray [
+ ["className", "Box_NATO_WpsSpecial_F"],
+ ["displayName", "Mortar MK6 Supply Crate"],
+ ["description", "A crate containing Mk6 mortar resupply (tubes) and tools."],
+ ["icon", "\A3\ui_f\data\igui\cfg\simpleTasks\types\scout_ca.paa"],
+ ["items", createHashMapFromArray [
+ ["backpacks", [
+ ["B_Mortar_01_support_F",3],
+ ["B_Mortar_01_weapon_F",6],
+ ["UK3CB_LSM_B_B_CARRYALL_RADIO_TIG_STRIPE_01",1]
+ ]],
+ ["weapons", [
+ ["ACE_Vector",2]
+ ]],
+ ["magazines", [
+ ["acex_intelitems_notepad",2]
+ ]],
+ ["items", [
+ ["ACE_artilleryTable",2],
+ ["ACE_RangeTable_82mm",2],
+ ["ACE_microDAGR",2],
+ ["ACE_MapTools",2]
+ ]]
+ ]
+ ]]],
+ ["MORTAR 60MM COMMANDO", createHashMapFromArray [
+ ["className", "Box_NATO_WpsSpecial_F"],
+ ["displayName", "Mortar 60mm Commando Supply Crate"],
+ ["description", "A crate containing COMMANDO 60mm mortar shells and some STANAGs."],
+ ["icon", "\A3\ui_f\data\igui\cfg\simpleTasks\types\scout_ca.paa"],
+ ["items", createHashMapFromArray [
+ ["backpacks", []],
+ ["weapons", []],
+ ["magazines", [
+ ["twc_2inch_he_1rnd",70],
+ ["twc_2inch_smoke_1rnd",15],
+ ["twc_2inch_illum_1rnd",15],
+ ["Tier1_30Rnd_556x45_Mk318Mod0_EMag",20]
+ ]],
+ ["items", []]
+ ]
+ ]]]
+];
\ No newline at end of file
diff --git a/functions/resupply/fn_createAmmoBox.sqf b/functions/resupply/fn_createAmmoBox.sqf
index 2e3f319..06da1f4 100644
--- a/functions/resupply/fn_createAmmoBox.sqf
+++ b/functions/resupply/fn_createAmmoBox.sqf
@@ -1,7 +1,7 @@
/*
* Author: Hizumi
*
- * Create Ammo resupply box for the 17th Batallion
+ * Create Ammo resupply box for the 17th Battalion
*
* Arguments:
* 0: Vehicle -