description.ext
b FHQ_fnc_aceLoadout.sqf Ԝb functions\fhq_tasktracker.hpp ~"\ functions\fhq_tasktracker\fn_ttAddBriefing.sqf nWw functions\fhq_tasktracker\fn_ttAddBriefingGroup.sqf Z functions\fhq_tasktracker\fn_ttAddTaskGroup.sqf wZ functions\fhq_tasktracker\fn_ttAddTasks.sqf 9\ functions\fhq_tasktracker\fn_ttAreTasksCompleted.sqf nW functions\fhq_tasktracker\fn_ttAreTasksSuccessful.sqf nW functions\fhq_tasktracker\fn_ttGetAllTasksWithState.sqf nWG functions\fhq_tasktracker\fn_ttGetTaskState.sqf nW functions\fhq_tasktracker\fn_ttiAddBriefingEntry.sqf nW9 functions\fhq_tasktracker\fn_ttiBuildCondition.sqf 6\m functions\fhq_tasktracker\fn_ttiCreateOrUpdateTask.sqf 0\G functions\fhq_tasktracker\fn_ttiFilterUnits.sqf ZX4 functions\fhq_tasktracker\fn_ttiGetTaskDesc.sqf nW functions\fhq_tasktracker\fn_ttiGetTaskId.sqf nW functions\fhq_tasktracker\fn_ttiGetTaskName.sqf nWm functions\fhq_tasktracker\fn_ttiGetTaskState.sqf q\] functions\fhq_tasktracker\fn_ttiGetTaskTarget.sqf nW functions\fhq_tasktracker\fn_ttiGetTaskTitle.sqf nW functions\fhq_tasktracker\fn_ttiGetTaskType.sqf nWC functions\fhq_tasktracker\fn_ttiGetTaskWp.sqf nW functions\fhq_tasktracker\fn_ttiHasBriefingEntry.sqf nW functions\fhq_tasktracker\fn_ttiInit.sqf rZq functions\fhq_tasktracker\fn_ttiIsFilter.sqf nW functions\fhq_tasktracker\fn_ttiIsTaskState.sqf nW functions\fhq_tasktracker\fn_ttiMissionBriefing.sqf nW) functions\fhq_tasktracker\fn_ttiMissionTasks.sqf nW, functions\fhq_tasktracker\fn_ttiPostInit.sqf %\ functions\fhq_tasktracker\fn_ttIsTaskCompleted.sqf nW functions\fhq_tasktracker\fn_ttIsTaskSuccessful.sqf nWL functions\fhq_tasktracker\fn_ttiTaskExists.sqf nWQ functions\fhq_tasktracker\fn_ttiUnitBriefing.sqf nWg functions\fhq_tasktracker\fn_ttiUnitTasks.sqf nW^ functions\fhq_tasktracker\fn_ttiUpdateBriefingList.sqf ZXM functions\fhq_tasktracker\fn_ttiUpdateTaskList.sqf \ functions\fhq_tasktracker\fn_ttMissionFlow.sqf Q\ functions\fhq_tasktracker\fn_ttSetTaskDescription.sqf 5ZC functions\fhq_tasktracker\fn_ttSetTaskState.sqf nWx functions\fhq_tasktracker\fn_ttSetTaskStateAndNext.sqf nW$ functions\fhq_tasktracker\fn_ttSetTaskTarget.sqf 7Zt functions\fhq_tasktracker\fn_ttSetTaskTargetAndTitles.sqf 7Z functions\fhq_tasktracker\fn_ttSetTaskTitle.sqf 5Z? functions\fhq_tasktracker\fn_ttSetTaskTitles.sqf 6Z functions\fhq_tasktracker\fn_ttTaskHint.sqf 8ZS images\compoundraid.jpg
b" init.sqf
b mission.sqm
bn author="Jsempri";
OnLoadName = "PMC: COMPOUND RAID";
OnLoadMission = "Time to get paid!";
class CfgFunctions
{
class FHQ
{
#include "functions\fhq_tasktracker.hpp"
};
};
/*
** Add ACE Specific items to a unit, based on an abstract class
**
** Parameters:
** _this select 0: (OBJECT) The unit to add the items to
** _this select 1: (STRING) A class name or
** (ARRAY) an array of class names
**
** Class name can be one of the following:
** "default" - A basic loadout with a fulton flashlight and ear plugs
** "maptools" - Adds map tools
** "sapper" - Adds a clacker
** "sniper" - Adds range card
** "spotter" - adds the spotting scope
** "vector", "vectorday" - give a Vector 21 and remove potential other binocs
**
** Example of use:
** Sniper-type unit: [this, ["default", "sniper"]] call FHQ_fnc_aceLoadout;
** Compassman: [this, ["default", "maptools"]] call FHQ_fnc_aceLoadout;
** Normal soldier: [this, "default"] call FHQ_fnc_aceLoadout;
*/
params [
["_unit", objNull],
"_class"
];
if (!isClass (configFile >> "CfgMods" >> "ace")) exitWith {}; // No ACE loaded
if (_class isEqualType "") then {
_class = [_class];
};
// Class is an array here no matter what
{
_varName = format ["FHQ_ACE_Handled_%1", _x];
// Check if this class was added already
if (!(_unit getVariable [_varName, false])) then {
_unit setVariable [_varName, true, true];
switch (_x) do {
case "default": {
// Fulton Flashlight and ear plugs
_unit addItemToBackpack "ACE_packingBandage";
_unit addItemToBackpack "ACE_packingBandage";
_unit addItemToBackpack "ACE_packingBandage";
_unit addItemToBackpack "ACE_packingBandage";
_unit addItemToBackpack "ACE_packingBandage";
_unit addItemToBackpack "ACE_packingBandage";
_unit addItemToBackpack "ACE_packingBandage";
_unit addItemToBackpack "ACE_packingBandage";
_unit addItemToBackpack "ACE_packingBandage";
_unit addItemToBackpack "ACE_packingBandage";
_unit addItemToBackpack "ACE_morphine";
_unit addItemToBackpack "ACE_morphine";
_unit addItemToBackpack "ACE_morphine";
_unit addItemToBackpack "ACE_morphine";
_unit addItemToBackpack "ACE_morphine";
_unit addItemToBackpack "ACE_morphine";
_unit addItemToBackpack "ACE_morphine";
_unit addItemToBackpack "ACE_morphine";
_unit addItemToBackpack "ACE_morphine";
_unit addItemToBackpack "ACE_morphine";
_unit addItemToBackpack "ACE_splint";
_unit addItemToBackpack "ACE_splint";
_unit addItemToBackpack "ACE_splint";
_unit addItemToBackpack "ACE_splint";
_unit addItemToBackpack "ACE_splint";
_unit addItemToBackpack "ACE_splint";
_unit addItemToBackpack "ACE_tourniquet";
_unit addItemToBackpack "ACE_tourniquet";
_unit addItemToBackpack "ACE_tourniquet";
_unit addItemToBackpack "ACE_tourniquet";
_unit addItemToBackpack "ACE_tourniquet";
_unit addItemToBackpack "ACE_tourniquet";
_unit addItemToBackpack "ACE_epinephrine";
_unit addItemToBackpack "ACE_epinephrine";
_unit addItemToBackpack "ACE_epinephrine";
_unit addItemToBackpack "ACE_epinephrine";
_unit addItemToBackpack "ACE_epinephrine";
_unit addItemToBackpack "ACE_epinephrine";
_unit addItemToBackpack "ACE_bloodIV";
_unit addItemToBackpack "ACE_bloodIV";
_unit addItemToBackpack "ACE_bloodIV_500";
_unit addItemToBackpack "ACE_bloodIV_500";
_unit addItemToBackpack "ACE_bloodIV_500";
_unit addItemToBackpack "ACE_bloodIV_500";
_unit addItemToBackpack "ACE_bloodIV_250";
_unit addItemToBackpack "ACE_bloodIV_250";
_unit addItemToBackpack "ACE_bloodIV_250";
_unit addItemToBackpack "ACE_bloodIV_250";
_unit addItemToBackpack "ACE_salineIV";
_unit addItemToBackpack "ACE_salineIV_500";
_unit addItemToBackpack "ACE_salineIV_500";
_unit addItemToBackpack "ACE_salineIV_250";
_unit addItemToBackpack "ACE_salineIV_250";
_unit addItemToBackpack "ACE_salineIV_250";
_unit addItemToBackpack "ACE_salineIV_250";
};
case "mineguy": {
_unit addItem "ACE_DefusalKit";
};
case "maptools": {
_unit addItem "ACE_MapTools";
};
case "sapper": {
_unit addItem "ACE_Clacker";
};
case "sniper": {
_unit addItem "ACE_RangeCard";
_unit addItemToBackpack "ACE_splint";
_unit addItemToBackpack "ACE_splint";
_unit addItemToBackpack "ACE_tourniquet";
_unit addItemToBackpack "ACE_tourniquet";
_unit addItemToBackpack "ACE_epinephrine";
_unit addItemToBackpack "ACE_bloodIV_500";
_unit addItemToBackpack "ACE_bloodIV_500";
_unit addItemToBackpack "ACE_salineIV_500";
};
case "spotter": {
_unit addItemToBackpack "ACE_splint";
_unit addItemToBackpack "ACE_splint";
_unit addItemToBackpack "ACE_tourniquet";
_unit addItemToBackpack "ACE_tourniquet";
_unit addItemToBackpack "ACE_epinephrine";
_unit addItemToBackpack "ACE_bloodIV_500";
_unit addItemToBackpack "ACE_bloodIV_500";
_unit addItemToBackpack "ACE_salineIV_500";
};
case "vector": {
_binoc = binocular _unit;
if (!(_binoc isEqualTo "")) then {
_unit removeWeapon _binoc;
};
_unit addWeapon "ACE_Vector";
};
case "vectorday": {
_binoc = binocular _unit;
if (!(_binoc isEqualTo "")) then {
_unit removeWeapon _binoc;
};
_unit addWeapon "ACE_VectorDay";
};
};
};
} forEach _class;#define INTERNAL_FUNCTION(x) \
class x \
{ \
description = "Internal Function"; \
};
#define EXPORTED_FUNCTION(x,y) \
class x \
{ \
description = y; \
};
class TaskTrackerInternal {
tag="FHQ";
file="functions\fhq_tasktracker";
class ttiInit
{
description = "Internal function, called automatically";
preInit = 1;
};
class ttiPostInit
{
description = "Internal function, called automatically";
postInit = 1;
};
INTERNAL_FUNCTION(ttifilterUnits)
INTERNAL_FUNCTION(ttiAddBriefingEntry)
INTERNAL_FUNCTION(ttiHasBriefingEntry)
INTERNAL_FUNCTION(ttiUpdateBriefingList)
INTERNAL_FUNCTION(ttiGetTaskId)
INTERNAL_FUNCTION(ttiGetTaskDesc)
INTERNAL_FUNCTION(ttiGetTaskTitle)
INTERNAL_FUNCTION(ttiGetTaskWp)
INTERNAL_FUNCTION(ttiGetTaskTarget)
INTERNAL_FUNCTION(ttiGetTaskState)
INTERNAL_FUNCTION(ttiGetTaskName)
INTERNAL_FUNCTION(ttiGetTaskType)
INTERNAL_FUNCTION(ttiTaskExists)
INTERNAL_FUNCTION(ttiCreateOrUpdateTask)
INTERNAL_FUNCTION(ttiUpdateTaskList)
INTERNAL_FUNCTION(ttiMissionTasks)
INTERNAL_FUNCTION(ttiMissionBriefing)
INTERNAL_FUNCTION(ttiUnitTasks)
INTERNAL_FUNCTION(ttiUnitBriefing)
INTERNAL_FUNCTION(ttiIsFilter)
INTERNAL_FUNCTION(ttiIsTaskState)
INTERNAL_FUNCTION(ttiBuildCondition)
};
class TaskTracker {
tag="FHQ";
file="functions\fhq_tasktracker";
EXPORTED_FUNCTION(ttTaskHint, "This function is called for every task hint to be displayed.")
EXPORTED_FUNCTION(ttAddBriefing, "Adds a briefing to the missing.")
EXPORTED_FUNCTION(ttAddTasks, "Adds tasks to the mission.")
EXPORTED_FUNCTION(ttGetTaskState, "Return the state of a task.")
EXPORTED_FUNCTION(ttSetTaskState, "Set the new state of a task.")
EXPORTED_FUNCTION(ttIsTaskCompleted, "Check whether a given task is completed")
EXPORTED_FUNCTION(ttAreTasksCompleted, "Check whether a list of tasks is completed")
EXPORTED_FUNCTION(ttIsTaskSuccessful, "Check whether a given task is successfully completed")
EXPORTED_FUNCTION(ttAreTasksSuccessful, "Check whether a list of tasks is successfully completed")
EXPORTED_FUNCTION(ttGetAllTasksWithState, "Return an array of all tasks with a given state")
EXPORTED_FUNCTION(ttSetTaskStateAndNext, "Set a task's state, and select the next one")
EXPORTED_FUNCTION(ttSetTaskTarget, "Change a task target")
EXPORTED_FUNCTION(ttSetTaskDescription, "Change a task description")
EXPORTED_FUNCTION(ttSetTaskTitle, "Change a task title")
EXPORTED_FUNCTION(ttSetTaskTitles, "Change title and description")
EXPORTED_FUNCTION(ttSetTaskTargetAndTitles, "Change target, title and description")
EXPORTED_FUNCTION(ttAddTaskGroup, "Adds an EdenTT defined group of tasks.")
EXPORTED_FUNCTION(ttAddBriefingGroup, "Adds an EdenTT defined briefing.")
EXPORTED_FUNCTION(ttMissionFlow, "Control mission flow automatically.")
};
/* FHQ_fnc_ttAddBriefing: Add a full briefing
*
* This functions receives an array as input. The elements of the input array
* are interpreted as follows:
* If the element is a two-element array consisting of two strings, the entry is
* interpreted as a new briefing topic. If the array has three strings, it's interpreted
* as a new briefing entry, with the first one being the general subject ("Diary" by default),
* and the two subsequent strings title and description.
* If the element is anything else, the following topics will only be presented to
* the units matching the element. For example, if the element is a group, the following
* entries are added to this group only.
*
* NOTE: The old hierarchical filtering is no longer supported. It wasn't that useful for
* real-world application and was posing severe problems with respawn missions.
*
* Example:
*
* [
* west,
* ["Mission", "Get some!"],
* ["Enemy Forces", "There's lots of ruskies around"],
* east,
* ["Mission", "Get those imperialistic americans"],
* ["Current Supply of Vodka", "Low"],
* {true},
* ["Credits", "Mission by", "Some Dude"],
* ["Credits", "Uses scripts by", "Some other dude
Yet another dude"]
* ] call FHQ_fnc_ttAddBriefing.
*
* The first two lines (Mission, Enemy Forces), are added under "Briefing" for west
* troops only, the second two lines (Mission, Current Supply of Vodka) only for east.
* The last two lines add two new entries "Mission by" and "Uses scripts by" into a new
* subject "Credits".
*
* NOTE: Do not over-use the additional subject feature. Briefing and all associated information
* should go to the default subject.
*
* Calling FHQ_TT_addBriefing with an already existing subject/title will add a new log entry
* if the text differs from the previous one.
*
* Notifications are shown after the initial briefing has been donwloaded by the clients, i.e.
* not at mission start, only when new briefing entries are added.
*/
private ["_currentFilter", "_i", "_current", "_x"];
_currentFilter = {true};
if (isServer) then {
/* Note: Server only code. Briefing entries must be added on the server, not on an
* individual client
*/
for [{_i = 0}, {_i < count _this}, {_i = _i + 1}] do {
_current = _this select _i;
if (_current call FHQ_fnc_ttiIsFilter) then {
_currentFilter = nil;
_currentFilter = _current;
} else {
/* It's a briefing entry. */
[_currentFilter, _current] call FHQ_fnc_ttiAddBriefingEntry;
};
};
publicVariable "FHQ_TTI_BriefingList";
if (!isDedicated) then {
FHQ_TTI_BriefingList call FHQ_fnc_ttiUpdateBriefingList;
};
FHQ_TTI_briefing = true;
publicVariable "FHQ_TTI_briefing";
};
/* FHQ_fnc_ttAddBriefingGroup: Add EdenTT defined briefing group
*
* For more information on the definition of briefing groups, see the
* EdenTT manual and examples.
*
* This function adds a given briefing group to the units defined by the filter.
* The filter itself follows the same rules as filters in FHQ_fnc_ttAddTasks.
*
* Usage: [_filter, _briefingGroup] call FHQ_fnc_ttAddBriefingGroup;
* _filter: A filter similar to that given in FHQ_fnc_ttAddTask/ttAddBriefing.
* _briefingGroup: Name of the briefing group to add.
*
* Example:
* // Add briefing from brief1 to units p1, p2, and p3
* [[p1, p2, p3], "brief1"] call FHQ_fnc_ttAddBriefingGroup;
*
*/
params [
["_filter", {true}],
["_briefingGroup", "", [""]]
];
if (isServer) then {
private _briefings = missionNamespace getVariable ["FHQ_tt_MissionBriefing", []];
private _units = (if (isMultiplayer) then {playableUnits+FHQ_TTI_extraUnits} else {switchableUnits});
private _i = 0;
_units = [_filter, _units] call FHQ_fnc_ttiFilterUnits;
if (count _units == 0) exitWith {/* Nothing to be done */};
for [{_i = 0}, {_i < count _briefings}, {_i = _i + 1}] do
{
private _briefing = _briefings select _i;
private _group = _briefing select 0;
private _entry = _briefing select 1;
if (_briefingGroup isEqualTo _group) then {
([_units] + _entry) call FHQ_fnc_ttAddBriefing;
};
};
};/* FHQ_fnc_ttAddTaskGroup: Add EdenTT defined task group
*
* For more information on the definition of task groups, see the
* EdenTT manual and examples.
*
* This function adds a given task group to the units defined by the filter.
* The filter itself follows the same rules as filters in FHQ_fnc_ttAddTasks.
*
* Usage: [_filter, _taskGroup] call FHQ_fnc_ttAddTaskGroup;
* _filter: A filter similar to that given in FHQ_fnc_ttAddTask/ttAddBriefing.
* _taskGroup: Name of the task group to add.
*
* Example:
* // Add tasks from task1group to units p1, p2, and p3
* [[p1, p2, p3], "task1group"] call FHQ_fnc_ttAddTaskGroup;
*
* // Add task from westTasks to all west units
* [west, "westTasks"] call FHQ_fnc_ttAddTaskGroup;
*/
params [
["_filter", {true}],
["_taskGroup", "", [""]]
];
if (isServer) then {
private _tasks = missionNamespace getVariable ["FHQ_tt_MissionTasks", []];
private _units = (if (isMultiplayer) then {playableUnits+FHQ_TTI_extraUnits} else {switchableUnits});
private _i = 0;
_units = [_filter, _units] call FHQ_fnc_ttiFilterUnits;
if (count _units == 0) exitWith {/* Nothing to be done */};
for [{_i = 0}, {_i < count _tasks}, {_i = _i + 1}] do
{
private _task = _tasks select _i;
private _group = _task select 0;
private _entry = _task select 1;
if (_taskGroup isEqualTo _group) then {
([_units] + [_entry]) call FHQ_fnc_ttAddTasks;
};
};
};
/* FHQ_fnc_ttAddTasks: Add tasks to the mission
*
* Task are defined similar to briefing entries. The function accepts an array as input.
* Each entry is either a filter (see FHQ_TT_addBriefing), or a task description.
*
* A task description itself is an array and can be one of the following format:
* [_taskName, _longDescription, _shortDescription, _waypointDescription, _target, _initialState, _type]
* [[_taskName, _parentTask], _longDescription, _shortDescription, _waypointDescription, _target, _initialState, _type]
*
* Both _target and _initialState are optional and can be left out.
*
* o _taskName is a symbolic name that is invisible to the player.
* o _longDescription is a text describing the task.
* o _shortDescription is used as a headline for the task in the task list and on task hints
* o _waypointDescription is displayed on the waypoint on the map and in the 3d view (if enabled).
* o _target can be a position (three-element array) or an object. If either is given, the
* task waypoint is shown on the map an the 3d view. Objects that move also move
* the waypoint marker.
* o _initialState is the initial state of the task ("succeeded", "failed", "canceled",
* "created", or "assigned"). By default, if _initialState is ommited, the state is set
* to "created". If set to "assigned", the task is also automatically assigned to everyone
* that knows about it.
* o _type is one of the defined task types, see the link for more information:
* https://community.bistudio.com/wiki/Arma_3_Tasks_Overhaul#Default_Task_Types:_Actions
*
* Example:
*
* [
* west,
* ["taskBoard1", "Board your chopper", "Board your chopper", "BOARD", westHelo1, "assigned"],
* ["taskCAS", "Fly around", "Fly around", "CAS"],
* ["taskRetreat1", "Return to LZ", "Return to LZ", "RETREAT", getMarkerPos "markLZ"],
* "BLU_G_F",
* ["taskSecret", "Secret: Betray NATO for whatever reason", "Secret: Betray NATO", ""],
* [["taskSecret1", "taskSecret"], "Because they are idiots", "Idiots", ""],
* [["taskSecret2", "taskSecret"], "Because I am evil", "Evil", ""]
* ] call FHQ_fnc_ttAddTasks;
*
* The first three tasks are assigned at all playable west units. The second bunch of three tasks is
* only assigned to FIA units. The latter two, taskSecret1 and taskSecret2 are created as subtasks
* of the task "taskSecret" and will be displayed immediately below their respective parent.
*
* NOTE: This function can only be called on the server. Calling it anywhere else will have no effect.
*/
private _currentFilter = {true};
if (isServer) then {
/* Note: Server only code. Briefing entries must be added on the server, not on an
* individual client
*/
private _i = 0;
for [{_i = 0}, {_i < count _this}, {_i = _i + 1}] do {
private _current = _this select _i;
if (_current call FHQ_fnc_ttiIsFilter) then {
/* Must be a filter */
_currentFilter = nil;
_currentFilter = _current;
} else {
/* Task entry.
* Check if the task already exists. If not, construct a full
* task entry with all redundant information filled in for easier
* access later on
*/
private _name = _current call FHQ_fnc_ttiGetTaskName;
if (([FHQ_TTI_TaskList, _name] call FHQ_fnc_ttiTaskExists) == -1) then {
private _newTask =
[_current call FHQ_fnc_ttiGetTaskId,
_current call FHQ_fnc_ttiGetTaskDesc,
_current call FHQ_fnc_ttiGetTaskTitle,
_current call FHQ_fnc_ttiGetTaskWp,
_current call FHQ_fnc_ttiGetTaskTarget,
_current call FHQ_fnc_ttiGetTaskState,
_current call FHQ_fnc_ttiGetTaskType];
FHQ_TTI_TaskList = FHQ_TTI_TaskList + [[_currentFilter, _newTask]];
};
};
};
publicVariable "FHQ_TTI_TaskList";
if (!isDedicated) then {
FHQ_TTI_TaskList call FHQ_fnc_ttiUpdateTaskList;
};
FHQ_TTI_tasks = true;
publicVariable "FHQ_TTI_tasks";
};
/* FHQ_fnc_ttAreTasksCompleted
*
* Check for all tasks given whether they are considered completed. This function can
* be called on the client as well as the server.
*
* Usage
* _result = [_taskName1, _taskName2, ...] call FHQ_fnc_ttAreTasksCompleted
*
* _taskName1 and following: Task names that are tested for being completed. If any of them is not
* completed, the function returns false, else true.
*/
private ["_result", "_x"];
_result = true;
{
if (!(tolower ([_x] call FHQ_fnc_ttGetTaskState) in ["succeeded", "canceled", "failed"])) exitWith
{
_result = false;
};
} forEach _this;
_result;
/* FHQ_fnc_ttAreTasksSuccessful
*
* Check success for all tasks given. This function can be called on the client as well as
* the server.
*
* _result = [_taskName1, _taskName2, ...] call FHQ_fnc_ttAreTasksSuccessful
*/
private ["_result", "_x"];
_result = true;
{
if (tolower ([_x] call FHQ_fnc_ttGetTaskState) != "succeeded") exitWith
{
_result = false;
};
} forEach _this;
_result;
/* FHQ_fnc_ttGetAllTasksWithState
*
* Get all tasks with a given state. This function can be called on the client as well as
* the server.
*
* _taskList = [_state] call FHQ_fnc_ttGetAllTasksWithState;
*/
#define FHQ_TTIF_TASKSTATE 5
private ["_result", "_taskState"];
_result = [];
_taskState = [_this, 0, "", [""]] call BIS_fnc_param;
{
if (((_x select 1) select FHQ_TTIF_TASKSTATE) == _taskState) then
{
_result = _result + [(_x select 1) call FHQ_fnc_ttiGetTaskName];
};
} forEach FHQ_TTI_TaskList;
_result;
/* FHQ_fnc_ttGetTaskState
*
* Get the state of a given task. This function can be called on the client as well as
* the server.
*
* Usage:
* _state = [_task] call FHQ_fnc_ttGetTaskState;
*
* _task: The name of a task defined via FHQ_fnc_ttAddTask
*
* Returns the state of the task ("succeeded", "failed", "canceled", "created", "assigned"), or an empty
* string if the task does not exist
*/
#define FHQ_TTIF_TASKSTATE 5
private ["_res", "_name", "_idx", "_entry"];
_res = "";
_name = [_this, 0, "", [""]] call BIS_fnc_param;
_idx = [FHQ_TTI_TaskList, _name] call FHQ_fnc_ttiTaskExists;
if (_idx != -1) then {
_entry = FHQ_TTI_TaskList select _idx;
_res = (_entry select 1) select FHQ_TTIF_TASKSTATE;
};
_res;
/* Internal: Add a briefing record on the server
* parameters:
* select 0: Filter
* select 1: [_section, _subject, _text]
*/
private _record = [_this, 1] call BIS_fnc_param;
private _filter = [_this, 0] call BIS_fnc_param;
private _subject = "Diary";
private _topic = _record select 0;
private _text = _record select 1;
if (count _record == 3) then {
_subject = _record select 0;
_topic = _record select 1;
_text = _record select 2;
};
FHQ_TTI_BriefingList = FHQ_TTI_BriefingList + [[_filter, [_subject, _topic, _text]]];
/* build a condition from the conditions in the given mission flow that we
* can use for waitUntil
*/
private _cond = "";
private _i = 0;
for "_i" from 0 to (count _this - 1) do {
private _current = _this select _i;
if (_i != 0) then {
_cond = format ["%1 or", _cond];
};
_cond = format ["%1 (%2)", _cond, _current select 0];
};
_cond;private ["_current", "_existing", "_unit", "_name", "_state", "_idx", "_record", "_object", "_taskID",
"_parented", "_target"];
_current = [_this, 0] call BIS_fnc_param;
_existing = [_this, 1] call BIS_fnc_param;
_unit = [_this, 2] call BIS_fnc_param;
_name = _current call FHQ_fnc_ttiGetTaskName;
_state = _current call FHQ_fnc_ttiGetTaskState;
private _target = _current call FHQ_fnc_ttiGetTaskTarget;
private _desc = _current call FHQ_fnc_ttiGetTaskDesc;
private _title = _current call FHQ_fnc_ttiGetTaskTitle;
private _updated = false;
_parented = false;
_idx = [_existing, _name] call FHQ_fnc_ttiTaskExists;
if (_idx != -1) then {
/* Update existing task */
_record = _existing select _idx;
if ((_record select 0) != _state) then {
/* Need to set new state */
_record set [0, _state];
if (_state == "assigned") then {
_unit setCurrentTask (_record select 1);
};
(_record select 1) setTaskState _state;
if (_unit == player && !FHQ_TTI_supressTaskHints) then
{
[_current call FHQ_fnc_ttiGetTaskTitle, _state, _current call FHQ_fnc_ttiGetTaskType] call FHQ_fnc_ttTaskHint;
};
/* Update the list */
_existing set [_idx, _record];
};
if (!(_target isEqualTo (_record select 3))) then {
private _target = _current call FHQ_fnc_ttiGetTaskTarget;
_record set [3, _target];
if (typeName _target == "ARRAY") then {
(_record select 1) setSimpleTaskDestination _target;
} else {
(_record select 1) setSimpleTaskTarget [_target, true];
};
_updated = true;
};
if (!(_desc isEqualTo (_record select 4))) then {
_record set [4, _desc];
(_record select 1) setSimpleTaskDescription [_desc, _title, _current call FHQ_fnc_ttiGetTaskWp];
_updated = true;
};
if (!(_title isEqualTo (_record select 5))) then {
_record set [5, _title];
(_record select 1) setSimpleTaskDescription [_desc, _title, _current call FHQ_fnc_ttiGetTaskWp];
_updated = true;
};
if (_unit == player && !FHQ_TTI_supressTaskHints && _updated) then {
[_current call FHQ_fnc_ttiGetTaskTitle, "update", _current call FHQ_fnc_ttiGetTaskType] call FHQ_fnc_ttTaskHint;
};
} else {
/* Create a new task */
_taskID = _current call FHQ_fnc_ttiGetTaskId;
if (typename _taskID == "STRING") then {
_object = _unit createSimpleTask [_name];
} else {
_object = _unit createSimpleTask [_name, _unit getVariable format["FHQ_TT_taskname_%1", _taskID select 1]];
_parented = true;
};
_object setSimpleTaskDescription [_current call FHQ_fnc_ttiGetTaskDesc,
_current call FHQ_fnc_ttiGetTaskTitle,
_current call FHQ_fnc_ttiGetTaskWp];
_target = _current call FHQ_fnc_ttiGetTaskTarget;
switch (typename _target) do
{
case "ARRAY": {
_object setSimpleTaskDestination _target;
};
case "OBJECT": {
_object setSimpleTaskTarget [_target, true];
};
};
private _taskType = _current call FHQ_fnc_ttiGetTaskType;
if (_taskType != "" && FHQ_TTI_version > 156) then {
[_object, _taskType] call compile "(_this select 0) setSimpleTaskType (_this select 1);"
};
if (!(_state call FHQ_fnc_ttiIsTaskState)) then {
/* Due to the way the type is handled, this can actually NOT be a state */
_state = "created";
};
_object setTaskState _state;
if (tolower(_state) == "assigned") then
{
_unit setCurrentTask _object;
};
_unit setVariable [format["FHQ_TT_taskname_%1", _name], _object]; // FIXME: propagate through network ?
if (_unit == player && !FHQ_TTI_supressTaskHints) then
{
[_current call FHQ_fnc_ttiGetTaskTitle, _state, _current call FHQ_fnc_ttiGetTaskType] call FHQ_fnc_ttTaskHint;
};
_existing = _existing + [ [_state, _object, _name, _target, _current call FHQ_fnc_ttiGetTaskDesc, _current call FHQ_fnc_ttiGetTaskTitle, _current call FHQ_fnc_ttiGetTaskWp] ];
_target = nil;
};
_existing;/* Internal function */
private ["_unitsArray", "_outputArray"];
_filter = [_this, 0] call BIS_fnc_param;
_unitsArray = [_this, 1, (if (isMultiplayer) then {playableUnits+FHQ_TTI_extraUnits} else {switchableUnits})] call BIS_fnc_param;
_outputArray = [];
switch (typename _filter) do
{
case "CODE":
{
// Filter all playable units by comparing them with the code
{if (_x call _filter) then {_outputArray = _outputArray + [_x];};} forEach _unitsArray;
};
case "GROUP":
{
// Filter out all objects not in group
{if (_x in units _filter) then {_outputArray = _outputArray + [_x];};} forEach _unitsArray;
};
case "OBJECT":
{
// Result is only the array containing the object
_outputArray = [_filter];
};
case "SIDE":
{
// Filter out all objects not belonging to side
{if (side _x == _filter) then {_outputArray = _outputArray + [_x];};} forEach _unitsArray;
};
case "STRING":
{
// Filer out all objects not belonging to the faction
{if (faction _x == _filter) then {_outputArray = _outputArray + [_x];};} forEach _unitsArray;
};
case "ARRAY":
{
// Result is the input
_outputArray = _filter;
}
};
_outputArray;
#define FHQ_TTIF_TASKNAME 0
#define FHQ_TTIF_TASKDESC 1
#define FHQ_TTIF_TASKTITLE 2
#define FHQ_TTIF_TASKWP 3
#define FHQ_TTIF_TASKTARGET 4
#define FHQ_TTIF_TASKSTATE 5
_res = _this select FHQ_TTIF_TASKDESC;
_res;#define FHQ_TTIF_TASKNAME 0
#define FHQ_TTIF_TASKDESC 1
#define FHQ_TTIF_TASKTITLE 2
#define FHQ_TTIF_TASKWP 3
#define FHQ_TTIF_TASKTARGET 4
#define FHQ_TTIF_TASKSTATE 5
_res = _this select FHQ_TTIF_TASKNAME;
_res;#define FHQ_TTIF_TASKNAME 0
#define FHQ_TTIF_TASKDESC 1
#define FHQ_TTIF_TASKTITLE 2
#define FHQ_TTIF_TASKWP 3
#define FHQ_TTIF_TASKTARGET 4
#define FHQ_TTIF_TASKSTATE 5
private _name = "";
private _task = _this select FHQ_TTIF_TASKNAME;
if (typename _task == "ARRAY") then
{
_name = _task select 0;
}
else
{
_name = _task;
};
_name;#define FHQ_TTIF_TASKNAME 0
#define FHQ_TTIF_TASKDESC 1
#define FHQ_TTIF_TASKTITLE 2
#define FHQ_TTIF_TASKWP 3
#define FHQ_TTIF_TASKTARGET 4
#define FHQ_TTIF_TASKSTATE 5
/* Might not be present */
private _res = "created";
if (count _this > FHQ_TTIF_TASKSTATE) then {
if ((_this select FHQ_TTIF_TASKSTATE) call FHQ_fnc_ttiIsTaskState) then {
_res = _this select FHQ_TTIF_TASKSTATE;
} else {
_res = "created";
};
} else {
if (count _this > FHQ_TTIF_TASKTARGET) then {
if (typename (_this select FHQ_TTIF_TASKTARGET) == "STRING") then {
if ((_this select FHQ_TTIF_TASKTARGET) call FHQ_fnc_ttiIsTaskState) then {
_res = _this select FHQ_TTIF_TASKTARGET;
} else {
_res = "created";
};
};
};
};
_res;#define FHQ_TTIF_TASKNAME 0
#define FHQ_TTIF_TASKDESC 1
#define FHQ_TTIF_TASKTITLE 2
#define FHQ_TTIF_TASKWP 3
#define FHQ_TTIF_TASKTARGET 4
#define FHQ_TTIF_TASKSTATE 5
/* Might not be present */
private _res = "";
if (count _this > FHQ_TTIF_TASKTARGET) then {
_thing = _this select FHQ_TTIF_TASKTARGET;
/* A string means it's the initial state (unless starting with # or @), so if it's not, it's either
* a position (array) or target (object)
*/
switch (typename _thing) do {
case "ARRAY": {
_res = nil;
_res = _thing;
};
case "OBJECT": {
_res = nil;
_res = _thing;
};
case "CODE": {
_res = nil;
_res = call _thing;
};
case "STRING": {
_res = nil;
if (_thing find "#" == 0) exitWith {
private _parts = _thing select [1];
_res = call compile _parts ;
};
if (_thing find "@" == 0) exitWith {
private _parts = _thing select [1];
_res = getMarkerPos _parts;
};
_res = "";
};
};
};
_res;
#define FHQ_TTIF_TASKNAME 0
#define FHQ_TTIF_TASKDESC 1
#define FHQ_TTIF_TASKTITLE 2
#define FHQ_TTIF_TASKWP 3
#define FHQ_TTIF_TASKTARGET 4
#define FHQ_TTIF_TASKSTATE 5
_res = _this select FHQ_TTIF_TASKTITLE;
_res;#define FHQ_TTIF_TASKNAME 0
#define FHQ_TTIF_TASKDESC 1
#define FHQ_TTIF_TASKTITLE 2
#define FHQ_TTIF_TASKWP 3
#define FHQ_TTIF_TASKTARGET 4
#define FHQ_TTIF_TASKSTATE 5
#define FHQ_TTIF_TASKTYPE 6
/* Might not be present */
private _res = "";
private _num = count _this;
/* It must be a string, and it must be the last one, so we're just checking if there's more than 4
* and the last one is a string that is not a target or a state
*/
if (_num > 4) then {
private _type = _this select (_num - 1);
if (typename _type == "STRING") then {
if (!(_type call FHQ_fnc_ttiIsTaskState) and (_type find "#" != 0) and (_type find "@" != 0)) then {
/* Last element is a string, but no position, and no state, so it must be a type */
_res = _type;
};
};
};
_res;#define FHQ_TTIF_TASKNAME 0
#define FHQ_TTIF_TASKDESC 1
#define FHQ_TTIF_TASKTITLE 2
#define FHQ_TTIF_TASKWP 3
#define FHQ_TTIF_TASKTARGET 4
#define FHQ_TTIF_TASKSTATE 5
_res = _this select FHQ_TTIF_TASKWP;
_res;private ["_x", "_res", "_test", "_inArray"];
_res = false;
_inArray = [_this, 1, []] call BIS_fnc_param;
_test = [_this, 0, []] call BIS_fnc_param;
{
if (_x select 0 == _inArray select 0 && ((_x select 1) select 0) == ((_inArray select 1) select 0)
&& ((_x select 1) select 1) == ((_inArray select 1) select 1)) exitWith {
_res = true;
};
} foreach _test;
_res; /* Internal function, called automatically */
FHQ_TT_subtaskPrefix = " > ";
FHQ_TTI_supressTaskHints = true;
FHQ_TTI_version = productVersion select 2;
FHQ_TTI_DoSpectator = true;
if (isServer) then
{
FHQ_TTI_BriefingList = [];
FHQ_TTI_TaskList = [];
};
if (!isDedicated) then
{
FHQ_TTI_ClientTaskList = [];
if (isNil {player} || isNull player) then
{
FHQ_TTI_isJIPPlayer = true;
};
[] spawn
{
// Wait for join in progress
waitUntil {!isNil {player}};
waitUntil {!isNull player};
waitUntil {!isNil "FHQ_TTI_PostInitDone"};
/* Wait until briefing is ready (on server).
* Note that we spawn this code, to cope with the possibility of having no briefing at all
*/
[] spawn {
waitUntil {!isNil "FHQ_TTI_briefing"};
FHQ_TTI_BriefingList call FHQ_fnc_ttiUpdateBriefingList;
"FHQ_TTI_BriefingList" addPublicVariableEventHandler {(_this select 1) call FHQ_fnc_ttiUpdateBriefingList};
};
// Wait until the task list is ready (on server)
waitUntil {!isNil "FHQ_TTI_tasks"};
FHQ_TTI_TaskList call FHQ_fnc_ttiUpdateTaskList;
"FHQ_TTI_TaskList" addPublicVariableEventHandler {(_this select 1) call FHQ_fnc_ttiUpdateTaskList};
FHQ_TTI_supressTaskHints = false;
};
};
/* Internal function */
private "_x";
private _filter = _this;
private _res = false;
switch (typename _filter) do
{
case "CODE":
{
_res = true;
};
case "GROUP":
{
_res = true;
};
case "OBJECT":
{
_res = true;
};
case "SIDE":
{
_res = true;
};
case "STRING":
{
_res = true;
};
case "ARRAY":
{
/* The complex case: If all elements are objects, then it's a filter */
private _nonObjects = 0;
{
if (typename _x != "OBJECT") then {
_nonObjects = _nonObjects + 1;
};
} foreach _filter;
if (_nonObjects == 0) then {
_res = true;
};
};
};
_res;/* Internal Function */
private _state = toLower _this;
private _res = false;
if (_state in ["succeeded", "failed", "canceled", "created", "assigned"]) then {
_res = true;
};
_res;/* Eden compatible mission briefing
* This function is called like
* [_value] call FHQ_fnc_ttiMissionBriefing;
*
* _value is an array of briefing blocks. Each block is an array in itself,
* with the following format:
* ["identifier", [ [FHQ_TT briefing entry],... ]]
*
* "identifier" is a string identifying a "block" of entries. Units can receive one
* such block, i.e. all briefing entries listed under the identifier will be given to
* the unit.
*/
missionNamespace setVariable ["FHQ_tt_MissionBriefing", param [0, []]]; /* Eden compatible mission tasks
* This function is called like
* [_value] call FHQ_fnc_ttiMissionTasks;
*
* _value is an array of tasks. Each entry is an identifier followed by
* a full FHQ TT task entry
*
*/
missionNamespace setVariable ["FHQ_tt_MissionTasks", param [0, []]]; /* PostInit function
* This function walks through all playable/switchable units and assigns tasks and briefings to them
*/
/* Briefings:
* FHQ_tt_MissionBriefing is a global variable that contains an array of briefing blocks.
* Each block has a unique ID and a list of entries.
*
* We process this by going through the briefing blocks first: For each entry, the units
* referencing the briefing are collected in an array, and
*/
if (!isServer) exitWith {};
FHQ_TTI_extraUnits = allMissionObjects "VirtualCurator_F"+allMissionObjects "VirtualSpectator_F";
FHQ_TTI_PostInitDone = true;
publicVariable "FHQ_TTI_extraUnits";
publicVariable "FHQ_TTI_PostInitDone";
private _briefings = missionNamespace getVariable ["FHQ_tt_MissionBriefing", []];
private _tasks = missionNamespace getVariable ["FHQ_tt_MissionTasks", []];
private _playable = (if (isMultiplayer) then {playableUnits+FHQ_TTI_extraUnits} else {switchableUnits});
private _i = 0;
for [{_i = 0}, {_i < count _briefings}, {_i = _i + 1}] do
{
private _briefing = _briefings select _i;
private _id = _briefing select 0;
private _entry = _briefing select 1;
private _units = allMissionObjects "VirtualCurator_F"; //[];
{
if (tolower(_id) == tolower(_x getVariable ["FHQ_tt_UnitBriefing", ""])) then {
_units = _units + [_x];
};
} foreach _playable;
if (count _units != 0) then {
([_units] + _entry) call FHQ_fnc_ttAddBriefing;
};
};
for [{_i = 0}, {_i < count _tasks}, {_i = _i + 1}] do
{
private _task = _tasks select _i;
private _id = _task select 0;
private _entry = _task select 1;
private _units = allMissionObjects "VirtualCurator_F"; //[];
{
if (_id in (_x getVariable ["FHQ_tt_UnitTasks", []])) then {
_units = _units + [_x];
};
} foreach _playable;
if (count _units != 0) then {
([_units] + [_entry]) call FHQ_fnc_ttAddTasks;
};
};
/* FHQ_fnc_ttIsTaskCompleted
*
* Check whether a task is canceled, successful or failed. Like all query functions, this can be called
* on any client as well as the server.
*
* _result = [_task] call FHQ_fnc_ttIsTaskCompleted;
*
* _task: Name of the task.
*
* Returns true or false if the task's state is considered a "completed" state, i.e.
* succeeded, canceled, or failed
*
*/
private "_result";
_result = (tolower(_this call FHQ_fnc_ttGetTaskState) in ["succeeded", "canceled", "failed"]);
_result;
/* FHQ_fnc_ttIsTaskSuccessful
*
* Check whether a task is ended successfully. This function can be called on the client as well as
* the server.
*
* _result = [_taskName] call FHQ_fnc_ttIsTaskSuccessful;
*/
private "_result";
_result = (tolower(_this call FHQ_fnc_ttGetTaskState) == "succeeded");
_result;
private ["_unitTaskList", "_name", "_res", "_current", "_i", "_checkName"];
_unitTaskList = [_this, 0] call BIS_fnc_param;
_name = [_this, 1] call BIS_fnc_param;
_res = -1;
for "_i" from 0 to count _unitTaskList - 1 do
{
_current = _unitTaskList select _i;
if (count _current == 2) then {
_checkName = (_current select 1) call FHQ_fnc_ttiGetTaskName; // Server list
} else {
_checkName = (_current select 2); // Client list
};
if (_checkName == _name) exitWith {
_res = _i;
};
} foreach _unitTaskList;
_res;/* Eden compatible mission briefing
* This function is called like
* [_unit, _value] call FHQ_fnc_ttiUnitBriefing;
*
* _unit is the unit that should receive the briefing, and _value
* denotes the briefing itself.
*/
private _unit = param [0, objNull];
private _value = param [1, ""];
_unit setVariable ["FHQ_tt_UnitBriefing", _value];/* Eden compatible mission tasks
* This function is called like
* [_unit, _value] call FHQ_fnc_ttiUnitTasks;
*
* _unit is the unit that should receive the briefing, and _value
* denotes the briefing itself.
*/
private _unit = param [0, objNull];
private _value = param [1, ""];
_unit setVariable ["FHQ_tt_UnitTasks", _value];private ["_i", "_idx", "_current", "_record", "_filter", "_units", "_x", "_briefing", "_list", "_existing", "_notify"];
_briefing = _this;
_notify = false;
{
_list = [];
for [{_i = 0}, {_i < count _briefing}, {_i = _i + 1}] do {
_current = _briefing select _i; // [_filter, [_section, _subject, _text]]
_filter = _current select 0;
_units = [_filter] call FHQ_fnc_ttiFilterUnits;
if (_x in _units) then {
_record = _current select 1;
_list = _list + [[_record select 0, [_record select 1, _record select 2]]];
};
};
/* Now add them in reverse order */
_existing = _x getVariable ["FHQ_TTI_ClientBriefingList", []];
for [{_i = count _list - 1}, {_i >= 0}, {_i = _i - 1}] do {
_current = _list select _i;
if (!([_existing, _current] call FHQ_fnc_ttiHasBriefingEntry)) then {
/* Check if the section exists and create it if necessary, then add the record */
if (!(_x diarySubjectExists (_current select 0))) then {
_x createDiarySubject [_current select 0, _current select 0];
};
_x createDiaryRecord [_current select 0, [(_current select 1) select 0, (_current select 1) select 1]];
if (player == _x && !FHQ_TTI_supressTaskHints) then
{
private "_title";
_title = _current select 0;
if (_title == "Diary") then {
_title = "Briefing";
};
[format ["%1/%2", _title, (_current select 1) select 0], "newbriefing"] call FHQ_fnc_ttTaskHint;
};
};
};
_x setVariable ["FHQ_TTI_ClientBriefingList", _list]; // FIXME ?
} foreach (if (isMultiplayer) then {playableUnits+FHQ_TTI_extraUnits} else {switchableUnits});private _tasks = _this;
private _i = 0;
{
private _list = [];
for [{_i = 0}, {_i < count _tasks}, {_i = _i + 1}] do {
private _current = _tasks select _i; // [_filter, [_section, _subject, _text]]
private _filter = _current select 0;
private _units = [_filter] call FHQ_fnc_ttiFilterUnits;
if (_x in _units) then {
//_list = _list + [_current select 1];
_list pushBack (_current select 1);
};
};
/* Now add them in reverse order */
private _existing = _x getVariable ["FHQ_TTI_ClientTaskList", []];
for [{_i = 0}, {_i < count _list}, {_i = _i + 1}] do {
private _current = _list select _i;
_existing = [_current, _existing, _x] call FHQ_fnc_ttiCreateOrUpdateTask;
};
_x setVariable ["FHQ_TTI_ClientTaskList", _existing];
} foreach (if (isMultiplayer) then {playableUnits+FHQ_TTI_extraUnits} else {switchableUnits});/*
* Control mission flow based on an array of conditions and actions.
*
* Mission flow through FSMs is a good possibility for ensuring a single point of execution for
* any events happening during the game session. Most of the time, though, the FSM is following
* a very rigid structure: A single "on mission" state branching out into a bunch of conditions
* that in term lead to code executed and then return to the on mission state.
*
* This can be collapsed into the conditions and the code executed when the condition is met.
* This function does exactly that: It runs in a thread on the server only, waiting for
* any of the conditions to become true, then execute the code associated to that condition.
* Each condition/code pair can be attributed with a set of attributes that determine what happens
* afterwards. For example, the "single" attribute means that the condition can happen exactly once
* and will be removed after it happened. This prevents, for example, that a condition is executed
* every frame from then on out.
*
* The function is called like this:
* _result = [_flow] call FHQ_fnc_missionFlow;
*
* NOTE: It must be called in a scheduled environment. If in doubt, spawn a thread.
*
* Parameters:
* _flow: An array describing the actual flow of the mission. Each entry consists of three elements:
* - Condition string (will be compiled and must evaluate to a boolean)
* - Code to be executed when the condition is met.
* - Array of strings that define attributes for the condition/action pair. Currently, the following
* attributes are defined. Unknown items are ignored:
* "single" - This action should only be executed once. The condition/action pair is removed from the
* mission flow array after it has been executed once. Note: If the array is omitted, "single"
* is assumed
* "end" - This action ends the mission. If an "end" attribute is encountered, FHQ_fnc_missionFlow
* will exit.
*
* Return value:
* _result: If an "end" action is found, the attribute array corresponding to this action is returned. This
* allows the user to check the attributes of the ending action.
*
* Example:
* private _flow = [
* ["!alive blowMeUp", {systemChat "BlowMeUp is no more";}, ["single"]],
* ["triggerActivated exfilTrigger", {systemChat "Thats it, end mission";}, ["end", "success"]]
* ];
*
* private _result = [_flow] call FHQ_fnc_missionFlow;
* if ("success" in _result) then {
* systemChat "The mission was a success";
* };
*/
private _result = [];
if (isServer) then {
private _running = true;
params [
["_flow", []]
];
while {_running} do {
/* Create the condition to wait for */
private _cond = _flow call FHQ_fnc_ttiBuildCondition;
/* And wait until one of them happens */
waitUntil {call compile _cond};
/* Find out which */
_deleteMes = [];
{
private "_attribX";
private _condX = _x select 0;
private _codeX = _x select 1;
if (count _x >= 3) then {
_attribX = _x select 2;
} else {
_attribX = ["single"];
};
if (call compile _condX) then {
/* ok, this one's triggered, execute the code */
if (typename _codeX == "CODE") then {
call _codeX;
};
if (typename _codeX == "STRING") then {
[_codeX, "succeeded"] call FHQ_fnc_ttSetTaskState;
};
if ("single" in _attribX) then {
_deleteMes pushBack _forEachIndex;
};
if ("end" in _attribX) exitWith {
_running = false;
_result = +_attribX;
};
};
} foreach _flow;
{
_flow deleteAt _x;
} forEach _deleteMes;
};
};
_result/* FHQ_fnc_ttSetTaskDescription
*
* Set the "long" description of the specified task, and alert the player if necessary.
*
* NOTE: Server callable only. Calling this on a client does not have an effect
*
* Usage:
* [_task, _newDesc] call FHQ_fnc_ttSetTaskDescription;
* _task: the task name defined with FHQ_fnc_ttAddTasks
* _newDesc: New description
*
*/
#define FHQ_TTIF_TASKDESC 1
private ["_name", "_desc", "_idx", "_record", "_entry"];
if (isServer) then {
_name = [_this, 0, "", [""]] call BIS_fnc_param;
_desc = [_this, 1, "", [""]] call BIS_fnc_param;
_idx = [FHQ_TTI_TaskList, _name] call FHQ_fnc_ttiTaskExists;
if (_idx != -1) then {
_entry = FHQ_TTI_TaskList select _idx;
_record = _entry select 1;
_record set [FHQ_TTIF_TASKDESC, _desc];
_entry set [1, _record];
FHQ_TTI_TaskList set [_idx, _entry];
publicVariable "FHQ_TTI_TaskList";
if (!isDedicated) then {
FHQ_TTI_TaskList call FHQ_fnc_ttiUpdateTaskList;
};
};
};/* FHQ_fnc_ttSetTaskState
*
* Set the state of the specified task to the specified state, and alert the player
* if necessary.
*
* NOTE: Server callable only. Calling this on a client does not have an effect
*
* Usage:
* [_task, _state] call FHQ_fnc_ttSetTaskState;
* _task: the task name defined with FHQ_fnc_ttAddTasks
* _state: One of "succeeded", "failed", "canceled", "created", "assigned"
*
*/
#define FHQ_TTIF_TASKSTATE 5
private ["_name", "_state", "_idx", "_record", "_entry"];
if (isServer) then {
_name = [_this, 0, "", [""]] call BIS_fnc_param;
_state = [_this, 1, "", [""]] call BIS_fnc_param;
_idx = [FHQ_TTI_TaskList, _name] call FHQ_fnc_ttiTaskExists;
if (_idx != -1) then {
_entry = FHQ_TTI_TaskList select _idx;
_record = _entry select 1;
_record set [FHQ_TTIF_TASKSTATE, _state];
_entry set [1, _record];
FHQ_TTI_TaskList set [_idx, _entry];
publicVariable "FHQ_TTI_TaskList";
if (!isDedicated) then {
FHQ_TTI_TaskList call FHQ_fnc_ttiUpdateTaskList;
};
};
};
/* FHQ_fnc_ttSetTaskStateAndNext
*
* Set the state of a given task to the given state, and select another task from a list of
* tasks which is not finished yet. The first task found will be set to assigned and a message will
* be shown to the player, if enabled.
*
* NOTE: Can only be called on the server
*
* Usage:
* [_task1, _state, _task2, ...] call FHQ_fnc_ttSetTaskStateAndNext;
*
* _task1: The task to set to _state
* _state: The state for _task1
* _task2 and following: The tasks are checked in turn for completion, and the first one not
* completed will be assigned.
*
* Example:
*
* ["taskGetVodka", "succeeded", "taskDrink", "taskBeMerry"] call FHQ_fnc_ttSetTaskStateAndNext;
*/
private "_i";
[_this select 0, _this select 1] call FHQ_fnc_ttSetTaskState;
for [ {_i = 2}, {_i < count _this}, {_i = _i + 1} ] do
{
if (!([_this select _i] call FHQ_fnc_ttIsTaskCompleted)) exitWith
{
[_this select _i, "assigned"] call FHQ_fnc_ttSetTaskState;
};
};
/* FHQ_fnc_ttSetTaskTarget
*
* Set the target of the specified task, and alert the player if necessary.
*
* NOTE: Server callable only. Calling this on a client does not have an effect
*
* Usage:
* [_task, _newTarget] call FHQ_fnc_ttSetTaskTarget;
* _task: the task name defined with FHQ_fnc_ttAddTasks
* _newTarget: The new target, can be an array (position) or an object
*
*/
#define FHQ_TTIF_TASKTARGET 4
private ["_name", "_target", "_idx", "_record", "_entry"];
if (isServer) then {
_name = [_this, 0, "", [""]] call BIS_fnc_param;
_target = [_this, 1, objNull, [objNull, [2,3]]] call BIS_fnc_param;
_idx = [FHQ_TTI_TaskList, _name] call FHQ_fnc_ttiTaskExists;
if (_idx != -1) then {
_entry = FHQ_TTI_TaskList select _idx;
_record = _entry select 1;
_record set [FHQ_TTIF_TASKTARGET, _target];
_entry set [1, _record];
FHQ_TTI_TaskList set [_idx, _entry];
publicVariable "FHQ_TTI_TaskList";
if (!isDedicated) then {
FHQ_TTI_TaskList call FHQ_fnc_ttiUpdateTaskList;
};
};
};/* FHQ_fnc_ttSetTaskTitlesAndTarget
*
* Set the title and description of the specified task, and alert the player if necessary.
*
* NOTE: Server callable only. Calling this on a client does not have an effect
*
* Usage:
* [_task,_newTarget, _newTitle, _newDesc] call FHQ_fnc_ttSetTaskTitle;
* _task: the task name defined with FHQ_fnc_ttAddTasks
* _newTitle: The new title
* _newDescription: The new description
*/
#define FHQ_TTIF_TASKDESC 1
#define FHQ_TTIF_TASKTITLE 2
#define FHQ_TTIF_TASKTARGET 4
private ["_name", "_title", "_desc", "_idx", "_record", "_entry", "_target"];
if (isServer) then {
_name = [_this, 0, "", [""]] call BIS_fnc_param;
_target = [_this, 1, objNull, [objNull, [2,3]]] call BIS_fnc_param;
_title = [_this, 2, "", [""]] call BIS_fnc_param;
_desc = [_this, 3, "", [""]] call BIS_fnc_param;
_idx = [FHQ_TTI_TaskList, _name] call FHQ_fnc_ttiTaskExists;
if (_idx != -1) then {
_entry = FHQ_TTI_TaskList select _idx;
_record = _entry select 1;
_record set [FHQ_TTIF_TASKTITLE, _title];
_record set [FHQ_TTIF_TASKDESC, _desc];
_record set [FHQ_TTIF_TASKTARGET, _target];
_entry set [1, _record];
FHQ_TTI_TaskList set [_idx, _entry];
publicVariable "FHQ_TTI_TaskList";
if (!isDedicated) then {
FHQ_TTI_TaskList call FHQ_fnc_ttiUpdateTaskList;
};
};
};/* FHQ_fnc_ttSetTaskTitle
*
* Set the "short" description of the specified task, and alert the player if necessary.
*
* NOTE: Server callable only. Calling this on a client does not have an effect
*
* Usage:
* [_task, _newTitle] call FHQ_fnc_ttSetTaskTitle;
* _task: the task name defined with FHQ_fnc_ttAddTasks
* _newTitle: The new title
*
*/
#define FHQ_TTIF_TASKTITLE 2
private ["_name", "_title", "_idx", "_record", "_entry"];
if (isServer) then {
_name = [_this, 0, "", [""]] call BIS_fnc_param;
_title = [_this, 1, "", [""]] call BIS_fnc_param;
_idx = [FHQ_TTI_TaskList, _name] call FHQ_fnc_ttiTaskExists;
if (_idx != -1) then {
_entry = FHQ_TTI_TaskList select _idx;
_record = _entry select 1;
_record set [FHQ_TTIF_TASKTITLE, _title];
_entry set [1, _record];
FHQ_TTI_TaskList set [_idx, _entry];
publicVariable "FHQ_TTI_TaskList";
if (!isDedicated) then {
FHQ_TTI_TaskList call FHQ_fnc_ttiUpdateTaskList;
};
};
};/* FHQ_fnc_ttSetTaskTitles
*
* Set the title and description of the specified task, and alert the player if necessary.
*
* NOTE: Server callable only. Calling this on a client does not have an effect
*
* Usage:
* [_task, _newTitle, _newDesc] call FHQ_fnc_ttSetTaskTitle;
* _task: the task name defined with FHQ_fnc_ttAddTasks
* _newTitle: The new title
* _newDescription: The new description
*/
#define FHQ_TTIF_TASKDESC 1
#define FHQ_TTIF_TASKTITLE 2
private ["_name", "_title", "_desc", "_idx", "_record", "_entry"];
if (isServer) then {
_name = [_this, 0, "", [""]] call BIS_fnc_param;
_title = [_this, 1, "", [""]] call BIS_fnc_param;
_desc = [_this, 2, "", [""]] call BIS_fnc_param;
_idx = [FHQ_TTI_TaskList, _name] call FHQ_fnc_ttiTaskExists;
if (_idx != -1) then {
_entry = FHQ_TTI_TaskList select _idx;
_record = _entry select 1;
_record set [FHQ_TTIF_TASKTITLE, _title];
_record set [FHQ_TTIF_TASKDESC, _desc];
_entry set [1, _record];
FHQ_TTI_TaskList set [_idx, _entry];
publicVariable "FHQ_TTI_TaskList";
if (!isDedicated) then {
FHQ_TTI_TaskList call FHQ_fnc_ttiUpdateTaskList;
};
};
}; /* Arma 3 */
private ["_notifyTemplate", "_desc", "_state"];
_desc = [_this, 0, ""] call BIS_fnc_param;
_state = [_this, 1, "created"] call BIS_fnc_param;
private _type = [_this, 2, ""] call BIS_fnc_param;
_notifyTemplate = "TaskCreated";
switch (tolower _state) do
{
case "created":
{
_notifyTemplate = "TaskCreated";
};
case "assigned":
{
_notifyTemplate = "TaskAssigned";
};
case "succeeded":
{
_notifyTemplate = "TaskSucceeded";
};
case "canceled":
{
_notifyTemplate = "TaskCanceled";
};
case "cancelled":
{
_notifyTemplate = "TaskCanceled";
};
case "failed":
{
_notifyTemplate = "TaskFailed";
};
case "newbriefing":
{
_notifyTemplate = "TaskAssigned";
if (isClass (missionConfigFile >> "CfgNotifications" >> "NewBriefing")) then {
_notifyTemplate = "NewBriefing";
};
};
case "update":
{
_notifyTemplate = "TaskUpdated";
};
};
if (count _type != 0) then {
_notifyTemplate = _notifyTemplate + "Icon";
if (isClass (missionConfigFile >> "CfgTaskTypes" >> _type)) then {
_type = getText (missionConfigFile >> "CfgTaskTypes" >> _type >> "icon");
} else {
_type = getText(configFile >> "CfgTaskTypes" >> _type >> "icon");
};
};
[_notifyTemplate, [_type, _desc]] call BIS_fnc_showNotification;Exif MM * 8 ( 1 ! 2 Շi $
'
'Adobe Photoshop 23.1 (Macintosh) 2022:02:16 23:54:57 0221 8 r z( H H Adobe_CM Adobe d
Z "
?
3 !1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw 5 !1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ? >t7Y{2mUۑ3؛
{gl G߫8c2juscI7ܗdэճf":