From 9deb73ec8ef5cbfeecacacbecb9447d7edbda87c Mon Sep 17 00:00:00 2001 From: Jacob Schmidt Date: Fri, 15 May 2026 18:50:28 -0500 Subject: [PATCH] Migrate task logic to object classes - Move task implementations from prototype scripts into `functions/objects` - Keep public task functions as compatibility adapters - Update docs and init wiring for the new object-based layout --- arma/server/addons/task/README.md | 19 +- arma/server/addons/task/XEH_PREP.hpp | 36 ++- arma/server/addons/task/XEH_postInit.sqf | 3 + .../helpers => backup}/fnc_heartBeat.sqf | 0 .../addons/task/functions/fnc_attack.sqf | 2 +- .../addons/task/functions/fnc_defend.sqf | 155 +++--------- .../addons/task/functions/fnc_defuse.sqf | 150 ++++-------- .../addons/task/functions/fnc_delivery.sqf | 139 +++-------- .../addons/task/functions/fnc_destroy.sqf | 153 ++++-------- .../addons/task/functions/fnc_hostage.sqf | 226 ++++-------------- arma/server/addons/task/functions/fnc_hvt.sqf | 175 ++++---------- .../addons/task/functions/fnc_makeCargo.sqf | 39 +-- .../addons/task/functions/fnc_makeHVT.sqf | 29 +-- .../addons/task/functions/fnc_makeHostage.sqf | 35 +-- .../addons/task/functions/fnc_makeIED.sqf | 34 ++- .../addons/task/functions/fnc_makeObject.sqf | 27 +-- .../addons/task/functions/fnc_makeShooter.sqf | 27 +-- .../addons/task/functions/fnc_makeTarget.sqf | 27 +-- .../addons/task/functions/objects/README.md | 62 +++++ .../fnc_AttackTaskBaseClass.sqf | 6 +- .../fnc_CargoEntityController.sqf | 6 +- .../fnc_DefendTaskBaseClass.sqf | 2 +- .../fnc_DefenseEnemyController.sqf | 2 +- .../fnc_DefuseTaskBaseClass.sqf | 86 ++++++- .../fnc_DeliveryTaskBaseClass.sqf | 2 +- .../fnc_DestroyTaskBaseClass.sqf | 2 +- .../fnc_EntityControllerBaseClass.sqf | 10 +- .../fnc_HVTEntityController.sqf | 2 +- .../fnc_HVTTaskBaseClass.sqf | 28 ++- .../fnc_HostageEntityController.sqf | 6 +- .../fnc_HostageTaskBaseClass.sqf | 6 +- .../fnc_IEDEntityController.sqf | 2 +- .../fnc_ProtectedEntityController.sqf | 2 +- .../fnc_ShooterEntityController.sqf | 2 +- .../fnc_TargetEntityController.sqf | 2 +- .../fnc_TaskInstanceBaseClass.sqf | 10 +- .../task/functions/prototypes/README.md | 66 ----- .../prototypes/fnc_initPrototypes.sqf | 64 ----- 38 files changed, 548 insertions(+), 1096 deletions(-) rename arma/server/addons/task/{functions/helpers => backup}/fnc_heartBeat.sqf (100%) create mode 100644 arma/server/addons/task/functions/objects/README.md rename arma/server/addons/task/functions/{prototypes => objects}/fnc_AttackTaskBaseClass.sqf (97%) rename arma/server/addons/task/functions/{prototypes => objects}/fnc_CargoEntityController.sqf (94%) rename arma/server/addons/task/functions/{prototypes => objects}/fnc_DefendTaskBaseClass.sqf (99%) rename arma/server/addons/task/functions/{prototypes => objects}/fnc_DefenseEnemyController.sqf (96%) rename arma/server/addons/task/functions/{prototypes => objects}/fnc_DefuseTaskBaseClass.sqf (67%) rename arma/server/addons/task/functions/{prototypes => objects}/fnc_DeliveryTaskBaseClass.sqf (99%) rename arma/server/addons/task/functions/{prototypes => objects}/fnc_DestroyTaskBaseClass.sqf (99%) rename arma/server/addons/task/functions/{prototypes => objects}/fnc_EntityControllerBaseClass.sqf (93%) rename arma/server/addons/task/functions/{prototypes => objects}/fnc_HVTEntityController.sqf (97%) rename arma/server/addons/task/functions/{prototypes => objects}/fnc_HVTTaskBaseClass.sqf (90%) rename arma/server/addons/task/functions/{prototypes => objects}/fnc_HostageEntityController.sqf (94%) rename arma/server/addons/task/functions/{prototypes => objects}/fnc_HostageTaskBaseClass.sqf (98%) rename arma/server/addons/task/functions/{prototypes => objects}/fnc_IEDEntityController.sqf (98%) rename arma/server/addons/task/functions/{prototypes => objects}/fnc_ProtectedEntityController.sqf (95%) rename arma/server/addons/task/functions/{prototypes => objects}/fnc_ShooterEntityController.sqf (95%) rename arma/server/addons/task/functions/{prototypes => objects}/fnc_TargetEntityController.sqf (95%) rename arma/server/addons/task/functions/{prototypes => objects}/fnc_TaskInstanceBaseClass.sqf (95%) delete mode 100644 arma/server/addons/task/functions/prototypes/README.md delete mode 100644 arma/server/addons/task/functions/prototypes/fnc_initPrototypes.sqf diff --git a/arma/server/addons/task/README.md b/arma/server/addons/task/README.md index e651fcc..db86626 100644 --- a/arma/server/addons/task/README.md +++ b/arma/server/addons/task/README.md @@ -41,17 +41,17 @@ system intentionally starts clean after each server or mission restart. - defuse progress - per-task entity registries for cargo, hostages, HVTs, IEDs, protected entities, shooters, and targets -### Object Model Prototype -A review-only prototype for object-based task instances lives under -`prototypes/`. It is not wired into runtime. +### Object Model +Object-style task instances and entity controllers live under +`functions/objects/` and are initialized directly from `XEH_preInit.sqf`. -- `forge_server_task_fnc_initPrototypes` -- `prototypes/README.md` +- `TaskInstanceBaseClass` +- `EntityControllerBaseClass` +- `functions/objects/README.md` -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. +The task functions are compatibility adapters around these object-style task +classes. This keeps the public task function names stable while moving stateful +task behavior into per-task `createHashMapObject` instances. ### Reward Handling `fnc_handleTaskRewards.sqf` applies org-owned rewards: @@ -212,6 +212,7 @@ If you want the accepting player's org to own the task rewards, use `fnc_handler - compiles functions - initializes `TaskStore` - `XEH_postInit.sqf` + - registers temporary task lifecycle event logs for migration testing - registers the ACE defuse event hook ## Notes diff --git a/arma/server/addons/task/XEH_PREP.hpp b/arma/server/addons/task/XEH_PREP.hpp index 2c3e5f2..d417e5e 100644 --- a/arma/server/addons/task/XEH_PREP.hpp +++ b/arma/server/addons/task/XEH_PREP.hpp @@ -19,7 +19,6 @@ PREP(initTaskStore); PREP_SUBDIR(generators,attackMissionGenerator); PREP_SUBDIR(helpers,handleTaskRewards); -PREP_SUBDIR(helpers,heartBeat); PREP_SUBDIR(helpers,parseRewards); PREP_SUBDIR(helpers,spawnEnemyWave); PREP_SUBDIR(helpers,startTask); @@ -37,21 +36,20 @@ PREP_SUBDIR(modules,hvtModule); PREP_SUBDIR(modules,protectedModule); PREP_SUBDIR(modules,shootersModule); -PREP_SUBDIR(prototypes,initPrototypes); -PREP_SUBDIR(prototypes,TaskInstanceBaseClass); -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); +PREP_SUBDIR(objects,TaskInstanceBaseClass); +PREP_SUBDIR(objects,EntityControllerBaseClass); +PREP_SUBDIR(objects,AttackTaskBaseClass); +PREP_SUBDIR(objects,HostageTaskBaseClass); +PREP_SUBDIR(objects,HostageEntityController); +PREP_SUBDIR(objects,TargetEntityController); +PREP_SUBDIR(objects,ShooterEntityController); +PREP_SUBDIR(objects,HVTEntityController); +PREP_SUBDIR(objects,CargoEntityController); +PREP_SUBDIR(objects,ProtectedEntityController); +PREP_SUBDIR(objects,IEDEntityController); +PREP_SUBDIR(objects,DefenseEnemyController); +PREP_SUBDIR(objects,DefuseTaskBaseClass); +PREP_SUBDIR(objects,DestroyTaskBaseClass); +PREP_SUBDIR(objects,DeliveryTaskBaseClass); +PREP_SUBDIR(objects,HVTTaskBaseClass); +PREP_SUBDIR(objects,DefendTaskBaseClass); diff --git a/arma/server/addons/task/XEH_postInit.sqf b/arma/server/addons/task/XEH_postInit.sqf index 0ea1d62..cb58054 100644 --- a/arma/server/addons/task/XEH_postInit.sqf +++ b/arma/server/addons/task/XEH_postInit.sqf @@ -1,6 +1,9 @@ #include "script_component.hpp" if (isNil QEGVAR(common,EventBus)) then { call EFUNC(common,eventBus); }; + +// Temporary migration instrumentation. Keep this visible while task lifecycle +// events are being moved onto the framework event bus. if (isNil QGVAR(TaskLifecycleEventLogTokens)) then { private _logTaskLifecycleEvent = { params ["_event"]; diff --git a/arma/server/addons/task/functions/helpers/fnc_heartBeat.sqf b/arma/server/addons/task/backup/fnc_heartBeat.sqf similarity index 100% rename from arma/server/addons/task/functions/helpers/fnc_heartBeat.sqf rename to arma/server/addons/task/backup/fnc_heartBeat.sqf diff --git a/arma/server/addons/task/functions/fnc_attack.sqf b/arma/server/addons/task/functions/fnc_attack.sqf index c1564f29..b7fa533 100644 --- a/arma/server/addons/task/functions/fnc_attack.sqf +++ b/arma/server/addons/task/functions/fnc_attack.sqf @@ -6,7 +6,7 @@ * * This public function is now a compatibility adapter around * AttackTaskBaseClass. Keep the argument list stable for Eden modules, - * startTask, and external scripts while the object-style task prototypes + * startTask, and external scripts while the object-style task objects * become the live implementation. * * Arguments: diff --git a/arma/server/addons/task/functions/fnc_defend.sqf b/arma/server/addons/task/functions/fnc_defend.sqf index ff9c1fc..872bfa5 100644 --- a/arma/server/addons/task/functions/fnc_defend.sqf +++ b/arma/server/addons/task/functions/fnc_defend.sqf @@ -1,35 +1,7 @@ #include "..\script_component.hpp" /* - * Author: IDSolutions - * Registers a defend task where players must hold a zone marked by a marker - * - * Arguments: - * 0: ID of the task - * 1: Defense zone marker name - * 2: Time to defend in seconds - * 3: Amount of funds the company receives if the task is successful (default: 0) - * 4: Amount of rating the company and player lose if the task is failed (default: 0) - * 5: Amount of rating the company and player receive if the task is successful (default: 0) - * 6: Should the mission end (MissionSuccess) if the task is successful (default: false) - * 7: Should the mission end (MissionFailed) if the task is failed (default: false) - * 8: Enemy wave count (default: 3) - * 9: Time between waves in seconds (default: 300) - * 10: Minimum BLUFOR units required in zone (default: 1) - * 11: Enemy template groups (default: []) - * 12: Equipment rewards (default: []) - * 13: Supply rewards (default: []) - * 14: Weapon rewards (default: []) - * 15: Vehicle rewards (default: []) - * 16: Special rewards (default: []) - * - * Return Value: - * None - * - * Example: - * ["defend_zone_1", "defend_marker", 900, 500000, -100, 400, false, false, 3, 300, 1, ["ItemGPS"], ["FirstAidKit"], ["arifle_MX_F"], ["B_MRAP_01_F"], ["B_UAV_01_F"]] spawn forge_server_task_fnc_defend; - * - * Public: Yes + * Compatibility adapter for the object-style defend task implementation. */ params [ @@ -52,103 +24,34 @@ params [ ["_specialRewards", [], [[]]] ]; -if (_defenseZone == "" || !(markerShape _defenseZone in ["RECTANGLE", "ELLIPSE"])) exitWith { - ["ERROR", format ["Invalid defense zone marker: %1", _defenseZone]] call EFUNC(common,log); -}; +private _taskParams = createHashMapFromArray [ + ["defenseZone", _defenseZone], + ["defendTime", _defendTime], + ["funds", _companyFunds], + ["ratingFail", _ratingFail], + ["ratingSuccess", _ratingSuccess], + ["endSuccess", _endSuccess], + ["endFail", _endFail], + ["waveCount", _waveCount], + ["waveCooldown", _waveCooldown], + ["minBlufor", _minBlufor], + ["enemyTemplates", _enemyTemplates], + ["useTaskStore", true] +]; -private _result = 0; -private _startTime = -1; -private _nextWaveTime = -1; -private _currentWave = 0; -private _zoneEmptyCounter = 0; -private _warningIssued = false; -private _defenseStarted = false; +if (_equipmentRewards isNotEqualTo []) then { _taskParams set ["equipment", _equipmentRewards]; }; +if (_supplyRewards isNotEqualTo []) then { _taskParams set ["supplies", _supplyRewards]; }; +if (_weaponRewards isNotEqualTo []) then { _taskParams set ["weapons", _weaponRewards]; }; +if (_vehicleRewards isNotEqualTo []) then { _taskParams set ["vehicles", _vehicleRewards]; }; +if (_specialRewards isNotEqualTo []) then { _taskParams set ["special", _specialRewards]; }; -waitUntil { - sleep 1; - GVAR(TaskStore) call ["isTaskAccepted", [_taskID]] -}; +private _task = createHashMapObject [ + GVAR(DefendTaskBaseClass), + [ + _taskID, + createHashMap, + _taskParams + ] +]; -waitUntil { - sleep 1; - GVAR(TaskStore) call ["trackParticipants", [_taskID, [], _defenseZone, 0]]; - - private _bluforInZone = count (allUnits select { _x isKindOf "CAManBase" && { side _x == west } && { alive _x }} inAreaArray _defenseZone); - private _readyToStart = _bluforInZone >= _minBlufor; - - if (_readyToStart) then { - _defenseStarted = true; - _startTime = time; - _nextWaveTime = _startTime; - - GVAR(TaskStore) call ["notifyParticipants", [_taskID, "info", "Tasks", "Defense has started. Hold the zone."]]; - }; - - _readyToStart -}; - -waitUntil { - sleep 1; - GVAR(TaskStore) call ["trackParticipants", [_taskID, [], _defenseZone, 0]]; - private _bluforInZone = count (allUnits select { _x isKindOf "CAManBase" && { side _x == west } && { alive _x }} inAreaArray _defenseZone); - private _timeElapsed = if (_defenseStarted) then { time - _startTime } else { 0 }; - - if (_bluforInZone < _minBlufor) then { - _zoneEmptyCounter = _zoneEmptyCounter + 1; - - if (_zoneEmptyCounter == 15 && !_warningIssued) then { - GVAR(TaskStore) call ["notifyParticipants", [_taskID, "warning", "Tasks", "Defense zone is empty. Return immediately."]]; - _warningIssued = true; - }; - } else { - _zoneEmptyCounter = 0; - _warningIssued = false; - }; - - if (_currentWave < _waveCount && _defenseStarted && { time >= _nextWaveTime }) then { - [_defenseZone, _taskID, _currentWave, _enemyTemplates] call FUNC(spawnEnemyWave); - - _currentWave = _currentWave + 1; - _nextWaveTime = time + _waveCooldown; - - GVAR(TaskStore) call ["notifyParticipants", [_taskID, "info", "Tasks", format ["Enemy forces approaching. Wave %1 of %2.", _currentWave, _waveCount]]]; - }; - - if (_zoneEmptyCounter >= 30) then { _result = 1; }; - - (_result == 1) or ((_bluforInZone >= _minBlufor) && (_timeElapsed >= _defendTime) && (_currentWave >= _waveCount)); -}; - -if (_result == 1) 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 { "EveryoneLost" call BFUNC(endMissionServer); }; -} else { - private _rewards = createHashMap; - _rewards set ["funds", _companyFunds]; - - if (_equipmentRewards isNotEqualTo []) then { _rewards set ["equipment", _equipmentRewards]; }; - if (_supplyRewards isNotEqualTo []) then { _rewards set ["supplies", _supplyRewards]; }; - if (_weaponRewards isNotEqualTo []) then { _rewards set ["weapons", _weaponRewards]; }; - if (_vehicleRewards isNotEqualTo []) then { _rewards set ["vehicles", _vehicleRewards]; }; - if (_specialRewards isNotEqualTo []) then { _rewards set ["special", _specialRewards]; }; - - [_taskID, _rewards] 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, [_companyFunds] call EFUNC(common,formatNumber)]]]; - GVAR(TaskStore) call ["applyRatingOutcome", [_taskID, _ratingSuccess]]; - GVAR(TaskStore) call ["clearTask", [_taskID]]; - - if (_endSuccess) then { "EveryoneWon" call BFUNC(endMissionServer); }; -}; +_task call ["runLoop", []]; diff --git a/arma/server/addons/task/functions/fnc_defuse.sqf b/arma/server/addons/task/functions/fnc_defuse.sqf index fea327d..9c56394 100644 --- a/arma/server/addons/task/functions/fnc_defuse.sqf +++ b/arma/server/addons/task/functions/fnc_defuse.sqf @@ -1,120 +1,52 @@ #include "..\script_component.hpp" /* - * Author: IDSolutions - * Registers a defuse task - * - * Arguments: - * 0: ID of the task - * 1: Amount of entities destroyed to fail the task - * 2: Amount of ieds defused to complete the task - * 3: Amount of funds the company recieves if the task is successful (default: 0) - * 4: Amount of rating the company and player lose if the task is failed (default: 0) - * 5: Amount of rating the company and player recieve if the task is successful (default: 0) - * 6: Should the mission end (MissionSuccess) if the task is successful (default: false) - * 7: Should the mission end (MissionFailed) if the task is failed (default: false) - * 8: Equipment rewards (default: []) - * 9: Supply rewards (default: []) - * 10: Weapon rewards (default: []) - * 11: Vehicle rewards (default: []) - * 12: Special rewards (default: []) - * - * Return Value: - * None - * - * Example: - * ["task_name", 2, 3, 375000, -75, 300, false, false] spawn forge_server_task_fnc_defuse; - * - * Public: Yes + * Compatibility adapter for the object-style defuse task implementation. */ params [ - ["_taskID", "", [""]], - ["_limitFail", -1, [0]], - ["_limitSuccess", -1, [0]], - ["_companyFunds", 0, [0]], - ["_ratingFail", 0, [0]], - ["_ratingSuccess", 0, [0]], - ["_endSuccess", false, [false]], - ["_endFail", false, [false]], - ["_equipmentRewards", [], [[]]], - ["_supplyRewards", [], [[]]], - ["_weaponRewards", [], [[]]], - ["_vehicleRewards", [], [[]]], - ["_specialRewards", [], [[]]] + ["_taskID", "", [""]], + ["_limitFail", -1, [0]], + ["_limitSuccess", -1, [0]], + ["_companyFunds", 0, [0]], + ["_ratingFail", 0, [0]], + ["_ratingSuccess", 0, [0]], + ["_endSuccess", false, [false]], + ["_endFail", false, [false]], + ["_equipmentRewards", [], [[]]], + ["_supplyRewards", [], [[]]], + ["_weaponRewards", [], [[]]], + ["_vehicleRewards", [], [[]]], + ["_specialRewards", [], [[]]] ]; -private _result = 0; -private _ieds = []; +private _taskParams = createHashMapFromArray [ + ["limitFail", _limitFail], + ["limitSuccess", _limitSuccess], + ["funds", _companyFunds], + ["ratingFail", _ratingFail], + ["ratingSuccess", _ratingSuccess], + ["endSuccess", _endSuccess], + ["endFail", _endFail], + ["useTaskStore", true] +]; -waitUntil { - sleep 1; - _ieds = GVAR(TaskStore) call ["getTaskEntities", ["ieds", _taskID]]; - count _ieds > 0 -}; +if (_equipmentRewards isNotEqualTo []) then { _taskParams set ["equipment", _equipmentRewards]; }; +if (_supplyRewards isNotEqualTo []) then { _taskParams set ["supplies", _supplyRewards]; }; +if (_weaponRewards isNotEqualTo []) then { _taskParams set ["weapons", _weaponRewards]; }; +if (_vehicleRewards isNotEqualTo []) then { _taskParams set ["vehicles", _vehicleRewards]; }; +if (_specialRewards isNotEqualTo []) then { _taskParams set ["special", _specialRewards]; }; -_ieds = GVAR(TaskStore) call ["getTaskEntities", ["ieds", _taskID]]; -private _entities = GVAR(TaskStore) call ["getTaskEntities", ["entities", _taskID]]; -private _requiredDefusals = if (_limitSuccess < 0) then { count _ieds } else { _limitSuccess }; -private _maxProtectedLosses = if (_limitFail < 0) then { count _entities } else { _limitFail }; -private _entitiesDestroyed = 0; -private _defusedCount = 0; -private _shouldFail = false; -private _shouldSucceed = false; -private _done = false; +private _task = createHashMapObject [ + GVAR(DefuseTaskBaseClass), + [ + _taskID, + createHashMapFromArray [ + ["ieds", GVAR(TaskStore) call ["getTaskEntities", ["ieds", _taskID]]], + ["protected", GVAR(TaskStore) call ["getTaskEntities", ["entities", _taskID]]] + ], + _taskParams + ] +]; -waitUntil { - sleep 1; - GVAR(TaskStore) call ["trackParticipants", [_taskID, _ieds + _entities, "", 250]]; - - _entitiesDestroyed = ({ !alive _x } count _entities); - _defusedCount = GVAR(TaskStore) call ["getDefuseCount", [_taskID]]; - _shouldFail = (_maxProtectedLosses > 0) && { _entitiesDestroyed >= _maxProtectedLosses }; - _shouldSucceed = (_requiredDefusals > 0) && { _defusedCount >= _requiredDefusals } && { (_maxProtectedLosses <= 0) || { _entitiesDestroyed < _maxProtectedLosses } }; - _done = false; - - if (_shouldFail) then { _result = 1; }; - if ((_result == 1) or _shouldSucceed) then { _done = true; }; - - _done -}; - -if (_result == 1) then { - { deleteVehicle _x } forEach _ieds; - { deleteVehicle _x } forEach _entities; - - [_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]]; - - if (_endFail) then { "EveryoneLost" call BFUNC(endMissionServer); }; -} else { - { deleteVehicle _x } forEach _ieds; - { deleteVehicle _x } forEach _entities; - - private _rewards = createHashMap; - _rewards set ["funds", _companyFunds]; - - if (_equipmentRewards isNotEqualTo []) then { _rewards set ["equipment", _equipmentRewards]; }; - if (_supplyRewards isNotEqualTo []) then { _rewards set ["supplies", _supplyRewards]; }; - if (_weaponRewards isNotEqualTo []) then { _rewards set ["weapons", _weaponRewards]; }; - if (_vehicleRewards isNotEqualTo []) then { _rewards set ["vehicles", _vehicleRewards]; }; - if (_specialRewards isNotEqualTo []) then { _rewards set ["special", _specialRewards]; }; - - [_taskID, _rewards] 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, [_companyFunds] call EFUNC(common,formatNumber)]]]; - GVAR(TaskStore) call ["applyRatingOutcome", [_taskID, _ratingSuccess]]; - - if (_endSuccess) then { "EveryoneWon" call BFUNC(endMissionServer); }; -}; - -GVAR(TaskStore) call ["clearTask", [_taskID]]; +_task call ["runLoop", []]; diff --git a/arma/server/addons/task/functions/fnc_delivery.sqf b/arma/server/addons/task/functions/fnc_delivery.sqf index 4c61fd7..291c262 100644 --- a/arma/server/addons/task/functions/fnc_delivery.sqf +++ b/arma/server/addons/task/functions/fnc_delivery.sqf @@ -1,34 +1,7 @@ #include "..\script_component.hpp" /* - * Author: IDSolutions - * Registers a delivery task - * - * Arguments: - * 0: ID of the task - * 1: Amount of damaged cargo to fail the task - * 2: Amount of cargo delivered to complete the task - * 3: Marker name for the delivery zone - * 4: Amount of funds the company receives if the task is successful (default: 0) - * 5: Amount of rating the company and player lose if the task is failed (default: 0) - * 6: Amount of rating the company and player receive if the task is successful (default: 0) - * 7: Should the mission end (MissionSuccess) if the task is successful (default: false) - * 8: Should the mission end (MissionFailed) if the task is failed (default: false) - * 9: Amount of time to complete delivery (default: 0) - * 10: Equipment rewards (default: []) - * 11: Supply rewards (default: []) - * 12: Weapon rewards (default: []) - * 13: Vehicle rewards (default: []) - * 14: Special rewards (default: []) - * - * Return Value: - * None - * - * Example: - * ["delivery_1", 1, 3, "delivery_zone", 250000, -75, 300, false, false] spawn forge_server_task_fnc_delivery; - * ["delivery_1", 1, 3, "delivery_zone", 250000, -75, 300, false, false, 900] spawn forge_server_task_fnc_delivery; - * - * Public: Yes + * Compatibility adapter for the object-style delivery task implementation. */ params [ @@ -43,88 +16,38 @@ params [ ["_endFail", false, [false]], ["_timeLimit", 0, [0]], ["_equipmentRewards", [], [[]]], - ["_supplyRewards", [], [[]]], - ["_weaponRewards", [], [[]]], - ["_vehicleRewards", [], [[]]], - ["_specialRewards", [], [[]]] + ["_supplyRewards", [], [[]]], + ["_weaponRewards", [], [[]]], + ["_vehicleRewards", [], [[]]], + ["_specialRewards", [], [[]]] ]; -private _result = 0; -private _cargo = []; +private _taskParams = createHashMapFromArray [ + ["limitFail", _limitFail], + ["limitSuccess", _limitSuccess], + ["deliveryZone", _deliveryZone], + ["funds", _companyFunds], + ["ratingFail", _ratingFail], + ["ratingSuccess", _ratingSuccess], + ["endSuccess", _endSuccess], + ["endFail", _endFail], + ["timeLimit", _timeLimit], + ["useTaskStore", true] +]; -waitUntil { - sleep 1; - _cargo = GVAR(TaskStore) call ["getTaskEntities", ["cargo", _taskID]]; - GVAR(TaskStore) call ["trackParticipants", [_taskID, _cargo, _deliveryZone, 125]]; - count _cargo > 0 -}; +if (_equipmentRewards isNotEqualTo []) then { _taskParams set ["equipment", _equipmentRewards]; }; +if (_supplyRewards isNotEqualTo []) then { _taskParams set ["supplies", _supplyRewards]; }; +if (_weaponRewards isNotEqualTo []) then { _taskParams set ["weapons", _weaponRewards]; }; +if (_vehicleRewards isNotEqualTo []) then { _taskParams set ["vehicles", _vehicleRewards]; }; +if (_specialRewards isNotEqualTo []) then { _taskParams set ["special", _specialRewards]; }; -_cargo = GVAR(TaskStore) call ["getTaskEntities", ["cargo", _taskID]]; +private _task = createHashMapObject [ + GVAR(DeliveryTaskBaseClass), + [ + _taskID, + createHashMapFromArray [["cargo", GVAR(TaskStore) call ["getTaskEntities", ["cargo", _taskID]]]], + _taskParams + ] +]; -if (_timeLimit isNotEqualTo 0) then { - waitUntil { - sleep 1; - GVAR(TaskStore) call ["isTaskAccepted", [_taskID]] - }; -}; - -private _startTime = if (_timeLimit isNotEqualTo 0) then { floor(time) } else { nil }; - -waitUntil { - sleep 1; - GVAR(TaskStore) call ["trackParticipants", [_taskID, _cargo, _deliveryZone, 125]]; - - private _cargoDelivered = ({ _x inArea _deliveryZone && (damage _x) < 0.7 } count _cargo); - private _cargoDamaged = ({ damage _x >= 0.7 } count _cargo); - - if (_timeLimit isNotEqualTo 0) then { - private _timeExpired = (floor time - _startTime >= _timeLimit); - - if (_cargoDamaged >= _limitFail) then { _result = 1; }; - if (_cargoDelivered < _limitSuccess && _timeExpired) then { _result = 1; }; - - (_result == 1) or ((_cargoDelivered >= _limitSuccess) && (_cargoDamaged < _limitFail)) - } else { - if (_cargoDamaged >= _limitFail) then { _result = 1; }; - - (_result == 1) or ((_cargoDelivered >= _limitSuccess) && (_cargoDamaged < _limitFail)) - }; -}; - -if (_result == 1) then { - { deleteVehicle _x } forEach _cargo; - - [_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 { "EveryoneLost" call BFUNC(endMissionServer); }; -} else { - { deleteVehicle _x } forEach _cargo; - - private _rewards = createHashMap; - _rewards set ["funds", _companyFunds]; - - if (_equipmentRewards isNotEqualTo []) then { _rewards set ["equipment", _equipmentRewards]; }; - if (_supplyRewards isNotEqualTo []) then { _rewards set ["supplies", _supplyRewards]; }; - if (_weaponRewards isNotEqualTo []) then { _rewards set ["weapons", _weaponRewards]; }; - if (_vehicleRewards isNotEqualTo []) then { _rewards set ["vehicles", _vehicleRewards]; }; - if (_specialRewards isNotEqualTo []) then { _rewards set ["special", _specialRewards]; }; - - [_taskID, _rewards] 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, [_companyFunds] call EFUNC(common,formatNumber)]]]; - GVAR(TaskStore) call ["applyRatingOutcome", [_taskID, _ratingSuccess]]; - GVAR(TaskStore) call ["clearTask", [_taskID]]; - - if (_endSuccess) then { "EveryoneWon" call BFUNC(endMissionServer); }; -}; +_task call ["runLoop", []]; diff --git a/arma/server/addons/task/functions/fnc_destroy.sqf b/arma/server/addons/task/functions/fnc_destroy.sqf index 95018b3..49ece7e 100644 --- a/arma/server/addons/task/functions/fnc_destroy.sqf +++ b/arma/server/addons/task/functions/fnc_destroy.sqf @@ -1,124 +1,51 @@ #include "..\script_component.hpp" /* - * Author: IDSolutions - * Registers an destroy task - * - * Arguments: - * 0: ID of the task - * 1: Amount of targets escaped to fail the task - * 2: Amount of targets eliminated to complete the task - * 3: Amount of funds the company recieves if the task is successful (default: 0) - * 4: Amount of rating the company and player lose if the task is failed (default: 0) - * 5: Amount of rating the company and player recieve if the task is successful (default: 0) - * 6: Should the mission end (MissionSuccess) if the task is successful (default: false) - * 7: Should the mission end (MissionFailed) if the task is failed (default: false) - * 8: Amount of time before target(s) escape (default: 0, 0 = no limit) - * 9: Equipment rewards (default: []) - * 10: Supply rewards (default: []) - * 11: Weapon rewards (default: []) - * 12: Vehicle rewards (default: []) - * 13: Special rewards (default: []) - * - * Return Value: - * None - * - * Example: - * ["task_name", 1, 2, 250000, -75, 300, false, false] spawn forge_server_task_fnc_destroy; - * ["task_name", 1, 2, 250000, -75, 300, false, false, 45] spawn forge_server_task_fnc_destroy; - * - * Public: Yes + * Compatibility adapter for the object-style destroy task implementation. */ params [ - ["_taskID", "", [""]], - ["_limitFail", -1, [0]], - ["_limitSuccess", -1, [0]], - ["_companyFunds", 0, [0]], - ["_ratingFail", 0, [0]], - ["_ratingSuccess", 0, [0]], - ["_endSuccess", false, [false]], - ["_endFail", false, [false]], - ["_timeLimit", 0, [0]], - ["_equipmentRewards", [], [[]]], - ["_supplyRewards", [], [[]]], - ["_weaponRewards", [], [[]]], - ["_vehicleRewards", [], [[]]], - ["_specialRewards", [], [[]]] + ["_taskID", "", [""]], + ["_limitFail", -1, [0]], + ["_limitSuccess", -1, [0]], + ["_companyFunds", 0, [0]], + ["_ratingFail", 0, [0]], + ["_ratingSuccess", 0, [0]], + ["_endSuccess", false, [false]], + ["_endFail", false, [false]], + ["_timeLimit", 0, [0]], + ["_equipmentRewards", [], [[]]], + ["_supplyRewards", [], [[]]], + ["_weaponRewards", [], [[]]], + ["_vehicleRewards", [], [[]]], + ["_specialRewards", [], [[]]] ]; -private _result = 0; -private _targets = []; +private _taskParams = createHashMapFromArray [ + ["limitFail", _limitFail], + ["limitSuccess", _limitSuccess], + ["funds", _companyFunds], + ["ratingFail", _ratingFail], + ["ratingSuccess", _ratingSuccess], + ["endSuccess", _endSuccess], + ["endFail", _endFail], + ["timeLimit", _timeLimit], + ["useTaskStore", true] +]; -waitUntil { - sleep 1; - _targets = GVAR(TaskStore) call ["getTaskEntities", ["targets", _taskID]]; - GVAR(TaskStore) call ["trackParticipants", [_taskID, _targets, "", 300]]; - count _targets > 0 -}; +if (_equipmentRewards isNotEqualTo []) then { _taskParams set ["equipment", _equipmentRewards]; }; +if (_supplyRewards isNotEqualTo []) then { _taskParams set ["supplies", _supplyRewards]; }; +if (_weaponRewards isNotEqualTo []) then { _taskParams set ["weapons", _weaponRewards]; }; +if (_vehicleRewards isNotEqualTo []) then { _taskParams set ["vehicles", _vehicleRewards]; }; +if (_specialRewards isNotEqualTo []) then { _taskParams set ["special", _specialRewards]; }; -_targets = GVAR(TaskStore) call ["getTaskEntities", ["targets", _taskID]]; +private _task = createHashMapObject [ + GVAR(DestroyTaskBaseClass), + [ + _taskID, + createHashMapFromArray [["targets", GVAR(TaskStore) call ["getTaskEntities", ["targets", _taskID]]]], + _taskParams + ] +]; -if (_timeLimit isNotEqualTo 0) then { - waitUntil { - sleep 1; - GVAR(TaskStore) call ["isTaskAccepted", [_taskID]] - }; -}; - -private _startTime = if (_timeLimit isNotEqualTo 0) then { floor(time) } else { nil }; - -waitUntil { - sleep 1; - GVAR(TaskStore) call ["trackParticipants", [_taskID, _targets, "", 300]]; - - private _targetsDestroyed = ({ !alive _x } count _targets); - - if (_timeLimit isNotEqualTo 0) then { - private _timeExpired = (floor time - _startTime >= _timeLimit); - - if (_targetsDestroyed < _limitSuccess && _timeExpired) then { _result = 1; }; - - (_result == 1) or (_targetsDestroyed >= _limitSuccess) - } else { - (_targetsDestroyed >= _limitSuccess) - }; -}; - -if (_result == 1) then { - { deleteVehicle _x } forEach _targets; - - [_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 { "EveryoneLost" call BFUNC(endMissionServer); }; -} else { - { deleteVehicle _x } forEach _targets; - - private _rewards = createHashMap; - _rewards set ["funds", _companyFunds]; - - if (_equipmentRewards isNotEqualTo []) then { _rewards set ["equipment", _equipmentRewards]; }; - if (_supplyRewards isNotEqualTo []) then { _rewards set ["supplies", _supplyRewards]; }; - if (_weaponRewards isNotEqualTo []) then { _rewards set ["weapons", _weaponRewards]; }; - if (_vehicleRewards isNotEqualTo []) then { _rewards set ["vehicles", _vehicleRewards]; }; - if (_specialRewards isNotEqualTo []) then { _rewards set ["special", _specialRewards]; }; - - [_taskID, _rewards] 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, [_companyFunds] call EFUNC(common,formatNumber)]]]; - GVAR(TaskStore) call ["applyRatingOutcome", [_taskID, _ratingSuccess]]; - GVAR(TaskStore) call ["clearTask", [_taskID]]; - - if (_endSuccess) then { "EveryoneWon" call BFUNC(endMissionServer); }; -}; +_task call ["runLoop", []]; diff --git a/arma/server/addons/task/functions/fnc_hostage.sqf b/arma/server/addons/task/functions/fnc_hostage.sqf index ca174fd..e6351fc 100644 --- a/arma/server/addons/task/functions/fnc_hostage.sqf +++ b/arma/server/addons/task/functions/fnc_hostage.sqf @@ -1,186 +1,62 @@ #include "..\script_component.hpp" /* - * Author: IDSolutions - * Registers an hostage task - * - * Arguments: - * 0: ID of the task - * 1: Amount of hostages KIA to fail the task - * 2: Amount of hostages rescued to complete the task - * 3: Marker name for the extraction zone - * 4: Amount of funds the company recieves if the task is successful (default: 0) - * 5: Amount of rating the company and player lose if the task is failed (default: 0) - * 6: Amount of rating the company and player recieve if the task is successful (default: 0) - * 7: Subcategory of task (default: [false, true]) - * 8: Should the mission end (MissionSuccess) if the task is successful (default: false) - * 9: Should the mission end (MissionFailed) if the task is failed (default: false) - * 10: Amount of time before hostage(s) are executed (default: 0, 0 = no limit) - * 11: Marker name for the cbrn zone (default: "") - * 12: Equipment rewards (default: []) - * 13: Supply rewards (default: []) - * 14: Weapon rewards (default: []) - * 15: Vehicle rewards (default: []) - * 16: Special rewards (default: []) - * - * Return Value: - * None - * - * Example: - * ["task_name", 1, 2, "marker_name", 1500000, -75, 500, [false, true], false, false] spawn forge_server_task_fnc_hostage; - * ["task_name", 1, 2, "marker_name", 1500000, -75, 500, [false, true], false, false, 45] spawn forge_server_task_fnc_hostage; - * ["task_name", 1, 2, "marker_name", 1500000, -75, 500, [true, false], false, false, 45, "marker_name"] spawn forge_server_task_fnc_hostage; - * - * Public: Yes + * Compatibility adapter for the object-style hostage task implementation. */ params [ - ["_taskID", ""], - ["_limitFail", -1], - ["_limitSuccess", -1], - ["_extZone", ""], - ["_companyFunds", 0], - ["_ratingFail", 0], - ["_ratingSuccess", 0], - ["_type", [["_cbrn", false, [false]], ["_hostage", true, [false]]]], - ["_endSuccess", false, [false]], - ["_endFail", false, [false]], - ["_timeLimit", 0, [0]], - ["_cbrnZone", "", [""]], - ["_equipmentRewards", [], [[]]], - ["_supplyRewards", [], [[]]], - ["_weaponRewards", [], [[]]], - ["_vehicleRewards", [], [[]]], - ["_specialRewards", [], [[]]] + ["_taskID", "", [""]], + ["_limitFail", -1, [0]], + ["_limitSuccess", -1, [0]], + ["_extZone", "", [""]], + ["_companyFunds", 0, [0]], + ["_ratingFail", 0, [0]], + ["_ratingSuccess", 0, [0]], + ["_type", [false, true], [[]]], + ["_endSuccess", false, [false]], + ["_endFail", false, [false]], + ["_timeLimit", 0, [0]], + ["_cbrnZone", "", [""]], + ["_equipmentRewards", [], [[]]], + ["_supplyRewards", [], [[]]], + ["_weaponRewards", [], [[]]], + ["_vehicleRewards", [], [[]]], + ["_specialRewards", [], [[]]] ]; -private _cbrn = (_this select 7) select 0; -private _hostage = (_this select 7) select 1; -private _result = 0; -private _hostages = []; -private _shooters = []; +private _taskParams = createHashMapFromArray [ + ["limitFail", _limitFail], + ["limitSuccess", _limitSuccess], + ["extractionZone", _extZone], + ["funds", _companyFunds], + ["ratingFail", _ratingFail], + ["ratingSuccess", _ratingSuccess], + ["type", _type], + ["cbrn", _type param [0, false, [false]]], + ["execution", _type param [1, true, [false]]], + ["endSuccess", _endSuccess], + ["endFail", _endFail], + ["timeLimit", _timeLimit], + ["cbrnZone", _cbrnZone], + ["useTaskStore", true] +]; -waitUntil { - sleep 1; - _hostages = GVAR(TaskStore) call ["getTaskEntities", ["hostages", _taskID]]; - count _hostages > 0 -}; +if (_equipmentRewards isNotEqualTo []) then { _taskParams set ["equipment", _equipmentRewards]; }; +if (_supplyRewards isNotEqualTo []) then { _taskParams set ["supplies", _supplyRewards]; }; +if (_weaponRewards isNotEqualTo []) then { _taskParams set ["weapons", _weaponRewards]; }; +if (_vehicleRewards isNotEqualTo []) then { _taskParams set ["vehicles", _vehicleRewards]; }; +if (_specialRewards isNotEqualTo []) then { _taskParams set ["special", _specialRewards]; }; -waitUntil { - sleep 1; - _shooters = GVAR(TaskStore) call ["getTaskEntities", ["shooters", _taskID]]; - GVAR(TaskStore) call ["trackParticipants", [_taskID, _hostages + _shooters, _extZone, 250]]; - count _shooters > 0 -}; +private _task = createHashMapObject [ + GVAR(HostageTaskBaseClass), + [ + _taskID, + createHashMapFromArray [ + ["hostages", GVAR(TaskStore) call ["getTaskEntities", ["hostages", _taskID]]], + ["shooters", GVAR(TaskStore) call ["getTaskEntities", ["shooters", _taskID]]] + ], + _taskParams + ] +]; -_hostages = GVAR(TaskStore) call ["getTaskEntities", ["hostages", _taskID]]; -_shooters = GVAR(TaskStore) call ["getTaskEntities", ["shooters", _taskID]]; -private _requiredRescues = if (_limitSuccess < 0) then { count _hostages } else { _limitSuccess }; -private _maxHostageLosses = if (_limitFail < 0) then { count _hostages } else { _limitFail }; - -if (_timeLimit isNotEqualTo 0) then { - waitUntil { - sleep 1; - GVAR(TaskStore) call ["isTaskAccepted", [_taskID]] - }; -}; - -private _startTime = if (_timeLimit isNotEqualTo 0) then { floor(time) } else { nil }; - -waitUntil { - sleep 1; - GVAR(TaskStore) call ["trackParticipants", [_taskID, _hostages + _shooters, _extZone, 250]]; - - private _hostagesInZone = ({ _x inArea _extZone } count _hostages); - private _hostagesKilled = ({ !alive _x } count _hostages); - private _shootersAlive = ({ alive _x } count _shooters); - private _hostageSucceeded = (_hostagesInZone >= _requiredRescues) && { _hostagesKilled < _maxHostageLosses }; - private _shootersClearedSucceeded = (!isNil "_shooters") && { _shootersAlive <= 0 } && { _hostageSucceeded }; - - if (_timeLimit isNotEqualTo 0) then { - private _timeExpired = (floor time - _startTime >= _timeLimit); - - if (!_hostageSucceeded && _timeExpired) then { _result = 1; }; - if (_hostagesKilled >= _maxHostageLosses) then { _result = 1; }; - - (_result == 1) or - _hostageSucceeded or - _shootersClearedSucceeded - } else { - if (_hostagesKilled >= _maxHostageLosses) then { _result = 1; }; - - (_result == 1) or - _hostageSucceeded or - _shootersClearedSucceeded - }; -}; - -if (_result == 1) then { - if (_cbrn) then { - "SmokeShellYellow" createVehicle getMarkerPos _cbrnZone; - - sleep 5; - - { - if (captive _x) then { - _x setDamage 0.9; - _x playMove "acts_executionvictim_kill_end"; - - sleep 2.75; - - _x setDamage 1; - } - } forEach _hostages; - }; - - if (_hostage) then { - { - _x enableAIFeature ["MOVE", true]; - _x playMove ""; - } forEach _shooters; - - sleep 1; - - { _x setCaptive false; } forEach _hostages; - - sleep 5; - }; - - { deleteVehicle _x } forEach _hostages; - { deleteVehicle _x } forEach _shooters; - - [_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 { "EveryoneLost" call BFUNC(endMissionServer); }; -} else { - { deleteVehicle _x } forEach _hostages; - { deleteVehicle _x } forEach _shooters; - - private _rewards = createHashMap; - _rewards set ["funds", _companyFunds]; - - if (_equipmentRewards isNotEqualTo []) then { _rewards set ["equipment", _equipmentRewards]; }; - if (_supplyRewards isNotEqualTo []) then { _rewards set ["supplies", _supplyRewards]; }; - if (_weaponRewards isNotEqualTo []) then { _rewards set ["weapons", _weaponRewards]; }; - if (_vehicleRewards isNotEqualTo []) then { _rewards set ["vehicles", _vehicleRewards]; }; - if (_specialRewards isNotEqualTo []) then { _rewards set ["special", _specialRewards]; }; - - [_taskID, _rewards] 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, [_companyFunds] call EFUNC(common,formatNumber)]]]; - GVAR(TaskStore) call ["applyRatingOutcome", [_taskID, _ratingSuccess]]; - GVAR(TaskStore) call ["clearTask", [_taskID]]; - - if (_endSuccess) then { "EveryoneWon" call BFUNC(endMissionServer); }; -}; +_task call ["runLoop", []]; diff --git a/arma/server/addons/task/functions/fnc_hvt.sqf b/arma/server/addons/task/functions/fnc_hvt.sqf index b4d1cff..0c1afa2 100644 --- a/arma/server/addons/task/functions/fnc_hvt.sqf +++ b/arma/server/addons/task/functions/fnc_hvt.sqf @@ -1,141 +1,56 @@ #include "..\script_component.hpp" /* - * Author: IDSolutions - * Registers an hvt task - * - * Arguments: - * 0: ID of the task - * 1: Amount of HVTs KIA to fail the task - * 2: Amount of HVTs Captured or KIA to complete the task - * 3: Marker name for the extraction zone - * 4: Amount of funds the company recieves if the task is successful (default: 0) - * 5: Amount of rating the company and player lose if the task is failed (default: 0) - * 6: Amount of rating the company and player recieve if the task is successful (default: 0) - * 7: Subcategory of task (default: [true, false]) - * 8: Should the mission end (MissionSuccess) if the task is successful (default: false) - * 9: Should the mission end (MissionFailed) if the task is failed (default: false) - * 10: Amount of time before HVT task fails (default: 0, 0 = no limit) - * 11: Equipment rewards (default: []) - * 12: Supply rewards (default: []) - * 13: Weapon rewards (default: []) - * 14: Vehicle rewards (default: []) - * 15: Special rewards (default: []) - * - * Return Value: - * None - * - * Example: - * ["task_name", 1, 1, "marker_name", 500000, -75, 300, [true, false], false, false] spawn forge_server_task_fnc_hvt; - * ["task_name", -1, 1, "", 500000, -75, 300, [false, true], false, false] spawn forge_server_task_fnc_hvt; - * ["task_name", 1, 1, "marker_name", 500000, -75, 300, [true, false], false, false, 45] spawn forge_server_task_fnc_hvt; - * ["task_name", -1, 1, "", 500000, -75, 300, [false, true], false, false, 45] spawn forge_server_task_fnc_hvt; - * - * Public: Yes + * Compatibility adapter for the object-style HVT task implementation. */ params [ - ["_taskID", "", [""]], - ["_limitFail", -1, [0]], - ["_limitSuccess", -1, [0]], - ["_extZone", "", [""]], - ["_companyFunds", 0, [0]], - ["_ratingFail", 0, [0]], - ["_ratingSuccess", 0, [0]], - ["_type", [["_capture", true, [false]], ["_eliminate", false, [false]]]], - ["_endSuccess", false, [false]], - ["_endFail", false, [false]], - ["_timeLimit", 0, [0]], - ["_equipmentRewards", [], [[]]], - ["_supplyRewards", [], [[]]], - ["_weaponRewards", [], [[]]], - ["_vehicleRewards", [], [[]]], - ["_specialRewards", [], [[]]] + ["_taskID", "", [""]], + ["_limitFail", -1, [0]], + ["_limitSuccess", -1, [0]], + ["_extZone", "", [""]], + ["_companyFunds", 0, [0]], + ["_ratingFail", 0, [0]], + ["_ratingSuccess", 0, [0]], + ["_type", [true, false], [[]]], + ["_endSuccess", false, [false]], + ["_endFail", false, [false]], + ["_timeLimit", 0, [0]], + ["_equipmentRewards", [], [[]]], + ["_supplyRewards", [], [[]]], + ["_weaponRewards", [], [[]]], + ["_vehicleRewards", [], [[]]], + ["_specialRewards", [], [[]]] ]; -private _capture = (_this select 7) select 0; -private _eliminate = (_this select 7) select 1; -private _result = 0; -private _hvts = []; +private _taskParams = createHashMapFromArray [ + ["limitFail", _limitFail], + ["limitSuccess", _limitSuccess], + ["extractionZone", _extZone], + ["funds", _companyFunds], + ["ratingFail", _ratingFail], + ["ratingSuccess", _ratingSuccess], + ["type", _type], + ["captureHvt", _type param [0, true, [false]]], + ["endSuccess", _endSuccess], + ["endFail", _endFail], + ["timeLimit", _timeLimit], + ["useTaskStore", true] +]; -waitUntil { - sleep 1; - _hvts = GVAR(TaskStore) call ["getTaskEntities", ["hvts", _taskID]]; - GVAR(TaskStore) call ["trackParticipants", [_taskID, _hvts, _extZone, 250]]; - count _hvts > 0 -}; +if (_equipmentRewards isNotEqualTo []) then { _taskParams set ["equipment", _equipmentRewards]; }; +if (_supplyRewards isNotEqualTo []) then { _taskParams set ["supplies", _supplyRewards]; }; +if (_weaponRewards isNotEqualTo []) then { _taskParams set ["weapons", _weaponRewards]; }; +if (_vehicleRewards isNotEqualTo []) then { _taskParams set ["vehicles", _vehicleRewards]; }; +if (_specialRewards isNotEqualTo []) then { _taskParams set ["special", _specialRewards]; }; -_hvts = GVAR(TaskStore) call ["getTaskEntities", ["hvts", _taskID]]; -private _requiredHvts = if (_limitSuccess < 0) then { count _hvts } else { _limitSuccess }; -private _maxHvtLosses = if (_limitFail < 0) then { count _hvts } else { _limitFail }; +private _task = createHashMapObject [ + GVAR(HVTTaskBaseClass), + [ + _taskID, + createHashMapFromArray [["hvts", GVAR(TaskStore) call ["getTaskEntities", ["hvts", _taskID]]]], + _taskParams + ] +]; -if (_timeLimit isNotEqualTo 0) then { - waitUntil { - sleep 1; - GVAR(TaskStore) call ["isTaskAccepted", [_taskID]] - }; -}; - -private _startTime = if (_timeLimit isNotEqualTo 0) then { floor(time) } else { nil }; - -waitUntil { - sleep 1; - GVAR(TaskStore) call ["trackParticipants", [_taskID, _hvts, _extZone, 250]]; - - private _hvtsKilled = ({ !alive _x } count _hvts); - private _hvtsInZone = ({ _x inArea _extZone } count _hvts); - private _captureSucceeded = _capture && { _hvtsInZone >= _requiredHvts } && { _hvtsKilled < _maxHvtLosses }; - private _eliminateSucceeded = _eliminate && { _hvtsKilled >= _requiredHvts }; - - if (_timeLimit isNotEqualTo 0) then { - private _timeExpired = (floor time - _startTime >= _timeLimit); - - if (_capture && { _hvtsKilled >= _maxHvtLosses }) then { _result = 1; }; - if (_capture && { !_captureSucceeded } && { _timeExpired }) then { _result = 1; }; - if (_eliminate && { !_eliminateSucceeded } && { _timeExpired }) then { _result = 1; }; - - (_result == 1) or _captureSucceeded or _eliminateSucceeded - } else { - if (_capture && { _hvtsKilled >= _maxHvtLosses }) then { _result = 1; }; - - (_result == 1) or _captureSucceeded or _eliminateSucceeded - }; -}; - -if (_result == 1) then { - { deleteVehicle _x } forEach _hvts; - - [_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 { "EveryoneLost" call BFUNC(endMissionServer); }; -} else { - { deleteVehicle _x } forEach _hvts; - - private _rewards = createHashMap; - _rewards set ["funds", _companyFunds]; - - if (_equipmentRewards isNotEqualTo []) then { _rewards set ["equipment", _equipmentRewards]; }; - if (_supplyRewards isNotEqualTo []) then { _rewards set ["supplies", _supplyRewards]; }; - if (_weaponRewards isNotEqualTo []) then { _rewards set ["weapons", _weaponRewards]; }; - if (_vehicleRewards isNotEqualTo []) then { _rewards set ["vehicles", _vehicleRewards]; }; - if (_specialRewards isNotEqualTo []) then { _rewards set ["special", _specialRewards]; }; - - [_taskID, _rewards] 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, [_companyFunds] call EFUNC(common,formatNumber)]]]; - GVAR(TaskStore) call ["applyRatingOutcome", [_taskID, _ratingSuccess]]; - GVAR(TaskStore) call ["clearTask", [_taskID]]; - - if (_endSuccess) then { "EveryoneWon" call BFUNC(endMissionServer); }; -}; +_task call ["runLoop", []]; diff --git a/arma/server/addons/task/functions/fnc_makeCargo.sqf b/arma/server/addons/task/functions/fnc_makeCargo.sqf index 098b6ea..5f53ca0 100644 --- a/arma/server/addons/task/functions/fnc_makeCargo.sqf +++ b/arma/server/addons/task/functions/fnc_makeCargo.sqf @@ -1,41 +1,22 @@ #include "..\script_component.hpp" /* - * Author: IDSolutions - * Assigns cargo to a task for delivery + * Assigns cargo to a task for delivery. * - * Arguments: - * 0: Object to convert to delivery cargo - * 1: Task ID to assign the cargo to - * - * Return Value: - * None - * - * Example: - * [_cargoObject, "delivery_1"] call forge_server_task_fnc_makeCargo; - * - * Public: Yes + * Public compatibility adapter around CargoEntityController. */ params [["_cargo", objNull, [objNull]], ["_taskID", "", [""]]]; ["INFO", format ["Make Cargo: %1", _this]] call EFUNC(common,log); -if (isNull _cargo) exitWith { ["ERROR", "Attempt to create cargo from null object"] call EFUNC(common,log); }; -if (_taskID == "") exitWith { ["ERROR", "No task ID provided for cargo"] call EFUNC(common,log); }; +if (isNull _cargo) exitWith { ["ERROR", "Attempt to create cargo from null object"] call EFUNC(common,log); false }; +if (_taskID isEqualTo "") exitWith { ["ERROR", "No task ID provided for cargo"] call EFUNC(common,log); false }; -SETPVAR(_cargo,assignedTask,_taskID); -GVAR(TaskStore) call ["registerTaskEntity", ["cargo", _taskID, _cargo]]; +private _controller = createHashMapObject [ + GVAR(CargoEntityController), + [_taskID, _cargo, createHashMap] +]; -_cargo addEventHandler ["Dammaged", { - params ["_unit", "_hitSelection", "_damage", "_hitPartIndex", "_hitPoint", "_shooter", "_projectile"]; - - if (damage _unit >= 0.7) then { - private _taskID = GETVAR(_unit,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]]]; - }; -}]; +if !(_controller call ["registerTaskEntity", ["cargo"]]) exitWith { false }; +_controller call ["watchDamage", []] diff --git a/arma/server/addons/task/functions/fnc_makeHVT.sqf b/arma/server/addons/task/functions/fnc_makeHVT.sqf index 8091035..54d7da5 100644 --- a/arma/server/addons/task/functions/fnc_makeHVT.sqf +++ b/arma/server/addons/task/functions/fnc_makeHVT.sqf @@ -1,30 +1,23 @@ #include "..\script_component.hpp" /* - * Author: IDSolutions - * Assigns an AI unit to a task as a hvt + * Assigns an AI unit to a task as an HVT. * - * Arguments: - * 0: The AI unit - * 1: ID of the task - * - * Return Value: - * None - * - * Example: - * [this, "task_name"] spawn forge_server_task_fnc_makeHVT; - * - * Public: Yes + * Public compatibility adapter around HVTEntityController. */ params [["_entity", objNull, [objNull, grpNull]], ["_taskID", "", [""]]]; -if (isNull _entity) exitWith { ["ERROR", "Attempt to create entity from null object"] call EFUNC(common,log); }; -if (_taskID == "") exitWith { ["ERROR", "No task ID provided for entity"] call EFUNC(common,log); }; +if (isNull _entity) exitWith { ["ERROR", "Attempt to create entity from null object"] call EFUNC(common,log); false }; +if (_taskID isEqualTo "") exitWith { ["ERROR", "No task ID provided for entity"] call EFUNC(common,log); false }; ["INFO", format ["Make HVT: %1", _this]] call EFUNC(common,log); -SETVAR(_entity,assignedTask,_taskID); -GVAR(TaskStore) call ["registerTaskEntity", ["hvts", _taskID, _entity]]; +private _controller = createHashMapObject [ + GVAR(HVTEntityController), + [_taskID, _entity, createHashMap] +]; -if (alive _entity) then { [_entity, "hvt"] spawn FUNC(heartBeat); }; +_controller call ["registerTaskEntity", ["hvts"]]; + +true diff --git a/arma/server/addons/task/functions/fnc_makeHostage.sqf b/arma/server/addons/task/functions/fnc_makeHostage.sqf index 2082fed..1e1ed2a 100644 --- a/arma/server/addons/task/functions/fnc_makeHostage.sqf +++ b/arma/server/addons/task/functions/fnc_makeHostage.sqf @@ -1,35 +1,24 @@ #include "..\script_component.hpp" /* - * Author: IDSolutions - * Assigns an AI unit to a task as a hostage + * Assigns an AI unit to a task as a hostage. * - * Arguments: - * 0: The AI unit - * 1: ID of the task - * - * Return Value: - * None - * - * Example: - * [this, "task_name"] spawn forge_server_task_fnc_makeHostage; - * - * Public: Yes + * Public compatibility adapter around HostageEntityController. The hostage + * task instance owns the rescue loop, so this helper only registers and + * applies initial state. */ params [["_entity", objNull, [objNull, grpNull]], ["_taskID", "", [""]]]; -if (isNull _entity) exitWith { ["ERROR", "Attempt to create entity from null object"] call EFUNC(common,log); }; -if (_taskID == "") exitWith { ["ERROR", "No task ID provided for entity"] call EFUNC(common,log); }; +if (isNull _entity) exitWith { ["ERROR", "Attempt to create entity from null object"] call EFUNC(common,log); false }; +if (_taskID isEqualTo "") exitWith { ["ERROR", "No task ID provided for entity"] call EFUNC(common,log); false }; ["INFO", format ["Make Hostage: %1", _this]] call EFUNC(common,log); -SETVAR(_entity,assignedTask,_taskID); -GVAR(TaskStore) call ["registerTaskEntity", ["hostages", _taskID, _entity]]; +private _controller = createHashMapObject [ + GVAR(HostageEntityController), + [_taskID, _entity, createHashMap] +]; -if (alive _entity) then { - _entity setCaptive true; - _entity enableAIFeature ["MOVE", false]; - - [_entity, "hostage"] spawn FUNC(heartBeat); -}; +if !(_controller call ["registerTaskEntity", ["hostages"]]) exitWith { false }; +_controller call ["applyInitialState", []] diff --git a/arma/server/addons/task/functions/fnc_makeIED.sqf b/arma/server/addons/task/functions/fnc_makeIED.sqf index cf3f6ee..92159cd 100644 --- a/arma/server/addons/task/functions/fnc_makeIED.sqf +++ b/arma/server/addons/task/functions/fnc_makeIED.sqf @@ -1,32 +1,26 @@ #include "..\script_component.hpp" /* - * Author: IDSolutions - * Assigns an IED to a task and starts its required countdown timer + * Assigns an IED to a task and starts its required countdown timer. * - * Arguments: - * 0: The object - * 1: ID of the task - * 2: Countdown timer in seconds (must be greater than 0) - * - * Return Value: - * None - * - * Example: - * [this, "task_name", 30] spawn forge_server_task_fnc_makeIED; - * - * Public: Yes + * Public compatibility adapter around IEDEntityController. */ params [["_entity", objNull, [objNull]], ["_taskID", "", [""]], ["_time", 0, [0]]]; -if (isNull _entity) exitWith { ["ERROR", "Attempt to create entity from null object"] call EFUNC(common,log); }; -if (_taskID == "") exitWith { ["ERROR", "No task ID provided for entity"] call EFUNC(common,log); }; -if (_time <= 0) exitWith { ["ERROR", "Invalid time provided for IED"] call EFUNC(common,log); }; +if (isNull _entity) exitWith { ["ERROR", "Attempt to create entity from null object"] call EFUNC(common,log); false }; +if (_taskID isEqualTo "") exitWith { ["ERROR", "No task ID provided for entity"] call EFUNC(common,log); false }; +if (_time <= 0) exitWith { ["ERROR", "Invalid time provided for IED"] call EFUNC(common,log); false }; ["INFO", format ["Make IED: %1", _this]] call EFUNC(common,log); -SETPVAR(_entity,assignedTask,_taskID); -GVAR(TaskStore) call ["registerTaskEntity", ["ieds", _taskID, _entity]]; +_entity setVariable [QGVAR(iedCountdown), _time, true]; -if (alive _entity) then { [_entity, "ied", _time] spawn FUNC(heartBeat); }; +private _controller = createHashMapObject [ + GVAR(IEDEntityController), + [_taskID, _entity, createHashMapFromArray [["countdown", _time]]] +]; + +_controller call ["registerTaskEntity", ["ieds"]]; + +true diff --git a/arma/server/addons/task/functions/fnc_makeObject.sqf b/arma/server/addons/task/functions/fnc_makeObject.sqf index 72c1d83..dcddff3 100644 --- a/arma/server/addons/task/functions/fnc_makeObject.sqf +++ b/arma/server/addons/task/functions/fnc_makeObject.sqf @@ -1,28 +1,21 @@ #include "..\script_component.hpp" /* - * Author: IDSolutions - * Assigns an object to a task as a protected target + * Assigns an object to a task as a protected target. * - * Arguments: - * 0: The object - * 1: ID of the task - * - * Return Value: - * None - * - * Example: - * [this, "task_name"] spawn forge_server_task_fnc_makeObject; - * - * Public: Yes + * Public compatibility adapter around ProtectedEntityController. */ params [["_entity", objNull, [objNull]], ["_taskID", "", [""]]]; -if (isNull _entity) exitWith { ["ERROR", "Attempt to create entity from null object"] call EFUNC(common,log); }; -if (_taskID == "") exitWith { ["ERROR", "No task ID provided for entity"] call EFUNC(common,log); }; +if (isNull _entity) exitWith { ["ERROR", "Attempt to create entity from null object"] call EFUNC(common,log); false }; +if (_taskID isEqualTo "") exitWith { ["ERROR", "No task ID provided for entity"] call EFUNC(common,log); false }; ["INFO", format ["Make Object: %1", _this]] call EFUNC(common,log); -SETPVAR(_entity,assignedTask,_taskID); -GVAR(TaskStore) call ["registerTaskEntity", ["entities", _taskID, _entity]]; +private _controller = createHashMapObject [ + GVAR(ProtectedEntityController), + [_taskID, _entity, createHashMap] +]; + +_controller call ["registerTaskEntity", ["entities"]] diff --git a/arma/server/addons/task/functions/fnc_makeShooter.sqf b/arma/server/addons/task/functions/fnc_makeShooter.sqf index ffce942..7a10e53 100644 --- a/arma/server/addons/task/functions/fnc_makeShooter.sqf +++ b/arma/server/addons/task/functions/fnc_makeShooter.sqf @@ -1,28 +1,21 @@ #include "..\script_component.hpp" /* - * Author: IDSolutions - * Assigns an AI unit to a task as a shooter + * Assigns an AI unit to a task as a shooter. * - * Arguments: - * 0: The AI unit - * 1: ID of the task - * - * Return Value: - * None - * - * Example: - * [this, "task_name"] spawn forge_server_task_fnc_makeShooter; - * - * Public: Yes + * Public compatibility adapter around ShooterEntityController. */ params [["_entity", objNull, [objNull, grpNull]], ["_taskID", "", [""]]]; -if (isNull _entity) exitWith { ["ERROR", "Attempt to create entity from null object"] call EFUNC(common,log); }; -if (_taskID == "") exitWith { ["ERROR", "No task ID provided for entity"] call EFUNC(common,log); }; +if (isNull _entity) exitWith { ["ERROR", "Attempt to create entity from null object"] call EFUNC(common,log); false }; +if (_taskID isEqualTo "") exitWith { ["ERROR", "No task ID provided for entity"] call EFUNC(common,log); false }; ["INFO", format ["Make Shooter: %1", _this]] call EFUNC(common,log); -SETVAR(_entity,assignedTask,_taskID); -GVAR(TaskStore) call ["registerTaskEntity", ["shooters", _taskID, _entity]]; +private _controller = createHashMapObject [ + GVAR(ShooterEntityController), + [_taskID, _entity, createHashMap] +]; + +_controller call ["registerTaskEntity", ["shooters"]] diff --git a/arma/server/addons/task/functions/fnc_makeTarget.sqf b/arma/server/addons/task/functions/fnc_makeTarget.sqf index 284ce4e..c5570df 100644 --- a/arma/server/addons/task/functions/fnc_makeTarget.sqf +++ b/arma/server/addons/task/functions/fnc_makeTarget.sqf @@ -1,28 +1,21 @@ #include "..\script_component.hpp" /* - * Author: IDSolutions - * Assigns an object to a task as a target + * Assigns an object to a task as a target. * - * Arguments: - * 0: The object - * 1: ID of the task - * - * Return Value: - * None - * - * Example: - * [this, "task_name"] spawn forge_server_task_fnc_makeTarget; - * - * Public: Yes + * Public compatibility adapter around TargetEntityController. */ params [["_entity", objNull, [objNull, grpNull]], ["_taskID", "", [""]]]; -if (isNull _entity) exitWith { ["ERROR", "Attempt to create entity from null object"] call EFUNC(common,log); }; -if (_taskID == "") exitWith { ["ERROR", "No task ID provided for entity"] call EFUNC(common,log); }; +if (isNull _entity) exitWith { ["ERROR", "Attempt to create entity from null object"] call EFUNC(common,log); false }; +if (_taskID isEqualTo "") exitWith { ["ERROR", "No task ID provided for entity"] call EFUNC(common,log); false }; ["INFO", format ["Make Target: %1", _this]] call EFUNC(common,log); -SETVAR(_entity,assignedTask,_taskID); -GVAR(TaskStore) call ["registerTaskEntity", ["targets", _taskID, _entity]]; +private _controller = createHashMapObject [ + GVAR(TargetEntityController), + [_taskID, _entity, createHashMap] +]; + +_controller call ["registerTaskEntity", ["targets"]] diff --git a/arma/server/addons/task/functions/objects/README.md b/arma/server/addons/task/functions/objects/README.md new file mode 100644 index 0000000..bde3cce --- /dev/null +++ b/arma/server/addons/task/functions/objects/README.md @@ -0,0 +1,62 @@ +# Task Objects + +This folder documents the active `createHashMapObject` task instances and entity +controllers. Their source lives under `functions/objects/`, and each class is +initialized directly from `XEH_preInit.sqf`. + +Current task objects: +- `TaskInstanceBaseClass` +- `EntityControllerBaseClass` +- `TargetEntityController` +- `ShooterEntityController` +- `AttackTaskBaseClass` +- `HostageTaskBaseClass` +- `HostageEntityController` +- `HVTEntityController` +- `CargoEntityController` +- `ProtectedEntityController` +- `IEDEntityController` +- `DefenseEnemyController` +- `DefuseTaskBaseClass` +- `DestroyTaskBaseClass` +- `DeliveryTaskBaseClass` +- `HVTTaskBaseClass` +- `DefendTaskBaseClass` + +Source entry points: +- [fnc_TaskInstanceBaseClass.sqf](./fnc_TaskInstanceBaseClass.sqf) +- [fnc_EntityControllerBaseClass.sqf](./fnc_EntityControllerBaseClass.sqf) +- [fnc_TargetEntityController.sqf](./fnc_TargetEntityController.sqf) +- [fnc_ShooterEntityController.sqf](./fnc_ShooterEntityController.sqf) +- [fnc_AttackTaskBaseClass.sqf](./fnc_AttackTaskBaseClass.sqf) +- [fnc_HostageTaskBaseClass.sqf](./fnc_HostageTaskBaseClass.sqf) +- [fnc_HostageEntityController.sqf](./fnc_HostageEntityController.sqf) +- [fnc_HVTEntityController.sqf](./fnc_HVTEntityController.sqf) +- [fnc_CargoEntityController.sqf](./fnc_CargoEntityController.sqf) +- [fnc_ProtectedEntityController.sqf](./fnc_ProtectedEntityController.sqf) +- [fnc_IEDEntityController.sqf](./fnc_IEDEntityController.sqf) +- [fnc_DefenseEnemyController.sqf](./fnc_DefenseEnemyController.sqf) +- [fnc_DefuseTaskBaseClass.sqf](./fnc_DefuseTaskBaseClass.sqf) +- [fnc_DestroyTaskBaseClass.sqf](./fnc_DestroyTaskBaseClass.sqf) +- [fnc_DeliveryTaskBaseClass.sqf](./fnc_DeliveryTaskBaseClass.sqf) +- [fnc_HVTTaskBaseClass.sqf](./fnc_HVTTaskBaseClass.sqf) +- [fnc_DefendTaskBaseClass.sqf](./fnc_DefendTaskBaseClass.sqf) + +Purpose: +- keep per-task instance state in task objects +- keep per-entity behavior in controller objects +- separate state ownership from long procedural function flows +- keep shared lifecycle and reward initialization in `TaskInstanceBaseClass` +- so concrete task objects only define task-specific state +- keep heartbeat-style AI/object behavior in separate entity controllers instead + of mixing it into task outcome loops + +Important design choice: +- these objects use explicit `markSucceeded`, `markFailed`, and `cleanup` + methods instead of relying on `#delete` +- task loops that use `sleep` or `waitUntil` with `sleep` must be started from + scheduled code, typically via `spawn` + +That is intentional. `createHashMapObject` destructor timing is reference-based, +so `#delete` is not a good primitive for mission-critical task completion or +reward flow. diff --git a/arma/server/addons/task/functions/prototypes/fnc_AttackTaskBaseClass.sqf b/arma/server/addons/task/functions/objects/fnc_AttackTaskBaseClass.sqf similarity index 97% rename from arma/server/addons/task/functions/prototypes/fnc_AttackTaskBaseClass.sqf rename to arma/server/addons/task/functions/objects/fnc_AttackTaskBaseClass.sqf index f50bcc5..119f1bb 100644 --- a/arma/server/addons/task/functions/prototypes/fnc_AttackTaskBaseClass.sqf +++ b/arma/server/addons/task/functions/objects/fnc_AttackTaskBaseClass.sqf @@ -1,13 +1,13 @@ #include "..\script_component.hpp" /* - * Review-only prototype attack task class. + * Object-style attack task class. * * Example: * call compile preprocessFileLineNumbers - * "\forge\forge_server\addons\task\prototypes\TaskInstanceBaseClass.sqf"; + * "\forge\forge_server\addons\task\objects\TaskInstanceBaseClass.sqf"; * call compile preprocessFileLineNumbers - * "\forge\forge_server\addons\task\prototypes\AttackTaskBaseClass.sqf"; + * "\forge\forge_server\addons\task\objects\AttackTaskBaseClass.sqf"; * * private _task = createHashMapObject [ * GVAR(AttackTaskBaseClass), diff --git a/arma/server/addons/task/functions/prototypes/fnc_CargoEntityController.sqf b/arma/server/addons/task/functions/objects/fnc_CargoEntityController.sqf similarity index 94% rename from arma/server/addons/task/functions/prototypes/fnc_CargoEntityController.sqf rename to arma/server/addons/task/functions/objects/fnc_CargoEntityController.sqf index 986b2ec..6d4b922 100644 --- a/arma/server/addons/task/functions/prototypes/fnc_CargoEntityController.sqf +++ b/arma/server/addons/task/functions/objects/fnc_CargoEntityController.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* - * Review-only prototype delivery cargo entity controller. + * Object-style delivery cargo entity controller. */ #pragma hemtt ignore_variables ["_self"] @@ -23,7 +23,7 @@ GVAR(CargoEntityController) = createHashMapFromArray [ ["#delete", compileFinal { _self call ["cleanup", []]; }], - ["installDamageWarningHandler", compileFinal { + ["watchDamage", compileFinal { private _entity = _self getOrDefault ["entity", objNull]; if (isNull _entity) exitWith { false }; @@ -64,7 +64,7 @@ GVAR(CargoEntityController) = createHashMapFromArray [ false }; - _self call ["installDamageWarningHandler", []]; + _self call ["watchDamage", []]; _self call ["markActive", []]; waitUntil { diff --git a/arma/server/addons/task/functions/prototypes/fnc_DefendTaskBaseClass.sqf b/arma/server/addons/task/functions/objects/fnc_DefendTaskBaseClass.sqf similarity index 99% rename from arma/server/addons/task/functions/prototypes/fnc_DefendTaskBaseClass.sqf rename to arma/server/addons/task/functions/objects/fnc_DefendTaskBaseClass.sqf index 8547176..87403e0 100644 --- a/arma/server/addons/task/functions/prototypes/fnc_DefendTaskBaseClass.sqf +++ b/arma/server/addons/task/functions/objects/fnc_DefendTaskBaseClass.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* - * Review-only prototype defend task class. + * Object-style defend task class. */ #pragma hemtt ignore_variables ["_self"] diff --git a/arma/server/addons/task/functions/prototypes/fnc_DefenseEnemyController.sqf b/arma/server/addons/task/functions/objects/fnc_DefenseEnemyController.sqf similarity index 96% rename from arma/server/addons/task/functions/prototypes/fnc_DefenseEnemyController.sqf rename to arma/server/addons/task/functions/objects/fnc_DefenseEnemyController.sqf index 1f86b57..8d589d6 100644 --- a/arma/server/addons/task/functions/prototypes/fnc_DefenseEnemyController.sqf +++ b/arma/server/addons/task/functions/objects/fnc_DefenseEnemyController.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* - * Review-only prototype defense enemy controller. + * Object-style defense enemy controller. */ #pragma hemtt ignore_variables ["_self"] diff --git a/arma/server/addons/task/functions/prototypes/fnc_DefuseTaskBaseClass.sqf b/arma/server/addons/task/functions/objects/fnc_DefuseTaskBaseClass.sqf similarity index 67% rename from arma/server/addons/task/functions/prototypes/fnc_DefuseTaskBaseClass.sqf rename to arma/server/addons/task/functions/objects/fnc_DefuseTaskBaseClass.sqf index ce43a3d..8536c22 100644 --- a/arma/server/addons/task/functions/prototypes/fnc_DefuseTaskBaseClass.sqf +++ b/arma/server/addons/task/functions/objects/fnc_DefuseTaskBaseClass.sqf @@ -1,13 +1,13 @@ #include "..\script_component.hpp" /* - * Review-only prototype defuse task class. + * Object-style defuse task class. * * Example: * call compile preprocessFileLineNumbers - * "\forge\forge_server\addons\task\prototypes\TaskInstanceBaseClass.sqf"; + * "\forge\forge_server\addons\task\objects\TaskInstanceBaseClass.sqf"; * call compile preprocessFileLineNumbers - * "\forge\forge_server\addons\task\prototypes\DefuseTaskBaseClass.sqf"; + * "\forge\forge_server\addons\task\objects\DefuseTaskBaseClass.sqf"; * * private _task = createHashMapObject [ * GVAR(DefuseTaskBaseClass), @@ -64,12 +64,89 @@ GVAR(DefuseTaskBaseClass) = createHashMapFromArray [ _self set ["iedTimer", _taskParams getOrDefault ["iedTimer", 300]]; _self set ["useTaskStore", _taskParams getOrDefault ["useTaskStore", false]]; _self set ["localDefuseCount", _taskParams getOrDefault ["localDefuseCount", 0]]; + _self set ["iedControllers", []]; _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 _ieds = GVAR(TaskStore) call ["getTaskEntities", ["ieds", _taskID]]; + private _protected = GVAR(TaskStore) call ["getTaskEntities", ["entities", _taskID]]; + _self set ["ieds", _ieds]; + _self set ["protected", _protected]; + + private _taskParams = _self getOrDefault ["taskParams", createHashMap]; + private _requiredDefusals = _taskParams getOrDefault ["limitSuccess", -1]; + if (_requiredDefusals < 0) then { _requiredDefusals = count _ieds; }; + + private _maxProtectedLosses = _taskParams getOrDefault ["limitFail", -1]; + if (_maxProtectedLosses < 0) then { _maxProtectedLosses = count _protected; }; + + _self set ["requiredDefusals", _requiredDefusals]; + _self set ["maxProtectedLosses", _maxProtectedLosses]; + true + }], + ["trackParticipants", compileFinal { + private _taskID = _self getOrDefault ["taskID", ""]; + if (_taskID isEqualTo "" || { !(_self getOrDefault ["useTaskStore", false]) }) exitWith { false }; + + GVAR(TaskStore) call ["trackParticipants", [_taskID, (_self getOrDefault ["ieds", []]) + (_self getOrDefault ["protected", []]), "", 250]]; + true + }], + ["waitForRequiredEntities", compileFinal { + if (_self getOrDefault ["useTaskStore", false]) then { + waitUntil { + sleep 1; + _self call ["refreshEntitiesFromStore", []]; + count (_self getOrDefault ["ieds", []]) > 0 + }; + } else { + waitUntil { + sleep 1; + count (_self getOrDefault ["ieds", []]) > 0 + }; + }; + + true + }], + ["startIedControllers", compileFinal { + if ((_self getOrDefault ["iedControllers", []]) isNotEqualTo []) exitWith { true }; + + private _taskID = _self getOrDefault ["taskID", ""]; + private _defaultCountdown = _self getOrDefault ["iedTimer", 300]; + private _controllers = []; + + { + if (!isNull _x) then { + private _countdown = _x getVariable [QGVAR(iedCountdown), _defaultCountdown]; + private _controller = createHashMapObject [ + GVAR(IEDEntityController), + [ + _taskID, + _x, + createHashMapFromArray [ + ["countdown", _countdown], + ["waitForAcceptance", true] + ] + ] + ]; + + _controllers pushBack _controller; + [_controller] spawn { + params ["_controller"]; + _controller call ["runLoop", []]; + }; + }; + } forEach (_self getOrDefault ["ieds", []]); + + _self set ["iedControllers", _controllers]; + true + }], ["countProtectedDestroyed", compileFinal { private _protected = _self getOrDefault ["protected", []]; { !alive _x } count _protected @@ -156,9 +233,12 @@ GVAR(DefuseTaskBaseClass) = createHashMapFromArray [ true }], ["runLoop", compileFinal { + _self call ["waitForRequiredEntities", []]; + _self call ["startIedControllers", []]; _self call ["markActive", []]; while { (_self call ["getStatus", []]) isEqualTo "active" } do { + _self call ["trackParticipants", []]; private _snapshot = _self call ["tick", []]; if (_snapshot getOrDefault ["shouldFail", false]) exitWith { diff --git a/arma/server/addons/task/functions/prototypes/fnc_DeliveryTaskBaseClass.sqf b/arma/server/addons/task/functions/objects/fnc_DeliveryTaskBaseClass.sqf similarity index 99% rename from arma/server/addons/task/functions/prototypes/fnc_DeliveryTaskBaseClass.sqf rename to arma/server/addons/task/functions/objects/fnc_DeliveryTaskBaseClass.sqf index 61f18fc..bc71dc8 100644 --- a/arma/server/addons/task/functions/prototypes/fnc_DeliveryTaskBaseClass.sqf +++ b/arma/server/addons/task/functions/objects/fnc_DeliveryTaskBaseClass.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* - * Review-only prototype delivery task class. + * Object-style delivery task class. */ #pragma hemtt ignore_variables ["_self"] diff --git a/arma/server/addons/task/functions/prototypes/fnc_DestroyTaskBaseClass.sqf b/arma/server/addons/task/functions/objects/fnc_DestroyTaskBaseClass.sqf similarity index 99% rename from arma/server/addons/task/functions/prototypes/fnc_DestroyTaskBaseClass.sqf rename to arma/server/addons/task/functions/objects/fnc_DestroyTaskBaseClass.sqf index ad0ba1d..c2ca6d3 100644 --- a/arma/server/addons/task/functions/prototypes/fnc_DestroyTaskBaseClass.sqf +++ b/arma/server/addons/task/functions/objects/fnc_DestroyTaskBaseClass.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* - * Review-only prototype destroy task class. + * Object-style destroy task class. */ #pragma hemtt ignore_variables ["_self"] diff --git a/arma/server/addons/task/functions/prototypes/fnc_EntityControllerBaseClass.sqf b/arma/server/addons/task/functions/objects/fnc_EntityControllerBaseClass.sqf similarity index 93% rename from arma/server/addons/task/functions/prototypes/fnc_EntityControllerBaseClass.sqf rename to arma/server/addons/task/functions/objects/fnc_EntityControllerBaseClass.sqf index abf4c3d..4b951f2 100644 --- a/arma/server/addons/task/functions/prototypes/fnc_EntityControllerBaseClass.sqf +++ b/arma/server/addons/task/functions/objects/fnc_EntityControllerBaseClass.sqf @@ -1,11 +1,11 @@ #include "..\script_component.hpp" /* - * Review-only prototype base class for object-based entity controllers. + * Object-style base class for object-based entity controllers. * * Example: * call compile preprocessFileLineNumbers - * "\forge\forge_server\addons\task\prototypes\EntityControllerBaseClass.sqf"; + * "\forge\forge_server\addons\task\objects\EntityControllerBaseClass.sqf"; * * private _controller = createHashMapObject [ * GVAR(EntityControllerBaseClass), @@ -105,9 +105,9 @@ GVAR(EntityControllerBaseClass) = createHashMapFromArray [ private _registryKey = _self call ["getRegistryKey", []]; if (_registryKey isEqualTo "") exitWith { false }; - private _registry = missionNamespace getVariable [QGVAR(PrototypeControllerInstances), createHashMap]; + private _registry = missionNamespace getVariable [QGVAR(ObjectControllerInstances), createHashMap]; _registry set [_registryKey, _self]; - missionNamespace setVariable [QGVAR(PrototypeControllerInstances), _registry]; + missionNamespace setVariable [QGVAR(ObjectControllerInstances), _registry]; missionNamespace setVariable [_registryKey, _self]; true }], @@ -115,7 +115,7 @@ GVAR(EntityControllerBaseClass) = createHashMapFromArray [ private _registryKey = _self call ["getRegistryKey", []]; if (_registryKey isEqualTo "") exitWith { false }; - private _registry = missionNamespace getVariable [QGVAR(PrototypeControllerInstances), createHashMap]; + private _registry = missionNamespace getVariable [QGVAR(ObjectControllerInstances), createHashMap]; _registry deleteAt _registryKey; missionNamespace setVariable [_registryKey, nil]; true diff --git a/arma/server/addons/task/functions/prototypes/fnc_HVTEntityController.sqf b/arma/server/addons/task/functions/objects/fnc_HVTEntityController.sqf similarity index 97% rename from arma/server/addons/task/functions/prototypes/fnc_HVTEntityController.sqf rename to arma/server/addons/task/functions/objects/fnc_HVTEntityController.sqf index f7eae62..fa26c09 100644 --- a/arma/server/addons/task/functions/prototypes/fnc_HVTEntityController.sqf +++ b/arma/server/addons/task/functions/objects/fnc_HVTEntityController.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* - * Review-only prototype HVT entity controller. + * Object-style HVT entity controller. */ #pragma hemtt ignore_variables ["_self"] diff --git a/arma/server/addons/task/functions/prototypes/fnc_HVTTaskBaseClass.sqf b/arma/server/addons/task/functions/objects/fnc_HVTTaskBaseClass.sqf similarity index 90% rename from arma/server/addons/task/functions/prototypes/fnc_HVTTaskBaseClass.sqf rename to arma/server/addons/task/functions/objects/fnc_HVTTaskBaseClass.sqf index 1c4de90..9c4e85a 100644 --- a/arma/server/addons/task/functions/prototypes/fnc_HVTTaskBaseClass.sqf +++ b/arma/server/addons/task/functions/objects/fnc_HVTTaskBaseClass.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* - * Review-only prototype HVT task class. + * Object-style HVT task class. */ #pragma hemtt ignore_variables ["_self"] @@ -42,6 +42,7 @@ GVAR(HVTTaskBaseClass) = createHashMapFromArray [ _self set ["eliminate", _eliminate]; _self set ["timeLimit", _taskParams getOrDefault ["timeLimit", 0]]; _self set ["useTaskStore", _taskParams getOrDefault ["useTaskStore", false]]; + _self set ["hvtControllers", []]; _self call ["registerInstance", []]; }], @@ -90,6 +91,30 @@ GVAR(HVTTaskBaseClass) = createHashMapFromArray [ _self set ["maxKilled", _maxKilled]; true }], + ["startHvtControllers", compileFinal { + if ((_self getOrDefault ["hvtControllers", []]) isNotEqualTo []) exitWith { true }; + + private _taskID = _self getOrDefault ["taskID", ""]; + private _controllers = []; + + { + if (!isNull _x) then { + private _controller = createHashMapObject [ + GVAR(HVTEntityController), + [_taskID, _x, createHashMapFromArray [["captureRadius", 2]]] + ]; + + _controllers pushBack _controller; + [_controller] spawn { + params ["_controller"]; + _controller call ["runLoop", []]; + }; + }; + } forEach (_self getOrDefault ["hvts", []]); + + _self set ["hvtControllers", _controllers]; + true + }], ["waitForAssignmentIfTimed", compileFinal { private _timeLimit = _self getOrDefault ["timeLimit", 0]; private _taskID = _self getOrDefault ["taskID", ""]; @@ -185,6 +210,7 @@ GVAR(HVTTaskBaseClass) = createHashMapFromArray [ }], ["runLoop", compileFinal { _self call ["waitForRequiredEntities", []]; + _self call ["startHvtControllers", []]; _self call ["waitForAssignmentIfTimed", []]; _self call ["markActive", []]; diff --git a/arma/server/addons/task/functions/prototypes/fnc_HostageEntityController.sqf b/arma/server/addons/task/functions/objects/fnc_HostageEntityController.sqf similarity index 94% rename from arma/server/addons/task/functions/prototypes/fnc_HostageEntityController.sqf rename to arma/server/addons/task/functions/objects/fnc_HostageEntityController.sqf index de61f2a..9d007db 100644 --- a/arma/server/addons/task/functions/prototypes/fnc_HostageEntityController.sqf +++ b/arma/server/addons/task/functions/objects/fnc_HostageEntityController.sqf @@ -1,13 +1,13 @@ #include "..\script_component.hpp" /* - * Review-only prototype hostage entity controller. + * Object-style hostage entity controller. * * Example: * call compile preprocessFileLineNumbers - * "\forge\forge_server\addons\task\prototypes\EntityControllerBaseClass.sqf"; + * "\forge\forge_server\addons\task\objects\EntityControllerBaseClass.sqf"; * call compile preprocessFileLineNumbers - * "\forge\forge_server\addons\task\prototypes\HostageEntityController.sqf"; + * "\forge\forge_server\addons\task\objects\HostageEntityController.sqf"; * * private _controller = createHashMapObject [ * GVAR(HostageEntityController), diff --git a/arma/server/addons/task/functions/prototypes/fnc_HostageTaskBaseClass.sqf b/arma/server/addons/task/functions/objects/fnc_HostageTaskBaseClass.sqf similarity index 98% rename from arma/server/addons/task/functions/prototypes/fnc_HostageTaskBaseClass.sqf rename to arma/server/addons/task/functions/objects/fnc_HostageTaskBaseClass.sqf index 89e5abd..cf4e4f9 100644 --- a/arma/server/addons/task/functions/prototypes/fnc_HostageTaskBaseClass.sqf +++ b/arma/server/addons/task/functions/objects/fnc_HostageTaskBaseClass.sqf @@ -1,13 +1,13 @@ #include "..\script_component.hpp" /* - * Review-only prototype hostage task class. + * Object-style hostage task class. * * Example: * call compile preprocessFileLineNumbers - * "\forge\forge_server\addons\task\prototypes\TaskInstanceBaseClass.sqf"; + * "\forge\forge_server\addons\task\objects\TaskInstanceBaseClass.sqf"; * call compile preprocessFileLineNumbers - * "\forge\forge_server\addons\task\prototypes\HostageTaskBaseClass.sqf"; + * "\forge\forge_server\addons\task\objects\HostageTaskBaseClass.sqf"; * * private _task = createHashMapObject [ * GVAR(HostageTaskBaseClass), diff --git a/arma/server/addons/task/functions/prototypes/fnc_IEDEntityController.sqf b/arma/server/addons/task/functions/objects/fnc_IEDEntityController.sqf similarity index 98% rename from arma/server/addons/task/functions/prototypes/fnc_IEDEntityController.sqf rename to arma/server/addons/task/functions/objects/fnc_IEDEntityController.sqf index 08baa0d..5ad3efd 100644 --- a/arma/server/addons/task/functions/prototypes/fnc_IEDEntityController.sqf +++ b/arma/server/addons/task/functions/objects/fnc_IEDEntityController.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* - * Review-only prototype IED entity controller. + * Object-style IED entity controller. */ #pragma hemtt ignore_variables ["_self"] diff --git a/arma/server/addons/task/functions/prototypes/fnc_ProtectedEntityController.sqf b/arma/server/addons/task/functions/objects/fnc_ProtectedEntityController.sqf similarity index 95% rename from arma/server/addons/task/functions/prototypes/fnc_ProtectedEntityController.sqf rename to arma/server/addons/task/functions/objects/fnc_ProtectedEntityController.sqf index 4f608dc..1195a65 100644 --- a/arma/server/addons/task/functions/prototypes/fnc_ProtectedEntityController.sqf +++ b/arma/server/addons/task/functions/objects/fnc_ProtectedEntityController.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* - * Review-only prototype protected entity controller. + * Object-style protected entity controller. */ #pragma hemtt ignore_variables ["_self"] diff --git a/arma/server/addons/task/functions/prototypes/fnc_ShooterEntityController.sqf b/arma/server/addons/task/functions/objects/fnc_ShooterEntityController.sqf similarity index 95% rename from arma/server/addons/task/functions/prototypes/fnc_ShooterEntityController.sqf rename to arma/server/addons/task/functions/objects/fnc_ShooterEntityController.sqf index f70e1f3..b3d1e40 100644 --- a/arma/server/addons/task/functions/prototypes/fnc_ShooterEntityController.sqf +++ b/arma/server/addons/task/functions/objects/fnc_ShooterEntityController.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* - * Review-only prototype shooter entity controller. + * Object-style shooter entity controller. */ #pragma hemtt ignore_variables ["_self"] diff --git a/arma/server/addons/task/functions/prototypes/fnc_TargetEntityController.sqf b/arma/server/addons/task/functions/objects/fnc_TargetEntityController.sqf similarity index 95% rename from arma/server/addons/task/functions/prototypes/fnc_TargetEntityController.sqf rename to arma/server/addons/task/functions/objects/fnc_TargetEntityController.sqf index 02b5d03..b7b85e7 100644 --- a/arma/server/addons/task/functions/prototypes/fnc_TargetEntityController.sqf +++ b/arma/server/addons/task/functions/objects/fnc_TargetEntityController.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* - * Review-only prototype target entity controller. + * Object-style target entity controller. */ #pragma hemtt ignore_variables ["_self"] diff --git a/arma/server/addons/task/functions/prototypes/fnc_TaskInstanceBaseClass.sqf b/arma/server/addons/task/functions/objects/fnc_TaskInstanceBaseClass.sqf similarity index 95% rename from arma/server/addons/task/functions/prototypes/fnc_TaskInstanceBaseClass.sqf rename to arma/server/addons/task/functions/objects/fnc_TaskInstanceBaseClass.sqf index a6d7f7d..305b565 100644 --- a/arma/server/addons/task/functions/prototypes/fnc_TaskInstanceBaseClass.sqf +++ b/arma/server/addons/task/functions/objects/fnc_TaskInstanceBaseClass.sqf @@ -1,11 +1,11 @@ #include "..\script_component.hpp" /* - * Review-only prototype base class for object-based task instances. + * Object-style base class for object-based task instances. * * Example: * call compile preprocessFileLineNumbers - * "\forge\forge_server\addons\task\prototypes\TaskInstanceBaseClass.sqf"; + * "\forge\forge_server\addons\task\objects\TaskInstanceBaseClass.sqf"; * * private _task = createHashMapObject [ * GVAR(TaskInstanceBaseClass), @@ -93,9 +93,9 @@ GVAR(TaskInstanceBaseClass) = createHashMapFromArray [ private _registryKey = _self call ["getRegistryKey", []]; if (_registryKey isEqualTo "") exitWith { false }; - private _registry = missionNamespace getVariable [QGVAR(PrototypeTaskInstances), createHashMap]; + private _registry = missionNamespace getVariable [QGVAR(ObjectTaskInstances), createHashMap]; _registry set [_registryKey, _self]; - missionNamespace setVariable [QGVAR(PrototypeTaskInstances), _registry]; + missionNamespace setVariable [QGVAR(ObjectTaskInstances), _registry]; missionNamespace setVariable [_registryKey, _self]; true }], @@ -103,7 +103,7 @@ GVAR(TaskInstanceBaseClass) = createHashMapFromArray [ private _registryKey = _self call ["getRegistryKey", []]; if (_registryKey isEqualTo "") exitWith { false }; - private _registry = missionNamespace getVariable [QGVAR(PrototypeTaskInstances), createHashMap]; + private _registry = missionNamespace getVariable [QGVAR(ObjectTaskInstances), createHashMap]; _registry deleteAt _registryKey; missionNamespace setVariable [_registryKey, nil]; true diff --git a/arma/server/addons/task/functions/prototypes/README.md b/arma/server/addons/task/functions/prototypes/README.md deleted file mode 100644 index c23987c..0000000 --- a/arma/server/addons/task/functions/prototypes/README.md +++ /dev/null @@ -1,66 +0,0 @@ -# Task Object Prototypes - -This folder contains review-only `createHashMapObject` prototypes for task -instances. Their source now lives under `functions/prototypes/`, and they are -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 -- show what per-entity heartbeat/controller objects could look like -- separate state ownership from the current long procedural functions -- avoid committing the live addon to a large refactor before the model is - reviewed -- keep shared lifecycle and reward initialization in `TaskInstanceBaseClass` - so concrete task prototypes only define task-specific state -- keep heartbeat-style AI/object behavior in separate entity controllers instead - of mixing it into task outcome loops - -Important design choice: -- these prototypes use explicit `markSucceeded`, `markFailed`, and `cleanup` - methods instead of relying on `#delete` -- task loops that use `sleep` or `waitUntil` with `sleep` must be started from - scheduled code, typically via `spawn` - -That is intentional. `createHashMapObject` destructor timing is reference-based, -so `#delete` is not a good primitive for mission-critical task completion or -reward flow. diff --git a/arma/server/addons/task/functions/prototypes/fnc_initPrototypes.sqf b/arma/server/addons/task/functions/prototypes/fnc_initPrototypes.sqf deleted file mode 100644 index d75e211..0000000 --- a/arma/server/addons/task/functions/prototypes/fnc_initPrototypes.sqf +++ /dev/null @@ -1,64 +0,0 @@ -#include "..\script_component.hpp" - -/* - * Review-only prototype initializer for object-based task instances. - * - * Usage in debug/testing: - * private _prototypes = [] call FUNC(initPrototypes); - * - * private _task = createHashMapObject [ - * _prototypes get "HostageTaskBaseClass", - * [ - * "task_hostage_review", - * createHashMapFromArray [ - * ["hostages", [hostage1, hostage2]], - * ["shooters", [shooter1, shooter2]] - * ], - * createHashMapFromArray [ - * ["extractionZone", "hostage_extract"], - * ["limitSuccess", 2], - * ["limitFail", 1], - * ["execution", true], - * ["timeLimit", 900] - * ] - * ] - * ]; - */ - -[] call FUNC(TaskInstanceBaseClass); -[] call FUNC(EntityControllerBaseClass); -[] 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)], - ["EntityControllerBaseClass", GVAR(EntityControllerBaseClass)], - ["AttackTaskBaseClass", GVAR(AttackTaskBaseClass)], - ["HostageTaskBaseClass", GVAR(HostageTaskBaseClass)], - ["HostageEntityController", GVAR(HostageEntityController)], - ["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)] -]