forge/arma/server/addons/task/functions/objects/fnc_DeliveryTaskBaseClass.sqf
2026-06-03 17:36:13 -05:00

212 lines
8.8 KiB
Plaintext

#include "..\script_component.hpp"
/*
* Object-style delivery task class.
*/
#pragma hemtt ignore_variables ["_self"]
GVAR(DeliveryTaskBaseClass) = +GVAR(TaskInstanceBaseClass);
GVAR(DeliveryTaskBaseClass) merge [createHashMapFromArray [
["#type", "DeliveryTaskBaseClass"],
["#create", compileFinal {
params [
["_taskID", "", [""]],
["_entities", createHashMap, [createHashMap]],
["_taskParams", createHashMap, [createHashMap]]
];
_self call ["initializeBaseState", [_taskID, "delivery", _entities, _taskParams]];
private _cargo = +(_entities getOrDefault ["cargo", []]);
private _requiredDelivered = _taskParams getOrDefault ["limitSuccess", -1];
if (_requiredDelivered < 0) then { _requiredDelivered = count _cargo; };
private _maxDamaged = _taskParams getOrDefault ["limitFail", -1];
if (_maxDamaged < 0) then { _maxDamaged = count _cargo; };
_self set ["cargo", _cargo];
_self set ["deliveryZone", _taskParams getOrDefault ["deliveryZone", ""]];
_self set ["requiredDelivered", _requiredDelivered];
_self set ["maxDamaged", _maxDamaged];
_self set ["timeLimit", _taskParams getOrDefault ["timeLimit", 0]];
_self set ["useTaskStore", _taskParams getOrDefault ["useTaskStore", false]];
_self call ["registerInstance", []];
}],
["#delete", compileFinal {
_self call ["unregisterInstance", []];
}],
["refreshEntitiesFromStore", compileFinal {
private _taskID = _self getOrDefault ["taskID", ""];
if (_taskID isEqualTo "" || { !(_self getOrDefault ["useTaskStore", false]) }) exitWith { false };
private _cargo = GVAR(TaskStore) call ["getTaskEntities", ["cargo", _taskID]];
_self set ["cargo", _cargo];
true
}],
["trackParticipants", compileFinal {
private _taskID = _self getOrDefault ["taskID", ""];
if (_taskID isEqualTo "" || { !(_self getOrDefault ["useTaskStore", false]) }) exitWith { false };
GVAR(TaskStore) call ["trackParticipants", [_taskID, _self getOrDefault ["cargo", []], _self getOrDefault ["deliveryZone", ""], 125]];
true
}],
["waitForRequiredEntities", compileFinal {
if (_self getOrDefault ["useTaskStore", false]) then {
waitUntil {
sleep 1;
_self call ["refreshEntitiesFromStore", []];
_self call ["trackParticipants", []];
!(_self call ["isTaskStoreOpen", []]) || { count (_self getOrDefault ["cargo", []]) > 0 }
};
} else {
waitUntil {
sleep 1;
count (_self getOrDefault ["cargo", []]) > 0
};
};
if !(_self call ["isTaskStoreOpen", []]) exitWith { false };
private _cargo = _self getOrDefault ["cargo", []];
private _taskParams = _self getOrDefault ["taskParams", createHashMap];
private _requiredDelivered = _taskParams getOrDefault ["limitSuccess", -1];
if (_requiredDelivered < 0) then { _requiredDelivered = count _cargo; };
private _maxDamaged = _taskParams getOrDefault ["limitFail", -1];
if (_maxDamaged < 0) then { _maxDamaged = count _cargo; };
_self set ["requiredDelivered", _requiredDelivered];
_self set ["maxDamaged", _maxDamaged];
true
}],
["waitForAssignment", compileFinal {
private _taskID = _self getOrDefault ["taskID", ""];
if (_taskID isEqualTo "" || { !(_self getOrDefault ["useTaskStore", false]) }) exitWith { true };
waitUntil {
sleep 1;
!(_self call ["isTaskStoreOpen", []]) || { GVAR(TaskStore) call ["isTaskAccepted", [_taskID]] }
};
_self call ["isTaskStoreOpen", []]
}],
["countDeliveredCargo", compileFinal {
private _deliveryZone = _self getOrDefault ["deliveryZone", ""];
private _cargo = _self getOrDefault ["cargo", []];
if (_deliveryZone isEqualTo "") exitWith { 0 };
{ _x inArea _deliveryZone && { damage _x < 0.7 } } count _cargo
}],
["countDamagedCargo", compileFinal {
private _cargo = _self getOrDefault ["cargo", []];
{ damage _x >= 0.7 } count _cargo
}],
["tick", compileFinal {
private _startedAt = _self getOrDefault ["startedAt", -1];
private _timeLimit = _self getOrDefault ["timeLimit", 0];
private _delivered = _self call ["countDeliveredCargo", []];
private _damaged = _self call ["countDamagedCargo", []];
private _requiredDelivered = _self getOrDefault ["requiredDelivered", 0];
private _maxDamaged = _self getOrDefault ["maxDamaged", 0];
private _timeExpired = false;
if (_timeLimit > 0 && { _startedAt >= 0 }) then {
_timeExpired = (serverTime - _startedAt) >= _timeLimit;
};
createHashMapFromArray [
["delivered", _delivered],
["damaged", _damaged],
["requiredDelivered", _requiredDelivered],
["maxDamaged", _maxDamaged],
["timeExpired", _timeExpired],
["shouldFail", (_damaged >= _maxDamaged) || { _timeExpired && { _delivered < _requiredDelivered } }],
["shouldSucceed", (_delivered >= _requiredDelivered) && { _damaged < _maxDamaged }]
]
}],
["handleFailureOutcome", compileFinal {
private _taskID = _self getOrDefault ["taskID", ""];
private _rewardData = _self getOrDefault ["rewardData", createHashMap];
private _ratingFail = _rewardData getOrDefault ["ratingFail", 0];
private _endFail = (_self getOrDefault ["taskParams", createHashMap]) getOrDefault ["endFail", false];
if (_self getOrDefault ["useTaskStore", false]) then {
[_taskID, "FAILED"] call BFUNC(taskSetState);
GVAR(TaskStore) call ["setTaskStatus", [_taskID, "failed"]];
sleep 1;
GVAR(TaskStore) call ["applyRatingOutcome", [_taskID, _ratingFail]];
GVAR(TaskStore) call ["notifyParticipants", [_taskID, "warning", "Tasks", format ["Task failed: %1 reputation", _ratingFail]]];
GVAR(TaskStore) call ["clearTask", [_taskID]];
};
if (_endFail) then { "EveryoneLost" call BFUNC(endMissionServer); };
true
}],
["handleSuccessOutcome", compileFinal {
private _taskID = _self getOrDefault ["taskID", ""];
private _rewardData = _self getOrDefault ["rewardData", createHashMap];
private _ratingSuccess = _rewardData getOrDefault ["ratingSuccess", 0];
private _funds = _rewardData getOrDefault ["funds", 0];
private _endSuccess = (_self getOrDefault ["taskParams", createHashMap]) getOrDefault ["endSuccess", false];
if (_self getOrDefault ["useTaskStore", false]) then {
[_taskID, "SUCCEEDED"] call BFUNC(taskSetState);
GVAR(TaskStore) call ["setTaskStatus", [_taskID, "succeeded"]];
[_taskID, _rewardData] call FUNC(handleTaskRewards);
sleep 1;
GVAR(TaskStore) call ["applyRatingOutcome", [_taskID, _ratingSuccess]];
GVAR(TaskStore) call ["notifyParticipants", [_taskID, "success", "Tasks", format ["Task completed: %1 reputation, $%2 funds", _ratingSuccess, [_funds] call EFUNC(common,formatNumber)]]];
GVAR(TaskStore) call ["clearTask", [_taskID]];
};
if (_endSuccess) then { "EveryoneWon" call BFUNC(endMissionServer); };
true
}],
["runLoop", compileFinal {
if !(_self call ["waitForRequiredEntities", []]) exitWith {
_self call ["markAborted", ["Task reached terminal status before required entities registered."]];
_self call ["cleanup", []];
false
};
if !(_self call ["waitForAssignment", []]) exitWith {
_self call ["markAborted", ["Task reached terminal status before assignment."]];
_self call ["cleanup", []];
false
};
_self call ["markActive", []];
while { _self call ["isTaskLoopActive", []] } do {
_self call ["trackParticipants", []];
private _snapshot = _self call ["tick", []];
if (_snapshot getOrDefault ["shouldFail", false]) exitWith {
_self call ["markFailed", ["Delivery fail conditions met.", _snapshot]];
};
if (_snapshot getOrDefault ["shouldSucceed", false]) exitWith {
_self call ["markSucceeded", [_snapshot]];
};
sleep 1;
};
private _finalStatus = _self call ["getStatus", []];
if (_finalStatus isEqualTo "failed") then {
_self call ["handleFailureOutcome", []];
};
if (_finalStatus isEqualTo "succeeded") then {
_self call ["handleSuccessOutcome", []];
};
_self call ["cleanup", []];
true
}]
], true];