#include "..\script_component.hpp" /* * Author: IDSolutions * Initializes the task store for task entity tracking, participant * contribution tracking, and task outcome application. * * Arguments: * None * * Return Value: * Task store object [HASHMAP OBJECT] * * Example: * call forge_server_task_fnc_initTaskStore * * Public: No */ #pragma hemtt ignore_variables ["_self"] GVAR(TaskStore) = createHashMapObject [[ ["#type", "TaskStore"], ["#create", compileFinal { _self set ["participantRegistry", createHashMap]; _self set ["defuseRegistry", createHashMap]; _self set ["taskOwnershipRegistry", createHashMap]; _self set ["taskStatusRegistry", createHashMap]; _self set ["completedTaskStatusRegistry", createHashMap]; _self set ["taskCatalogRegistry", createHashMap]; _self set ["taskEntityRegistries", createHashMapFromArray [ ["cargo", createHashMap], ["hostages", createHashMap], ["hvts", createHashMap], ["ieds", createHashMap], ["entities", createHashMap], ["shooters", createHashMap], ["targets", createHashMap] ]]; }], ["bindTaskOwnership", compileFinal { params [["_taskID", "", [""]], ["_requesterUid", "", [""]]]; private _result = createHashMapFromArray [ ["success", false], ["requesterUid", _requesterUid], ["orgID", "default"], ["message", ""] ]; if (_taskID isEqualTo "") exitWith { _result set ["message", "Missing task ID."]; _result }; if (_requesterUid isEqualTo "") exitWith { private _taskOwnershipRegistry = _self getOrDefault ["taskOwnershipRegistry", createHashMap]; _taskOwnershipRegistry set [_taskID, createHashMapFromArray [ ["requesterUid", ""], ["orgID", "default"] ]]; _self set ["taskOwnershipRegistry", _taskOwnershipRegistry]; _result set ["success", true]; _result set ["message", "No requester UID provided. Bound task to default organization."]; _result }; private _actor = EGVAR(actor,Registry) getOrDefault [_requesterUid, createHashMap]; if (_actor isEqualTo createHashMap) then { _actor = EGVAR(actor,ActorStore) call ["init", [_requesterUid]]; }; if (_actor isEqualTo createHashMap) exitWith { _result set ["message", format ["Failed to load actor for %1.", _requesterUid]]; _result }; private _orgID = _actor getOrDefault ["organization", ""]; if (_orgID isEqualTo "") then { _orgID = "default"; }; private _taskOwnershipRegistry = _self getOrDefault ["taskOwnershipRegistry", createHashMap]; _taskOwnershipRegistry set [_taskID, createHashMapFromArray [ ["requesterUid", _requesterUid], ["orgID", _orgID] ]]; _self set ["taskOwnershipRegistry", _taskOwnershipRegistry]; private _taskCatalogRegistry = _self getOrDefault ["taskCatalogRegistry", createHashMap]; private _catalogEntry = +(_taskCatalogRegistry getOrDefault [_taskID, createHashMap]); if (_catalogEntry isNotEqualTo createHashMap) then { _catalogEntry set ["requesterUid", _requesterUid]; _catalogEntry set ["orgID", _orgID]; _catalogEntry set ["accepted", true]; _taskCatalogRegistry set [_taskID, _catalogEntry]; _self set ["taskCatalogRegistry", _taskCatalogRegistry]; }; _result set ["success", true]; _result set ["orgID", _orgID]; _result }], ["releaseTaskOwnership", compileFinal { params [["_taskID", "", [""]]]; if (_taskID isEqualTo "") exitWith { false }; private _taskOwnershipRegistry = _self getOrDefault ["taskOwnershipRegistry", createHashMap]; _taskOwnershipRegistry deleteAt _taskID; _self set ["taskOwnershipRegistry", _taskOwnershipRegistry]; private _taskCatalogRegistry = _self getOrDefault ["taskCatalogRegistry", createHashMap]; private _catalogEntry = +(_taskCatalogRegistry getOrDefault [_taskID, createHashMap]); if (_catalogEntry isNotEqualTo createHashMap) then { _catalogEntry set ["requesterUid", ""]; _catalogEntry set ["orgID", "default"]; _catalogEntry set ["accepted", false]; _taskCatalogRegistry set [_taskID, _catalogEntry]; _self set ["taskCatalogRegistry", _taskCatalogRegistry]; }; true }], ["registerTaskCatalogEntry", compileFinal { params [["_taskID", "", [""]], ["_entry", createHashMap, [createHashMap]]]; if (_taskID isEqualTo "" || { _entry isEqualTo createHashMap }) exitWith { false }; private _taskCatalogRegistry = _self getOrDefault ["taskCatalogRegistry", createHashMap]; _taskCatalogRegistry set [_taskID, +_entry]; _self set ["taskCatalogRegistry", _taskCatalogRegistry]; true }], ["getActiveTaskCatalog", compileFinal { private _taskCatalogRegistry = _self getOrDefault ["taskCatalogRegistry", createHashMap]; private _taskStatusRegistry = _self getOrDefault ["taskStatusRegistry", createHashMap]; private _entries = []; { if ((_taskStatusRegistry getOrDefault [_x, ""]) isNotEqualTo "active") then { continue; }; private _entry = +_y; _entry set ["taskID", _x]; _entry set ["status", "active"]; _entries pushBack _entry; } forEach _taskCatalogRegistry; _entries }], ["acceptTask", compileFinal { params [["_taskID", "", [""]], ["_requesterUid", "", [""]]]; private _result = createHashMapFromArray [ ["success", false], ["message", "Unable to accept task."], ["entry", createHashMap] ]; if (_taskID isEqualTo "" || { _requesterUid isEqualTo "" }) exitWith { _result set ["message", "Missing task ID or requester UID."]; _result }; if ((_self call ["getTaskStatus", [_taskID]]) isNotEqualTo "active") exitWith { _result set ["message", "Task is no longer active."]; _result }; private _taskCatalogRegistry = _self getOrDefault ["taskCatalogRegistry", createHashMap]; private _entry = +(_taskCatalogRegistry getOrDefault [_taskID, createHashMap]); if (_entry isEqualTo createHashMap) exitWith { _result set ["message", "Task does not exist."]; _result }; private _taskOwnershipRegistry = _self getOrDefault ["taskOwnershipRegistry", createHashMap]; private _ownership = _taskOwnershipRegistry getOrDefault [_taskID, createHashMap]; private _currentRequesterUid = _ownership getOrDefault ["requesterUid", ""]; if (_currentRequesterUid isNotEqualTo "" && { _currentRequesterUid isNotEqualTo _requesterUid }) exitWith { _result set ["message", "Task has already been accepted."]; _result set ["entry", _entry]; _result }; private _bindResult = _self call ["bindTaskOwnership", [_taskID, _requesterUid]]; if !(_bindResult getOrDefault ["success", false]) exitWith { _result set ["message", _bindResult getOrDefault ["message", "Failed to bind task ownership."]]; _result }; private _updatedTaskCatalogRegistry = _self getOrDefault ["taskCatalogRegistry", createHashMap]; private _updatedEntry = +(_updatedTaskCatalogRegistry getOrDefault [_taskID, _entry]); _updatedEntry set ["accepted", true]; _updatedEntry set ["requesterUid", _requesterUid]; _updatedEntry set ["orgID", _bindResult getOrDefault ["orgID", "default"]]; _updatedTaskCatalogRegistry set [_taskID, _updatedEntry]; _self set ["taskCatalogRegistry", _updatedTaskCatalogRegistry]; _result set ["success", true]; _result set ["message", "Task accepted."]; _result set ["entry", _updatedEntry]; _result }], ["setTaskStatus", compileFinal { params [["_taskID", "", [""]], ["_status", "", [""]]]; if (_taskID isEqualTo "" || { _status isEqualTo "" }) exitWith { false }; private _taskStatusRegistry = _self getOrDefault ["taskStatusRegistry", createHashMap]; private _completedTaskStatusRegistry = _self getOrDefault ["completedTaskStatusRegistry", createHashMap]; _taskStatusRegistry set [_taskID, _status]; if (_status in ["succeeded", "failed"]) then { _completedTaskStatusRegistry set [_taskID, _status]; } else { _completedTaskStatusRegistry deleteAt _taskID; }; _self set ["taskStatusRegistry", _taskStatusRegistry]; _self set ["completedTaskStatusRegistry", _completedTaskStatusRegistry]; true }], ["getTaskStatus", compileFinal { params [["_taskID", "", [""]]]; if (_taskID isEqualTo "") exitWith { "" }; private _taskStatusRegistry = _self getOrDefault ["taskStatusRegistry", createHashMap]; private _status = _taskStatusRegistry getOrDefault [_taskID, ""]; if (_status isNotEqualTo "") exitWith { _status }; private _completedTaskStatusRegistry = _self getOrDefault ["completedTaskStatusRegistry", createHashMap]; _completedTaskStatusRegistry getOrDefault [_taskID, ""] }], ["clearTaskStatus", compileFinal { params [["_taskID", "", [""]]]; if (_taskID isEqualTo "") exitWith { false }; private _taskStatusRegistry = _self getOrDefault ["taskStatusRegistry", createHashMap]; private _completedTaskStatusRegistry = _self getOrDefault ["completedTaskStatusRegistry", createHashMap]; _taskStatusRegistry deleteAt _taskID; _completedTaskStatusRegistry deleteAt _taskID; _self set ["taskStatusRegistry", _taskStatusRegistry]; _self set ["completedTaskStatusRegistry", _completedTaskStatusRegistry]; true }], ["registerTaskEntity", compileFinal { params [["_registryKey", "", [""]], ["_taskID", "", [""]], ["_entity", objNull, [objNull]]]; if (_registryKey isEqualTo "" || { _taskID isEqualTo "" } || { isNull _entity }) exitWith { false }; private _taskEntityRegistries = _self getOrDefault ["taskEntityRegistries", createHashMap]; private _registry = +(_taskEntityRegistries getOrDefault [_registryKey, createHashMap]); private _entities = +(_registry getOrDefault [_taskID, []]); _entities pushBackUnique _entity; _registry set [_taskID, _entities]; _taskEntityRegistries set [_registryKey, _registry]; _self set ["taskEntityRegistries", _taskEntityRegistries]; true }], ["getTaskEntities", compileFinal { params [["_registryKey", "", [""]], ["_taskID", "", [""]]]; if (_registryKey isEqualTo "" || { _taskID isEqualTo "" }) exitWith { [] }; private _taskEntityRegistries = _self getOrDefault ["taskEntityRegistries", createHashMap]; private _registry = _taskEntityRegistries getOrDefault [_registryKey, createHashMap]; +(_registry getOrDefault [_taskID, []]) }], ["clearTaskEntities", compileFinal { params [["_taskID", "", [""]]]; if (_taskID isEqualTo "") exitWith { false }; private _taskEntityRegistries = _self getOrDefault ["taskEntityRegistries", createHashMap]; { private _registry = +_y; _registry deleteAt _taskID; _taskEntityRegistries set [_x, _registry]; } forEach _taskEntityRegistries; _self set ["taskEntityRegistries", _taskEntityRegistries]; true }], ["trackParticipants", compileFinal { params [["_taskID", "", [""]], ["_entities", [], [[]]], ["_marker", "", [""]], ["_radius", 300, [0]]]; if (_taskID isEqualTo "") exitWith { createHashMap }; private _participantRegistry = _self getOrDefault ["participantRegistry", createHashMap]; private _participantSnapshots = +(_participantRegistry getOrDefault [_taskID, createHashMap]); private _activePlayers = allPlayers select { alive _x && { side group _x isEqualTo west } }; if (_marker isNotEqualTo "" && { markerShape _marker in ["RECTANGLE", "ELLIPSE"] }) then { { private _uid = getPlayerUID _x; if (_uid isNotEqualTo "" && { _x inArea _marker }) then { if !(_uid in _participantSnapshots) then { _participantSnapshots set [_uid, createHashMapFromArray [ ["startRating", rating _x] ]]; }; }; } forEach _activePlayers; }; if (_radius > 0 && { _entities isNotEqualTo [] }) then { { private _entity = _x; if (isNull _entity) then { continue; }; { private _uid = getPlayerUID _x; if (_uid isNotEqualTo "" && { (_x distance2D _entity) <= _radius }) then { if !(_uid in _participantSnapshots) then { _participantSnapshots set [_uid, createHashMapFromArray [ ["startRating", rating _x] ]]; }; }; } forEach _activePlayers; } forEach _entities; }; _participantRegistry set [_taskID, _participantSnapshots]; _self set ["participantRegistry", _participantRegistry]; _participantSnapshots }], ["resolveRewardContext", compileFinal { params [["_taskID", "", [""]]]; private _result = createHashMapFromArray [ ["requesterUid", ""], ["orgID", ""], ["memberUids", []] ]; if (_taskID isEqualTo "") exitWith { _result }; private _taskOwnershipRegistry = _self getOrDefault ["taskOwnershipRegistry", createHashMap]; private _ownership = _taskOwnershipRegistry getOrDefault [_taskID, createHashMap]; if (_ownership isEqualTo createHashMap) exitWith { _result }; private _requesterUid = _ownership getOrDefault ["requesterUid", ""]; private _resolvedOrgID = _ownership getOrDefault ["orgID", ""]; if (_resolvedOrgID isEqualTo "") exitWith { _result }; private _org = EGVAR(org,OrgStore) call ["loadById", [_resolvedOrgID]]; private _memberUids = []; if (_org isNotEqualTo createHashMap) then { _memberUids = EGVAR(org,OrgTreasuryService) call ["resolveOrgMemberUids", [_org, _requesterUid]]; }; _result set ["requesterUid", _requesterUid]; _result set ["orgID", _resolvedOrgID]; _result set ["memberUids", _memberUids]; _result }], ["incrementDefuseCount", compileFinal { params [["_taskID", "", [""]]]; if (_taskID isEqualTo "") exitWith { 0 }; private _defuseRegistry = _self getOrDefault ["defuseRegistry", createHashMap]; private _nextCount = 1 + (_defuseRegistry getOrDefault [_taskID, 0]); _defuseRegistry set [_taskID, _nextCount]; _self set ["defuseRegistry", _defuseRegistry]; _nextCount }], ["getDefuseCount", compileFinal { params [["_taskID", "", [""]]]; if (_taskID isEqualTo "") exitWith { 0 }; private _defuseRegistry = _self getOrDefault ["defuseRegistry", createHashMap]; _defuseRegistry getOrDefault [_taskID, 0] }], ["notifyParticipants", compileFinal { params [ ["_taskID", "", [""]], ["_type", "info", [""]], ["_title", "Tasks", [""]], ["_message", "", [""]] ]; if (_taskID isEqualTo "" || { _message isEqualTo "" }) exitWith { false }; private _participantRegistry = _self getOrDefault ["participantRegistry", createHashMap]; private _participantSnapshots = +(_participantRegistry getOrDefault [_taskID, createHashMap]); if (_participantSnapshots isEqualTo createHashMap) exitWith { false }; { private _player = [_x] call EFUNC(common,getPlayer); if (isNull _player) then { continue; }; [CRPC(notifications,recieveNotification), [_type, _title, _message], _player] call CFUNC(targetEvent); } forEach (keys _participantSnapshots); true }], ["clearTask", compileFinal { params [["_taskID", "", [""]]]; if (_taskID isEqualTo "") exitWith { false }; private _participantRegistry = _self getOrDefault ["participantRegistry", createHashMap]; private _defuseRegistry = _self getOrDefault ["defuseRegistry", createHashMap]; private _taskOwnershipRegistry = _self getOrDefault ["taskOwnershipRegistry", createHashMap]; private _taskStatusRegistry = _self getOrDefault ["taskStatusRegistry", createHashMap]; private _taskCatalogRegistry = _self getOrDefault ["taskCatalogRegistry", createHashMap]; _participantRegistry deleteAt _taskID; _defuseRegistry deleteAt _taskID; _taskOwnershipRegistry deleteAt _taskID; _taskStatusRegistry deleteAt _taskID; _taskCatalogRegistry deleteAt _taskID; _self set ["participantRegistry", _participantRegistry]; _self set ["defuseRegistry", _defuseRegistry]; _self set ["taskOwnershipRegistry", _taskOwnershipRegistry]; _self set ["taskStatusRegistry", _taskStatusRegistry]; _self set ["taskCatalogRegistry", _taskCatalogRegistry]; _self call ["clearTaskEntities", [_taskID]]; true }], ["applyRatingOutcome", compileFinal { params [["_taskID", "", [""]], ["_delta", 0, [0]]]; private _result = createHashMapFromArray [ ["participantUids", []], ["orgIds", []], ["contributions", createHashMap] ]; if (_taskID isEqualTo "" || { _delta isEqualTo 0 }) exitWith { _result }; private _participantRegistry = _self getOrDefault ["participantRegistry", createHashMap]; private _participantSnapshots = +(_participantRegistry getOrDefault [_taskID, createHashMap]); if (_participantSnapshots isEqualTo createHashMap) exitWith { _result }; private _rewardContext = _self call ["resolveRewardContext", [_taskID]]; private _participantUids = keys _participantSnapshots; if (_participantUids isEqualTo [] && { _delta > 0 }) then { private _requesterUid = _rewardContext getOrDefault ["requesterUid", ""]; if (_requesterUid isNotEqualTo "") then { private _requesterPlayer = [_requesterUid] call EFUNC(common,getPlayer); if (!isNull _requesterPlayer) then { _participantUids pushBack _requesterUid; _participantSnapshots set [_requesterUid, createHashMapFromArray [ ["startRating", rating _requesterPlayer] ]]; _participantRegistry set [_taskID, _participantSnapshots]; _self set ["participantRegistry", _participantRegistry]; ["WARNING", format ["Task %1 had no tracked participants at payout time; falling back to requester %2 for personal earnings.", _taskID, _requesterUid]] call EFUNC(common,log); }; }; }; if (_participantUids isEqualTo []) exitWith { _result }; private _orgIds = []; private _contributions = createHashMap; private _totalContribution = 0; if (_delta > 0) then { { private _uid = _x; private _player = [_uid] call EFUNC(common,getPlayer); if (isNull _player) then { continue; }; _contributions set [_uid, 1]; _totalContribution = _totalContribution + 1; } forEach _participantUids; }; if (_totalContribution <= 0) exitWith { _self call ["clearTask", [_taskID]]; _result }; { private _uid = _x; 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", ""]; if (_orgID isNotEqualTo "") then { _orgIds pushBackUnique _orgID; }; if (_delta > 0) then { private _contribution = _contributions getOrDefault [_uid, 0]; if (_contribution <= 0) then { continue; }; private _account = EGVAR(bank,BankStore) call ["get", [_uid, ""]]; if (_account isEqualTo createHashMap) then { _account = EGVAR(bank,BankStore) call ["init", [_uid]]; }; if (_account isNotEqualTo createHashMap) then { private _earnings = _account getOrDefault ["earnings", 0]; private _earningsDelta = round ((_delta * _contribution) / _totalContribution); if (_earningsDelta <= 0) then { continue; }; private _patch = EGVAR(bank,BankStore) call [ "mset", [ _uid, createHashMapFromArray [["earnings", (_earnings + _earningsDelta)]], false ] ]; if !(_patch isEqualType createHashMap) then { continue; }; if (_patch isEqualTo createHashMap) then { continue; }; EGVAR(bank,BankMessenger) call ["sendAccountSync", [_uid, _patch]]; }; }; } forEach _participantUids; private _ownerOrgID = _rewardContext getOrDefault ["orgID", ""]; if (_ownerOrgID isNotEqualTo "") then { private _org = EGVAR(org,OrgStore) call ["loadById", [_ownerOrgID]]; if (_org isNotEqualTo createHashMap) then { private _reputation = _org getOrDefault ["reputation", 0]; private _nextReputation = round (_reputation + _delta); private _patch = EGVAR(org,OrgStore) call [ "set", [ _ownerOrgID, "reputation", _nextReputation, false ] ]; private _memberUids = _rewardContext getOrDefault ["memberUids", []]; { private _player = [_x] call EFUNC(common,getPlayer); if (isNull _player) then { continue; }; [CRPC(org,responseSyncOrg), [_patch], _player] call CFUNC(targetEvent); } forEach _memberUids; _orgIds = [_ownerOrgID]; }; }; _result set ["participantUids", _participantUids]; _result set ["orgIds", _orgIds]; _result set ["contributions", _contributions]; _result }] ]]; GVAR(TaskStore)