description.ext bZ] functions\fhq_tasktracker.hpp ."\ functions\fhq_tasktracker\fn_ttAddBriefing.sqf 6Ww functions\fhq_tasktracker\fn_ttAddBriefingGroup.sqf Z functions\fhq_tasktracker\fn_ttAddTaskGroup.sqf ?Z functions\fhq_tasktracker\fn_ttAddTasks.sqf i\ functions\fhq_tasktracker\fn_ttAreTasksCompleted.sqf 6W functions\fhq_tasktracker\fn_ttAreTasksSuccessful.sqf 6W functions\fhq_tasktracker\fn_ttGetAllTasksWithState.sqf 6WG functions\fhq_tasktracker\fn_ttGetTaskState.sqf 6W functions\fhq_tasktracker\fn_ttiAddBriefingEntry.sqf 6W9 functions\fhq_tasktracker\fn_ttiBuildCondition.sqf :
\m functions\fhq_tasktracker\fn_ttiCreateOrUpdateTask.sqf i\G functions\fhq_tasktracker\fn_ttiFilterUnits.sqf 6ZX4 functions\fhq_tasktracker\fn_ttiGetTaskDesc.sqf 6W functions\fhq_tasktracker\fn_ttiGetTaskId.sqf 6W functions\fhq_tasktracker\fn_ttiGetTaskName.sqf 6Wm functions\fhq_tasktracker\fn_ttiGetTaskState.sqf !i\] functions\fhq_tasktracker\fn_ttiGetTaskTarget.sqf 6W functions\fhq_tasktracker\fn_ttiGetTaskTitle.sqf 6W functions\fhq_tasktracker\fn_ttiGetTaskType.sqf 6WC functions\fhq_tasktracker\fn_ttiGetTaskWp.sqf 6W functions\fhq_tasktracker\fn_ttiHasBriefingEntry.sqf 6W functions\fhq_tasktracker\fn_ttiInit.sqf 2Zq functions\fhq_tasktracker\fn_ttiIsFilter.sqf 6W functions\fhq_tasktracker\fn_ttiIsTaskState.sqf 6W functions\fhq_tasktracker\fn_ttiMissionBriefing.sqf 6W) functions\fhq_tasktracker\fn_ttiMissionTasks.sqf 6W, functions\fhq_tasktracker\fn_ttiPostInit.sqf x;Z functions\fhq_tasktracker\fn_ttIsTaskCompleted.sqf 6W functions\fhq_tasktracker\fn_ttIsTaskSuccessful.sqf 6WL functions\fhq_tasktracker\fn_ttiTaskExists.sqf 6WQ functions\fhq_tasktracker\fn_ttiUnitBriefing.sqf 6Wg functions\fhq_tasktracker\fn_ttiUnitTasks.sqf 6W^ functions\fhq_tasktracker\fn_ttiUpdateBriefingList.sqf LZXM functions\fhq_tasktracker\fn_ttiUpdateTaskList.sqf Qd\ functions\fhq_tasktracker\fn_ttMissionFlow.sqf x\ functions\fhq_tasktracker\fn_ttSetTaskDescription.sqf xZC functions\fhq_tasktracker\fn_ttSetTaskState.sqf 6Wx functions\fhq_tasktracker\fn_ttSetTaskStateAndNext.sqf 6W$ functions\fhq_tasktracker\fn_ttSetTaskTarget.sqf Zt functions\fhq_tasktracker\fn_ttSetTaskTargetAndTitles.sqf Z functions\fhq_tasktracker\fn_ttSetTaskTitle.sqf nZ? functions\fhq_tasktracker\fn_ttSetTaskTitles.sqf lZ functions\fhq_tasktracker\fn_ttTaskHint.sqf ZS groupmarker.sqf ˲z]D init.sqf ]M initServer.sqf /] media\overview.jpg "] media\zamak.jpg ] mission.sqm Y^@ class CfgFunctions
{
class FHQ
{
#include "functions\fhq_tasktracker.hpp"
};
};
#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 = [];
{
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 = [];
{
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;/*source: https://www.reddit.com/r/armadev/comments/1qvzjt/make_a_moving_marker_stay_with_the_group/cdh62rt/
original: http://www.armaholic.com/forums.php?m=posts&id=12587 ?
adjusted sleep time
needs a marker created with a variablename, use markername for name on map.
choose one unit from a group and put in the init field (check scriptname): nul = ["mk1", this] execVM "groupmarker.sqf" where mk1 is the variablename used in the marker, unit does not need a variablename.
2019/09/12 discord CiA editing help:
[19:27] Varanon: The problem with this is that if you overdo this, you have tons of threads running that are basically hogging performance
[19:27] Varanon: Ideally, you would have a "EachFrame" event handler that would handle it
[19:28] Verstanden: would performance be an issue for our low group count at the moment (2-5 markers)?
[19:28] Varanon: Not really, but keep it in mind
[19:29] Verstanden: will do for sure. so execVM is the right way to run the script in a dedicated server environment?
[19:30] Varanon: execvm creates a thread from the script. It will return immediately and leave the script running, so yeah, it's the correct thing to use in this situation
FHQ has also made unit tracker script, which might be in our forums?
https://community.bistudio.com/wiki/onEachFramee
http://killzonekid.com/arma-scripting-tutorials-loops-v2/
*/
_marker = _this select 0;
_unit = _this select 1;
_unitGroup = group _unit;
while {(count (units _unitGroup) > 0)} do
{
_marker setmarkerpos (getpos leader _unitGroup);
sleep 1;
};
deletemarker _marker;/*{_x allowfleeing 0} foreach allunits;
{
_x addCuratorEditableObjects [allUnits, true];
_x addCuratorEditableObjects [vehicles, true];
_x addCuratorEditableObjects [allUnitsUAV, true];
_x addCuratorEditableObjects [allMines, true];
} forEach allCurators;
*/
part1 = false;
part2 = false;
part3 = false;
objective1 = false; //zmk1 alive?
objective2 = false; //zmk2 alive?
objective3 = false; //airfield seized?
objective4 = false; //Outpost reachend/Exfil?
complete = false;
if isServer then {
if isClass (configFile >> "CfgPatches" >> "ace_explosives") then {
badger addItemCargoGlobal ["ACE_Clacker", 5];
};
}; JFIF ,, *Exif II* J R ( 1
Z 2 h | , , GIMP 2.10.12 2019:09:16 22:01:16 : JFIF C
$.' ",#(7),01444'9=82<.342 C
2!!22222222222222222222222222222222222222222222222222 "
} !1AQa"q2#BR$3br
%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
w !1AQaq"2B #3Rbr
$4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ? 3ĚNص''UoZlLrgpEt:GI 4@Gq S'ꭔ8'$6MyuBiY-[#뵿ƻ
+u╿ qkḢ#`è4}GtX=
\[3 }KAmJ/-k. AK9F$aܚaH-.bH