// 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 // execute for all if (isNil "milsim_respawn_setting_reinsertion_maxRangeToReady") then { // configured in CBA settings milsim_respawn_setting_reinsertion_maxRangeToReady = 400; // distance in meters from a base at which players can ready up for pickup. players removed from the queue if they move further away than this distance }; milsim_respawn_bases = allMissionObjects "ModuleRespawnPosition_F"; // array of all respawn modules in the mission // on the server, initialize the queue and register the CBA event handler by which players can ready up if (isServer) then { // register queue milsim_respawn_reinsertionQueue = []; publicVariable "milsim_respawn_reinsertionQueue"; milsim_respawn_reinsertionOverTimeoutLastNotificationTime = 0; // register event handlers ["milsim_respawn_fileReinsertRequest", { params ["_unit", "_closestBaseName", "_time"]; milsim_respawn_reinsertionQueue pushBackUnique [_unit, _closestBaseName, _time]; diag_log text format [ "[milsim] (respawn_reinsertion) ADDED name=%1 playerUID=%2 group=%3 filedAtBase=%4", name _unit, getPlayerUID _unit, groupId (group _unit), _closestBaseName ]; publicVariable "milsim_respawn_reinsertionQueue"; }] call CBA_fnc_addEventHandler; ["milsim_respawn_removeReinsertRequest", { params ["_unit"]; private _unitArrs = milsim_respawn_reinsertionQueue select {_x#0 isEqualTo _unit}; if (count _unitArrs isEqualTo 0) exitWith {}; milsim_respawn_reinsertionQueue = milsim_respawn_reinsertionQueue - _unitArrs; // sort _unitArrs by time in queue, descending [_unitArrs, [], { _x#2 }, "DESCEND"] call BIS_fnc_sortBy; (_unitArrs#0) params ["_unit", "_baseName", "_timeFiled"]; // _unitArr = [unit, baseName, timeInQueue] private _timeInQueue = diag_tickTime - (_timeFiled); diag_log text format ["[milsim] (respawn_reinsertion) REMOVED BY REQUEST name=%1 playerUID=%2 group=%3 filedAtBase=%4 inQueue=%5s", name _unit, getPlayerUID _unit, groupId (group _unit), _baseName, _timeInQueue ]; publicVariable "milsim_respawn_reinsertionQueue"; }] call CBA_fnc_addEventHandler; [{ // every 60 seconds, 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 = []; { _x params ["_player", "_baseName", "_timeFiled"]; // _unitArr = [unit, baseName, timeInQueue] private _nearestDistance = 99999; { private _baseLocation = _x; private _distanceFromBase = _player distance _baseLocation; if (_distanceFromBase < _nearestDistance) then { _nearestDistance = _distanceFromBase; }; } forEach milsim_respawn_bases; private _nearBase = _nearestDistance < milsim_respawn_setting_reinsertion_maxRangeToReady; if (_nearBase && alive _player) then { _stillValid pushBackUnique _x; } else { diag_log text format [ "[milsim] (respawn_reinsertion) REMOVED AUTOMATICALLY name=%1 playerUID=%2 group=%3 filedAtBase=%4 nearestBaseDistance=%5m inQueue=%6s", name _player, getPlayerUID _player, groupId (group _player), _baseName, _nearestDistance, diag_tickTime - _timeFiled ]; }; } forEach milsim_respawn_reinsertionQueue; // broadcast new list to all machines milsim_respawn_reinsertionQueue = _stillValid; publicVariable "milsim_respawn_reinsertionQueue"; // if at least 1 player in the queue has been waiting longer than the configured timeout, // show a notification to all players if the last notification was more than 5 minutes ago private _needNotification = diag_tickTime - milsim_respawn_reinsertionOverTimeoutLastNotificationTime > 60*5; // if last notification was more than 5 minutes ago if (_needNotification) then { private _timeout = missionNamespace getVariable ["milsim_respawn_setting_reinsertion_timeout", 60*20]; // default 20 minutes private _timeoutPlayers = milsim_respawn_reinsertionQueue select { alive (_x#0) && (diag_tickTime - (_x#2)) > _timeout }; if (count _timeoutPlayers > 0) then { // sort _timeoutPlayers by time in queue, descending _timeoutPlayers = [_timeoutPlayers, [], { _x#2 }, "DESCEND"] call BIS_fnc_sortBy; private _playerLines = [["Players are still waiting for Re-insert!"]]; { private _timeInQueue = diag_tickTime - (_x#2); private _groupId = groupID (group (_x#0)); _playerLines pushBack ([format [ "%1: %2 [%3]", _groupId, name (_x#0), [_timeInQueue, "MM:SS"] call BIS_fnc_secondsToString ], 0.8, [0.8, 0.8, 0.8, 1]]); } forEach _timeoutPlayers; _playerLines remoteExec ["CBA_fnc_notify", [0, -2] select isDedicated]; milsim_respawn_reinsertionOverTimeoutLastNotificationTime = diag_tickTime; diag_log text format [ "[milsim] (respawn_reinsertion) PLAYERS WAITING LONGER THAN %1s: %2", _timeout, _timeoutPlayers apply { format[ "%1: %2 [%3]", groupId (group (_x#0)), name (_x#0), diag_tickTime - (_x#2) ] } ]; }; }; }, 60] call CBA_fnc_addPerFrameHandler; }; // if a player, register the ACE self-interaction to ready up if (hasInterface) then { // ACE SELF-INTERACTIONS FOR FILING AND RESCINDING REINSERT REQUESTS NEAR BASE - ALL PLAYERS localNamespace setVariable ["milsim_respawn_fileForReinsertClassesAdded", []]; private _addReinsertRequestSelfActions = { params ["_type"]; // string of the object's classname if (!(_type isKindOf "CAManBase")) exitWith {}; if ( (localNamespace getVariable ["milsim_respawn_fileForReinsertClassesAdded", []]) find _type != -1 ) exitWith {}; private _fileForReinsertAction = [ "milsim_respawn_fileReinsertRequest", "File Re-insert Request", "\A3\ui_f\data\igui\cfg\simpleTasks\types\takeoff_ca.paa", { params ["_target", "_player", "_params"]; private _closestBase = [milsim_respawn_bases, _player] call BIS_fnc_nearestPosition; private _closestBaseName = _closestBase getVariable ["name", ""]; if (_closestBaseName == "") then {_closestBaseName = format["near %1", text (nearestLocation [_closestBase, ""])]}; ["milsim_respawn_fileReinsertRequest", [_player, _closestBaseName, diag_tickTime]] call CBA_fnc_serverEvent; [["Re-insert Request Filed"], [format["Pickup at %1", _closestBaseName]]] call CBA_fnc_notify; }, { params ["_target", "_player", "_params"]; private _closestBase = [milsim_respawn_bases, _player] call BIS_fnc_nearestPosition; missionNamespace getVariable ["milsim_respawn_setting_reinsertion_enabled", true] && (_player distance _closestBase < milsim_respawn_setting_reinsertion_maxRangeToReady) && not (_player in ((missionNamespace getVariable ["milsim_respawn_reinsertionQueue", []]) apply {_x#0})) } ] call ace_interact_menu_fnc_createAction; [_type, 1, ["ACE_SelfActions"], _fileForReinsertAction, true] call ace_interact_menu_fnc_addActionToClass; private _removeFileForReinsertAction = [ "milsim_respawn_removeReinsertRequest", "Remove Re-insert Request", "\A3\ui_f\data\igui\cfg\simpleTasks\types\land_ca.paa", { params ["_target", "_player", "_params"]; ["milsim_respawn_removeReinsertRequest", [_player]] call CBA_fnc_serverEvent; "Re-insert Request Rescinded" call CBA_fnc_notify; }, { params ["_target", "_player", "_params"]; missionNamespace getVariable ["milsim_respawn_setting_reinsertion_enabled", true] && (_player in ((missionNamespace getVariable ["milsim_respawn_reinsertionQueue", []]) 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_respawn_fileForReinsertClassesAdded", []]); _classesActionsAddedTo pushBackUnique _type; localNamespace setVariable ["milsim_respawn_fileForReinsertClassesAdded", _classesActionsAddedTo]; }; [typeOf player] call _addReinsertRequestSelfActions; ["ace_interact_menu_newControllableObject", { _thisArgs params ["_fnc"]; _this call _fnc; }, [_addReinsertRequestSelfActions]] call CBA_fnc_addEventHandlerArgs; ///////////////////////////////////////////////////// // PILOTS ONLY // ACE SELF-INTERACTIONS FOR CHECKING REINSERT QUEUE - ONLY FOR PILOTS localNamespace setVariable ["milsim_respawn_checkReinsertQueueClassesAdded", []]; localNamespace setVariable ["milsim_respawn_lastReinsertQueueCheck", diag_tickTime]; private _addCheckReinsertQueueSelfAction = { params ["_type"]; // string of the object's classname if (!(_type isKindOf "CAManBase")) exitWith {}; if (!(_type in ["B_Helipilot_F", "B_helicrew_F"])) exitWith {}; if ( (localNamespace getVariable ["milsim_respawn_checkReinsertQueueClassesAdded", []]) find _type != -1 ) exitWith {}; private _checkReinsertQueueAction = [ "milsim_respawn_checkReinsertQueue", "[PILOT] Check Re-insert Queue", "\A3\ui_f\data\igui\cfg\simpleTasks\types\land_ca.paa", { params ["_target", "_player", "_params"]; // reset last check time localNamespace setVariable ["milsim_respawn_lastReinsertQueueCheck", diag_tickTime]; call milsim_respawn_fnc_showReinsertQueueNotification; }, { missionNamespace getVariable ["milsim_respawn_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_respawn_checkReinsertQueueClassesAdded", []]); _classesActionsAddedTo pushBackUnique _type; localNamespace setVariable ["milsim_respawn_checkReinsertQueueClassesAdded", _classesActionsAddedTo]; }; [typeOf player] call _addCheckReinsertQueueSelfAction; ["ace_interact_menu_newControllableObject", { _thisArgs params ["_fnc"]; _this call _fnc; }, [_addCheckReinsertQueueSelfAction]] call CBA_fnc_addEventHandlerArgs; // 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 (not ( missionNamespace getVariable ["milsim_respawn_setting_reinsertion_enabled", true] && missionNamespace getVariable ["milsim_respawn_setting_reinsertion_pilotForcedCheckEnabled", true] )) exitWith {}; private _lastCheck = localNamespace getVariable ["milsim_respawn_lastReinsertQueueCheck", diag_tickTime]; if ( diag_tickTime - _lastCheck < missionNamespace getVariable ["milsim_respawn_setting_reinsertion_pilotForcedCheckInterval", 60*20] ) exitWith {}; // if last check was less than X minutes ago, skip // if last check was greater than 20 minutes ago, we'll prompt the notification now and reset the timer localNamespace setVariable ["milsim_respawn_lastReinsertQueueCheck", diag_tickTime]; call milsim_respawn_fnc_showReinsertQueueNotification; }, 30] call CBA_fnc_addPerFrameHandler; }; ///////////////////////////////////////////////////// };