#include "..\script_component.hpp" /* * File: fnc_initCadStore.sqf * Author: IDSolutions * Date: 2026-03-29 * Public: Yes * * Description: * Initializes the CAD store for group tracking, assignment state, * activity history, and CAD hydrate payloads. * * Arguments: * None * * Return Value: * CAD store object [HASHMAP OBJECT] * * Example: * call forge_server_cad_fnc_initCadStore */ #pragma hemtt ignore_variables ["_self"] GVAR(CadStoreBaseClass) = compileFinal createHashMapFromArray [ ["#type", "CadStoreBaseClass"], ["#create", compileFinal { _self set ["groupRegistry", createHashMap]; _self set ["assignmentRegistry", createHashMap]; _self set ["activityRegistry", []]; _self set ["validStatuses", [ "available", "en_route", "on_task", "holding", "danger", "refit", "offline" ]]; ["INFO", "CAD Store Initialized!"] call EFUNC(common,log); }], ["appendActivity", compileFinal { params [ ["_type", "", [""]], ["_message", "", [""]], ["_taskID", "", [""]], ["_groupID", "", [""]], ["_actorUid", "", [""]] ]; if (_type isEqualTo "" || { _message isEqualTo "" }) exitWith { false }; private _activityRegistry = +(_self getOrDefault ["activityRegistry", []]); _activityRegistry pushBack createHashMapFromArray [ ["type", _type], ["message", _message], ["timestamp", serverTime], ["taskId", _taskID], ["groupId", _groupID], ["actorUid", _actorUid] ]; if ((count _activityRegistry) > 50) then { _activityRegistry deleteRange [0, (count _activityRegistry) - 50]; }; _self set ["activityRegistry", _activityRegistry]; true }], ["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 }], ["canDispatch", compileFinal { params [["_uid", "", [""]]]; if (_uid isEqualTo "") exitWith { false }; private _actor = EGVAR(actor,Registry) getOrDefault [_uid, createHashMap]; if (_actor isEqualTo createHashMap) then { _actor = EGVAR(actor,ActorStore) call ["init", [_uid]]; }; private _orgID = _actor getOrDefault ["organization", "default"]; private _org = EGVAR(org,Registry) getOrDefault [_orgID, createHashMap]; if (_org isEqualTo createHashMap) then { _org = EGVAR(org,OrgStore) call ["loadById", [_orgID]]; }; if (_org getOrDefault ["owner", ""] isEqualTo _uid) exitWith { true }; private _player = [_uid] call EFUNC(common,getPlayer); if (_player isEqualTo objNull) exitWith { false }; (_orgID isEqualTo "default") && { vehicleVarName _player isEqualTo "ceo" } }], ["getCurrentTaskIdForGroup", compileFinal { params [["_groupID", "", [""]]]; if (_groupID isEqualTo "") exitWith { "" }; private _assignmentRegistry = _self 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 _nextRegistry = createHashMap; { if (side _x isNotEqualTo west) then { continue; }; private _members = (units _x) select { isPlayer _x }; if (_members isEqualTo []) then { continue; }; private _leader = leader _x; if (isNull _leader || { !isPlayer _leader }) then { _leader = _members # 0; }; private _groupID = _self call ["resolveGroupId", [_x]]; 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 _memberUids = []; { private _memberUid = getPlayerUID _x; if (_memberUid isNotEqualTo "") then { _memberUids pushBack _memberUid; }; } forEach _members; private _record = createHashMapFromArray [ ["groupId", _groupID], ["callsign", [groupId _x, _groupID] select ((groupId _x) isEqualTo "")], ["leaderUid", _leaderUid], ["leaderName", name _leader], ["memberUids", _memberUids], ["orgId", _orgID], ["role", _existingRecord getOrDefault ["role", "infantry"]], ["status", _existingRecord getOrDefault ["status", "available"]], ["position", getPosATL _leader], ["currentTaskId", _self call ["getCurrentTaskIdForGroup", [_groupID]]], ["lastUpdate", serverTime] ]; _nextRegistry set [_groupID, _record]; } forEach allGroups; _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 }], ["pruneAssignments", compileFinal { private _assignmentRegistry = _self getOrDefault ["assignmentRegistry", createHashMap]; private _keysToRemove = []; { private _status = EGVAR(task,TaskStore) call ["getTaskStatus", [_x]]; if !(_status in ["active", ""]) then { _keysToRemove pushBack _x; }; } forEach _assignmentRegistry; { _assignmentRegistry deleteAt _x; } forEach _keysToRemove; _self set ["assignmentRegistry", _assignmentRegistry]; count _keysToRemove }], ["buildContracts", compileFinal { _self call ["pruneAssignments", []]; private _assignmentRegistry = _self getOrDefault ["assignmentRegistry", createHashMap]; private _contracts = []; { private _taskID = _x getOrDefault ["taskID", ""]; if (_taskID isEqualTo "") then { continue; }; private _assignment = _assignmentRegistry getOrDefault [_taskID, createHashMap]; private _entry = +_x; _entry set ["taskId", _taskID]; _entry set ["assignedGroupId", _assignment getOrDefault ["groupId", ""]]; _entry set ["assignmentState", [_assignment getOrDefault ["state", ""], "unassigned"] select (_assignment isEqualTo createHashMap)]; _contracts pushBack _entry; } forEach (EGVAR(task,TaskStore) call ["getActiveTaskCatalog", []]); _contracts }], ["buildGroups", compileFinal { private _groupRegistry = _self call ["syncGroups", []]; private _groups = []; { _groups pushBack +_y; } forEach _groupRegistry; _groups }], ["buildHydratePayload", compileFinal { params [["_uid", "", [""]]]; private _activity = +(_self getOrDefault ["activityRegistry", []]); private _actor = EGVAR(actor,Registry) getOrDefault [_uid, createHashMap]; if (_actor isEqualTo createHashMap && { _uid isNotEqualTo "" }) then { _actor = EGVAR(actor,ActorStore) call ["init", [_uid]]; }; createHashMapFromArray [ ["groups", _self call ["buildGroups", []]], ["contracts", _self call ["buildContracts", []]], ["assignments", values (_self getOrDefault ["assignmentRegistry", createHashMap])], ["activity", _activity], ["session", createHashMapFromArray [ ["uid", _uid], ["orgId", _actor getOrDefault ["organization", "default"]], ["isDispatcher", _self call ["canDispatch", [_uid]]], ["groupId", _self call ["getPlayerGroupId", [_uid]]], ["isLeader", _self call ["isGroupLeader", [_uid, _self call ["getPlayerGroupId", [_uid]]]]] ]] ] }], ["notifyPlayer", compileFinal { params [ ["_uid", "", [""]], ["_type", "info", [""]], ["_title", "CAD", [""]], ["_message", "", [""]] ]; if (_uid isEqualTo "" || { _message isEqualTo "" }) exitWith { false }; private _player = [_uid] call EFUNC(common,getPlayer); if (_player isEqualTo objNull) exitWith { false }; [CRPC(notifications,recieveNotification), [_type, _title, _message], _player] call CFUNC(targetEvent); true }], ["assignTaskToGroup", compileFinal { params [ ["_requesterUid", "", [""]], ["_taskID", "", [""]], ["_groupID", "", [""]], ["_note", "", [""]] ]; private _result = createHashMapFromArray [ ["success", false], ["message", "Unable to assign task."], ["assignment", createHashMap] ]; if !(_self call ["canDispatch", [_requesterUid]]) exitWith { _result set ["message", "You are not authorized to assign contracts."]; _result }; if ((EGVAR(task,TaskStore) call ["getTaskStatus", [_taskID]]) isNotEqualTo "active") exitWith { _result set ["message", "Task is no longer active."]; _result }; private _groupRecord = _self call ["getGroupRecord", [_groupID]]; if (_groupRecord isEqualTo createHashMap) exitWith { _result set ["message", "Selected group is unavailable."]; _result }; private _leaderUid = _groupRecord getOrDefault ["leaderUid", ""]; if (_leaderUid isEqualTo "") exitWith { _result set ["message", "Selected group has no online leader."]; _result }; private _requesterPlayer = [_requesterUid] call EFUNC(common,getPlayer); private _assignmentRegistry = _self getOrDefault ["assignmentRegistry", createHashMap]; private _assignment = createHashMapFromArray [ ["taskId", _taskID], ["groupId", _groupID], ["assignedByUid", _requesterUid], ["assignedByName", ["Dispatcher", name _requesterPlayer] select (_requesterPlayer isNotEqualTo objNull)], ["assignedAt", serverTime], ["state", "assigned"], ["note", _note] ]; _assignmentRegistry set [_taskID, _assignment]; _self set ["assignmentRegistry", _assignmentRegistry]; _self call ["appendActivity", [ "task_assigned", format ["%1 assigned %2 to %3.", _assignment get "assignedByName", _taskID, _groupRecord getOrDefault ["callsign", _groupID]], _taskID, _groupID, _requesterUid ]]; _self call ["notifyPlayer", [ _leaderUid, "info", "Tasks", format ["Contract assigned: %1. Open CAD to review and acknowledge.", _taskID] ]]; _result set ["success", true]; _result set ["message", "Task assigned."]; _result set ["assignment", _assignment]; _result }], ["acknowledgeTask", compileFinal { params [["_requesterUid", "", [""]], ["_taskID", "", [""]]]; private _result = createHashMapFromArray [ ["success", false], ["message", "Unable to acknowledge task."], ["assignment", createHashMap] ]; private _assignmentRegistry = _self getOrDefault ["assignmentRegistry", createHashMap]; private _assignment = +(_assignmentRegistry getOrDefault [_taskID, createHashMap]); if (_assignment isEqualTo createHashMap) exitWith { _result set ["message", "Task is not assigned."]; _result }; private _groupID = _assignment getOrDefault ["groupId", ""]; if !(_self call ["isGroupLeader", [_requesterUid, _groupID]]) exitWith { _result set ["message", "Only the assigned group leader can acknowledge this task."]; _result }; private _bindResult = EGVAR(task,TaskStore) call ["bindTaskOwnership", [_taskID, _requesterUid]]; if !(_bindResult getOrDefault ["success", false]) exitWith { _result set ["message", _bindResult getOrDefault ["message", "Failed to bind task ownership."]]; _result }; _assignment set ["state", "acknowledged"]; _assignment set ["acknowledgedAt", serverTime]; _assignmentRegistry set [_taskID, _assignment]; _self set ["assignmentRegistry", _assignmentRegistry]; _self call ["appendActivity", [ "task_acknowledged", format ["%1 acknowledged %2.", _requesterUid, _taskID], _taskID, _groupID, _requesterUid ]]; _result set ["success", true]; _result set ["message", "Task acknowledged."]; _result set ["assignment", _assignment]; _result }], ["declineTask", compileFinal { params [["_requesterUid", "", [""]], ["_taskID", "", [""]]]; private _result = createHashMapFromArray [ ["success", false], ["message", "Unable to decline task."], ["assignment", createHashMap] ]; private _assignmentRegistry = _self getOrDefault ["assignmentRegistry", createHashMap]; private _assignment = +(_assignmentRegistry getOrDefault [_taskID, createHashMap]); if (_assignment isEqualTo createHashMap) exitWith { _result set ["message", "Task is not assigned."]; _result }; private _groupID = _assignment getOrDefault ["groupId", ""]; if !(_self call ["isGroupLeader", [_requesterUid, _groupID]]) exitWith { _result set ["message", "Only the assigned group leader can decline this task."]; _result }; _assignment set ["state", "declined"]; _assignment set ["declinedAt", serverTime]; _assignmentRegistry set [_taskID, _assignment]; _self set ["assignmentRegistry", _assignmentRegistry]; _self call ["appendActivity", [ "task_declined", format ["%1 declined %2.", _requesterUid, _taskID], _taskID, _groupID, _requesterUid ]]; _result set ["success", true]; _result set ["message", "Task declined."]; _result set ["assignment", _assignment]; _result }], ["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 _isAuthorized = (_self call ["isGroupLeader", [_requesterUid, _groupID]]) || { _self 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]; _self 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 }] ]; GVAR(CadStore) = createHashMapObject [GVAR(CadStoreBaseClass)]; GVAR(CadStore)