From 5576cc4746b74173fd779b9ad9f9eb07a6f35dde Mon Sep 17 00:00:00 2001 From: Jacob Schmidt Date: Fri, 17 Apr 2026 19:34:21 -0500 Subject: [PATCH] Refactor task modules for improved parameter handling and logging - Updated fnc_defuseModule, fnc_deliveryModule, fnc_destroyModule, fnc_hostageModule, fnc_hvtModule to enhance parameter retrieval and logging. - Introduced error handling for missing task IDs across modules. - Consolidated task initialization logic into fnc_startTask for better maintainability. - Added fnc_cargoModule as a sync target for cargo entities in delivery tasks. - Improved logging to provide clearer insights into task parameters and synced entities. --- arma/server/addons/task/CfgVehicles.hpp | 150 +++++++++++++ arma/server/addons/task/XEH_PREP.hpp | 2 + .../task/functions/fnc_attackModule.sqf | 53 +++-- .../addons/task/functions/fnc_cargoModule.sqf | 23 ++ .../task/functions/fnc_defendModule.sqf | 93 ++++---- .../task/functions/fnc_defuseModule.sqf | 70 +++--- .../task/functions/fnc_deliveryModule.sqf | 98 +++++---- .../task/functions/fnc_destroyModule.sqf | 53 +++-- .../task/functions/fnc_hostageModule.sqf | 96 ++++---- .../addons/task/functions/fnc_hvtModule.sqf | 69 +++--- .../task/functions/fnc_missionManager.sqf | 89 +++----- .../addons/task/functions/fnc_startTask.sqf | 206 ++++++++++++++++++ 12 files changed, 695 insertions(+), 307 deletions(-) create mode 100644 arma/server/addons/task/functions/fnc_cargoModule.sqf create mode 100644 arma/server/addons/task/functions/fnc_startTask.sqf diff --git a/arma/server/addons/task/CfgVehicles.hpp b/arma/server/addons/task/CfgVehicles.hpp index 06a1a39..f045710 100644 --- a/arma/server/addons/task/CfgVehicles.hpp +++ b/arma/server/addons/task/CfgVehicles.hpp @@ -638,6 +638,156 @@ class CfgVehicles { }; }; + class FORGE_Module_Delivery: Module_F { + scope = 2; + displayName = "Delivery Task"; + category = "FORGE_Modules"; + + function = QFUNC(deliveryModule); + functionPriority = 1; + isGlobal = 1; + isTriggerActivated = 1; + isDisposable = 1; + is3DEN = 0; + + canSetArea = 0; + canSetAreaShape = 0; + canSetAreaHeight = 0; + + class AttributeValues {}; + class Attributes: AttributesBase { + class TaskID: Edit { + property = "FORGE_Module_Delivery_TaskID"; + displayName = "Task ID"; + tooltip = "Unique identifier for this task"; + typeName = "STRING"; + }; + class DeliveryZone: Edit { + property = "FORGE_Module_Delivery_DeliveryZone"; + displayName = "Delivery Zone Marker"; + tooltip = "Name of the marker defining the delivery destination"; + typeName = "STRING"; + }; + class LimitFail: Edit { + property = "FORGE_Module_Delivery_LimitFail"; + displayName = "Fail Limit"; + tooltip = "Number of cargo items damaged or lost before failing"; + typeName = "NUMBER"; + defaultValue = 1; + }; + class LimitSuccess: Edit { + property = "FORGE_Module_Delivery_LimitSuccess"; + displayName = "Success Limit"; + tooltip = "Number of cargo items that must reach the delivery zone"; + typeName = "NUMBER"; + defaultValue = 1; + }; + class CompanyFunds: Edit { + property = "FORGE_Module_Delivery_CompanyFunds"; + displayName = "Reward Funds"; + tooltip = "Amount of funds awarded on success"; + typeName = "NUMBER"; + defaultValue = 0; + }; + class RatingFail: Edit { + property = "FORGE_Module_Delivery_RatingFail"; + displayName = "Rating Loss"; + tooltip = "Amount of rating lost on failure"; + typeName = "NUMBER"; + defaultValue = 0; + }; + class RatingSuccess: Edit { + property = "FORGE_Module_Delivery_RatingSuccess"; + displayName = "Rating Gain"; + tooltip = "Amount of rating gained on success"; + typeName = "NUMBER"; + defaultValue = 0; + }; + class EndSuccess: Combo { + property = "FORGE_Module_Delivery_EndSuccess"; + displayName = "End on Success"; + tooltip = "End mission when task is completed successfully"; + typeName = "BOOL"; + defaultValue = 0; + + class Values { + class EnableEndSuccess { name = "Enable"; value = 1; }; + class DisableEndSuccess { name = "Disable"; value = 0; }; + }; + }; + class EndFail: Combo { + property = "FORGE_Module_Delivery_EndFail"; + displayName = "End on Failure"; + tooltip = "End mission when task fails"; + typeName = "BOOL"; + defaultValue = 0; + + class Values { + class EnableEndFail { name = "Enable"; value = 1; }; + class DisableEndFail { name = "Disable"; value = 0; }; + }; + }; + class TimeLimit: Edit { + property = "FORGE_Module_Delivery_TimeLimit"; + displayName = "Time Limit"; + tooltip = "Seconds to complete delivery (-1 for no limit)"; + typeName = "NUMBER"; + defaultValue = -1; + }; + }; + + class ModuleDescription: ModuleDescription { + description = "Creates a delivery task. Sync with a FORGE_Module_Cargo to register cargo objects."; + sync[] = { "Anything" }; + + class Anything { + description[] = { + "Delivery task module", + "Sync with FORGE_Module_Cargo which groups the cargo objects" + }; + position = 1; + direction = 1; + optional = 1; + duplicate = 1; + }; + }; + }; + + class FORGE_Module_Cargo: Module_F { + scope = 2; + displayName = "Cargo Entities"; + category = "FORGE_Modules"; + + function = QFUNC(cargoModule); + functionPriority = 1; + isGlobal = 1; + isTriggerActivated = 0; + isDisposable = 1; + is3DEN = 0; + + canSetArea = 0; + canSetAreaShape = 0; + canSetAreaHeight = 0; + + class AttributeValues {}; + class Attributes: AttributesBase {}; + class ModuleDescription: ModuleDescription { + description = "Grouping module for cargo objects in a delivery task. Sync with objects to mark as cargo, then sync this module to FORGE_Module_Delivery."; + sync[] = { "Anything" }; + + class Anything { + description[] = { + "Cargo entities module", + "Sync with objects to mark as delivery cargo" + }; + position = 1; + direction = 1; + optional = 1; + duplicate = 1; + }; + }; + }; + class FORGE_Module_HVT: Module_F { scope = 2; displayName = "HVT Task"; diff --git a/arma/server/addons/task/XEH_PREP.hpp b/arma/server/addons/task/XEH_PREP.hpp index 1fb187a..db12aaa 100644 --- a/arma/server/addons/task/XEH_PREP.hpp +++ b/arma/server/addons/task/XEH_PREP.hpp @@ -1,5 +1,6 @@ PREP(attack); PREP(attackModule); +PREP(cargoModule); PREP(defend); PREP(defendModule); PREP(defuse); @@ -29,3 +30,4 @@ PREP(initTaskStore); PREP(protectedModule); PREP(shootersModule); PREP(spawnEnemyWave); +PREP(startTask); diff --git a/arma/server/addons/task/functions/fnc_attackModule.sqf b/arma/server/addons/task/functions/fnc_attackModule.sqf index 7a364d6..e0cd214 100644 --- a/arma/server/addons/task/functions/fnc_attackModule.sqf +++ b/arma/server/addons/task/functions/fnc_attackModule.sqf @@ -23,29 +23,38 @@ params [["_logic", objNull, [objNull]], ["_units", [], [[]]], ["_activated", tru if !(_activated) exitWith {}; private _taskID = _logic getVariable ["TaskID", ""]; -private _limitFail = _logic getVariable ["LimitFail", -1]; -private _limitSuccess = _logic getVariable ["LimitSuccess", -1]; -private _companyFunds = _logic getVariable ["CompanyFunds", 0]; -private _ratingFail = _logic getVariable ["RatingFail", 0]; -private _ratingSuccess = _logic getVariable ["RatingSuccess", 0]; -private _endSuccess = _logic getVariable ["EndSuccess", false]; -private _endFail = _logic getVariable ["EndFail", false]; -private _timeLimit = _logic getVariable ["TimeLimit", 0]; - -["INFO", format ["Attack Module Parameters: TaskID: %1, LimitFail: %2, LimitSuccess: %3, Funds: %4, RatingFail: %5, RatingSuccess: %6, EndSuccess: %7, EndFail: %8, Time: %9", _taskID, _limitFail, _limitSuccess, _companyFunds, _ratingFail, _ratingSuccess, _endSuccess, _endFail, _timeLimit]] call EFUNC(common,log); - -private _syncedEntities = synchronizedObjects _logic; -["INFO", format ["Attack Module Synced Entities: %1", _syncedEntities]] call EFUNC(common,log); - -{ - [_x, _taskID] spawn FUNC(makeTarget); -} forEach _syncedEntities; - -private _params = [_taskID, _limitFail, _limitSuccess, _companyFunds, _ratingFail, _ratingSuccess, _endSuccess, _endFail]; -if (_timeLimit != 0) then { - _params pushBack _timeLimit; +if (_taskID isEqualTo "") exitWith { + ["ERROR", "Attack module: no task ID configured."] call EFUNC(common,log); }; -["attack", _params, 0, ""] spawn FUNC(handler); +private _syncedEntities = synchronizedObjects _logic; +["INFO", format ["Attack Module: TaskID: %1, Synced entities: %2", _taskID, count _syncedEntities]] call EFUNC(common,log); + +private _taskPos = if (_syncedEntities isNotEqualTo []) then { + getPosATL (_syncedEntities select 0) +} else { + getPosATL _logic +}; + +[ + "attack", + _taskID, + _taskPos, + format ["Attack: %1", _taskID], + "Eliminate all hostile forces in the area.", + createHashMapFromArray [ + ["targets", _syncedEntities] + ], + createHashMapFromArray [ + ["limitFail", _logic getVariable ["LimitFail", -1]], + ["limitSuccess", _logic getVariable ["LimitSuccess", -1]], + ["funds", _logic getVariable ["CompanyFunds", 0]], + ["ratingFail", _logic getVariable ["RatingFail", 0]], + ["ratingSuccess", _logic getVariable ["RatingSuccess", 0]], + ["endSuccess", _logic getVariable ["EndSuccess", false]], + ["endFail", _logic getVariable ["EndFail", false]], + ["timeLimit", _logic getVariable ["TimeLimit", -1]] + ] +] call FUNC(startTask); deleteVehicle _logic; diff --git a/arma/server/addons/task/functions/fnc_cargoModule.sqf b/arma/server/addons/task/functions/fnc_cargoModule.sqf new file mode 100644 index 0000000..6971693 --- /dev/null +++ b/arma/server/addons/task/functions/fnc_cargoModule.sqf @@ -0,0 +1,23 @@ +#include "..\script_component.hpp" + +/* + * Author: IDSolutions + * Grouping module for cargo entities in a delivery task. + * This module has no logic of its own — it acts as a sync target so that + * cargo objects can be grouped and discovered by the parent delivery module + * via synchronizedObjects + typeOf "FORGE_Module_Cargo". + * + * Arguments: + * 0: Logic + * 1: Units + * 2: Activated + * + * Return Value: + * None + * + * Public: No + */ + +params [["_logic", objNull, [objNull]], ["_units", [], [[]]], ["_activated", true, [true]]]; + +if !(_activated) exitWith {}; diff --git a/arma/server/addons/task/functions/fnc_defendModule.sqf b/arma/server/addons/task/functions/fnc_defendModule.sqf index 8d8dbe3..37f9cd0 100644 --- a/arma/server/addons/task/functions/fnc_defendModule.sqf +++ b/arma/server/addons/task/functions/fnc_defendModule.sqf @@ -2,60 +2,65 @@ /* * Author: IDSolutions - * Creates a defend task module + * Initializes the defend task module. + * Reads parameters from the logic object and delegates to fnc_startTask. + * The designer must place a named marker in Eden for the defense zone. + * Enemy waves are spawned automatically by fnc_defend — no entities need + * to be synced to this module. * * Arguments: - * None + * 0: Logic + * 1: Units + * 2: Activated * * Return Value: * None * - * Example: - * call forge_server_task_fnc_defendModule; - * * Public: No */ -// Module category -private _category = "Forge Tasks"; -private _subCategory = "Defense Tasks"; +params [["_logic", objNull, [objNull]], ["_units", [], [[]]], ["_activated", true, [true]]]; -// Create the module -private _module = createDialog "RscDisplayAttributes"; -_module setVariable ["category", _category]; -_module setVariable ["subcategory", _subCategory]; -_module setVariable ["description", "Configure a defend task"]; +if !(_activated) exitWith {}; -// Add fields for task configuration -[_module, "Task ID", "taskID", "", true] call BIS_fnc_addAttribute; -[_module, "Defense Zone Marker", "defenseZone", "", true] call BIS_fnc_addAttribute; -[_module, "Defense Time (seconds)", "defendTime", "600", true] call BIS_fnc_addAttribute; -[_module, "Min BLUFOR in Zone", "minBlufor", "1", true] call BIS_fnc_addAttribute; -[_module, "Company Funds Reward", "companyFunds", "500000", true] call BIS_fnc_addAttribute; -[_module, "Rating Loss on Fail", "ratingFail", "-100", true] call BIS_fnc_addAttribute; -[_module, "Rating Gain on Success", "ratingSuccess", "400", true] call BIS_fnc_addAttribute; -[_module, "End Mission on Success", "endSuccess", "false", false] call BIS_fnc_addAttribute; -[_module, "End Mission on Fail", "endFail", "false", false] call BIS_fnc_addAttribute; -[_module, "Enemy Wave Count", "waveCount", "3", false] call BIS_fnc_addAttribute; -[_module, "Time Between Waves (seconds)", "waveCooldown", "300", false] call BIS_fnc_addAttribute; +private _taskID = _logic getVariable ["TaskID", ""]; +private _defenseZone = _logic getVariable ["DefenseZone", ""]; -// Add confirm button handler -_module setVariable ["onConfirm", { - params ["_module"]; - private _taskID = _module getVariable ["taskID", ""]; - private _defenseZone = _module getVariable ["defenseZone", ""]; - private _defendTime = parseNumber (_module getVariable ["defendTime", "600"]); - private _companyFunds = parseNumber (_module getVariable ["companyFunds", "500000"]); - private _ratingFail = parseNumber (_module getVariable ["ratingFail", "-100"]); - private _ratingSuccess = parseNumber (_module getVariable ["ratingSuccess", "400"]); - private _endSuccess = _module getVariable ["endSuccess", "false"] == "true"; - private _endFail = _module getVariable ["endFail", "false"] == "true"; - private _waveCount = parseNumber (_module getVariable ["waveCount", "3"]); - private _waveCooldown = parseNumber (_module getVariable ["waveCooldown", "300"]); - private _minBlufor = parseNumber (_module getVariable ["minBlufor", "1"]); +if (_taskID isEqualTo "") exitWith { + ["ERROR", "Defend module: no task ID configured."] call EFUNC(common,log); +}; +if (_defenseZone isEqualTo "" || { markerShape _defenseZone isEqualTo "" }) exitWith { + ["ERROR", format ["Defend module '%1': DefenseZone marker '%2' is missing or invalid.", _taskID, _defenseZone]] call EFUNC(common,log); +}; - // Create the task - private _params = [_taskID, _defenseZone, _defendTime, _companyFunds, _ratingFail, _ratingSuccess, _endSuccess, _endFail, _waveCount, _waveCooldown, _minBlufor]; - private _requesterUid = ["", getPlayerUID player] select hasInterface; - ["defend", _params, 0, _requesterUid] spawn FUNC(handler); -}]; +["INFO", format [ + "Defend Module Parameters: TaskID: %1, DefenseZone: %2, DefendTime: %3, WaveCount: %4, WaveCooldown: %5, MinBlufor: %6", + _taskID, _defenseZone, + _logic getVariable ["DefendTime", 600], + _logic getVariable ["WaveCount", 3], + _logic getVariable ["WaveCooldown", 300], + _logic getVariable ["MinBlufor", 1] +]] call EFUNC(common,log); + +[ + "defend", + _taskID, + getMarkerPos _defenseZone, + format ["Defend: %1", _taskID], + "Hold the defense zone against incoming enemy forces.", + createHashMap, + createHashMapFromArray [ + ["funds", _logic getVariable ["CompanyFunds", 0]], + ["ratingFail", _logic getVariable ["RatingFail", 0]], + ["ratingSuccess", _logic getVariable ["RatingSuccess", 0]], + ["endSuccess", _logic getVariable ["EndSuccess", false]], + ["endFail", _logic getVariable ["EndFail", false]], + ["defenseZone", _defenseZone], + ["defendTime", _logic getVariable ["DefendTime", 600]], + ["waveCount", _logic getVariable ["WaveCount", 3]], + ["waveCooldown", _logic getVariable ["WaveCooldown", 300]], + ["minBlufor", _logic getVariable ["MinBlufor", 1]] + ] +] call FUNC(startTask); + +deleteVehicle _logic; diff --git a/arma/server/addons/task/functions/fnc_defuseModule.sqf b/arma/server/addons/task/functions/fnc_defuseModule.sqf index 759c62b..e3b8b1e 100644 --- a/arma/server/addons/task/functions/fnc_defuseModule.sqf +++ b/arma/server/addons/task/functions/fnc_defuseModule.sqf @@ -23,42 +23,48 @@ params [["_logic", objNull, [objNull]], ["_units", [], [[]]], ["_activated", tru if !(_activated) exitWith {}; private _taskID = _logic getVariable ["TaskID", ""]; -private _limitFail = _logic getVariable ["LimitFail", -1]; -private _limitSuccess = _logic getVariable ["LimitSuccess", -1]; -private _companyFunds = _logic getVariable ["CompanyFunds", 0]; -private _ratingFail = _logic getVariable ["RatingFail", 0]; -private _ratingSuccess = _logic getVariable ["RatingSuccess", 0]; -private _endSuccess = _logic getVariable ["EndSuccess", false]; -private _endFail = _logic getVariable ["EndFail", false]; -private _timeLimit = _logic getVariable ["TimeLimit", 0]; - -["INFO", format ["Defuse Module Parameters: TaskID: %1, LimitFail: %2, LimitSuccess: %3, Funds: %4, RatingFail: %5, RatingSuccess: %6, EndSuccess: %7, EndFail: %8, Time: %9", _taskID, _limitFail, _limitSuccess, _companyFunds, _ratingFail, _ratingSuccess, _endSuccess, _endFail, _timeLimit]] call EFUNC(common,log); +if (_taskID isEqualTo "") exitWith { + ["ERROR", "Defuse module: no task ID configured."] call EFUNC(common,log); +}; private _syncedModules = synchronizedObjects _logic; -["INFO", format ["Defuse Module Synced Modules: %1", _syncedModules]] call EFUNC(common,log); +private _iedModule = (_syncedModules select { typeOf _x isEqualTo "FORGE_Module_Explosives" }) param [0, objNull]; +private _protectedModule = (_syncedModules select { typeOf _x isEqualTo "FORGE_Module_Protected" }) param [0, objNull]; +private _iedEntities = if (!isNull _iedModule) then { synchronizedObjects _iedModule } else { [] }; +private _protectedEntities = if (!isNull _protectedModule) then { synchronizedObjects _protectedModule } else { [] }; -private _iedModule = (_syncedModules select { typeOf _x == "FORGE_Module_Explosives" }) select 0; -private _protectedModule = (_syncedModules select { typeOf _x == "FORGE_Module_Protected" }) select 0; +["INFO", format [ + "Defuse Module: TaskID: %1, IEDs: %2, Protected: %3, IED timer: %4s", + _taskID, count _iedEntities, count _protectedEntities, + _logic getVariable ["TimeLimit", 0] +]] call EFUNC(common,log); -private _explosiveEntities = synchronizedObjects _iedModule; -["INFO", format ["Defuse Module Explosive Entites: %1", _explosiveEntities]] call EFUNC(common,log); +private _taskPos = if (_iedEntities isNotEqualTo []) then { + getPosATL (_iedEntities select 0) +} else { + getPosATL _logic +}; -private _protectedEntities = synchronizedObjects _protectedModule; -["INFO", format ["Defuse Module Protected Entities: %1", _protectedEntities]] call EFUNC(common,log); - -{ - if (!isNull _x) then { - [_x, _taskID, _timeLimit] spawn FUNC(makeIED); - }; -} forEach _explosiveEntities; - -{ - if (!isNull _x) then { - [_x, _taskID] spawn FUNC(makeObject); - }; -} forEach _protectedEntities; - -private _params = [_taskID, _limitFail, _limitSuccess, _companyFunds, _ratingFail, _ratingSuccess, _endSuccess, _endFail]; -["defuse", _params, 0, ""] spawn FUNC(handler); +[ + "defuse", + _taskID, + _taskPos, + format ["Defuse: %1", _taskID], + "Locate and defuse all explosive devices before they detonate.", + createHashMapFromArray [ + ["ieds", _iedEntities], + ["protected", _protectedEntities] + ], + createHashMapFromArray [ + ["limitFail", _logic getVariable ["LimitFail", -1]], + ["limitSuccess", _logic getVariable ["LimitSuccess", -1]], + ["funds", _logic getVariable ["CompanyFunds", 0]], + ["ratingFail", _logic getVariable ["RatingFail", 0]], + ["ratingSuccess", _logic getVariable ["RatingSuccess", 0]], + ["endSuccess", _logic getVariable ["EndSuccess", false]], + ["endFail", _logic getVariable ["EndFail", false]], + ["iedTimer", _logic getVariable ["TimeLimit", 0]] + ] +] call FUNC(startTask); deleteVehicle _logic; diff --git a/arma/server/addons/task/functions/fnc_deliveryModule.sqf b/arma/server/addons/task/functions/fnc_deliveryModule.sqf index 19ead22..2a9c151 100644 --- a/arma/server/addons/task/functions/fnc_deliveryModule.sqf +++ b/arma/server/addons/task/functions/fnc_deliveryModule.sqf @@ -2,66 +2,70 @@ /* * Author: IDSolutions - * Creates a delivery task module + * Initializes the delivery task module. + * Reads parameters from the logic object, collects cargo from the synced + * FORGE_Module_Cargo grouping module, and delegates to fnc_startTask. + * + * Eden layout: + * [FORGE_Module_Delivery] --sync--> [FORGE_Module_Cargo] --sync--> cargo_obj1, cargo_obj2 * * Arguments: - * None + * 0: Logic + * 1: Units + * 2: Activated * * Return Value: * None * - * Example: - * call forge_server_task_fnc_deliveryModule; - * * Public: No */ -// Module category -private _category = "Forge Tasks"; -private _subCategory = "Delivery Tasks"; +params [["_logic", objNull, [objNull]], ["_units", [], [[]]], ["_activated", true, [true]]]; -// Create the module -private _module = createDialog "RscDisplayAttributes"; -_module setVariable ["category", _category]; -_module setVariable ["subcategory", _subCategory]; -_module setVariable ["description", "Configure a delivery task"]; +if !(_activated) exitWith {}; -// Add fields for task configuration -[_module, "Task ID", "taskID", "", true] call BIS_fnc_addAttribute; -[_module, "Fail Limit", "limitFail", "1", true] call BIS_fnc_addAttribute; -[_module, "Success Count", "limitSuccess", "3", true] call BIS_fnc_addAttribute; -[_module, "Delivery Zone", "deliveryZone", "", true] call BIS_fnc_addAttribute; -[_module, "Company Funds Reward", "companyFunds", "250000", true] call BIS_fnc_addAttribute; -[_module, "Rating Loss on Fail", "ratingFail", "-75", true] call BIS_fnc_addAttribute; -[_module, "Rating Gain on Success", "ratingSuccess", "300", true] call BIS_fnc_addAttribute; -[_module, "End Mission on Success", "endSuccess", "false", false] call BIS_fnc_addAttribute; -[_module, "End Mission on Fail", "endFail", "false", false] call BIS_fnc_addAttribute; -[_module, "Time Limit (seconds)", "timeLimit", "", false] call BIS_fnc_addAttribute; +private _taskID = _logic getVariable ["TaskID", ""]; +if (_taskID isEqualTo "") exitWith { + ["ERROR", "Delivery module: no task ID configured."] call EFUNC(common,log); +}; -// Add confirm button handler -_module setVariable ["onConfirm", { - params ["_module"]; +private _syncedModules = synchronizedObjects _logic; +private _cargoModule = (_syncedModules select { typeOf _x isEqualTo "FORGE_Module_Cargo" }) param [0, objNull]; +private _cargoEntities = if (!isNull _cargoModule) then { synchronizedObjects _cargoModule } else { [] }; - private _taskID = _module getVariable ["taskID", ""]; - private _limitFail = parseNumber (_module getVariable ["limitFail", "1"]); - private _limitSuccess = parseNumber (_module getVariable ["limitSuccess", "3"]); - private _deliveryZone = _module getVariable ["deliveryZone", ""]; - private _companyFunds = parseNumber (_module getVariable ["companyFunds", "250000"]); - private _ratingFail = parseNumber (_module getVariable ["ratingFail", "-75"]); - private _ratingSuccess = parseNumber (_module getVariable ["ratingSuccess", "300"]); - private _endSuccess = _module getVariable ["endSuccess", "false"] == "true"; - private _endFail = _module getVariable ["endFail", "false"] == "true"; - private _timeLimit = _module getVariable ["timeLimit", ""]; +["INFO", format [ + "Delivery Module Parameters: TaskID: %1, DeliveryZone: %2, Cargo count: %3", + _taskID, + _logic getVariable ["DeliveryZone", ""], + count _cargoEntities +]] call EFUNC(common,log); - // Convert time limit to number or nil - private _timeLimitNum = if (_timeLimit == "") then { nil } else { parseNumber _timeLimit }; +private _taskPos = if (_cargoEntities isNotEqualTo []) then { + getPosATL (_cargoEntities select 0) +} else { + getPosATL _logic +}; - // Create the task - private _params = [_taskID, _limitFail, _limitSuccess, _deliveryZone, _companyFunds, _ratingFail, _ratingSuccess, _endSuccess, _endFail]; - if (!isNil "_timeLimitNum") then { - _params pushBack _timeLimitNum; - }; +[ + "delivery", + _taskID, + _taskPos, + format ["Delivery: %1", _taskID], + "Transport all cargo to the designated delivery zone.", + createHashMapFromArray [ + ["cargo", _cargoEntities] + ], + createHashMapFromArray [ + ["limitFail", _logic getVariable ["LimitFail", -1]], + ["limitSuccess", _logic getVariable ["LimitSuccess", -1]], + ["funds", _logic getVariable ["CompanyFunds", 0]], + ["ratingFail", _logic getVariable ["RatingFail", 0]], + ["ratingSuccess", _logic getVariable ["RatingSuccess", 0]], + ["endSuccess", _logic getVariable ["EndSuccess", false]], + ["endFail", _logic getVariable ["EndFail", false]], + ["timeLimit", _logic getVariable ["TimeLimit", -1]], + ["deliveryZone", _logic getVariable ["DeliveryZone", ""]] + ] +] call FUNC(startTask); - private _requesterUid = ["", getPlayerUID player] select hasInterface; - ["delivery", _params, 0, _requesterUid] spawn FUNC(handler); -}]; +deleteVehicle _logic; diff --git a/arma/server/addons/task/functions/fnc_destroyModule.sqf b/arma/server/addons/task/functions/fnc_destroyModule.sqf index eaac010..b3b2015 100644 --- a/arma/server/addons/task/functions/fnc_destroyModule.sqf +++ b/arma/server/addons/task/functions/fnc_destroyModule.sqf @@ -23,29 +23,38 @@ params [["_logic", objNull, [objNull]], ["_units", [], [[]]], ["_activated", tru if !(_activated) exitWith {}; private _taskID = _logic getVariable ["TaskID", ""]; -private _limitFail = _logic getVariable ["LimitFail", -1]; -private _limitSuccess = _logic getVariable ["LimitSuccess", -1]; -private _companyFunds = _logic getVariable ["CompanyFunds", 0]; -private _ratingFail = _logic getVariable ["RatingFail", 0]; -private _ratingSuccess = _logic getVariable ["RatingSuccess", 0]; -private _endSuccess = _logic getVariable ["EndSuccess", false]; -private _endFail = _logic getVariable ["EndFail", false]; -private _timeLimit = _logic getVariable ["TimeLimit", 0]; - -["INFO", format ["Destroy Module Parameters: TaskID: %1, LimitFail: %2, LimitSuccess: %3, Funds: %4, RatingFail: %5, RatingSuccess: %6, EndSuccess: %7, EndFail: %8, Time: %9", _taskID, _limitFail, _limitSuccess, _companyFunds, _ratingFail, _ratingSuccess, _endSuccess, _endFail, _timeLimit]] call EFUNC(common,log); - -private _syncedEntities = synchronizedObjects _logic; -["INFO", format ["Destroy Module Synced Entities: %1", _syncedEntities]] call EFUNC(common,log); - -{ - [_x, _taskID] spawn FUNC(makeTarget); -} forEach _syncedEntities; - -private _params = [_taskID, _limitFail, _limitSuccess, _companyFunds, _ratingFail, _ratingSuccess, _endSuccess, _endFail]; -if (_timeLimit != 0) then { - _params pushBack _timeLimit; +if (_taskID isEqualTo "") exitWith { + ["ERROR", "Destroy module: no task ID configured."] call EFUNC(common,log); }; -["destroy", _params, 0, ""] spawn FUNC(handler); +private _syncedEntities = synchronizedObjects _logic; +["INFO", format ["Destroy Module: TaskID: %1, Synced entities: %2", _taskID, count _syncedEntities]] call EFUNC(common,log); + +private _taskPos = if (_syncedEntities isNotEqualTo []) then { + getPosATL (_syncedEntities select 0) +} else { + getPosATL _logic +}; + +[ + "destroy", + _taskID, + _taskPos, + format ["Destroy: %1", _taskID], + "Locate and destroy all designated targets.", + createHashMapFromArray [ + ["targets", _syncedEntities] + ], + createHashMapFromArray [ + ["limitFail", _logic getVariable ["LimitFail", -1]], + ["limitSuccess", _logic getVariable ["LimitSuccess", -1]], + ["funds", _logic getVariable ["CompanyFunds", 0]], + ["ratingFail", _logic getVariable ["RatingFail", 0]], + ["ratingSuccess", _logic getVariable ["RatingSuccess", 0]], + ["endSuccess", _logic getVariable ["EndSuccess", false]], + ["endFail", _logic getVariable ["EndFail", false]], + ["timeLimit", _logic getVariable ["TimeLimit", -1]] + ] +] call FUNC(startTask); deleteVehicle _logic; diff --git a/arma/server/addons/task/functions/fnc_hostageModule.sqf b/arma/server/addons/task/functions/fnc_hostageModule.sqf index b5d2a9a..b40de6c 100644 --- a/arma/server/addons/task/functions/fnc_hostageModule.sqf +++ b/arma/server/addons/task/functions/fnc_hostageModule.sqf @@ -23,54 +23,56 @@ params [["_logic", objNull, [objNull]], ["_units", [], [[]]], ["_activated", tru if !(_activated) exitWith {}; private _taskID = _logic getVariable ["TaskID", ""]; -private _limitFail = _logic getVariable ["LimitFail", -1]; -private _limitSuccess = _logic getVariable ["LimitSuccess", -1]; -private _extraction = _logic getVariable ["ExtZone", ""]; -private _companyFunds = _logic getVariable ["CompanyFunds", 0]; -private _ratingFail = _logic getVariable ["RatingFail", 0]; -private _ratingSuccess = _logic getVariable ["RatingSuccess", 0]; -private _cbrn = _logic getVariable ["CBRN", false]; -private _execution = _logic getVariable ["Execution", false]; -private _endSuccess = _logic getVariable ["EndSuccess", false]; -private _endFail = _logic getVariable ["EndFail", false]; -private _timeLimit = _logic getVariable ["TimeLimit", 0]; -private _cbrnZone = _logic getVariable ["CBRNZone", ""]; - -["INFO", format [ - "Hostage Module Parameters: TaskID: %1, LimitFail: %2, LimitSuccess: %3, ExtractionZone: %4, Funds: %5, RatingFail: %6, RatingSuccess: %7, CBRN: %8, Execution: %9, EndSuccess: %10, EndFail: %11, Time: %12, CBRNZone: %13", - _taskID, _limitFail, _limitSuccess, _extraction, _companyFunds, _ratingFail, _ratingSuccess, _cbrn, _execution, _endSuccess, _endFail, _timeLimit, _cbrnZone -]] call EFUNC(common,log); - -private _syncedModules = synchronizedObjects _logic; -["INFO", format ["Hostage Module Synced Entities: %1", _syncedModules]] call EFUNC(common,log); - -private _hostageModule = (_syncedModules select { typeOf _x == "FORGE_Module_Hostages" }) select 0; -private _shooterModule = (_syncedModules select { typeOf _x == "FORGE_Module_Shooters" }) select 0; - -private _hostageEntities = synchronizedObjects _hostageModule; -["INFO", format ["Hostage Module Hostage Entities: %1", _hostageEntities]] call EFUNC(common,log); - -private _shooterEntities = synchronizedObjects _shooterModule; -["INFO", format ["Hostage Module Shooter Entities: %1", _shooterEntities]] call EFUNC(common,log); - -{ - if (!isNull _x && (_x isNotEqualTo str objNull)) then { - [_x, _taskID] spawn FUNC(makeHostage); - }; -} forEach _hostageEntities; - -{ - if (!isNull _x && (_x isNotEqualTo str objNull)) then { - [_x, _taskID] spawn FUNC(makeShooter); - }; -} forEach _shooterEntities; - -private _params = [_taskID, _limitFail, _limitSuccess, _extraction, _companyFunds, _ratingFail, _ratingSuccess, [_cbrn, _execution], _endSuccess, _endFail]; -if (_timeLimit != 0) then { - _params pushBack _timeLimit; - _params pushBack _cbrnZone; +if (_taskID isEqualTo "") exitWith { + ["ERROR", "Hostage module: no task ID configured."] call EFUNC(common,log); }; -["hostage", _params, 0, ""] spawn FUNC(handler); +private _syncedModules = synchronizedObjects _logic; +private _hostageModule = (_syncedModules select { typeOf _x isEqualTo "FORGE_Module_Hostages" }) param [0, objNull]; +private _shooterModule = (_syncedModules select { typeOf _x isEqualTo "FORGE_Module_Shooters" }) param [0, objNull]; +private _hostageEntities = if (!isNull _hostageModule) then { synchronizedObjects _hostageModule } else { [] }; +private _shooterEntities = if (!isNull _shooterModule) then { synchronizedObjects _shooterModule } else { [] }; + +["INFO", format [ + "Hostage Module: TaskID: %1, ExtZone: %2, Hostages: %3, Shooters: %4, CBRN: %5, Execution: %6", + _taskID, + _logic getVariable ["ExtZone", ""], + count _hostageEntities, + count _shooterEntities, + _logic getVariable ["CBRN", false], + _logic getVariable ["Execution", false] +]] call EFUNC(common,log); + +private _taskPos = if (_hostageEntities isNotEqualTo []) then { + getPosATL (_hostageEntities select 0) +} else { + getPosATL _logic +}; + +[ + "hostage", + _taskID, + _taskPos, + format ["Hostage Rescue: %1", _taskID], + "Locate and rescue the hostages and bring them to the extraction zone.", + createHashMapFromArray [ + ["hostages", _hostageEntities], + ["shooters", _shooterEntities] + ], + createHashMapFromArray [ + ["limitFail", _logic getVariable ["LimitFail", -1]], + ["limitSuccess", _logic getVariable ["LimitSuccess", -1]], + ["funds", _logic getVariable ["CompanyFunds", 0]], + ["ratingFail", _logic getVariable ["RatingFail", 0]], + ["ratingSuccess", _logic getVariable ["RatingSuccess", 0]], + ["endSuccess", _logic getVariable ["EndSuccess", false]], + ["endFail", _logic getVariable ["EndFail", false]], + ["timeLimit", _logic getVariable ["TimeLimit", -1]], + ["extractionZone", _logic getVariable ["ExtZone", ""]], + ["cbrn", _logic getVariable ["CBRN", false]], + ["execution", _logic getVariable ["Execution", false]], + ["cbrnZone", _logic getVariable ["CBRNZone", ""]] + ] +] call FUNC(startTask); deleteVehicle _logic; diff --git a/arma/server/addons/task/functions/fnc_hvtModule.sqf b/arma/server/addons/task/functions/fnc_hvtModule.sqf index 2ed59b0..fdc2672 100644 --- a/arma/server/addons/task/functions/fnc_hvtModule.sqf +++ b/arma/server/addons/task/functions/fnc_hvtModule.sqf @@ -23,37 +23,46 @@ params [["_logic", objNull, [objNull]], ["_units", [], [[]]], ["_activated", tru if !(_activated) exitWith {}; private _taskID = _logic getVariable ["TaskID", ""]; -private _limitFail = _logic getVariable ["LimitFail", -1]; -private _limitSuccess = _logic getVariable ["LimitSuccess", -1]; -private _extraction = _logic getVariable ["ExtZone", ""]; -private _companyFunds = _logic getVariable ["CompanyFunds", 0]; -private _ratingFail = _logic getVariable ["RatingFail", 0]; -private _ratingSuccess = _logic getVariable ["RatingSuccess", 0]; -private _capture = _logic getVariable ["CaptureHVT", true]; -private _eliminate = _logic getVariable ["EliminateHVT", false]; -private _endSuccess = _logic getVariable ["EndSuccess", false]; -private _endFail = _logic getVariable ["EndFail", false]; -private _timeLimit = _logic getVariable ["TimeLimit", 0]; - -["INFO", format [ - "HVT Module Parameters: TaskID: %1, LimitFail: %2, LimitSuccess: %3, ExtractionZone: %4, Funds: %5, RatingFail: %6, RatingSuccess: %7, CaptureHvt: %8, EliminateHvt: %9, EndSuccess: %10, EndFail: %11, Time: %12", - _taskID, _limitFail, _limitSuccess, _extraction, _companyFunds, _ratingFail, _ratingSuccess, _capture, _eliminate, _endSuccess, _endFail, _timeLimit -]] call EFUNC(common,log); - -private _syncedEntities = synchronizedObjects _logic; -["INFO", format ["HVT Module Synced Entities: %1", _syncedEntities]] call EFUNC(common,log); - -{ - if (!isNull _x && (_x isNotEqualTo str objNull)) then { - [_x, _taskID] spawn FUNC(makeHVT); - }; -} forEach _syncedEntities; - -private _params = [_taskID, _limitFail, _limitSuccess, _extraction, _companyFunds, _ratingFail, _ratingSuccess, [_capture, _eliminate], _endSuccess, _endFail]; -if (_timeLimit != 0) then { - _params pushBack _timeLimit; +if (_taskID isEqualTo "") exitWith { + ["ERROR", "HVT module: no task ID configured."] call EFUNC(common,log); }; -["hvt", _params, 0, ""] spawn FUNC(handler); +private _syncedEntities = synchronizedObjects _logic; +["INFO", format [ + "HVT Module: TaskID: %1, ExtZone: %2, CaptureHVT: %3, HVTs: %4", + _taskID, + _logic getVariable ["ExtZone", ""], + _logic getVariable ["CaptureHVT", true], + count _syncedEntities +]] call EFUNC(common,log); + +private _taskPos = if (_syncedEntities isNotEqualTo []) then { + getPosATL (_syncedEntities select 0) +} else { + getPosATL _logic +}; + +[ + "hvt", + _taskID, + _taskPos, + format ["HVT: %1", _taskID], + "Locate and capture or eliminate the high-value target.", + createHashMapFromArray [ + ["hvts", _syncedEntities] + ], + createHashMapFromArray [ + ["limitFail", _logic getVariable ["LimitFail", -1]], + ["limitSuccess", _logic getVariable ["LimitSuccess", -1]], + ["funds", _logic getVariable ["CompanyFunds", 0]], + ["ratingFail", _logic getVariable ["RatingFail", 0]], + ["ratingSuccess", _logic getVariable ["RatingSuccess", 0]], + ["endSuccess", _logic getVariable ["EndSuccess", false]], + ["endFail", _logic getVariable ["EndFail", false]], + ["timeLimit", _logic getVariable ["TimeLimit", -1]], + ["extractionZone", _logic getVariable ["ExtZone", ""]], + ["captureHvt", _logic getVariable ["CaptureHVT", true]] + ] +] call FUNC(startTask); deleteVehicle _logic; diff --git a/arma/server/addons/task/functions/fnc_missionManager.sqf b/arma/server/addons/task/functions/fnc_missionManager.sqf index e471b27..bde5f6f 100644 --- a/arma/server/addons/task/functions/fnc_missionManager.sqf +++ b/arma/server/addons/task/functions/fnc_missionManager.sqf @@ -244,42 +244,11 @@ GVAR(MissionManagerBaseClass) = compileFinal createHashMapFromArray [ ["special", _specialRewards] ] }], - ["createAttackTask", compileFinal { - params [ - ["_taskID", "", [""]], - ["_position", [0, 0, 0], [[]]], - ["_locationConfig", configNull, [configNull]] - ]; - - if (_taskID isEqualTo "" || { isNull _locationConfig }) exitWith { false }; - - private _locationKey = configName _locationConfig; - private _locationType = getText (_locationConfig >> "type"); - if (_locationType isEqualTo "") then { _locationType = "area"; }; - - [ - west, - _taskID, - [ - format ["Eliminate hostile forces operating near %1.", _locationKey], - format ["Attack: %1", _locationKey], - _locationType - ], - _position, - "CREATED", - 1, - true, - "attack" - ] call BFUNC(taskCreate); - - true - }], ["startAttackMission", compileFinal { private _attackConfig = _self getOrDefault ["attackConfig", configNull]; private _locationData = _self call ["selectAttackLocation"]; if (_locationData isEqualTo createHashMap) exitWith { "" }; - private _location = _locationData getOrDefault ["config", configNull]; private _locationKey = _locationData getOrDefault ["key", ""]; private _position = _locationData getOrDefault ["position", [0, 0, 0]]; private _group = _self call ["spawnAttackGroup", [_position]]; @@ -292,45 +261,40 @@ GVAR(MissionManagerBaseClass) = compileFinal createHashMapFromArray [ }; private _taskID = format ["task_attack_%1", round (diag_tickTime * 1000)]; - { - [_x, _taskID] call FUNC(makeTarget); - } forEach _units; - - _self call ["createAttackTask", [_taskID, _position, _location]]; - GVAR(TaskStore) call ["registerTaskCatalogEntry", [_taskID, createHashMapFromArray [ - ["type", "attack"], - ["title", format ["Attack: %1", _locationKey]], - ["description", format ["Eliminate hostile forces operating near %1.", _locationKey]], - ["position", _position], - ["locationKey", _locationKey], - ["accepted", false], - ["requesterUid", ""], - ["orgID", "default"], - ["source", "mission_manager"] - ]]]; - private _rewardRange = getArray (_attackConfig >> "Rewards" >> "money"); private _reputationRange = getArray (_attackConfig >> "Rewards" >> "reputation"); private _penaltyRange = getArray (_attackConfig >> "penalty"); private _timeRange = getArray (_attackConfig >> "timeLimit"); private _rewards = _self call ["rollRewards"]; - private _params = [ + private _success = [ + "attack", _taskID, + _position, + format ["Attack: %1", _locationKey], + format ["Eliminate hostile forces operating near %1.", _locationKey], + createHashMapFromArray [["targets", _units]], + createHashMapFromArray [ + ["limitFail", 0], + ["limitSuccess", count _units], + ["funds", _rewardRange call BFUNC(randomNum)], + ["ratingFail", _penaltyRange call BFUNC(randomNum)], + ["ratingSuccess", _reputationRange call BFUNC(randomNum)], + ["endSuccess", false], + ["endFail", false], + ["timeLimit", _timeRange call BFUNC(randomNum)], + ["equipment", _rewards get "equipment"], + ["supplies", _rewards get "supplies"], + ["weapons", _rewards get "weapons"], + ["vehicles", _rewards get "vehicles"], + ["special", _rewards get "special"] + ], 0, - count _units, - _rewardRange call BFUNC(randomNum), - _penaltyRange call BFUNC(randomNum), - _reputationRange call BFUNC(randomNum), - false, - false, - _timeRange call BFUNC(randomNum), - _rewards get "equipment", - _rewards get "supplies", - _rewards get "weapons", - _rewards get "vehicles", - _rewards get "special" - ]; + "", + "mission_manager" + ] call FUNC(startTask); + + if !(_success) exitWith { "" }; private _activeMissionRegistry = _self getOrDefault ["activeMissionRegistry", createHashMap]; _activeMissionRegistry set [_taskID, createHashMapFromArray [ @@ -339,7 +303,6 @@ GVAR(MissionManagerBaseClass) = compileFinal createHashMapFromArray [ ]]; _self set ["activeMissionRegistry", _activeMissionRegistry]; - ["attack", _params, 0, ""] spawn FUNC(handler); _taskID }], ["completeMission", compileFinal { diff --git a/arma/server/addons/task/functions/fnc_startTask.sqf b/arma/server/addons/task/functions/fnc_startTask.sqf new file mode 100644 index 0000000..761bc9b --- /dev/null +++ b/arma/server/addons/task/functions/fnc_startTask.sqf @@ -0,0 +1,206 @@ +#include "..\script_component.hpp" + +/* + * Author: IDSolutions + * Unified task initializer used by both Eden modules and missionManager-generated + * tasks. Registers entities, creates the BIS task, registers the catalog entry, + * and dispatches to the task handler. + * + * Arguments: + * 0: Task type ("attack"|"defuse"|"destroy"|"delivery"|"hostage"|"hvt"|"defend") + * 1: Task ID + * 2: Task position + * 3: Task title + * 4: Task description + * 5: Task entities + * Keys: "targets" -- attack, destroy + * "hostages" -- hostage + * "shooters" -- hostage + * "hvts" -- hvt + * "ieds" -- defuse + * "protected" -- defuse + * "cargo" -- delivery + * 6: Task parameters + * Common keys: + * "limitFail" (default: -1) + * "limitSuccess" (default: -1) + * "funds" (default: 0) + * "ratingFail" (default: 0) + * "ratingSuccess" (default: 0) + * "endSuccess" (default: false) + * "endFail" (default: false) + * "timeLimit" (default: -1, -1 = no limit) + * Reward keys: + * "equipment" , "supplies" , "weapons" , + * "vehicles" , "special" + * Type-specific keys: + * defuse: "iedTimer" -- IED countdown in seconds (default: 0) + * delivery: "deliveryZone" -- marker name + * hostage: "extractionZone" -- marker name + * "cbrn" (default: false) + * "execution" (default: false) + * "cbrnZone" (default: "") + * hvt: "extractionZone" -- marker name (capture mode only) + * "captureHvt" (default: true) + * defend: "defenseZone" -- marker name + * "defendTime" (default: 600) + * "waveCount" (default: 3) + * "waveCooldown" (default: 300) + * "minBlufor" (default: 1) + * 7: Minimum org reputation required (default: 0) + * 8: Requester UID (default: "") + * 9: Source tag (default: "eden") -- "eden"|"mission_manager"|"script" + * + * Return Value: + * Success + * + * Examples: + * // From a unit init field -- register entity first, then start task from trigger/init.sqf: + * [this, "compound_attack_01"] call forge_server_task_fnc_makeTarget; + * + * // From a trigger or init.sqf (all-in-one): + * [ + * "attack", "compound_attack_01", getPosATL leader1, + * "Attack: East Compound", "Eliminate all hostile forces.", + * createHashMapFromArray [["targets", [unit1, unit2, unit3]]], + * createHashMapFromArray [ + * ["limitFail", 0], ["limitSuccess", 3], + * ["funds", 50000], ["ratingFail", -10], ["ratingSuccess", 20], + * ["timeLimit", 900] + * ] + * ] call forge_server_task_fnc_startTask; + * + * Public: Yes + */ + +params [ + ["_taskType", "", [""]], + ["_taskID", "", [""]], + ["_position", [0, 0, 0], [[]]], + ["_title", "", [""]], + ["_description", "", [""]], + ["_entities", createHashMap, [createHashMap]], + ["_taskParams", createHashMap, [createHashMap]], + ["_minRating", 0, [0]], + ["_requesterUid", "", [""]], + ["_source", "eden", [""]] +]; + +if (_taskType isEqualTo "" || { _taskID isEqualTo "" }) exitWith { + ["ERROR", "startTask: missing task type or task ID."] call EFUNC(common,log); + false +}; + +// --- 1. Register task entities --- + +private _iedTimer = _taskParams getOrDefault ["iedTimer", 0]; + +{ + private _role = _x; + private _objects = _entities getOrDefault [_role, []]; + { + if (isNull _x) then { continue; }; + switch (_role) do { + case "targets": { [_x, _taskID] call FUNC(makeTarget); }; + case "hostages": { [_x, _taskID] call FUNC(makeHostage); }; + case "shooters": { [_x, _taskID] call FUNC(makeShooter); }; + case "hvts": { [_x, _taskID] call FUNC(makeHVT); }; + case "ieds": { [_x, _taskID, _iedTimer] call FUNC(makeIED); }; + case "protected": { [_x, _taskID] call FUNC(makeObject); }; + case "cargo": { [_x, _taskID] call FUNC(makeCargo); }; + }; + } forEach _objects; +} forEach ["targets", "hostages", "shooters", "hvts", "ieds", "protected", "cargo"]; + +// --- 2. Create BIS task --- + +[west, _taskID, [_description, _title, _taskType], _position, "CREATED", 1, true, _taskType] call BFUNC(taskCreate); + +// --- 3. Register catalog entry --- + +GVAR(TaskStore) call ["registerTaskCatalogEntry", [_taskID, createHashMapFromArray [ + ["type", _taskType], + ["title", _title], + ["description", _description], + ["position", _position], + ["accepted", false], + ["requesterUid", _requesterUid], + ["orgID", "default"], + ["source", _source] +]]]; + +// --- 4. Assemble type-specific handler args --- + +private _limitFail = _taskParams getOrDefault ["limitFail", -1]; +private _limitSuccess = _taskParams getOrDefault ["limitSuccess", -1]; +private _funds = _taskParams getOrDefault ["funds", 0]; +private _ratingFail = _taskParams getOrDefault ["ratingFail", 0]; +private _ratingSuccess = _taskParams getOrDefault ["ratingSuccess", 0]; +private _endSuccess = _taskParams getOrDefault ["endSuccess", false]; +private _endFail = _taskParams getOrDefault ["endFail", false]; +private _timeLimit = _taskParams getOrDefault ["timeLimit", -1]; +private _equipRewards = _taskParams getOrDefault ["equipment", []]; +private _supplyRewards = _taskParams getOrDefault ["supplies", []]; +private _weaponRewards = _taskParams getOrDefault ["weapons", []]; +private _vehicleRewards = _taskParams getOrDefault ["vehicles", []]; +private _specialRewards = _taskParams getOrDefault ["special", []]; + +private _rewardTail = [_equipRewards, _supplyRewards, _weaponRewards, _vehicleRewards, _specialRewards]; + +private _handlerArgs = switch (_taskType) do { + case "attack"; + case "destroy": { + private _args = [_taskID, _limitFail, _limitSuccess, _funds, _ratingFail, _ratingSuccess, _endSuccess, _endFail]; + if (_timeLimit >= 0) then { _args pushBack _timeLimit; }; + _args + _rewardTail + }; + case "defuse": { + [_taskID, _limitFail, _limitSuccess, _funds, _ratingFail, _ratingSuccess, _endSuccess, _endFail] + _rewardTail + }; + case "delivery": { + private _deliveryZone = _taskParams getOrDefault ["deliveryZone", ""]; + private _args = [_taskID, _limitFail, _limitSuccess, _deliveryZone, _funds, _ratingFail, _ratingSuccess, _endSuccess, _endFail]; + if (_timeLimit >= 0) then { _args pushBack _timeLimit; }; + _args + _rewardTail + }; + case "hostage": { + private _extZone = _taskParams getOrDefault ["extractionZone", ""]; + private _cbrn = _taskParams getOrDefault ["cbrn", false]; + private _execution = _taskParams getOrDefault ["execution", false]; + private _cbrnZone = _taskParams getOrDefault ["cbrnZone", ""]; + private _args = [_taskID, _limitFail, _limitSuccess, _extZone, _funds, _ratingFail, _ratingSuccess, [_cbrn, _execution], _endSuccess, _endFail]; + if (_timeLimit >= 0) then { + _args pushBack _timeLimit; + _args pushBack _cbrnZone; + }; + _args + _rewardTail + }; + case "hvt": { + private _extZone = _taskParams getOrDefault ["extractionZone", ""]; + private _captureHvt = _taskParams getOrDefault ["captureHvt", true]; + private _args = [_taskID, _limitFail, _limitSuccess, _extZone, _funds, _ratingFail, _ratingSuccess, [_captureHvt, !_captureHvt], _endSuccess, _endFail]; + if (_timeLimit >= 0) then { _args pushBack _timeLimit; }; + _args + _rewardTail + }; + case "defend": { + private _defenseZone = _taskParams getOrDefault ["defenseZone", ""]; + private _defendTime = _taskParams getOrDefault ["defendTime", 600]; + private _waveCount = _taskParams getOrDefault ["waveCount", 3]; + private _waveCooldown = _taskParams getOrDefault ["waveCooldown", 300]; + private _minBlufor = _taskParams getOrDefault ["minBlufor", 1]; + [_taskID, _defenseZone, _defendTime, _funds, _ratingFail, _ratingSuccess, _endSuccess, _endFail, + _waveCount, _waveCooldown, _minBlufor] + _rewardTail + }; + default { + ["ERROR", format ["startTask: unknown task type '%1'.", _taskType]] call EFUNC(common,log); + [] + }; +}; + +if (_handlerArgs isEqualTo []) exitWith { false }; + +// --- 5. Dispatch handler --- + +[_taskType, _handlerArgs, _minRating, _requesterUid] spawn FUNC(handler); + +true