diff --git a/arma/mod/addons/task/CfgVehicles.hpp b/arma/mod/addons/task/CfgVehicles.hpp index f3ddedb..8d3b974 100644 --- a/arma/mod/addons/task/CfgVehicles.hpp +++ b/arma/mod/addons/task/CfgVehicles.hpp @@ -3,6 +3,7 @@ class CfgVehicles { class Module_F: Logic { class AttributesBase { class Edit; + class EditMulti; class Combo; }; class ModuleDescription {}; @@ -34,6 +35,7 @@ class CfgVehicles { typeName = "STRING"; // defaultValue = """"; }; + TASK_DISPLAY_ATTRIBUTES(FORGE_Module_Attack,attack) TASK_CHAIN_ATTRIBUTES(FORGE_Module_Attack) class LimitFail: Edit { property = "FORGE_Module_Attack_LimitFail"; @@ -293,6 +295,7 @@ class CfgVehicles { tooltip = "Unique identifier for this task"; typeName = "STRING"; }; + TASK_DISPLAY_ATTRIBUTES(FORGE_Module_Defend,defend) TASK_CHAIN_ATTRIBUTES(FORGE_Module_Defend) class DefenseZone: Edit { property = "FORGE_Module_Defend_DefenseZone"; @@ -419,6 +422,7 @@ class CfgVehicles { typeName = "STRING"; // defaultValue = """"; }; + TASK_DISPLAY_ATTRIBUTES(FORGE_Module_Defuse,danger) TASK_CHAIN_ATTRIBUTES(FORGE_Module_Defuse) class LimitFail: Edit { property = "FORGE_Module_Defuse_LimitFail"; @@ -532,6 +536,7 @@ class CfgVehicles { typeName = "STRING"; // defaultValue = """"; }; + TASK_DISPLAY_ATTRIBUTES(FORGE_Module_Destroy,destroy) TASK_CHAIN_ATTRIBUTES(FORGE_Module_Destroy) class LimitFail: Edit { property = "FORGE_Module_Destroy_LimitFail"; @@ -645,6 +650,7 @@ class CfgVehicles { typeName = "STRING"; // defaultValue = """"; }; + TASK_DISPLAY_ATTRIBUTES(FORGE_Module_Hostage,help) TASK_CHAIN_ATTRIBUTES(FORGE_Module_Hostage) class LimitFail: Edit { property = "FORGE_Module_Hostage_LimitFail"; @@ -794,6 +800,7 @@ class CfgVehicles { tooltip = "Unique identifier for this task"; typeName = "STRING"; }; + TASK_DISPLAY_ATTRIBUTES(FORGE_Module_Delivery,truck) TASK_CHAIN_ATTRIBUTES(FORGE_Module_Delivery) class DeliveryZone: Edit { property = "FORGE_Module_Delivery_DeliveryZone"; @@ -948,6 +955,7 @@ class CfgVehicles { typeName = "STRING"; // defaultValue = """"; }; + TASK_DISPLAY_ATTRIBUTES(FORGE_Module_HVT,target) TASK_CHAIN_ATTRIBUTES(FORGE_Module_HVT) class LimitFail: Edit { property = "FORGE_Module_HVT_LimitFail"; diff --git a/arma/mod/addons/task/script_component.hpp b/arma/mod/addons/task/script_component.hpp index 7d66e07..c22478a 100644 --- a/arma/mod/addons/task/script_component.hpp +++ b/arma/mod/addons/task/script_component.hpp @@ -42,3 +42,87 @@ tooltip = "Comma-separated task IDs that must succeed before this task appears in CAD or can be assigned"; \ typeName = "STRING"; \ }; + +#define TASK_DISPLAY_ATTRIBUTES(PREFIX, DEFAULT_ICON) \ + class TaskTitle: Edit { \ + property = QUOTE(DOUBLES(PREFIX,TaskTitle)); \ + displayName = "Task Title"; \ + tooltip = "Optional title shown in CAD, the map task list, and task notifications. Leave blank to use the Forge default."; \ + typeName = "STRING"; \ + }; \ + class TaskDescription: EditMulti { \ + property = QUOTE(DOUBLES(PREFIX,TaskDescription)); \ + displayName = "Task Description"; \ + tooltip = "Optional description shown in CAD and the map task list. Leave blank to use the Forge default."; \ + typeName = "STRING"; \ + }; \ + class TaskIcon: Combo { \ + property = QUOTE(DOUBLES(PREFIX,TaskIcon)); \ + displayName = "Task Icon"; \ + tooltip = "Arma 3 task framework type/icon used for the BIS map task."; \ + typeName = "STRING"; \ + defaultValue = QUOTE(DEFAULT_ICON); \ + class Values { \ + class AirDrop { name = "airdrop"; value = "airdrop"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\airdrop_ca.paa"; }; \ + class Armor { name = "armor"; value = "armor"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\armor_ca.paa"; }; \ + class Attack { name = "attack"; value = "attack"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\attack_ca.paa"; }; \ + class Backpack { name = "backpack"; value = "backpack"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\backpack_ca.paa"; }; \ + class Boat { name = "boat"; value = "boat"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\boat_ca.paa"; }; \ + class Box { name = "box"; value = "box"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\box_ca.paa"; }; \ + class Car { name = "car"; value = "car"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\car_ca.paa"; }; \ + class Container { name = "container"; value = "container"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\container_ca.paa"; }; \ + class Danger { name = "danger"; value = "danger"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\danger_ca.paa"; }; \ + class Default { name = "default"; value = "default"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\default_ca.paa"; }; \ + class Defend { name = "defend"; value = "defend"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\defend_ca.paa"; }; \ + class Destroy { name = "destroy"; value = "destroy"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\destroy_ca.paa"; }; \ + class Documents { name = "documents"; value = "documents"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\documents_ca.paa"; }; \ + class Download { name = "download"; value = "download"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\download_ca.paa"; }; \ + class Exit { name = "exit"; value = "exit"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\exit_ca.paa"; }; \ + class GetIn { name = "getin"; value = "getin"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\getin_ca.paa"; }; \ + class GetOut { name = "getout"; value = "getout"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\getout_ca.paa"; }; \ + class Ghosts { name = "ghosts"; value = "ghosts"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\ghosts_ca.paa"; }; \ + class Heal { name = "heal"; value = "heal"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\heal_ca.paa"; }; \ + class Heli { name = "heli"; value = "heli"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\heli_ca.paa"; }; \ + class Help { name = "help"; value = "help"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\help_ca.paa"; }; \ + class Intel { name = "intel"; value = "intel"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\intel_ca.paa"; }; \ + class Interact { name = "interact"; value = "interact"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\interact_ca.paa"; }; \ + class Kill { name = "kill"; value = "kill"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\kill_ca.paa"; }; \ + class Land { name = "land"; value = "land"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\land_ca.paa"; }; \ + class Listen { name = "listen"; value = "listen"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\listen_ca.paa"; }; \ + class Map { name = "map"; value = "map"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\map_ca.paa"; }; \ + class Meet { name = "meet"; value = "meet"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\meet_ca.paa"; }; \ + class Mine { name = "mine"; value = "mine"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\mine_ca.paa"; }; \ + class Move { name = "move"; value = "move"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\move_ca.paa"; }; \ + class Move1 { name = "move1"; value = "move1"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\move1_ca.paa"; }; \ + class Move2 { name = "move2"; value = "move2"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\move2_ca.paa"; }; \ + class Move3 { name = "move3"; value = "move3"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\move3_ca.paa"; }; \ + class Move4 { name = "move4"; value = "move4"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\move4_ca.paa"; }; \ + class Move5 { name = "move5"; value = "move5"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\move5_ca.paa"; }; \ + class Navigate { name = "navigate"; value = "navigate"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\navigate_ca.paa"; }; \ + class Plane { name = "plane"; value = "plane"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\plane_ca.paa"; }; \ + class Radio { name = "radio"; value = "radio"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\radio_ca.paa"; }; \ + class Rearm { name = "rearm"; value = "rearm"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\rearm_ca.paa"; }; \ + class Refuel { name = "refuel"; value = "refuel"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\refuel_ca.paa"; }; \ + class Repair { name = "repair"; value = "repair"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\repair_ca.paa"; }; \ + class Rifle { name = "rifle"; value = "rifle"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\rifle_ca.paa"; }; \ + class Run { name = "run"; value = "run"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\run_ca.paa"; }; \ + class Scout { name = "scout"; value = "scout"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\scout_ca.paa"; }; \ + class Search { name = "search"; value = "search"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\search_ca.paa"; }; \ + class Slingload { name = "slingload"; value = "slingload"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\slingload_ca.paa"; }; \ + class Takeoff { name = "takeoff"; value = "takeoff"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\takeoff_ca.paa"; }; \ + class Talk { name = "talk"; value = "talk"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\talk_ca.paa"; }; \ + class Talk1 { name = "talk1"; value = "talk1"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\talk1_ca.paa"; }; \ + class Talk2 { name = "talk2"; value = "talk2"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\talk2_ca.paa"; }; \ + class Talk3 { name = "talk3"; value = "talk3"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\talk3_ca.paa"; }; \ + class Talk4 { name = "talk4"; value = "talk4"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\talk4_ca.paa"; }; \ + class Talk5 { name = "talk5"; value = "talk5"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\talk5_ca.paa"; }; \ + class Target { name = "target"; value = "target"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\target_ca.paa"; }; \ + class Truck { name = "truck"; value = "truck"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\truck_ca.paa"; }; \ + class Unknown { name = "unknown"; value = "unknown"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\unknown_ca.paa"; }; \ + class Upload { name = "upload"; value = "upload"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\upload_ca.paa"; }; \ + class Use { name = "use"; value = "use"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\use_ca.paa"; }; \ + class Wait { name = "wait"; value = "wait"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\wait_ca.paa"; }; \ + class Walk { name = "walk"; value = "walk"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\walk_ca.paa"; }; \ + class Whiteboard { name = "whiteboard"; value = "whiteboard"; picture = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\whiteboard_ca.paa"; }; \ + }; \ + }; diff --git a/arma/server/addons/cad/functions/fnc_initAssignmentRepository.sqf b/arma/server/addons/cad/functions/fnc_initAssignmentRepository.sqf index 4a75cbc..b6d63b4 100644 --- a/arma/server/addons/cad/functions/fnc_initAssignmentRepository.sqf +++ b/arma/server/addons/cad/functions/fnc_initAssignmentRepository.sqf @@ -514,15 +514,17 @@ GVAR(AssignmentRepositoryBaseClass) = compileFinal createHashMapFromArray [ _result }; + private _transitionAllowed = true; switch (_transition) do { case "acknowledge": { if (!_isDispatchOrder) then { private _acceptResult = EGVAR(task,TaskStore) call ["acceptTask", [_taskID, _requesterUid]]; - if !(_acceptResult getOrDefault ["success", false]) exitWith { + if !(_acceptResult getOrDefault ["success", false]) then { _result set ["message", _acceptResult getOrDefault ["message", "Failed to accept task."]]; - _result + _transitionAllowed = false; + } else { + EGVAR(task,TaskStore) call ["setTaskStatus", [_taskID, "active"]]; }; - EGVAR(task,TaskStore) call ["setTaskStatus", [_taskID, "active"]]; }; }; case "decline": { @@ -533,6 +535,7 @@ GVAR(AssignmentRepositoryBaseClass) = compileFinal createHashMapFromArray [ }; }; + if (!_transitionAllowed) exitWith { _result }; if (_result getOrDefault ["success", false]) exitWith { _result }; private _persistenceService = _self getOrDefault ["persistenceService", createHashMap]; diff --git a/arma/server/addons/task/XEH_PREP.hpp b/arma/server/addons/task/XEH_PREP.hpp index 784f8b0..24872fa 100644 --- a/arma/server/addons/task/XEH_PREP.hpp +++ b/arma/server/addons/task/XEH_PREP.hpp @@ -31,6 +31,7 @@ PREP_SUBDIR(helpers,getMissionSettingRange); PREP_SUBDIR(helpers,handleTaskRewards); PREP_SUBDIR(helpers,parseTaskChainAttributes); PREP_SUBDIR(helpers,parseRewards); +PREP_SUBDIR(helpers,resolveTaskDisplay); PREP_SUBDIR(helpers,spawnEnemyWave); PREP_SUBDIR(helpers,startTask); PREP_SUBDIR(helpers,updateEnemyCountFromActivePlayers); diff --git a/arma/server/addons/task/functions/fnc_handler.sqf b/arma/server/addons/task/functions/fnc_handler.sqf index a26640d..b1d66b3 100644 --- a/arma/server/addons/task/functions/fnc_handler.sqf +++ b/arma/server/addons/task/functions/fnc_handler.sqf @@ -23,6 +23,8 @@ params [["_taskType", "", [""]], ["_args", [], [[]]], ["_minRating", 0, [0]], [" private _taskID = ""; private _shouldStartTaskLogic = true; +private _catalogEntry = createHashMap; +private _source = ""; if (_minRating > 0) then { if (_requesterUid isEqualTo "") then { @@ -48,14 +50,14 @@ if (_args isNotEqualTo [] && { (_args select 0) isEqualType "" }) then { }; if (_taskID isNotEqualTo "") then { - private _catalogEntry = GVAR(TaskStore) call ["getTaskCatalogEntry", [_taskID]]; - private _source = if (_catalogEntry isEqualType createHashMap) then { + _catalogEntry = GVAR(TaskStore) call ["getTaskCatalogEntry", [_taskID]]; + _source = if (_catalogEntry isEqualType createHashMap) then { _catalogEntry getOrDefault ["source", ""] } else { "" }; - if (_requesterUid isNotEqualTo "" || { _source isNotEqualTo "mission_manager" }) then { + if (_requesterUid isNotEqualTo "") then { private _ownershipResult = GVAR(TaskStore) call ["bindTaskOwnership", [_taskID, _requesterUid]]; if !(_ownershipResult getOrDefault ["success", false]) then { ["WARNING", format [ @@ -67,8 +69,9 @@ if (_taskID isNotEqualTo "") then { }; } else { ["INFO", format [ - "Skipped automatic ownership bind for generated mission %1 so it remains unaccepted until a player accepts it.", - _taskID + "Skipped automatic ownership bind for %1 from source '%2' so it remains unaccepted until CAD acknowledgement.", + _taskID, + _source ]] call EFUNC(common,log); }; @@ -86,10 +89,34 @@ if (_taskID isNotEqualTo "") then { ["WARNING", format ["Task %1 was cleared before its chained prerequisites unlocked.", _taskID]] call EFUNC(common,log); }; }; + + if (_shouldStartTaskLogic && { _source in ["eden", "mission_manager"] }) then { + ["INFO", format ["Task %1 from source '%2' is waiting for dispatcher assignment acknowledgement before task logic starts.", _taskID, _source]] call EFUNC(common,log); + waitUntil { + sleep 2; + private _status = GVAR(TaskStore) call ["getTaskStatus", [_taskID]]; + _status in ["active", "failed", "succeeded", ""] + }; + + private _acknowledgedStatus = GVAR(TaskStore) call ["getTaskStatus", [_taskID]]; + if (_acknowledgedStatus isNotEqualTo "active") then { + _shouldStartTaskLogic = false; + ["WARNING", format [ + "Task %1 from source '%2' did not become active before task logic start. Status=%3", + _taskID, + _source, + _acknowledgedStatus + ]] call EFUNC(common,log); + }; + }; }; if !(_shouldStartTaskLogic) exitWith {}; +if (_taskID isNotEqualTo "") then { + GVAR(TaskStore) call ["ensureBisTaskCreated", [_taskID]]; +}; + switch (_taskType) do { case "attack": { private _thread = _args spawn FUNC(attack); diff --git a/arma/server/addons/task/functions/fnc_initTaskStore.sqf b/arma/server/addons/task/functions/fnc_initTaskStore.sqf index 4c0dbb3..0924139 100644 --- a/arma/server/addons/task/functions/fnc_initTaskStore.sqf +++ b/arma/server/addons/task/functions/fnc_initTaskStore.sqf @@ -89,6 +89,9 @@ GVAR(TaskStore) = createHashMapObject [[ ["acceptTask", compileFinal { GVAR(TaskCatalogStore) call ["acceptTask", _this] }], + ["ensureBisTaskCreated", compileFinal { + GVAR(TaskCatalogStore) call ["ensureBisTaskCreated", _this] + }], ["setTaskStatus", compileFinal { GVAR(TaskCatalogStore) call ["setTaskStatus", _this] }], diff --git a/arma/server/addons/task/functions/helpers/fnc_resolveTaskDisplay.sqf b/arma/server/addons/task/functions/helpers/fnc_resolveTaskDisplay.sqf new file mode 100644 index 0000000..cbc12e2 --- /dev/null +++ b/arma/server/addons/task/functions/helpers/fnc_resolveTaskDisplay.sqf @@ -0,0 +1,65 @@ +#include "..\script_component.hpp" + +/* + * File: fnc_resolveTaskDisplay.sqf + * Author: IDSolutions + * Date: 2026-05-28 + * Public: No + * + * Description: + * Resolves task title and description for framework task modules. If a vanilla + * task with the same ID already exists, its BIS task framework description is + * preferred so Eden Create Task metadata is preserved in CAD. + * + * Arguments: + * 0: Task ID + * 1: Fallback title + * 2: Fallback description + * + * Return Value: + * [title, description] + * + * Example: + * ["task_1", "Attack: task_1", "Eliminate all hostile forces."] call forge_server_task_fnc_resolveTaskDisplay + */ + +params [ + ["_taskID", "", [""]], + ["_fallbackTitle", "", [""]], + ["_fallbackDescription", "", [""]] +]; + +private _title = _fallbackTitle; +private _description = _fallbackDescription; +private _resolveTextValue = { + params ["_value"]; + + if (_value isEqualType "") exitWith { _value }; + if (_value isEqualType [] && { count _value > 0 }) exitWith { + private _firstValue = _value select 0; + if (_firstValue isEqualType "") exitWith { _firstValue }; + "" + }; + + "" +}; + +if (_taskID isEqualTo "") exitWith { [_title, _description] }; + +private _taskExists = [_taskID] call BFUNC(taskExists); + +if (_taskExists) then { + private _taskDescription = _taskID call BFUNC(taskDescription); + + if (_taskDescription isEqualType [] && { count _taskDescription >= 2 }) then { + private _descriptionValue = _taskDescription select 0; + private _titleValue = _taskDescription select 1; + private _resolvedTitleValue = [_titleValue] call _resolveTextValue; + private _resolvedDescriptionValue = [_descriptionValue] call _resolveTextValue; + + if (_resolvedTitleValue isNotEqualTo "") then { _title = _resolvedTitleValue; }; + if (_resolvedDescriptionValue isNotEqualTo "") then { _description = _resolvedDescriptionValue; }; + }; +}; + +[_title, _description] diff --git a/arma/server/addons/task/functions/helpers/fnc_startTask.sqf b/arma/server/addons/task/functions/helpers/fnc_startTask.sqf index 9640383..6cd30a3 100644 --- a/arma/server/addons/task/functions/helpers/fnc_startTask.sqf +++ b/arma/server/addons/task/functions/helpers/fnc_startTask.sqf @@ -118,12 +118,6 @@ private _iedTimer = _taskParams getOrDefault ["iedTimer", 0]; } 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 --- - private _prerequisiteTaskIds = _taskParams getOrDefault [ "prerequisiteTaskIds", _taskParams getOrDefault [ @@ -131,11 +125,15 @@ private _prerequisiteTaskIds = _taskParams getOrDefault [ _taskParams getOrDefault ["requiresTaskIds", []] ] ]; +private _displayType = _taskParams getOrDefault ["displayType", _taskType]; + +// --- 2. Register catalog entry --- GVAR(TaskStore) call ["registerTaskCatalogEntry", [_taskID, createHashMapFromArray [ ["taskID", _taskID], ["taskId", _taskID], - ["type", _taskType], + ["type", _displayType], + ["taskType", _taskType], ["title", _title], ["description", _description], ["position", _position], @@ -146,7 +144,7 @@ GVAR(TaskStore) call ["registerTaskCatalogEntry", [_taskID, createHashMapFromArr ["prerequisiteTaskIds", _prerequisiteTaskIds] ]]]; -// --- 4. Assemble type-specific handler args --- +// --- 3. Assemble type-specific handler args --- private _limitFail = _taskParams getOrDefault ["limitFail", -1]; private _limitSuccess = _taskParams getOrDefault ["limitSuccess", -1]; @@ -210,7 +208,7 @@ private _handlerArgs = switch (_taskType) do { if (_handlerArgs isEqualTo []) exitWith { false }; -// --- 5. Dispatch handler --- +// --- 4. Dispatch handler --- [_taskType, _handlerArgs, _minRating, _requesterUid] spawn FUNC(handler); diff --git a/arma/server/addons/task/functions/modules/fnc_attackModule.sqf b/arma/server/addons/task/functions/modules/fnc_attackModule.sqf index aa57225..a5906f0 100644 --- a/arma/server/addons/task/functions/modules/fnc_attackModule.sqf +++ b/arma/server/addons/task/functions/modules/fnc_attackModule.sqf @@ -42,13 +42,23 @@ private _weaponRewards = [_logic getVariable ["WeaponRewards", "[]"], _taskID, " private _vehicleRewards = [_logic getVariable ["VehicleRewards", "[]"], _taskID, "vehicles"] call FUNC(parseRewards); private _specialRewards = [_logic getVariable ["SpecialRewards", "[]"], _taskID, "special"] call FUNC(parseRewards); private _taskChainParams = [_logic] call FUNC(parseTaskChainAttributes); +private _taskTitle = _logic getVariable ["TaskTitle", ""]; +if (_taskTitle isEqualTo "") then { _taskTitle = format ["Attack: %1", _taskID]; }; +private _taskDescription = _logic getVariable ["TaskDescription", ""]; +if (_taskDescription isEqualTo "") then { _taskDescription = "Eliminate all hostile forces in the area."; }; +private _taskIcon = _logic getVariable ["TaskIcon", "attack"]; +private _display = [ + _taskID, + _taskTitle, + _taskDescription +] call FUNC(resolveTaskDisplay); [ "attack", _taskID, _taskPos, - format ["Attack: %1", _taskID], - "Eliminate all hostile forces in the area.", + _display select 0, + _display select 1, createHashMapFromArray [ ["targets", _syncedEntities] ], @@ -61,6 +71,7 @@ private _taskChainParams = [_logic] call FUNC(parseTaskChainAttributes); ["endSuccess", _logic getVariable ["EndSuccess", false]], ["endFail", _logic getVariable ["EndFail", false]], ["timeLimit", _logic getVariable ["TimeLimit", 0]], + ["displayType", _taskIcon], ["equipment", _equipmentRewards], ["supplies", _supplyRewards], ["weapons", _weaponRewards], diff --git a/arma/server/addons/task/functions/modules/fnc_defendModule.sqf b/arma/server/addons/task/functions/modules/fnc_defendModule.sqf index a61eee9..7c94793 100644 --- a/arma/server/addons/task/functions/modules/fnc_defendModule.sqf +++ b/arma/server/addons/task/functions/modules/fnc_defendModule.sqf @@ -85,13 +85,23 @@ private _weaponRewards = [_logic getVariable ["WeaponRewards", "[]"], _taskID, " private _vehicleRewards = [_logic getVariable ["VehicleRewards", "[]"], _taskID, "vehicles"] call FUNC(parseRewards); private _specialRewards = [_logic getVariable ["SpecialRewards", "[]"], _taskID, "special"] call FUNC(parseRewards); private _taskChainParams = [_logic] call FUNC(parseTaskChainAttributes); +private _taskTitle = _logic getVariable ["TaskTitle", ""]; +if (_taskTitle isEqualTo "") then { _taskTitle = format ["Defend: %1", _taskID]; }; +private _taskDescription = _logic getVariable ["TaskDescription", ""]; +if (_taskDescription isEqualTo "") then { _taskDescription = "Hold the defense zone against incoming enemy forces."; }; +private _taskIcon = _logic getVariable ["TaskIcon", "defend"]; +private _display = [ + _taskID, + _taskTitle, + _taskDescription +] call FUNC(resolveTaskDisplay); [ "defend", _taskID, getMarkerPos _defenseZone, - format ["Defend: %1", _taskID], - "Hold the defense zone against incoming enemy forces.", + _display select 0, + _display select 1, createHashMap, createHashMapFromArray ([ ["funds", _logic getVariable ["CompanyFunds", 0]], @@ -105,6 +115,7 @@ private _taskChainParams = [_logic] call FUNC(parseTaskChainAttributes); ["waveCooldown", _logic getVariable ["WaveCooldown", 300]], ["minBlufor", _logic getVariable ["MinBlufor", 1]], ["enemyTemplates", _templateGroups], + ["displayType", _taskIcon], ["equipment", _equipmentRewards], ["supplies", _supplyRewards], ["weapons", _weaponRewards], diff --git a/arma/server/addons/task/functions/modules/fnc_defuseModule.sqf b/arma/server/addons/task/functions/modules/fnc_defuseModule.sqf index b1f1f1c..14af213 100644 --- a/arma/server/addons/task/functions/modules/fnc_defuseModule.sqf +++ b/arma/server/addons/task/functions/modules/fnc_defuseModule.sqf @@ -59,13 +59,23 @@ private _weaponRewards = [_logic getVariable ["WeaponRewards", "[]"], _taskID, " private _vehicleRewards = [_logic getVariable ["VehicleRewards", "[]"], _taskID, "vehicles"] call FUNC(parseRewards); private _specialRewards = [_logic getVariable ["SpecialRewards", "[]"], _taskID, "special"] call FUNC(parseRewards); private _taskChainParams = [_logic] call FUNC(parseTaskChainAttributes); +private _taskTitle = _logic getVariable ["TaskTitle", ""]; +if (_taskTitle isEqualTo "") then { _taskTitle = format ["Defuse: %1", _taskID]; }; +private _taskDescription = _logic getVariable ["TaskDescription", ""]; +if (_taskDescription isEqualTo "") then { _taskDescription = "Locate and defuse all explosive devices before they detonate."; }; +private _taskIcon = _logic getVariable ["TaskIcon", "danger"]; +private _display = [ + _taskID, + _taskTitle, + _taskDescription +] call FUNC(resolveTaskDisplay); [ "defuse", _taskID, _taskPos, - format ["Defuse: %1", _taskID], - "Locate and defuse all explosive devices before they detonate.", + _display select 0, + _display select 1, createHashMapFromArray [ ["ieds", _iedEntities], ["protected", _protectedEntities] @@ -79,6 +89,7 @@ private _taskChainParams = [_logic] call FUNC(parseTaskChainAttributes); ["endSuccess", _logic getVariable ["EndSuccess", false]], ["endFail", _logic getVariable ["EndFail", false]], ["iedTimer", _logic getVariable ["TimeLimit", 300]], + ["displayType", _taskIcon], ["equipment", _equipmentRewards], ["supplies", _supplyRewards], ["weapons", _weaponRewards], diff --git a/arma/server/addons/task/functions/modules/fnc_deliveryModule.sqf b/arma/server/addons/task/functions/modules/fnc_deliveryModule.sqf index 3528638..ebbceee 100644 --- a/arma/server/addons/task/functions/modules/fnc_deliveryModule.sqf +++ b/arma/server/addons/task/functions/modules/fnc_deliveryModule.sqf @@ -52,13 +52,23 @@ private _weaponRewards = [_logic getVariable ["WeaponRewards", "[]"], _taskID, " private _vehicleRewards = [_logic getVariable ["VehicleRewards", "[]"], _taskID, "vehicles"] call FUNC(parseRewards); private _specialRewards = [_logic getVariable ["SpecialRewards", "[]"], _taskID, "special"] call FUNC(parseRewards); private _taskChainParams = [_logic] call FUNC(parseTaskChainAttributes); +private _taskTitle = _logic getVariable ["TaskTitle", ""]; +if (_taskTitle isEqualTo "") then { _taskTitle = format ["Delivery: %1", _taskID]; }; +private _taskDescription = _logic getVariable ["TaskDescription", ""]; +if (_taskDescription isEqualTo "") then { _taskDescription = "Transport all cargo to the designated delivery zone."; }; +private _taskIcon = _logic getVariable ["TaskIcon", "truck"]; +private _display = [ + _taskID, + _taskTitle, + _taskDescription +] call FUNC(resolveTaskDisplay); [ "delivery", _taskID, _taskPos, - format ["Delivery: %1", _taskID], - "Transport all cargo to the designated delivery zone.", + _display select 0, + _display select 1, createHashMapFromArray [ ["cargo", _cargoEntities] ], @@ -72,6 +82,7 @@ private _taskChainParams = [_logic] call FUNC(parseTaskChainAttributes); ["endFail", _logic getVariable ["EndFail", false]], ["timeLimit", _logic getVariable ["TimeLimit", 0]], ["deliveryZone", _logic getVariable ["DeliveryZone", ""]], + ["displayType", _taskIcon], ["equipment", _equipmentRewards], ["supplies", _supplyRewards], ["weapons", _weaponRewards], diff --git a/arma/server/addons/task/functions/modules/fnc_destroyModule.sqf b/arma/server/addons/task/functions/modules/fnc_destroyModule.sqf index 46f6c88..a014ca2 100644 --- a/arma/server/addons/task/functions/modules/fnc_destroyModule.sqf +++ b/arma/server/addons/task/functions/modules/fnc_destroyModule.sqf @@ -42,13 +42,23 @@ private _weaponRewards = [_logic getVariable ["WeaponRewards", "[]"], _taskID, " private _vehicleRewards = [_logic getVariable ["VehicleRewards", "[]"], _taskID, "vehicles"] call FUNC(parseRewards); private _specialRewards = [_logic getVariable ["SpecialRewards", "[]"], _taskID, "special"] call FUNC(parseRewards); private _taskChainParams = [_logic] call FUNC(parseTaskChainAttributes); +private _taskTitle = _logic getVariable ["TaskTitle", ""]; +if (_taskTitle isEqualTo "") then { _taskTitle = format ["Destroy: %1", _taskID]; }; +private _taskDescription = _logic getVariable ["TaskDescription", ""]; +if (_taskDescription isEqualTo "") then { _taskDescription = "Locate and destroy all designated targets."; }; +private _taskIcon = _logic getVariable ["TaskIcon", "destroy"]; +private _display = [ + _taskID, + _taskTitle, + _taskDescription +] call FUNC(resolveTaskDisplay); [ "destroy", _taskID, _taskPos, - format ["Destroy: %1", _taskID], - "Locate and destroy all designated targets.", + _display select 0, + _display select 1, createHashMapFromArray [ ["targets", _syncedEntities] ], @@ -61,6 +71,7 @@ private _taskChainParams = [_logic] call FUNC(parseTaskChainAttributes); ["endSuccess", _logic getVariable ["EndSuccess", false]], ["endFail", _logic getVariable ["EndFail", false]], ["timeLimit", _logic getVariable ["TimeLimit", 0]], + ["displayType", _taskIcon], ["equipment", _equipmentRewards], ["supplies", _supplyRewards], ["weapons", _weaponRewards], diff --git a/arma/server/addons/task/functions/modules/fnc_hostageModule.sqf b/arma/server/addons/task/functions/modules/fnc_hostageModule.sqf index 46389fc..e60ed51 100644 --- a/arma/server/addons/task/functions/modules/fnc_hostageModule.sqf +++ b/arma/server/addons/task/functions/modules/fnc_hostageModule.sqf @@ -67,13 +67,23 @@ private _weaponRewards = [_logic getVariable ["WeaponRewards", "[]"], _taskID, " private _vehicleRewards = [_logic getVariable ["VehicleRewards", "[]"], _taskID, "vehicles"] call FUNC(parseRewards); private _specialRewards = [_logic getVariable ["SpecialRewards", "[]"], _taskID, "special"] call FUNC(parseRewards); private _taskChainParams = [_logic] call FUNC(parseTaskChainAttributes); +private _taskTitle = _logic getVariable ["TaskTitle", ""]; +if (_taskTitle isEqualTo "") then { _taskTitle = format ["Hostage Rescue: %1", _taskID]; }; +private _taskDescription = _logic getVariable ["TaskDescription", ""]; +if (_taskDescription isEqualTo "") then { _taskDescription = "Locate and rescue the hostages and bring them to the extraction zone."; }; +private _taskIcon = _logic getVariable ["TaskIcon", "help"]; +private _display = [ + _taskID, + _taskTitle, + _taskDescription +] call FUNC(resolveTaskDisplay); [ "hostage", _taskID, _taskPos, - format ["Hostage Rescue: %1", _taskID], - "Locate and rescue the hostages and bring them to the extraction zone.", + _display select 0, + _display select 1, createHashMapFromArray [ ["hostages", _hostageEntities], ["shooters", _shooterEntities] @@ -91,6 +101,7 @@ private _taskChainParams = [_logic] call FUNC(parseTaskChainAttributes); ["cbrn", _logic getVariable ["CBRN", false]], ["execution", _logic getVariable ["Execution", false]], ["cbrnZone", _logic getVariable ["CBRNZone", ""]], + ["displayType", _taskIcon], ["equipment", _equipmentRewards], ["supplies", _supplyRewards], ["weapons", _weaponRewards], diff --git a/arma/server/addons/task/functions/modules/fnc_hvtModule.sqf b/arma/server/addons/task/functions/modules/fnc_hvtModule.sqf index 77d220e..206aebd 100644 --- a/arma/server/addons/task/functions/modules/fnc_hvtModule.sqf +++ b/arma/server/addons/task/functions/modules/fnc_hvtModule.sqf @@ -48,13 +48,23 @@ private _weaponRewards = [_logic getVariable ["WeaponRewards", "[]"], _taskID, " private _vehicleRewards = [_logic getVariable ["VehicleRewards", "[]"], _taskID, "vehicles"] call FUNC(parseRewards); private _specialRewards = [_logic getVariable ["SpecialRewards", "[]"], _taskID, "special"] call FUNC(parseRewards); private _taskChainParams = [_logic] call FUNC(parseTaskChainAttributes); +private _taskTitle = _logic getVariable ["TaskTitle", ""]; +if (_taskTitle isEqualTo "") then { _taskTitle = format ["HVT: %1", _taskID]; }; +private _taskDescription = _logic getVariable ["TaskDescription", ""]; +if (_taskDescription isEqualTo "") then { _taskDescription = "Locate and capture or eliminate the high-value target."; }; +private _taskIcon = _logic getVariable ["TaskIcon", "target"]; +private _display = [ + _taskID, + _taskTitle, + _taskDescription +] call FUNC(resolveTaskDisplay); [ "hvt", _taskID, _taskPos, - format ["HVT: %1", _taskID], - "Locate and capture or eliminate the high-value target.", + _display select 0, + _display select 1, createHashMapFromArray [ ["hvts", _syncedEntities] ], @@ -69,6 +79,7 @@ private _taskChainParams = [_logic] call FUNC(parseTaskChainAttributes); ["timeLimit", _logic getVariable ["TimeLimit", 0]], ["extractionZone", _logic getVariable ["ExtZone", ""]], ["captureHvt", _logic getVariable ["CaptureHVT", true]], + ["displayType", _taskIcon], ["equipment", _equipmentRewards], ["supplies", _supplyRewards], ["weapons", _weaponRewards], diff --git a/arma/server/addons/task/functions/objects/fnc_TaskCatalogStore.sqf b/arma/server/addons/task/functions/objects/fnc_TaskCatalogStore.sqf index b719c5a..e9fccd7 100644 --- a/arma/server/addons/task/functions/objects/fnc_TaskCatalogStore.sqf +++ b/arma/server/addons/task/functions/objects/fnc_TaskCatalogStore.sqf @@ -358,6 +358,27 @@ GVAR(TaskCatalogStore) = createHashMapObject [[ _result set ["entry", _entry]; _result }], + ["ensureBisTaskCreated", compileFinal { + params [["_taskID", "", [""]]]; + + if (_taskID isEqualTo "") exitWith { false }; + if ([_taskID] call BFUNC(taskExists)) exitWith { true }; + + [(_self call ["getTaskCatalogEntry", [_taskID]])] params [["_entry", createHashMap, [createHashMap]]]; + if (_entry isEqualTo createHashMap) exitWith { + ["WARNING", format ["Unable to create BIS task for %1 because no task catalog entry exists.", _taskID]] call EFUNC(common,log); + false + }; + + private _taskType = _entry getOrDefault ["taskType", "task"]; + private _title = _entry getOrDefault ["title", _taskID]; + private _description = _entry getOrDefault ["description", ""]; + private _position = _entry getOrDefault ["position", [0, 0, 0]]; + private _displayType = _entry getOrDefault ["type", _taskType]; + + [west, _taskID, [_description, _title, _displayType], _position, "CREATED", 1, true, _displayType] call BFUNC(taskCreate); + true + }], ["setTaskStatus", compileFinal { params [["_taskID", "", [""]], ["_status", "", [""]]]; @@ -417,6 +438,10 @@ GVAR(TaskCatalogStore) = createHashMapObject [[ ]] call EFUNC(common,log); }; + if (_normalizedStatus isEqualTo "active") then { + _self call ["ensureBisTaskCreated", [_taskID]]; + }; + _statusResult }], ["getTaskStatus", compileFinal {