diff --git a/functions/CfgFunctions.hpp b/functions/CfgFunctions.hpp index 4bd975c..f9035e1 100644 --- a/functions/CfgFunctions.hpp +++ b/functions/CfgFunctions.hpp @@ -69,4 +69,12 @@ class milsim class mapMarkerToString {}; //needs refactor class stringToMapMarker {}; //needs refactor }; +}; + +class milsim_respawn { + class functions { + file = "functions\respawn"; + class init { postInit = 1; }; + class showReinsertQueueNotification {}; + }; }; \ No newline at end of file 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; // 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 = _timeoutPlayers apply { + private _timeInQueue = diag_tickTime - (_x#2); + private _groupId = groupID (_x#0); + [format [ + "%1: %2 [%2s]", + _groupId, + name (_x#0), + [_timeInQueue, "MM:SS"] call BIS_fnc_secondsToString + ], 0.8, [0.8, 0.8, 0.8, 1]]; + }; + ["Players are still waiting for Re-insert!", _playerLines] remoteExec ["CBA_fnc_notify", -2]; + + 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 (_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; + }; + ///////////////////////////////////////////////////// +}; diff --git a/functions/respawn/fn_showReinsertQueueNotification.sqf b/functions/respawn/fn_showReinsertQueueNotification.sqf new file mode 100644 index 0000000..4ae775c --- /dev/null +++ b/functions/respawn/fn_showReinsertQueueNotification.sqf @@ -0,0 +1,40 @@ +private _par = [["Players Awaiting Reinsert", 1.2, [1,0.64,0,1]]]; +private _baseNames = (missionNamespace getVariable ["milsim_respawn_reinsertionQueue", []]) apply {_x#1}; +{ + private _baseName = _x; + private _peopleAtThisBase = (missionNamespace getVariable ["milsim_respawn_reinsertionQueue", []]) select { + _x#1 isEqualTo _baseName + } apply { + [name (_x#0), 0.7, [1,1,1,1]]; + }; + + private _playerCountText = ""; + switch (count _peopleAtThisBase) do { + case 0: { + _playerCountText = "No players"; + }; + case 1: { + _playerCountText = "1 player"; + }; + default { + _playerCountText = format ["%1 players", count _peopleAtThisBase]; + }; + }; + + _par pushBack [ + format ["Location: %1 (%2)", + _baseName, + _playerCountText + ], + 1, + [0,1,0,1] + ]; + + { + _par pushBack _x; + } forEach _peopleAtThisBase; +} forEach _baseNames; + +_par call CBA_fnc_notify; + +true; \ No newline at end of file diff --git a/functions/settings/fn_addCBASettings.sqf b/functions/settings/fn_addCBASettings.sqf index dc0ef30..c541b2b 100644 --- a/functions/settings/fn_addCBASettings.sqf +++ b/functions/settings/fn_addCBASettings.sqf @@ -125,6 +125,74 @@ ] call CBA_fnc_addSetting; +//--------------------- +// Respawn Settings +[ + "milsim_respawn_setting_reinsertion_enabled", // variable + "CHECKBOX", // type + ["Enabled", "Whether or not players can file for reinsert and pilots can check the reinsert queue"], // title + ["17th Battalion", "Re-insert Queue"], // category + true, // default value + true, // global setting + { + params ["_value"]; + diag_log format["[milsim] (respawn_reinsertion) enabled set to %1", _value]; + } +] call CBA_fnc_addSetting; + +[ + "milsim_respawn_setting_reinsertion_maxRangeToReady", // variable + "SLIDER", // type + ["Max Request Filing Range", "Maximum distance from a respawn point a player can be to ready up"], // title + ["17th Battalion", "Re-insert Queue"], // category + [0, 1000, 400, 0, false], // [_min, _max, _default, _trailingDecimals, _isPercentage] + true, // global setting + { + params ["_value"]; + diag_log format["[milsim] (respawn_reinsertion) maxRangeToReady set to %1", _value]; + } +] call CBA_fnc_addSetting; + +[ + "milsim_respawn_setting_reinsertion_pilotForcedCheckEnabled", // variable + "CHECKBOX", // type + ["Enabled", "Whether or not pilots are forced to view the contents of the reinsertion queue per interval"], // title + ["17th Battalion", "Re-insert Queue"], // category + true, // default value + true, // global setting + { + params ["_value"]; + diag_log format["[milsim] (respawn_reinsertion) pilotForcedCheckEnabled set to %1", _value]; + } +] call CBA_fnc_addSetting; + +[ + "milsim_respawn_setting_reinsertion_pilotForcedCheckInterval", // variable + "SLIDER", // type + ["Pilot Check Interval", "Pilots will be force shown the queue if they haven't checked it in X seconds"], // title + ["17th Battalion", "Re-insert Queue"], // category + [60*10, 60*30, 60*20, 0, false], // [_min, _max, _default, _trailingDecimals, _isPercentage + true, + { + params ["_value"]; + diag_log format["[milsim] (respawn_reinsertion) pilotForcedCheckInterval set to %1", _value]; + + } +] call CBA_fnc_addSetting; + +[ + "milsim_respawn_setting_reinsertion_timeout", // variable + "SLIDER", // type + ["Request Timeout", "How long should at least one person be waiting before prompting a global notification."], // title + ["17th Battalion", "Re-insert Queue"], // category + [60*10, 60*30, 60*20, 0, false], // [_min, _max, _default, _trailingDecimals, _isPercentage + true, + { + params ["_value"]; + diag_log format["[milsim] (respawn_reinsertion) timeout set to %1", _value]; + } +] call CBA_fnc_addSetting; + diag_log text "[MILSIM] (settings) Custom CBA settings initialized"; nil; \ No newline at end of file