forge/arma/server/addons/cad/functions/fnc_initGroupRepository.sqf
Jacob Schmidt 1ca2499af7 Add dispatcher mode to CAD UI
- Add a dispatcher web view and layout switching
- Route group role updates and dispatcher hydration through the UI bridge
- Refresh top bar and hide map/side panel outside operations mode
2026-03-30 20:22:48 -05:00

305 lines
12 KiB
Plaintext

#include "..\script_component.hpp"
/*
* File: fnc_initGroupRepository.sqf
* Author: IDSolutions
* Date: 2026-03-30
* Public: No
*
* Description:
* Initializes the CAD group repository for live group state, roles,
* and dispatcher/leader-managed group profiles.
*
* Arguments:
* None
*
* Return Value:
* CAD group repository object [HASHMAP OBJECT]
*
* Example:
* call forge_server_cad_fnc_initGroupRepository
*/
#pragma hemtt ignore_variables ["_self"]
GVAR(GroupRepositoryBaseClass) = compileFinal createHashMapFromArray [
["#type", "CadGroupRepositoryBaseClass"],
["#create", compileFinal {
_self set ["groupRegistry", createHashMap];
_self set ["groupProfileRegistry", createHashMap];
_self set ["validStatuses", [
"available",
"en_route",
"on_task",
"holding",
"danger",
"refit",
"offline"
]];
_self set ["validRoles", [
"infantry",
"recon",
"armor",
"air",
"logistics",
"support"
]];
}],
["resolveGroupId", compileFinal {
params [["_group", grpNull, [grpNull]]];
if (isNull _group) exitWith { "" };
private _leader = leader _group;
private _leaderUid = if (isNull _leader) then { "" } else { getPlayerUID _leader };
if (_leaderUid isNotEqualTo "") exitWith { format ["group:%1", _leaderUid] };
private _groupLabel = groupId _group;
if (_groupLabel isNotEqualTo "") exitWith { format ["group:%1", _groupLabel] };
str _group
}],
["getCurrentTaskIdForGroup", compileFinal {
params [["_groupID", "", [""]]];
if (_groupID isEqualTo "") exitWith { "" };
private _assignmentRepository = _self getOrDefault ["assignmentRepository", createHashMap];
private _assignmentRegistry = _assignmentRepository getOrDefault ["assignmentRegistry", createHashMap];
private _taskID = "";
{
if ((_y getOrDefault ["groupId", ""]) isNotEqualTo _groupID) then { continue; };
if !((_y getOrDefault ["state", ""]) in ["assigned", "acknowledged"]) then { continue; };
if ((EGVAR(task,TaskStore) call ["getTaskStatus", [_x]]) isNotEqualTo "active") then { continue; };
_taskID = _x;
} forEach _assignmentRegistry;
_taskID
}],
["syncGroups", compileFinal {
private _previousRegistry = _self getOrDefault ["groupRegistry", createHashMap];
private _profileRegistry = _self getOrDefault ["groupProfileRegistry", createHashMap];
private _nextRegistry = createHashMap;
{
private _group = _x;
if (side _group isNotEqualTo west) then { continue; };
private _members = allPlayers select { group _x isEqualTo _group };
if (_members isEqualTo []) then { continue; };
private _leader = leader _group;
if (isNull _leader || { !isPlayer _leader }) then {
_leader = _members # 0;
};
private _groupID = _self call ["resolveGroupId", [_group]];
if (_groupID isEqualTo "") then { continue; };
private _leaderUid = getPlayerUID _leader;
private _actor = EGVAR(actor,Registry) getOrDefault [_leaderUid, createHashMap];
if (_actor isEqualTo createHashMap && { _leaderUid isNotEqualTo "" }) then {
_actor = EGVAR(actor,ActorStore) call ["init", [_leaderUid]];
};
private _orgID = _actor getOrDefault ["organization", "default"];
if (_orgID isEqualTo "") then { _orgID = "default"; };
private _existingRecord = +(_previousRegistry getOrDefault [_groupID, createHashMap]);
private _profile = +(_profileRegistry getOrDefault [_groupID, createHashMap]);
private _memberUids = [];
private _memberRoster = [];
{
private _memberUid = getPlayerUID _x;
private _memberState = toLowerANSI (lifeState _x);
if (_memberUid isNotEqualTo "") then {
_memberUids pushBack _memberUid;
};
_memberRoster pushBack (createHashMapFromArray [
["uid", _memberUid],
["name", name _x],
["lifeState", _memberState],
["isLeader", _x isEqualTo _leader]
]);
} forEach _members;
private _record = createHashMapFromArray [
["groupId", _groupID],
["callsign", [groupId _group, _groupID] select ((groupId _group) isEqualTo "")],
["leaderUid", _leaderUid],
["leaderName", name _leader],
["memberUids", _memberUids],
["members", _memberRoster],
["orgId", _orgID],
["role", [_existingRecord getOrDefault ["role", "infantry"], _profile getOrDefault ["role", _existingRecord getOrDefault ["role", "infantry"]]] select (_profile isNotEqualTo createHashMap)],
["status", [_existingRecord getOrDefault ["status", "available"], _profile getOrDefault ["status", _existingRecord getOrDefault ["status", "available"]]] select (_profile isNotEqualTo createHashMap)],
["position", getPosATL _leader],
["currentTaskId", _self call ["getCurrentTaskIdForGroup", [_groupID]]],
["lastUpdate", serverTime]
];
_nextRegistry set [_groupID, _record];
_profileRegistry set [_groupID, createHashMapFromArray [
["role", _record getOrDefault ["role", "infantry"]],
["status", _record getOrDefault ["status", "available"]]
]];
} forEach allGroups;
_self set ["groupProfileRegistry", _profileRegistry];
_self set ["groupRegistry", _nextRegistry];
_nextRegistry
}],
["getGroupRecord", compileFinal {
params [["_groupID", "", [""]]];
if (_groupID isEqualTo "") exitWith { createHashMap };
private _groupRegistry = _self call ["syncGroups", []];
+(_groupRegistry getOrDefault [_groupID, createHashMap])
}],
["getPlayerGroupId", compileFinal {
params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { "" };
private _player = [_uid] call EFUNC(common,getPlayer);
if (_player isEqualTo objNull) exitWith { "" };
_self call ["resolveGroupId", [group _player]]
}],
["isGroupLeader", compileFinal {
params [["_uid", "", [""]], ["_groupID", "", [""]]];
if (_uid isEqualTo "" || { _groupID isEqualTo "" }) exitWith { false };
private _groupRecord = _self call ["getGroupRecord", [_groupID]];
(_groupRecord getOrDefault ["leaderUid", ""]) isEqualTo _uid
}],
["buildGroups", compileFinal {
private _groupRegistry = _self call ["syncGroups", []];
private _groups = [];
{
_groups pushBack +_y;
} forEach _groupRegistry;
_groups
}],
["updateGroupStatus", compileFinal {
params [["_requesterUid", "", [""]], ["_groupID", "", [""]], ["_status", "", [""]]];
private _result = createHashMapFromArray [
["success", false],
["message", "Unable to update group status."],
["group", createHashMap]
];
private _finalStatus = toLowerANSI _status;
if !(_finalStatus in (_self getOrDefault ["validStatuses", []])) exitWith {
_result set ["message", "Invalid group status."];
_result
};
private _permissionService = _self getOrDefault ["permissionService", createHashMap];
private _isAuthorized = (_self call ["isGroupLeader", [_requesterUid, _groupID]]) || { _permissionService call ["canDispatch", [_requesterUid]] };
if !_isAuthorized exitWith {
_result set ["message", "You are not authorized to update that group."];
_result
};
private _groupRegistry = _self call ["syncGroups", []];
private _groupRecord = +(_groupRegistry getOrDefault [_groupID, createHashMap]);
if (_groupRecord isEqualTo createHashMap) exitWith {
_result set ["message", "Group could not be resolved."];
_result
};
_groupRecord set ["status", _finalStatus];
_groupRecord set ["lastUpdate", serverTime];
_groupRegistry set [_groupID, _groupRecord];
_self set ["groupRegistry", _groupRegistry];
private _profileRegistry = _self getOrDefault ["groupProfileRegistry", createHashMap];
private _profile = +(_profileRegistry getOrDefault [_groupID, createHashMap]);
_profile set ["role", _groupRecord getOrDefault ["role", "infantry"]];
_profile set ["status", _finalStatus];
_profileRegistry set [_groupID, _profile];
_self set ["groupProfileRegistry", _profileRegistry];
private _activityRepository = _self getOrDefault ["activityRepository", createHashMap];
_activityRepository call ["appendActivity", [
"group_status",
format ["%1 updated %2 to %3.", _requesterUid, _groupRecord getOrDefault ["callsign", _groupID], _finalStatus],
"",
_groupID,
_requesterUid
]];
_result set ["success", true];
_result set ["message", "Group status updated."];
_result set ["group", _groupRecord];
_result
}],
["updateGroupRole", compileFinal {
params [["_requesterUid", "", [""]], ["_groupID", "", [""]], ["_role", "", [""]]];
private _result = createHashMapFromArray [
["success", false],
["message", "Unable to update group role."],
["group", createHashMap]
];
private _finalRole = toLowerANSI _role;
if !(_finalRole in (_self getOrDefault ["validRoles", []])) exitWith {
_result set ["message", "Invalid group role."];
_result
};
private _permissionService = _self getOrDefault ["permissionService", createHashMap];
private _isAuthorized = (_self call ["isGroupLeader", [_requesterUid, _groupID]]) || { _permissionService call ["canDispatch", [_requesterUid]] };
if !_isAuthorized exitWith {
_result set ["message", "You are not authorized to update that group role."];
_result
};
private _groupRegistry = _self call ["syncGroups", []];
private _groupRecord = +(_groupRegistry getOrDefault [_groupID, createHashMap]);
if (_groupRecord isEqualTo createHashMap) exitWith {
_result set ["message", "Group could not be resolved."];
_result
};
_groupRecord set ["role", _finalRole];
_groupRecord set ["lastUpdate", serverTime];
_groupRegistry set [_groupID, _groupRecord];
_self set ["groupRegistry", _groupRegistry];
private _profileRegistry = _self getOrDefault ["groupProfileRegistry", createHashMap];
private _profile = +(_profileRegistry getOrDefault [_groupID, createHashMap]);
_profile set ["role", _finalRole];
_profile set ["status", _groupRecord getOrDefault ["status", "available"]];
_profileRegistry set [_groupID, _profile];
_self set ["groupProfileRegistry", _profileRegistry];
private _activityRepository = _self getOrDefault ["activityRepository", createHashMap];
_activityRepository call ["appendActivity", [
"group_role",
format ["%1 updated %2 role to %3.", _requesterUid, _groupRecord getOrDefault ["callsign", _groupID], _finalRole],
"",
_groupID,
_requesterUid
]];
_result set ["success", true];
_result set ["message", "Group role updated."];
_result set ["group", _groupRecord];
_result
}]
];
createHashMapObject [GVAR(GroupRepositoryBaseClass)]