// 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"]; milsim_respawn_reinsertionQueue pushBackUnique [ _unit, _closestBaseName, diag_tickTime ]; diag_log text format [ "[milsim] (respawn_reinsertion) PLAYER FILED REQUEST :: filedAtBase=""%1"" %2", _closestBaseName, [_unit] call milsim_fnc_getPlayerLogString ]; 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) PLAYER RESCINDED REQUEST :: filedAtBase=""%1"" inQueueDuration=""%2s"" %3", _baseName, _timeInQueue, [_unit] call milsim_fnc_getPlayerLogString ]; 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 = []; private _maxRangeToReady = missionNamespace getVariable ["milsim_respawn_setting_reinsertion_maxRangeToReady", 400]; { _x params ["_player", "_baseName", "_timeFiled"]; // _unitArr = [unit, baseName, timeInQueue] private _nearBase = _nearestDistance < _maxRangeToReady; if (_nearBase && alive _player) then { _stillValid pushBackUnique _x; } else { diag_log text format [ "[milsim] (respawn_reinsertion) PLAYER DEQUEUED AUTOMATICALLY :: filedAtBase=""%1"" nearestBaseDistance=""%2m"" maxDistanceSetting=""%3m"" inQueueDuration=""%4s"" %5", _baseName, _nearestDistance, _maxRangeToReady, diag_tickTime - _timeFiled, [_player] call milsim_fnc_getPlayerLogString ]; }; } 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; // GLOBAL CBA NOTIFY private _playerLines = [["Players are still waiting for Re-insert!"]]; { _playerLines pushBack ([format [ "%1: %2 [%3]", groupID (group (_x#0)), name (_x#0), [diag_tickTime - (_x#2), "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]; // RESET NOTIFICATION TIMER milsim_respawn_reinsertionOverTimeoutLastNotificationTime = diag_tickTime; // LOG TO RPT { diag_log text format [ "[milsim] (respawn_reinsertion) PLAYER WAITING OVER TIMEOUT :: timeout=""%1s"" inQueueDuration=""%2s"" %3", _timeout, diag_tickTime - (_x#2), [_x#0] call milsim_fnc_getPlayerLogString ]; } forEach _timeoutPlayers; }; }; }, 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"]; // find nearest base or location ([_player] call milsim_respawn_fnc_getNearestBase) params [ "_baseDistance", "_baseName" ]; // send event to server ["milsim_respawn_fileReinsertRequest", [_player, _baseName]] call CBA_fnc_serverEvent; // notify player their request was filed [["Re-insert Request Filed"], [format["Location: %1", _baseName]]] call CBA_fnc_notify; }, { params ["_target", "_player", "_params"]; // find nearest base or location ([_player] call milsim_respawn_fnc_getNearestBase) params [ "_baseDistance", "_baseName" ]; private _maxRangeToReady = missionNamespace getVariable ["milsim_respawn_setting_reinsertion_maxRangeToReady", 400]; private _existingQueue = missionNamespace getVariable ["milsim_respawn_reinsertionQueue", []]; // check if module is enabled, player is near a base, and player is not already in the queue missionNamespace getVariable ["milsim_respawn_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_respawn_removeReinsertRequest", "Remove Re-insert Request", "\A3\ui_f\data\igui\cfg\simpleTasks\types\land_ca.paa", { params ["_target", "_player", "_params"]; // send event to server ["milsim_respawn_removeReinsertRequest", [_player]] call CBA_fnc_serverEvent; // notify player their request was rescinded "Re-insert Request Rescinded" call CBA_fnc_notify; }, { params ["_target", "_player", "_params"]; private _existingQueue = missionNamespace getVariable ["milsim_respawn_reinsertionQueue", []]; // check if module is enabled, player is in the queue missionNamespace getVariable ["milsim_respawn_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_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; }; ///////////////////////////////////////////////////// };