From 53a2bb428068ab264cc3a5ba892c4c0a22ac7d65 Mon Sep 17 00:00:00 2001 From: Jacob Schmidt Date: Sat, 2 May 2026 21:54:23 -0500 Subject: [PATCH] Add review-only task prototype classes - Add defend, delivery, destroy, and HVT prototype task flows - Add supporting entity controller prototypes and init settings - Gate mission manager PFH behind `enableGenerator` --- arma/server/addons/task/README.md | 7 +- arma/server/addons/task/XEH_PREP.hpp | 11 + arma/server/addons/task/XEH_preInit.sqf | 4 + .../task/functions/fnc_missionManager.sqf | 14 +- .../task/functions/prototypes/README.md | 22 ++ .../prototypes/fnc_AttackTaskBaseClass.sqf | 4 +- .../prototypes/fnc_CargoEntityController.sqf | 80 +++++++ .../prototypes/fnc_DefendTaskBaseClass.sqf | 214 ++++++++++++++++++ .../prototypes/fnc_DefenseEnemyController.sqf | 52 +++++ .../prototypes/fnc_DefuseTaskBaseClass.sqf | 58 +++++ .../prototypes/fnc_DeliveryTaskBaseClass.sqf | 205 +++++++++++++++++ .../prototypes/fnc_DestroyTaskBaseClass.sqf | 185 +++++++++++++++ .../fnc_EntityControllerBaseClass.sqf | 35 ++- .../prototypes/fnc_HVTEntityController.sqf | 72 ++++++ .../prototypes/fnc_HVTTaskBaseClass.sqf | 212 +++++++++++++++++ .../prototypes/fnc_HostageTaskBaseClass.sqf | 13 +- .../prototypes/fnc_IEDEntityController.sqf | 88 +++++++ .../fnc_ProtectedEntityController.sqf | 41 ++++ .../fnc_ShooterEntityController.sqf | 41 ++++ .../prototypes/fnc_TargetEntityController.sqf | 41 ++++ .../prototypes/fnc_TaskInstanceBaseClass.sqf | 1 + .../prototypes/fnc_initPrototypes.sqf | 24 +- arma/server/addons/task/initSettings.inc.sqf | 5 + arma/server/addons/task/stringtable.xml | 6 + 24 files changed, 1420 insertions(+), 15 deletions(-) create mode 100644 arma/server/addons/task/functions/prototypes/fnc_CargoEntityController.sqf create mode 100644 arma/server/addons/task/functions/prototypes/fnc_DefendTaskBaseClass.sqf create mode 100644 arma/server/addons/task/functions/prototypes/fnc_DefenseEnemyController.sqf create mode 100644 arma/server/addons/task/functions/prototypes/fnc_DeliveryTaskBaseClass.sqf create mode 100644 arma/server/addons/task/functions/prototypes/fnc_DestroyTaskBaseClass.sqf create mode 100644 arma/server/addons/task/functions/prototypes/fnc_HVTEntityController.sqf create mode 100644 arma/server/addons/task/functions/prototypes/fnc_HVTTaskBaseClass.sqf create mode 100644 arma/server/addons/task/functions/prototypes/fnc_IEDEntityController.sqf create mode 100644 arma/server/addons/task/functions/prototypes/fnc_ProtectedEntityController.sqf create mode 100644 arma/server/addons/task/functions/prototypes/fnc_ShooterEntityController.sqf create mode 100644 arma/server/addons/task/functions/prototypes/fnc_TargetEntityController.sqf create mode 100644 arma/server/addons/task/initSettings.inc.sqf diff --git a/arma/server/addons/task/README.md b/arma/server/addons/task/README.md index 14af7e7..c5dab82 100644 --- a/arma/server/addons/task/README.md +++ b/arma/server/addons/task/README.md @@ -48,9 +48,10 @@ A review-only prototype for object-based task instances lives under - `forge_server_task_fnc_initPrototypes` - `prototypes/README.md` -The prototype sketches `TaskInstanceBaseClass`, `HostageTaskBaseClass`, and -`DefuseTaskBaseClass` using `createHashMapObject` so the team can review a -stateful per-task design without replacing the current procedural task flows. +The prototype sketches task classes for attack, defuse, defend, delivery, +destroy, hostage, and HVT flows using `createHashMapObject` so the team can +review a stateful per-task design without replacing the current procedural task +flows. ### Reward Handling `fnc_handleTaskRewards.sqf` applies org-owned rewards: diff --git a/arma/server/addons/task/XEH_PREP.hpp b/arma/server/addons/task/XEH_PREP.hpp index aad944b..2c3e5f2 100644 --- a/arma/server/addons/task/XEH_PREP.hpp +++ b/arma/server/addons/task/XEH_PREP.hpp @@ -43,4 +43,15 @@ PREP_SUBDIR(prototypes,EntityControllerBaseClass); PREP_SUBDIR(prototypes,AttackTaskBaseClass); PREP_SUBDIR(prototypes,HostageTaskBaseClass); PREP_SUBDIR(prototypes,HostageEntityController); +PREP_SUBDIR(prototypes,TargetEntityController); +PREP_SUBDIR(prototypes,ShooterEntityController); +PREP_SUBDIR(prototypes,HVTEntityController); +PREP_SUBDIR(prototypes,CargoEntityController); +PREP_SUBDIR(prototypes,ProtectedEntityController); +PREP_SUBDIR(prototypes,IEDEntityController); +PREP_SUBDIR(prototypes,DefenseEnemyController); PREP_SUBDIR(prototypes,DefuseTaskBaseClass); +PREP_SUBDIR(prototypes,DestroyTaskBaseClass); +PREP_SUBDIR(prototypes,DeliveryTaskBaseClass); +PREP_SUBDIR(prototypes,HVTTaskBaseClass); +PREP_SUBDIR(prototypes,DefendTaskBaseClass); diff --git a/arma/server/addons/task/XEH_preInit.sqf b/arma/server/addons/task/XEH_preInit.sqf index c3fddf6..9602e35 100644 --- a/arma/server/addons/task/XEH_preInit.sqf +++ b/arma/server/addons/task/XEH_preInit.sqf @@ -4,4 +4,8 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +private _category = [QUOTE(MOD_NAME), LLSTRING(displayName)]; + +#include "initSettings.inc.sqf" + call FUNC(initTaskStore); diff --git a/arma/server/addons/task/functions/fnc_missionManager.sqf b/arma/server/addons/task/functions/fnc_missionManager.sqf index 91bd46d..16934c5 100644 --- a/arma/server/addons/task/functions/fnc_missionManager.sqf +++ b/arma/server/addons/task/functions/fnc_missionManager.sqf @@ -131,13 +131,15 @@ GVAR(MissionManagerBaseClass) = compileFinal createHashMapFromArray [ ]; GVAR(MissionManager) = createHashMapObject [GVAR(MissionManagerBaseClass)]; -GVAR(MissionManagerPFH) = [{ - GVAR(MissionManager) call ["cleanupCompletedMissions", []]; +if (GVAR(enableGenerator)) then { + GVAR(MissionManagerPFH) = [{ + GVAR(MissionManager) call ["cleanupCompletedMissions", []]; - private _taskID = GVAR(MissionManager) call ["startAvailableMissions", []]; - if (_taskID isEqualTo "") exitWith {}; + private _taskID = GVAR(MissionManager) call ["startAvailableMissions", []]; + if (_taskID isEqualTo "") exitWith {}; - ["INFO", format ["Mission manager started mission %1.", _taskID]] call EFUNC(common,log); -}, GVAR(MissionManager) call ["getMissionInterval", []], []] call CFUNC(addPerFrameHandler); + ["INFO", format ["Mission manager started mission %1.", _taskID]] call EFUNC(common,log); + }, GVAR(MissionManager) call ["getMissionInterval", []], []] call CFUNC(addPerFrameHandler); +}; true diff --git a/arma/server/addons/task/functions/prototypes/README.md b/arma/server/addons/task/functions/prototypes/README.md index 40ae95a..c23987c 100644 --- a/arma/server/addons/task/functions/prototypes/README.md +++ b/arma/server/addons/task/functions/prototypes/README.md @@ -7,20 +7,42 @@ loaded for review with `[] call forge_server_task_fnc_initPrototypes;`. Current prototypes: - `TaskInstanceBaseClass` - `EntityControllerBaseClass` +- `TargetEntityController` +- `ShooterEntityController` - `AttackTaskBaseClass` - `HostageTaskBaseClass` - `HostageEntityController` +- `HVTEntityController` +- `CargoEntityController` +- `ProtectedEntityController` +- `IEDEntityController` +- `DefenseEnemyController` - `DefuseTaskBaseClass` +- `DestroyTaskBaseClass` +- `DeliveryTaskBaseClass` +- `HVTTaskBaseClass` +- `DefendTaskBaseClass` Review entry points: - [taskObjectPrototypes.sqf](./taskObjectPrototypes.sqf) - [fnc_initPrototypes.sqf](../functions/prototypes/fnc_initPrototypes.sqf) - [fnc_TaskInstanceBaseClass.sqf](../functions/prototypes/fnc_TaskInstanceBaseClass.sqf) - [fnc_EntityControllerBaseClass.sqf](../functions/prototypes/fnc_EntityControllerBaseClass.sqf) +- [fnc_TargetEntityController.sqf](../functions/prototypes/fnc_TargetEntityController.sqf) +- [fnc_ShooterEntityController.sqf](../functions/prototypes/fnc_ShooterEntityController.sqf) - [fnc_AttackTaskBaseClass.sqf](../functions/prototypes/fnc_AttackTaskBaseClass.sqf) - [fnc_HostageTaskBaseClass.sqf](../functions/prototypes/fnc_HostageTaskBaseClass.sqf) - [fnc_HostageEntityController.sqf](../functions/prototypes/fnc_HostageEntityController.sqf) +- [fnc_HVTEntityController.sqf](../functions/prototypes/fnc_HVTEntityController.sqf) +- [fnc_CargoEntityController.sqf](../functions/prototypes/fnc_CargoEntityController.sqf) +- [fnc_ProtectedEntityController.sqf](../functions/prototypes/fnc_ProtectedEntityController.sqf) +- [fnc_IEDEntityController.sqf](../functions/prototypes/fnc_IEDEntityController.sqf) +- [fnc_DefenseEnemyController.sqf](../functions/prototypes/fnc_DefenseEnemyController.sqf) - [fnc_DefuseTaskBaseClass.sqf](../functions/prototypes/fnc_DefuseTaskBaseClass.sqf) +- [fnc_DestroyTaskBaseClass.sqf](../functions/prototypes/fnc_DestroyTaskBaseClass.sqf) +- [fnc_DeliveryTaskBaseClass.sqf](../functions/prototypes/fnc_DeliveryTaskBaseClass.sqf) +- [fnc_HVTTaskBaseClass.sqf](../functions/prototypes/fnc_HVTTaskBaseClass.sqf) +- [fnc_DefendTaskBaseClass.sqf](../functions/prototypes/fnc_DefendTaskBaseClass.sqf) Purpose: - show what per-task instance objects could look like diff --git a/arma/server/addons/task/functions/prototypes/fnc_AttackTaskBaseClass.sqf b/arma/server/addons/task/functions/prototypes/fnc_AttackTaskBaseClass.sqf index 6592f7f..af20e47 100644 --- a/arma/server/addons/task/functions/prototypes/fnc_AttackTaskBaseClass.sqf +++ b/arma/server/addons/task/functions/prototypes/fnc_AttackTaskBaseClass.sqf @@ -158,7 +158,7 @@ GVAR(AttackTaskBaseClass) = createHashMapFromArray [ GVAR(TaskStore) call ["clearTask", [_taskID]]; }; - if (_endFail) then { ["MissionFail", false] remoteExec ["BIS_fnc_endMission", playerSide]; }; + if (_endFail) then { ["MissionFail", false] remoteExecCall ["BIS_fnc_endMission", playerSide]; }; } else { { deleteVehicle _x } forEach _targets; @@ -174,7 +174,7 @@ GVAR(AttackTaskBaseClass) = createHashMapFromArray [ GVAR(TaskStore) call ["clearTask", [_taskID]]; }; - if (_endSuccess) then { ["MissionSuccess", true] remoteExec ["BIS_fnc_endMission", playerSide]; }; + if (_endSuccess) then { ["MissionSuccess", true] remoteExecCall ["BIS_fnc_endMission", playerSide]; }; }; _self call ["cleanup", []]; diff --git a/arma/server/addons/task/functions/prototypes/fnc_CargoEntityController.sqf b/arma/server/addons/task/functions/prototypes/fnc_CargoEntityController.sqf new file mode 100644 index 0000000..986b2ec --- /dev/null +++ b/arma/server/addons/task/functions/prototypes/fnc_CargoEntityController.sqf @@ -0,0 +1,80 @@ +#include "..\script_component.hpp" + +/* + * Review-only prototype delivery cargo entity controller. + */ + +#pragma hemtt ignore_variables ["_self"] +GVAR(CargoEntityController) = createHashMapFromArray [ + ["#base", GVAR(EntityControllerBaseClass)], + ["#type", "CargoEntityController"], + ["#create", compileFinal { + params [ + ["_taskID", "", [""]], + ["_entity", objNull, [objNull]], + ["_controllerParams", createHashMap, [createHashMap]] + ]; + + _self call ["initializeControllerState", [_taskID, _entity, "cargo", _controllerParams]]; + _self set ["damageThreshold", _controllerParams getOrDefault ["damageThreshold", 0.7]]; + _self set ["damageEventId", -1]; + _self call ["registerInstance", []]; + }], + ["#delete", compileFinal { + _self call ["cleanup", []]; + }], + ["installDamageWarningHandler", compileFinal { + private _entity = _self getOrDefault ["entity", objNull]; + if (isNull _entity) exitWith { false }; + + private _threshold = _self getOrDefault ["damageThreshold", 0.7]; + _entity setVariable [QGVAR(cargoDamageThreshold), _threshold]; + + private _eventId = _entity addEventHandler ["Dammaged", { + params ["_unit"]; + + private _threshold = _unit getVariable [QGVAR(cargoDamageThreshold), 0.7]; + if (damage _unit < _threshold) exitWith {}; + + private _taskID = _unit getVariable ["assignedTask", _unit getVariable [QGVAR(assignedTask), ""]]; + if (_taskID isEqualTo "") exitWith {}; + if (_unit getVariable [QGVAR(cargoDamageWarned), false]) exitWith {}; + + _unit setVariable [QGVAR(cargoDamageWarned), true]; + GVAR(TaskStore) call ["notifyParticipants", [_taskID, "warning", "Tasks", format ["Cargo for task %1 has been severely damaged.", _taskID]]]; + }]; + + _self set ["damageEventId", _eventId]; + true + }], + ["cleanup", compileFinal { + private _entity = _self getOrDefault ["entity", objNull]; + private _eventId = _self getOrDefault ["damageEventId", -1]; + + if (!isNull _entity && { _eventId >= 0 }) then { + _entity removeEventHandler ["Dammaged", _eventId]; + }; + + _self call ["unregisterInstance", []] + }], + ["runLoop", compileFinal { + if !(_self call ["registerTaskEntity", ["cargo"]]) exitWith { + _self call ["markAborted", []]; + _self call ["cleanup", []]; + false + }; + + _self call ["installDamageWarningHandler", []]; + _self call ["markActive", []]; + + waitUntil { + sleep 1; + private _entity = _self getOrDefault ["entity", objNull]; + isNull _entity || { !alive _entity } || { damage _entity >= (_self getOrDefault ["damageThreshold", 0.7]) } + }; + + _self call ["markFinished", []]; + _self call ["cleanup", []]; + true + }] +]; diff --git a/arma/server/addons/task/functions/prototypes/fnc_DefendTaskBaseClass.sqf b/arma/server/addons/task/functions/prototypes/fnc_DefendTaskBaseClass.sqf new file mode 100644 index 0000000..aca6d41 --- /dev/null +++ b/arma/server/addons/task/functions/prototypes/fnc_DefendTaskBaseClass.sqf @@ -0,0 +1,214 @@ +#include "..\script_component.hpp" + +/* + * Review-only prototype defend task class. + */ + +#pragma hemtt ignore_variables ["_self"] +GVAR(DefendTaskBaseClass) = createHashMapFromArray [ + ["#base", GVAR(TaskInstanceBaseClass)], + ["#type", "DefendTaskBaseClass"], + ["#create", compileFinal { + params [ + ["_taskID", "", [""]], + ["_entities", createHashMap, [createHashMap]], + ["_taskParams", createHashMap, [createHashMap]] + ]; + + _self call ["initializeBaseState", [_taskID, "defend", _entities, _taskParams]]; + + _self set ["defenseZone", _taskParams getOrDefault ["defenseZone", ""]]; + _self set ["defendTime", _taskParams getOrDefault ["defendTime", 600]]; + _self set ["waveCount", _taskParams getOrDefault ["waveCount", 3]]; + _self set ["waveCooldown", _taskParams getOrDefault ["waveCooldown", 300]]; + _self set ["minBlufor", _taskParams getOrDefault ["minBlufor", 1]]; + _self set ["nextWaveTime", -1]; + _self set ["currentWave", 0]; + _self set ["zoneEmptyCounter", 0]; + _self set ["warningIssued", false]; + _self set ["useTaskStore", _taskParams getOrDefault ["useTaskStore", false]]; + + _self call ["registerInstance", []]; + }], + ["#delete", compileFinal { + _self call ["unregisterInstance", []]; + }], + ["isValidDefenseZone", compileFinal { + private _defenseZone = _self getOrDefault ["defenseZone", ""]; + _defenseZone isNotEqualTo "" && { markerShape _defenseZone in ["RECTANGLE", "ELLIPSE"] } + }], + ["trackParticipants", compileFinal { + private _taskID = _self getOrDefault ["taskID", ""]; + if (_taskID isEqualTo "" || { !(_self getOrDefault ["useTaskStore", false]) }) exitWith { false }; + + GVAR(TaskStore) call ["trackParticipants", [_taskID, [], _self getOrDefault ["defenseZone", ""], 0]]; + true + }], + ["waitForAssignment", compileFinal { + private _taskID = _self getOrDefault ["taskID", ""]; + if (_taskID isEqualTo "" || { !(_self getOrDefault ["useTaskStore", false]) }) exitWith { true }; + + waitUntil { + sleep 1; + GVAR(TaskStore) call ["isTaskAccepted", [_taskID]] + }; + + true + }], + ["countBluforInZone", compileFinal { + private _defenseZone = _self getOrDefault ["defenseZone", ""]; + if (_defenseZone isEqualTo "") exitWith { 0 }; + + count (allUnits select { _x isKindOf "CAManBase" && { side _x == west } && { alive _x }} inAreaArray _defenseZone) + }], + ["waitForDefenseStart", compileFinal { + private _minBlufor = _self getOrDefault ["minBlufor", 1]; + + waitUntil { + sleep 1; + _self call ["trackParticipants", []]; + + private _ready = (_self call ["countBluforInZone", []]) >= _minBlufor; + if (_ready) then { + _self call ["markActive", []]; + _self set ["nextWaveTime", serverTime]; + + if (_self getOrDefault ["useTaskStore", false]) then { + GVAR(TaskStore) call ["notifyParticipants", [_self getOrDefault ["taskID", ""], "info", "Tasks", "Defense has started. Hold the zone."]]; + }; + }; + + _ready + }; + + true + }], + ["tick", compileFinal { + private _taskID = _self getOrDefault ["taskID", ""]; + private _defenseZone = _self getOrDefault ["defenseZone", ""]; + private _defendTime = _self getOrDefault ["defendTime", 600]; + private _waveCount = _self getOrDefault ["waveCount", 3]; + private _waveCooldown = _self getOrDefault ["waveCooldown", 300]; + private _minBlufor = _self getOrDefault ["minBlufor", 1]; + private _currentWave = _self getOrDefault ["currentWave", 0]; + private _nextWaveTime = _self getOrDefault ["nextWaveTime", -1]; + private _zoneEmptyCounter = _self getOrDefault ["zoneEmptyCounter", 0]; + private _warningIssued = _self getOrDefault ["warningIssued", false]; + private _bluforInZone = _self call ["countBluforInZone", []]; + private _elapsed = serverTime - (_self getOrDefault ["startedAt", serverTime]); + + if (_bluforInZone < _minBlufor) then { + _zoneEmptyCounter = _zoneEmptyCounter + 1; + + if (_zoneEmptyCounter == 15 && { !_warningIssued } && { _self getOrDefault ["useTaskStore", false] }) then { + GVAR(TaskStore) call ["notifyParticipants", [_taskID, "warning", "Tasks", "Defense zone is empty. Return immediately."]]; + _warningIssued = true; + }; + } else { + _zoneEmptyCounter = 0; + _warningIssued = false; + }; + + if (_currentWave < _waveCount && { serverTime >= _nextWaveTime }) then { + [_defenseZone, _taskID, _currentWave] call FUNC(spawnEnemyWave); + + _currentWave = _currentWave + 1; + _nextWaveTime = serverTime + _waveCooldown; + + if (_self getOrDefault ["useTaskStore", false]) then { + GVAR(TaskStore) call ["notifyParticipants", [_taskID, "info", "Tasks", format ["Enemy forces approaching. Wave %1 of %2.", _currentWave, _waveCount]]]; + }; + }; + + _self set ["currentWave", _currentWave]; + _self set ["nextWaveTime", _nextWaveTime]; + _self set ["zoneEmptyCounter", _zoneEmptyCounter]; + _self set ["warningIssued", _warningIssued]; + + createHashMapFromArray [ + ["bluforInZone", _bluforInZone], + ["elapsed", _elapsed], + ["currentWave", _currentWave], + ["waveCount", _waveCount], + ["zoneEmptyCounter", _zoneEmptyCounter], + ["shouldFail", _zoneEmptyCounter >= 30], + ["shouldSucceed", (_bluforInZone >= _minBlufor) && { _elapsed >= _defendTime } && { _currentWave >= _waveCount }] + ] + }], + ["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 ["notifyParticipants", [_taskID, "warning", "Tasks", format ["Task failed: %1 reputation", _ratingFail]]]; + GVAR(TaskStore) call ["applyRatingOutcome", [_taskID, _ratingFail]]; + GVAR(TaskStore) call ["clearTask", [_taskID]]; + }; + + if (_endFail) then { ["MissionFail", false] remoteExecCall ["BIS_fnc_endMission", playerSide]; }; + 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, _rewardData] call FUNC(handleTaskRewards); + [_taskID, "SUCCEEDED"] call BFUNC(taskSetState); + GVAR(TaskStore) call ["setTaskStatus", [_taskID, "succeeded"]]; + + sleep 1; + + GVAR(TaskStore) call ["notifyParticipants", [_taskID, "success", "Tasks", format ["Task completed: %1 reputation, $%2 funds", _ratingSuccess, [_funds] call EFUNC(common,formatNumber)]]]; + GVAR(TaskStore) call ["applyRatingOutcome", [_taskID, _ratingSuccess]]; + GVAR(TaskStore) call ["clearTask", [_taskID]]; + }; + + if (_endSuccess) then { ["MissionSuccess", true] remoteExecCall ["BIS_fnc_endMission", playerSide]; }; + true + }], + ["runLoop", compileFinal { + if !(_self call ["isValidDefenseZone", []]) exitWith { + _self call ["markFailed", ["Invalid defense zone.", createHashMap]]; + _self call ["cleanup", []]; + false + }; + + _self call ["waitForAssignment", []]; + _self call ["waitForDefenseStart", []]; + + while { (_self call ["getStatus", []]) isEqualTo "active" } do { + _self call ["trackParticipants", []]; + private _snapshot = _self call ["tick", []]; + + if (_snapshot getOrDefault ["shouldFail", false]) exitWith { + _self call ["markFailed", ["Defend fail conditions met.", _snapshot]]; + }; + + if (_snapshot getOrDefault ["shouldSucceed", false]) exitWith { + _self call ["markSucceeded", [_snapshot]]; + }; + + sleep 1; + }; + + if ((_self call ["getStatus", []]) isEqualTo "failed") then { + _self call ["handleFailureOutcome", []]; + } else { + _self call ["handleSuccessOutcome", []]; + }; + + _self call ["cleanup", []]; + true + }] +]; diff --git a/arma/server/addons/task/functions/prototypes/fnc_DefenseEnemyController.sqf b/arma/server/addons/task/functions/prototypes/fnc_DefenseEnemyController.sqf new file mode 100644 index 0000000..1f86b57 --- /dev/null +++ b/arma/server/addons/task/functions/prototypes/fnc_DefenseEnemyController.sqf @@ -0,0 +1,52 @@ +#include "..\script_component.hpp" + +/* + * Review-only prototype defense enemy controller. + */ + +#pragma hemtt ignore_variables ["_self"] +GVAR(DefenseEnemyController) = createHashMapFromArray [ + ["#base", GVAR(EntityControllerBaseClass)], + ["#type", "DefenseEnemyController"], + ["#create", compileFinal { + params [ + ["_taskID", "", [""]], + ["_entity", objNull, [objNull]], + ["_controllerParams", createHashMap, [createHashMap]] + ]; + + _self call ["initializeControllerState", [_taskID, _entity, "defense_enemy", _controllerParams]]; + _self set ["defenseZone", _controllerParams getOrDefault ["defenseZone", ""]]; + _self call ["registerInstance", []]; + }], + ["#delete", compileFinal { + _self call ["unregisterInstance", []]; + }], + ["applyInitialState", compileFinal { + private _entity = _self getOrDefault ["entity", objNull]; + if (isNull _entity || { !alive _entity }) exitWith { false }; + + _self call ["assignTaskVariable", []]; + _entity setBehaviour "AWARE"; + _entity setSpeedMode "NORMAL"; + _entity enableDynamicSimulation true; + true + }], + ["runLoop", compileFinal { + if !(_self call ["applyInitialState", []]) exitWith { + _self call ["markAborted", []]; + _self call ["cleanup", []]; + false + }; + + _self call ["markActive", []]; + waitUntil { + sleep 1; + !(_self call ["isEntityUsable", []]) + }; + + _self call ["markFinished", []]; + _self call ["cleanup", []]; + true + }] +]; diff --git a/arma/server/addons/task/functions/prototypes/fnc_DefuseTaskBaseClass.sqf b/arma/server/addons/task/functions/prototypes/fnc_DefuseTaskBaseClass.sqf index 569cade..9917ba0 100644 --- a/arma/server/addons/task/functions/prototypes/fnc_DefuseTaskBaseClass.sqf +++ b/arma/server/addons/task/functions/prototypes/fnc_DefuseTaskBaseClass.sqf @@ -103,6 +103,58 @@ GVAR(DefuseTaskBaseClass) = createHashMapFromArray [ ["shouldSucceed", (_defusedCount >= _requiredDefusals) && { _requiredDefusals > 0 } && { _protectedDestroyed < _maxProtectedLosses || { _maxProtectedLosses <= 0 } }] ] }], + ["handleFailureOutcome", compileFinal { + private _taskID = _self getOrDefault ["taskID", ""]; + private _ieds = _self getOrDefault ["ieds", []]; + private _protected = _self getOrDefault ["protected", []]; + private _rewardData = _self getOrDefault ["rewardData", createHashMap]; + private _ratingFail = _rewardData getOrDefault ["ratingFail", 0]; + private _endFail = (_self getOrDefault ["taskParams", createHashMap]) getOrDefault ["endFail", false]; + + { deleteVehicle _x } forEach _ieds; + { deleteVehicle _x } forEach _protected; + + if (_self getOrDefault ["useTaskStore", false]) then { + [_taskID, "FAILED"] call BFUNC(taskSetState); + GVAR(TaskStore) call ["setTaskStatus", [_taskID, "failed"]]; + + sleep 1; + + GVAR(TaskStore) call ["notifyParticipants", [_taskID, "warning", "Tasks", format ["Task failed: %1 reputation", _ratingFail]]]; + GVAR(TaskStore) call ["applyRatingOutcome", [_taskID, _ratingFail]]; + GVAR(TaskStore) call ["clearTask", [_taskID]]; + }; + + if (_endFail) then { ["MissionFail", false] remoteExecCall ["BIS_fnc_endMission", playerSide]; }; + true + }], + ["handleSuccessOutcome", compileFinal { + private _taskID = _self getOrDefault ["taskID", ""]; + private _ieds = _self getOrDefault ["ieds", []]; + private _protected = _self getOrDefault ["protected", []]; + 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]; + + { deleteVehicle _x } forEach _ieds; + { deleteVehicle _x } forEach _protected; + + if (_self getOrDefault ["useTaskStore", false]) then { + [_taskID, _rewardData] call FUNC(handleTaskRewards); + [_taskID, "SUCCEEDED"] call BFUNC(taskSetState); + GVAR(TaskStore) call ["setTaskStatus", [_taskID, "succeeded"]]; + + sleep 1; + + GVAR(TaskStore) call ["notifyParticipants", [_taskID, "success", "Tasks", format ["Task completed: %1 reputation, $%2 funds", _ratingSuccess, [_funds] call EFUNC(common,formatNumber)]]]; + GVAR(TaskStore) call ["applyRatingOutcome", [_taskID, _ratingSuccess]]; + GVAR(TaskStore) call ["clearTask", [_taskID]]; + }; + + if (_endSuccess) then { ["MissionSuccess", true] remoteExecCall ["BIS_fnc_endMission", playerSide]; }; + true + }], ["runLoop", compileFinal { _self call ["markActive", []]; @@ -120,6 +172,12 @@ GVAR(DefuseTaskBaseClass) = createHashMapFromArray [ sleep 1; }; + if ((_self call ["getStatus", []]) isEqualTo "failed") then { + _self call ["handleFailureOutcome", []]; + } else { + _self call ["handleSuccessOutcome", []]; + }; + _self call ["cleanup", []]; true }] diff --git a/arma/server/addons/task/functions/prototypes/fnc_DeliveryTaskBaseClass.sqf b/arma/server/addons/task/functions/prototypes/fnc_DeliveryTaskBaseClass.sqf new file mode 100644 index 0000000..424df77 --- /dev/null +++ b/arma/server/addons/task/functions/prototypes/fnc_DeliveryTaskBaseClass.sqf @@ -0,0 +1,205 @@ +#include "..\script_component.hpp" + +/* + * Review-only prototype delivery task class. + */ + +#pragma hemtt ignore_variables ["_self"] +GVAR(DeliveryTaskBaseClass) = createHashMapFromArray [ + ["#base", GVAR(TaskInstanceBaseClass)], + ["#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", []]; + count (_self getOrDefault ["cargo", []]) > 0 + }; + } else { + waitUntil { + sleep 1; + count (_self getOrDefault ["cargo", []]) > 0 + }; + }; + + 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 + }], + ["waitForAssignmentIfTimed", compileFinal { + private _timeLimit = _self getOrDefault ["timeLimit", 0]; + private _taskID = _self getOrDefault ["taskID", ""]; + + if (_timeLimit <= 0 || { _taskID isEqualTo "" } || { !(_self getOrDefault ["useTaskStore", false]) }) exitWith { true }; + + waitUntil { + sleep 1; + GVAR(TaskStore) call ["isTaskAccepted", [_taskID]] + }; + + true + }], + ["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 _cargo = _self getOrDefault ["cargo", []]; + private _rewardData = _self getOrDefault ["rewardData", createHashMap]; + private _ratingFail = _rewardData getOrDefault ["ratingFail", 0]; + private _endFail = (_self getOrDefault ["taskParams", createHashMap]) getOrDefault ["endFail", false]; + + { deleteVehicle _x } forEach _cargo; + + if (_self getOrDefault ["useTaskStore", false]) then { + [_taskID, "FAILED"] call BFUNC(taskSetState); + GVAR(TaskStore) call ["setTaskStatus", [_taskID, "failed"]]; + + sleep 1; + + GVAR(TaskStore) call ["notifyParticipants", [_taskID, "warning", "Tasks", format ["Task failed: %1 reputation", _ratingFail]]]; + GVAR(TaskStore) call ["applyRatingOutcome", [_taskID, _ratingFail]]; + GVAR(TaskStore) call ["clearTask", [_taskID]]; + }; + + if (_endFail) then { ["MissionFail", false] remoteExecCall ["BIS_fnc_endMission", playerSide]; }; + true + }], + ["handleSuccessOutcome", compileFinal { + private _taskID = _self getOrDefault ["taskID", ""]; + private _cargo = _self getOrDefault ["cargo", []]; + 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]; + + { deleteVehicle _x } forEach _cargo; + + if (_self getOrDefault ["useTaskStore", false]) then { + [_taskID, _rewardData] call FUNC(handleTaskRewards); + [_taskID, "SUCCEEDED"] call BFUNC(taskSetState); + GVAR(TaskStore) call ["setTaskStatus", [_taskID, "succeeded"]]; + + sleep 1; + + GVAR(TaskStore) call ["notifyParticipants", [_taskID, "success", "Tasks", format ["Task completed: %1 reputation, $%2 funds", _ratingSuccess, [_funds] call EFUNC(common,formatNumber)]]]; + GVAR(TaskStore) call ["applyRatingOutcome", [_taskID, _ratingSuccess]]; + GVAR(TaskStore) call ["clearTask", [_taskID]]; + }; + + if (_endSuccess) then { ["MissionSuccess", true] remoteExecCall ["BIS_fnc_endMission", playerSide]; }; + true + }], + ["runLoop", compileFinal { + _self call ["waitForRequiredEntities", []]; + _self call ["waitForAssignmentIfTimed", []]; + _self call ["markActive", []]; + + while { (_self call ["getStatus", []]) isEqualTo "active" } 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; + }; + + if ((_self call ["getStatus", []]) isEqualTo "failed") then { + _self call ["handleFailureOutcome", []]; + } else { + _self call ["handleSuccessOutcome", []]; + }; + + _self call ["cleanup", []]; + true + }] +]; diff --git a/arma/server/addons/task/functions/prototypes/fnc_DestroyTaskBaseClass.sqf b/arma/server/addons/task/functions/prototypes/fnc_DestroyTaskBaseClass.sqf new file mode 100644 index 0000000..62edf56 --- /dev/null +++ b/arma/server/addons/task/functions/prototypes/fnc_DestroyTaskBaseClass.sqf @@ -0,0 +1,185 @@ +#include "..\script_component.hpp" + +/* + * Review-only prototype destroy task class. + */ + +#pragma hemtt ignore_variables ["_self"] +GVAR(DestroyTaskBaseClass) = createHashMapFromArray [ + ["#base", GVAR(TaskInstanceBaseClass)], + ["#type", "DestroyTaskBaseClass"], + ["#create", compileFinal { + params [ + ["_taskID", "", [""]], + ["_entities", createHashMap, [createHashMap]], + ["_taskParams", createHashMap, [createHashMap]] + ]; + + _self call ["initializeBaseState", [_taskID, "destroy", _entities, _taskParams]]; + + private _targets = +(_entities getOrDefault ["targets", []]); + private _requiredDestroyed = _taskParams getOrDefault ["limitSuccess", -1]; + if (_requiredDestroyed < 0) then { _requiredDestroyed = count _targets; }; + + _self set ["targets", _targets]; + _self set ["requiredDestroyed", _requiredDestroyed]; + _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 _targets = GVAR(TaskStore) call ["getTaskEntities", ["targets", _taskID]]; + _self set ["targets", _targets]; + true + }], + ["trackParticipants", compileFinal { + private _taskID = _self getOrDefault ["taskID", ""]; + if (_taskID isEqualTo "" || { !(_self getOrDefault ["useTaskStore", false]) }) exitWith { false }; + + GVAR(TaskStore) call ["trackParticipants", [_taskID, _self getOrDefault ["targets", []], "", 300]]; + true + }], + ["waitForRequiredEntities", compileFinal { + if (_self getOrDefault ["useTaskStore", false]) then { + waitUntil { + sleep 1; + _self call ["refreshEntitiesFromStore", []]; + _self call ["trackParticipants", []]; + count (_self getOrDefault ["targets", []]) > 0 + }; + } else { + waitUntil { + sleep 1; + count (_self getOrDefault ["targets", []]) > 0 + }; + }; + + private _targets = _self getOrDefault ["targets", []]; + private _taskParams = _self getOrDefault ["taskParams", createHashMap]; + private _requiredDestroyed = _taskParams getOrDefault ["limitSuccess", -1]; + if (_requiredDestroyed < 0) then { _requiredDestroyed = count _targets; }; + + _self set ["requiredDestroyed", _requiredDestroyed]; + true + }], + ["waitForAssignmentIfTimed", compileFinal { + private _timeLimit = _self getOrDefault ["timeLimit", 0]; + private _taskID = _self getOrDefault ["taskID", ""]; + + if (_timeLimit <= 0 || { _taskID isEqualTo "" } || { !(_self getOrDefault ["useTaskStore", false]) }) exitWith { true }; + + waitUntil { + sleep 1; + GVAR(TaskStore) call ["isTaskAccepted", [_taskID]] + }; + + true + }], + ["countDestroyedTargets", compileFinal { + private _targets = _self getOrDefault ["targets", []]; + { !alive _x } count _targets + }], + ["tick", compileFinal { + private _startedAt = _self getOrDefault ["startedAt", -1]; + private _timeLimit = _self getOrDefault ["timeLimit", 0]; + private _destroyed = _self call ["countDestroyedTargets", []]; + private _requiredDestroyed = _self getOrDefault ["requiredDestroyed", 0]; + private _timeExpired = false; + + if (_timeLimit > 0 && { _startedAt >= 0 }) then { + _timeExpired = (serverTime - _startedAt) >= _timeLimit; + }; + + createHashMapFromArray [ + ["destroyed", _destroyed], + ["requiredDestroyed", _requiredDestroyed], + ["timeExpired", _timeExpired], + ["shouldFail", _timeExpired && { _destroyed < _requiredDestroyed }], + ["shouldSucceed", _destroyed >= _requiredDestroyed] + ] + }], + ["handleFailureOutcome", compileFinal { + private _taskID = _self getOrDefault ["taskID", ""]; + private _targets = _self getOrDefault ["targets", []]; + private _rewardData = _self getOrDefault ["rewardData", createHashMap]; + private _ratingFail = _rewardData getOrDefault ["ratingFail", 0]; + private _endFail = (_self getOrDefault ["taskParams", createHashMap]) getOrDefault ["endFail", false]; + + { deleteVehicle _x } forEach _targets; + + if (_self getOrDefault ["useTaskStore", false]) then { + [_taskID, "FAILED"] call BFUNC(taskSetState); + GVAR(TaskStore) call ["setTaskStatus", [_taskID, "failed"]]; + + sleep 1; + + GVAR(TaskStore) call ["notifyParticipants", [_taskID, "warning", "Tasks", format ["Task failed: %1 reputation", _ratingFail]]]; + GVAR(TaskStore) call ["applyRatingOutcome", [_taskID, _ratingFail]]; + GVAR(TaskStore) call ["clearTask", [_taskID]]; + }; + + if (_endFail) then { ["MissionFail", false] remoteExecCall ["BIS_fnc_endMission", playerSide]; }; + true + }], + ["handleSuccessOutcome", compileFinal { + private _taskID = _self getOrDefault ["taskID", ""]; + private _targets = _self getOrDefault ["targets", []]; + 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]; + + { deleteVehicle _x } forEach _targets; + + if (_self getOrDefault ["useTaskStore", false]) then { + [_taskID, _rewardData] call FUNC(handleTaskRewards); + [_taskID, "SUCCEEDED"] call BFUNC(taskSetState); + GVAR(TaskStore) call ["setTaskStatus", [_taskID, "succeeded"]]; + + sleep 1; + + GVAR(TaskStore) call ["notifyParticipants", [_taskID, "success", "Tasks", format ["Task completed: %1 reputation, $%2 funds", _ratingSuccess, [_funds] call EFUNC(common,formatNumber)]]]; + GVAR(TaskStore) call ["applyRatingOutcome", [_taskID, _ratingSuccess]]; + GVAR(TaskStore) call ["clearTask", [_taskID]]; + }; + + if (_endSuccess) then { ["MissionSuccess", true] remoteExecCall ["BIS_fnc_endMission", playerSide]; }; + true + }], + ["runLoop", compileFinal { + _self call ["waitForRequiredEntities", []]; + _self call ["waitForAssignmentIfTimed", []]; + _self call ["markActive", []]; + + while { (_self call ["getStatus", []]) isEqualTo "active" } do { + _self call ["trackParticipants", []]; + private _snapshot = _self call ["tick", []]; + + if (_snapshot getOrDefault ["shouldFail", false]) exitWith { + _self call ["markFailed", ["Destroy fail conditions met.", _snapshot]]; + }; + + if (_snapshot getOrDefault ["shouldSucceed", false]) exitWith { + _self call ["markSucceeded", [_snapshot]]; + }; + + sleep 1; + }; + + if ((_self call ["getStatus", []]) isEqualTo "failed") then { + _self call ["handleFailureOutcome", []]; + } else { + _self call ["handleSuccessOutcome", []]; + }; + + _self call ["cleanup", []]; + true + }] +]; diff --git a/arma/server/addons/task/functions/prototypes/fnc_EntityControllerBaseClass.sqf b/arma/server/addons/task/functions/prototypes/fnc_EntityControllerBaseClass.sqf index 6616bc1..abf4c3d 100644 --- a/arma/server/addons/task/functions/prototypes/fnc_EntityControllerBaseClass.sqf +++ b/arma/server/addons/task/functions/prototypes/fnc_EntityControllerBaseClass.sqf @@ -67,7 +67,39 @@ GVAR(EntityControllerBaseClass) = createHashMapFromArray [ private _entity = _self getOrDefault ["entity", objNull]; if (isNull _entity) exitWith { "" }; - format ["hostage_controller_%1", netId _entity] + format ["%1_controller_%2", _self getOrDefault ["controllerType", "custom"], netId _entity] + }], + ["getTaskID", compileFinal { + _self getOrDefault ["taskID", ""] + }], + ["isEntityUsable", compileFinal { + private _entity = _self getOrDefault ["entity", objNull]; + !isNull _entity && { alive _entity } + }], + ["assignTaskVariable", compileFinal { + private _entity = _self getOrDefault ["entity", objNull]; + private _taskID = _self getOrDefault ["taskID", ""]; + if (isNull _entity || { _taskID isEqualTo "" }) exitWith { false }; + + _entity setVariable ["assignedTask", _taskID, true]; + _entity setVariable [QGVAR(assignedTask), _taskID, true]; + true + }], + ["registerTaskEntity", compileFinal { + params [["_role", "", [""]]]; + + private _taskID = _self getOrDefault ["taskID", ""]; + private _entity = _self getOrDefault ["entity", objNull]; + private _useTaskStore = (_self getOrDefault ["controllerParams", createHashMap]) getOrDefault ["useTaskStore", true]; + + if (_role isEqualTo "" || { _taskID isEqualTo "" } || { isNull _entity }) exitWith { false }; + _self call ["assignTaskVariable", []]; + + if (_useTaskStore) then { + GVAR(TaskStore) call ["registerTaskEntity", [_role, _taskID, _entity]]; + }; + + true }], ["registerInstance", compileFinal { private _registryKey = _self call ["getRegistryKey", []]; @@ -75,6 +107,7 @@ GVAR(EntityControllerBaseClass) = createHashMapFromArray [ private _registry = missionNamespace getVariable [QGVAR(PrototypeControllerInstances), createHashMap]; _registry set [_registryKey, _self]; + missionNamespace setVariable [QGVAR(PrototypeControllerInstances), _registry]; missionNamespace setVariable [_registryKey, _self]; true }], diff --git a/arma/server/addons/task/functions/prototypes/fnc_HVTEntityController.sqf b/arma/server/addons/task/functions/prototypes/fnc_HVTEntityController.sqf new file mode 100644 index 0000000..f7eae62 --- /dev/null +++ b/arma/server/addons/task/functions/prototypes/fnc_HVTEntityController.sqf @@ -0,0 +1,72 @@ +#include "..\script_component.hpp" + +/* + * Review-only prototype HVT entity controller. + */ + +#pragma hemtt ignore_variables ["_self"] +GVAR(HVTEntityController) = createHashMapFromArray [ + ["#base", GVAR(EntityControllerBaseClass)], + ["#type", "HVTEntityController"], + ["#create", compileFinal { + params [ + ["_taskID", "", [""]], + ["_entity", objNull, [objNull]], + ["_controllerParams", createHashMap, [createHashMap]] + ]; + + _self call ["initializeControllerState", [_taskID, _entity, "hvt", _controllerParams]]; + _self set ["captureRadius", _controllerParams getOrDefault ["captureRadius", 2]]; + _self call ["registerInstance", []]; + }], + ["#delete", compileFinal { + _self call ["unregisterInstance", []]; + }], + ["findNearbyCapturer", compileFinal { + private _entity = _self getOrDefault ["entity", objNull]; + if (isNull _entity || { !alive _entity }) exitWith { objNull }; + + private _radius = _self getOrDefault ["captureRadius", 2]; + private _nearPlayers = allPlayers inAreaArray [ASLToAGL getPosASL _entity, _radius, _radius, 0, false, 2]; + if (_nearPlayers isEqualTo []) exitWith { objNull }; + + _nearPlayers select 0 + }], + ["transitionToCaptured", compileFinal { + private _entity = _self getOrDefault ["entity", objNull]; + if (isNull _entity || { !alive _entity }) exitWith { false }; + + _entity setCaptive true; + doStop _entity; + true + }], + ["runLoop", compileFinal { + if !(_self call ["registerTaskEntity", ["hvts"]]) exitWith { + _self call ["markAborted", []]; + _self call ["cleanup", []]; + false + }; + + _self call ["markActive", []]; + + private _capturer = objNull; + waitUntil { + sleep 1; + if !(_self call ["isEntityUsable", []]) exitWith { true }; + + _capturer = _self call ["findNearbyCapturer", []]; + !isNull _capturer + }; + + if !(_self call ["isEntityUsable", []]) exitWith { + _self call ["markAborted", []]; + _self call ["cleanup", []]; + false + }; + + _self call ["transitionToCaptured", []]; + _self call ["markFinished", []]; + _self call ["cleanup", []]; + true + }] +]; diff --git a/arma/server/addons/task/functions/prototypes/fnc_HVTTaskBaseClass.sqf b/arma/server/addons/task/functions/prototypes/fnc_HVTTaskBaseClass.sqf new file mode 100644 index 0000000..9ba2d70 --- /dev/null +++ b/arma/server/addons/task/functions/prototypes/fnc_HVTTaskBaseClass.sqf @@ -0,0 +1,212 @@ +#include "..\script_component.hpp" + +/* + * Review-only prototype HVT task class. + */ + +#pragma hemtt ignore_variables ["_self"] +GVAR(HVTTaskBaseClass) = createHashMapFromArray [ + ["#base", GVAR(TaskInstanceBaseClass)], + ["#type", "HVTTaskBaseClass"], + ["#create", compileFinal { + params [ + ["_taskID", "", [""]], + ["_entities", createHashMap, [createHashMap]], + ["_taskParams", createHashMap, [createHashMap]] + ]; + + _self call ["initializeBaseState", [_taskID, "hvt", _entities, _taskParams]]; + + private _hvts = +(_entities getOrDefault ["hvts", []]); + private _required = _taskParams getOrDefault ["limitSuccess", -1]; + if (_required < 0) then { _required = count _hvts; }; + + private _maxKilled = _taskParams getOrDefault ["limitFail", -1]; + if (_maxKilled < 0) then { _maxKilled = count _hvts; }; + + private _type = _taskParams getOrDefault ["type", []]; + private _captureHvt = _taskParams getOrDefault ["captureHvt", true]; + private _capture = _captureHvt; + private _eliminate = !_captureHvt; + + if (_type isEqualType [] && { count _type >= 2 }) then { + _capture = _type param [0, true, [false]]; + _eliminate = _type param [1, false, [false]]; + }; + + _self set ["hvts", _hvts]; + _self set ["extractionZone", _taskParams getOrDefault ["extractionZone", ""]]; + _self set ["required", _required]; + _self set ["maxKilled", _maxKilled]; + _self set ["capture", _capture]; + _self set ["eliminate", _eliminate]; + _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 _hvts = GVAR(TaskStore) call ["getTaskEntities", ["hvts", _taskID]]; + _self set ["hvts", _hvts]; + true + }], + ["trackParticipants", compileFinal { + private _taskID = _self getOrDefault ["taskID", ""]; + if (_taskID isEqualTo "" || { !(_self getOrDefault ["useTaskStore", false]) }) exitWith { false }; + + GVAR(TaskStore) call ["trackParticipants", [_taskID, _self getOrDefault ["hvts", []], _self getOrDefault ["extractionZone", ""], 250]]; + true + }], + ["waitForRequiredEntities", compileFinal { + if (_self getOrDefault ["useTaskStore", false]) then { + waitUntil { + sleep 1; + _self call ["refreshEntitiesFromStore", []]; + _self call ["trackParticipants", []]; + count (_self getOrDefault ["hvts", []]) > 0 + }; + } else { + waitUntil { + sleep 1; + count (_self getOrDefault ["hvts", []]) > 0 + }; + }; + + private _hvts = _self getOrDefault ["hvts", []]; + private _taskParams = _self getOrDefault ["taskParams", createHashMap]; + private _required = _taskParams getOrDefault ["limitSuccess", -1]; + if (_required < 0) then { _required = count _hvts; }; + + private _maxKilled = _taskParams getOrDefault ["limitFail", -1]; + if (_maxKilled < 0) then { _maxKilled = count _hvts; }; + + _self set ["required", _required]; + _self set ["maxKilled", _maxKilled]; + true + }], + ["waitForAssignmentIfTimed", compileFinal { + private _timeLimit = _self getOrDefault ["timeLimit", 0]; + private _taskID = _self getOrDefault ["taskID", ""]; + + if (_timeLimit <= 0 || { _taskID isEqualTo "" } || { !(_self getOrDefault ["useTaskStore", false]) }) exitWith { true }; + + waitUntil { + sleep 1; + GVAR(TaskStore) call ["isTaskAccepted", [_taskID]] + }; + + true + }], + ["tick", compileFinal { + private _startedAt = _self getOrDefault ["startedAt", -1]; + private _timeLimit = _self getOrDefault ["timeLimit", 0]; + private _hvts = _self getOrDefault ["hvts", []]; + private _extZone = _self getOrDefault ["extractionZone", ""]; + private _capture = _self getOrDefault ["capture", true]; + private _eliminate = _self getOrDefault ["eliminate", false]; + private _required = _self getOrDefault ["required", 0]; + private _maxKilled = _self getOrDefault ["maxKilled", 0]; + private _captives = { captive _x } count _hvts; + private _killed = { !alive _x } count _hvts; + private _inZone = if (_extZone isEqualTo "") then { 0 } else { { _x inArea _extZone } count _hvts }; + private _timeExpired = false; + + if (_timeLimit > 0 && { _startedAt >= 0 }) then { + _timeExpired = (serverTime - _startedAt) >= _timeLimit; + }; + + createHashMapFromArray [ + ["captives", _captives], + ["killed", _killed], + ["inZone", _inZone], + ["required", _required], + ["maxKilled", _maxKilled], + ["timeExpired", _timeExpired], + ["shouldFail", (_capture && { _killed >= _maxKilled }) || { _timeExpired && { (_capture && { _captives < _required }) || { _eliminate && { _killed < _required } } } }], + ["shouldSucceed", (_capture && { _inZone >= _required } && { _killed < _maxKilled }) || { _eliminate && { _killed >= _required } }] + ] + }], + ["handleFailureOutcome", compileFinal { + private _taskID = _self getOrDefault ["taskID", ""]; + private _hvts = _self getOrDefault ["hvts", []]; + private _rewardData = _self getOrDefault ["rewardData", createHashMap]; + private _ratingFail = _rewardData getOrDefault ["ratingFail", 0]; + private _endFail = (_self getOrDefault ["taskParams", createHashMap]) getOrDefault ["endFail", false]; + + { deleteVehicle _x } forEach _hvts; + + if (_self getOrDefault ["useTaskStore", false]) then { + [_taskID, "FAILED"] call BFUNC(taskSetState); + GVAR(TaskStore) call ["setTaskStatus", [_taskID, "failed"]]; + + sleep 1; + + GVAR(TaskStore) call ["notifyParticipants", [_taskID, "warning", "Tasks", format ["Task failed: %1 reputation", _ratingFail]]]; + GVAR(TaskStore) call ["applyRatingOutcome", [_taskID, _ratingFail]]; + GVAR(TaskStore) call ["clearTask", [_taskID]]; + }; + + if (_endFail) then { ["MissionFail", false] remoteExecCall ["BIS_fnc_endMission", playerSide]; }; + true + }], + ["handleSuccessOutcome", compileFinal { + private _taskID = _self getOrDefault ["taskID", ""]; + private _hvts = _self getOrDefault ["hvts", []]; + 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]; + + { deleteVehicle _x } forEach _hvts; + + if (_self getOrDefault ["useTaskStore", false]) then { + [_taskID, _rewardData] call FUNC(handleTaskRewards); + [_taskID, "SUCCEEDED"] call BFUNC(taskSetState); + GVAR(TaskStore) call ["setTaskStatus", [_taskID, "succeeded"]]; + + sleep 1; + + GVAR(TaskStore) call ["notifyParticipants", [_taskID, "success", "Tasks", format ["Task completed: %1 reputation, $%2 funds", _ratingSuccess, [_funds] call EFUNC(common,formatNumber)]]]; + GVAR(TaskStore) call ["applyRatingOutcome", [_taskID, _ratingSuccess]]; + GVAR(TaskStore) call ["clearTask", [_taskID]]; + }; + + if (_endSuccess) then { ["MissionSuccess", true] remoteExecCall ["BIS_fnc_endMission", playerSide]; }; + true + }], + ["runLoop", compileFinal { + _self call ["waitForRequiredEntities", []]; + _self call ["waitForAssignmentIfTimed", []]; + _self call ["markActive", []]; + + while { (_self call ["getStatus", []]) isEqualTo "active" } do { + _self call ["trackParticipants", []]; + private _snapshot = _self call ["tick", []]; + + if (_snapshot getOrDefault ["shouldFail", false]) exitWith { + _self call ["markFailed", ["HVT fail conditions met.", _snapshot]]; + }; + + if (_snapshot getOrDefault ["shouldSucceed", false]) exitWith { + _self call ["markSucceeded", [_snapshot]]; + }; + + sleep 1; + }; + + if ((_self call ["getStatus", []]) isEqualTo "failed") then { + _self call ["handleFailureOutcome", []]; + } else { + _self call ["handleSuccessOutcome", []]; + }; + + _self call ["cleanup", []]; + true + }] +]; diff --git a/arma/server/addons/task/functions/prototypes/fnc_HostageTaskBaseClass.sqf b/arma/server/addons/task/functions/prototypes/fnc_HostageTaskBaseClass.sqf index 0685cfe..8456fd3 100644 --- a/arma/server/addons/task/functions/prototypes/fnc_HostageTaskBaseClass.sqf +++ b/arma/server/addons/task/functions/prototypes/fnc_HostageTaskBaseClass.sqf @@ -60,12 +60,21 @@ GVAR(HostageTaskBaseClass) = createHashMapFromArray [ private _maxHostageLosses = _taskParams getOrDefault ["limitFail", -1]; if (_maxHostageLosses < 0) then { _maxHostageLosses = count _hostages; }; + private _type = _taskParams getOrDefault ["type", []]; + private _cbrn = _taskParams getOrDefault ["cbrn", false]; + private _execution = _taskParams getOrDefault ["execution", false]; + + if (_type isEqualType [] && { count _type >= 2 }) then { + _cbrn = _type param [0, false, [false]]; + _execution = _type param [1, true, [false]]; + }; + _self set ["hostages", _hostages]; _self set ["shooters", _shooters]; _self set ["extractionZone", _taskParams getOrDefault ["extractionZone", ""]]; _self set ["timeLimit", _taskParams getOrDefault ["timeLimit", 0]]; - _self set ["execution", _taskParams getOrDefault ["execution", false]]; - _self set ["cbrn", _taskParams getOrDefault ["cbrn", false]]; + _self set ["execution", _execution]; + _self set ["cbrn", _cbrn]; _self set ["cbrnZone", _taskParams getOrDefault ["cbrnZone", ""]]; _self set ["useTaskStore", _taskParams getOrDefault ["useTaskStore", false]]; _self set ["requiredRescues", _requiredRescues]; diff --git a/arma/server/addons/task/functions/prototypes/fnc_IEDEntityController.sqf b/arma/server/addons/task/functions/prototypes/fnc_IEDEntityController.sqf new file mode 100644 index 0000000..08baa0d --- /dev/null +++ b/arma/server/addons/task/functions/prototypes/fnc_IEDEntityController.sqf @@ -0,0 +1,88 @@ +#include "..\script_component.hpp" + +/* + * Review-only prototype IED entity controller. + */ + +#pragma hemtt ignore_variables ["_self"] +GVAR(IEDEntityController) = createHashMapFromArray [ + ["#base", GVAR(EntityControllerBaseClass)], + ["#type", "IEDEntityController"], + ["#create", compileFinal { + params [ + ["_taskID", "", [""]], + ["_entity", objNull, [objNull]], + ["_controllerParams", createHashMap, [createHashMap]] + ]; + + _self call ["initializeControllerState", [_taskID, _entity, "ied", _controllerParams]]; + _self set ["countdown", _controllerParams getOrDefault ["countdown", _controllerParams getOrDefault ["iedTimer", 0]]]; + _self set ["waitForAcceptance", _controllerParams getOrDefault ["waitForAcceptance", true]]; + _self call ["registerInstance", []]; + }], + ["#delete", compileFinal { + _self call ["unregisterInstance", []]; + }], + ["waitForAssignment", compileFinal { + private _taskID = _self getOrDefault ["taskID", ""]; + if (_taskID isEqualTo "" || { !(_self getOrDefault ["waitForAcceptance", true]) }) exitWith { true }; + + waitUntil { + sleep 1; + GVAR(TaskStore) call ["isTaskAccepted", [_taskID]] + }; + + true + }], + ["playCountdownSound", compileFinal { + params [["_timeRemaining", 0, [0]]]; + + private _entity = _self getOrDefault ["entity", objNull]; + if (isNull _entity) exitWith { false }; + + if (_timeRemaining > 10) exitWith { _entity say3D "FORGE_timerBeep"; true }; + if (_timeRemaining > 5) exitWith { _entity say3D "FORGE_timerBeepShort"; true }; + + _entity say3D "FORGE_timerEnd"; + true + }], + ["detonate", compileFinal { + private _entity = _self getOrDefault ["entity", objNull]; + if (isNull _entity || { !alive _entity }) exitWith { false }; + + _entity setDamage 1; + true + }], + ["runLoop", compileFinal { + private _countdown = _self getOrDefault ["countdown", 0]; + if (_countdown <= 0) exitWith { + _self call ["markAborted", []]; + _self call ["cleanup", []]; + false + }; + + if !(_self call ["registerTaskEntity", ["ieds"]]) exitWith { + _self call ["markAborted", []]; + _self call ["cleanup", []]; + false + }; + + _self call ["waitForAssignment", []]; + _self call ["markActive", []]; + + while { (_self call ["isEntityUsable", []]) && { _countdown > 0 } } do { + _self call ["playCountdownSound", [_countdown]]; + _countdown = _countdown - 1; + _self set ["countdown", _countdown]; + sleep 1; + }; + + if ((_self call ["isEntityUsable", []]) && { _countdown <= 0 }) then { + _self call ["detonate", []]; + }; + + _self call ["markFinished", []]; + _self call ["cleanup", []]; + true + }] +]; diff --git a/arma/server/addons/task/functions/prototypes/fnc_ProtectedEntityController.sqf b/arma/server/addons/task/functions/prototypes/fnc_ProtectedEntityController.sqf new file mode 100644 index 0000000..4f608dc --- /dev/null +++ b/arma/server/addons/task/functions/prototypes/fnc_ProtectedEntityController.sqf @@ -0,0 +1,41 @@ +#include "..\script_component.hpp" + +/* + * Review-only prototype protected entity controller. + */ + +#pragma hemtt ignore_variables ["_self"] +GVAR(ProtectedEntityController) = createHashMapFromArray [ + ["#base", GVAR(EntityControllerBaseClass)], + ["#type", "ProtectedEntityController"], + ["#create", compileFinal { + params [ + ["_taskID", "", [""]], + ["_entity", objNull, [objNull]], + ["_controllerParams", createHashMap, [createHashMap]] + ]; + + _self call ["initializeControllerState", [_taskID, _entity, "protected", _controllerParams]]; + _self call ["registerInstance", []]; + }], + ["#delete", compileFinal { + _self call ["unregisterInstance", []]; + }], + ["runLoop", compileFinal { + if !(_self call ["registerTaskEntity", ["entities"]]) exitWith { + _self call ["markAborted", []]; + _self call ["cleanup", []]; + false + }; + + _self call ["markActive", []]; + waitUntil { + sleep 1; + !(_self call ["isEntityUsable", []]) + }; + + _self call ["markFinished", []]; + _self call ["cleanup", []]; + true + }] +]; diff --git a/arma/server/addons/task/functions/prototypes/fnc_ShooterEntityController.sqf b/arma/server/addons/task/functions/prototypes/fnc_ShooterEntityController.sqf new file mode 100644 index 0000000..f70e1f3 --- /dev/null +++ b/arma/server/addons/task/functions/prototypes/fnc_ShooterEntityController.sqf @@ -0,0 +1,41 @@ +#include "..\script_component.hpp" + +/* + * Review-only prototype shooter entity controller. + */ + +#pragma hemtt ignore_variables ["_self"] +GVAR(ShooterEntityController) = createHashMapFromArray [ + ["#base", GVAR(EntityControllerBaseClass)], + ["#type", "ShooterEntityController"], + ["#create", compileFinal { + params [ + ["_taskID", "", [""]], + ["_entity", objNull, [objNull]], + ["_controllerParams", createHashMap, [createHashMap]] + ]; + + _self call ["initializeControllerState", [_taskID, _entity, "shooter", _controllerParams]]; + _self call ["registerInstance", []]; + }], + ["#delete", compileFinal { + _self call ["unregisterInstance", []]; + }], + ["runLoop", compileFinal { + if !(_self call ["registerTaskEntity", ["shooters"]]) exitWith { + _self call ["markAborted", []]; + _self call ["cleanup", []]; + false + }; + + _self call ["markActive", []]; + waitUntil { + sleep 1; + !(_self call ["isEntityUsable", []]) + }; + + _self call ["markFinished", []]; + _self call ["cleanup", []]; + true + }] +]; diff --git a/arma/server/addons/task/functions/prototypes/fnc_TargetEntityController.sqf b/arma/server/addons/task/functions/prototypes/fnc_TargetEntityController.sqf new file mode 100644 index 0000000..02b5d03 --- /dev/null +++ b/arma/server/addons/task/functions/prototypes/fnc_TargetEntityController.sqf @@ -0,0 +1,41 @@ +#include "..\script_component.hpp" + +/* + * Review-only prototype target entity controller. + */ + +#pragma hemtt ignore_variables ["_self"] +GVAR(TargetEntityController) = createHashMapFromArray [ + ["#base", GVAR(EntityControllerBaseClass)], + ["#type", "TargetEntityController"], + ["#create", compileFinal { + params [ + ["_taskID", "", [""]], + ["_entity", objNull, [objNull]], + ["_controllerParams", createHashMap, [createHashMap]] + ]; + + _self call ["initializeControllerState", [_taskID, _entity, "target", _controllerParams]]; + _self call ["registerInstance", []]; + }], + ["#delete", compileFinal { + _self call ["unregisterInstance", []]; + }], + ["runLoop", compileFinal { + if !(_self call ["registerTaskEntity", ["targets"]]) exitWith { + _self call ["markAborted", []]; + _self call ["cleanup", []]; + false + }; + + _self call ["markActive", []]; + waitUntil { + sleep 1; + !(_self call ["isEntityUsable", []]) + }; + + _self call ["markFinished", []]; + _self call ["cleanup", []]; + true + }] +]; diff --git a/arma/server/addons/task/functions/prototypes/fnc_TaskInstanceBaseClass.sqf b/arma/server/addons/task/functions/prototypes/fnc_TaskInstanceBaseClass.sqf index 87782fa..a92b769 100644 --- a/arma/server/addons/task/functions/prototypes/fnc_TaskInstanceBaseClass.sqf +++ b/arma/server/addons/task/functions/prototypes/fnc_TaskInstanceBaseClass.sqf @@ -95,6 +95,7 @@ GVAR(TaskInstanceBaseClass) = createHashMapFromArray [ private _registry = missionNamespace getVariable [QGVAR(PrototypeTaskInstances), createHashMap]; _registry set [_registryKey, _self]; + missionNamespace setVariable [QGVAR(PrototypeTaskInstances), _registry]; missionNamespace setVariable [_registryKey, _self]; true }], diff --git a/arma/server/addons/task/functions/prototypes/fnc_initPrototypes.sqf b/arma/server/addons/task/functions/prototypes/fnc_initPrototypes.sqf index a40f107..d75e211 100644 --- a/arma/server/addons/task/functions/prototypes/fnc_initPrototypes.sqf +++ b/arma/server/addons/task/functions/prototypes/fnc_initPrototypes.sqf @@ -30,7 +30,18 @@ [] call FUNC(AttackTaskBaseClass); [] call FUNC(HostageTaskBaseClass); [] call FUNC(HostageEntityController); +[] call FUNC(TargetEntityController); +[] call FUNC(ShooterEntityController); +[] call FUNC(HVTEntityController); +[] call FUNC(CargoEntityController); +[] call FUNC(ProtectedEntityController); +[] call FUNC(IEDEntityController); +[] call FUNC(DefenseEnemyController); [] call FUNC(DefuseTaskBaseClass); +[] call FUNC(DestroyTaskBaseClass); +[] call FUNC(DeliveryTaskBaseClass); +[] call FUNC(HVTTaskBaseClass); +[] call FUNC(DefendTaskBaseClass); createHashMapFromArray [ ["TaskInstanceBaseClass", GVAR(TaskInstanceBaseClass)], @@ -38,5 +49,16 @@ createHashMapFromArray [ ["AttackTaskBaseClass", GVAR(AttackTaskBaseClass)], ["HostageTaskBaseClass", GVAR(HostageTaskBaseClass)], ["HostageEntityController", GVAR(HostageEntityController)], - ["DefuseTaskBaseClass", GVAR(DefuseTaskBaseClass)] + ["TargetEntityController", GVAR(TargetEntityController)], + ["ShooterEntityController", GVAR(ShooterEntityController)], + ["HVTEntityController", GVAR(HVTEntityController)], + ["CargoEntityController", GVAR(CargoEntityController)], + ["ProtectedEntityController", GVAR(ProtectedEntityController)], + ["IEDEntityController", GVAR(IEDEntityController)], + ["DefenseEnemyController", GVAR(DefenseEnemyController)], + ["DefuseTaskBaseClass", GVAR(DefuseTaskBaseClass)], + ["DestroyTaskBaseClass", GVAR(DestroyTaskBaseClass)], + ["DeliveryTaskBaseClass", GVAR(DeliveryTaskBaseClass)], + ["HVTTaskBaseClass", GVAR(HVTTaskBaseClass)], + ["DefendTaskBaseClass", GVAR(DefendTaskBaseClass)] ] diff --git a/arma/server/addons/task/initSettings.inc.sqf b/arma/server/addons/task/initSettings.inc.sqf new file mode 100644 index 0000000..151813a --- /dev/null +++ b/arma/server/addons/task/initSettings.inc.sqf @@ -0,0 +1,5 @@ +[ + QGVAR(enableGenerator), "CHECKBOX", + [LSTRING(enableGenerator), LSTRING(enableGeneratorTooltip)], + _category, false, true +] call CBA_fnc_addSetting; diff --git a/arma/server/addons/task/stringtable.xml b/arma/server/addons/task/stringtable.xml index ea8a314..5464616 100644 --- a/arma/server/addons/task/stringtable.xml +++ b/arma/server/addons/task/stringtable.xml @@ -4,5 +4,11 @@ Task + + Enable Generator + + + Enable Task Generator +