Advertisement
aeroson

Arma 3: FHQ TaskTracker with disabledAi=1; support

Apr 28th, 2013
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 26.43 KB | None | 0 0
  1. /* FHQ TaskTracker with disabledAi=1; support
  2. *
  3. * Will work with any type of respawn.
  4. *
  5. * Filters are now saved instead of filtered units.
  6. * One drawback is, filters are now not complementing each other,
  7. * so in the example mission you would have to change west filter to
  8. * { playerside == west && ! (player in units PlayerGroup) }
  9. *
  10. */
  11.  
  12. /* FHQ TaskTracker for the FHQ Multiplayer framework
  13. *
  14. * This scriptset is used to create briefings and tasks, and keep track of
  15. * task states.
  16. *
  17. * In general, briefings and tasks can be created for individual players, for
  18. * groups of players, and specific to the side or faction of the player.
  19. *
  20. * Unit filters:
  21. * Whenever a unit filter is asked for, there are several possibilities to
  22. * define what you need to assign to:
  23. * single object: A single player
  24. * group: All players of a group
  25. * side: All players of a side
  26. * faction (string): All players of a certain faction
  27. * code: The piece of code is called for every playable character. Return true if you want
  28. * the character to be selected, or false otherwise. The only parameter is the playable
  29. * object to be tested
  30. *
  31. * When calling a function that assigns briefings or tasks, a pool of all playable units is created.
  32. * The filter is tested against those units, and all units matching the filter will have the tasks/briefing
  33. * assigned to them. Subsequently, these units (that mached the filter) are removed from the pool. Further
  34. * filtering is done on the remaining units.
  35. *
  36. * This essentially means that you should define tasks/briefing entries from specific to general. For example,
  37. * assuming one player group is west (whith special tasks), and the rest of the players share another set of tasks,
  38. * you would first use the specific group as filter value, followed by west to assign the following tasks to all
  39. * remaining west players.
  40. *
  41. * Examples:
  42. * {(side _this) != west): All playable characters that are not BLUFOR
  43. * player: the player on the current client
  44. * group westMan1_1: All units in westMan1_1's group
  45. * east: All playable characters on the OPFOR side
  46. * "BIS_BAF": All playable british soliders
  47. *
  48. *
  49. * Briefing entries:
  50. * Briefing entries are defined as an array of two strings. The first string is the title as it
  51. * will appear in the middle colum when the "Notes" section is highlighted in the left colum.
  52. * The second string is a text that can contains links to markers, code, and some html formatting
  53. * and will be displayed on the right column when the title in the center column is highlited.
  54. *
  55. *
  56. * Task entries:
  57. * A single task entry is an array. The elements in the array are as follows:
  58. * String: task name
  59. * String: Task text (the text that will appear in the right colum)
  60. * String: Task title (it will appear in the center column when "Tasks" is highlited in the left column).
  61. * String: optional Waypoint title (Will appear on the waypoint marker in the player's main view).
  62. * Object or position: The destination for this task, either an object, or a position.
  63. * String: Optional initial state ("created" if nothing given)
  64. *
  65. *
  66. * Commonly used examples:
  67. *
  68. * 1. Assign a task as current task:
  69. * ["taskDestroy", "assigned"] call FHQ_TT_setTaskState;
  70. *
  71. *
  72. * 2. Check if a task is completed (Note, might be successful, failed or cancelled)
  73. * if (["taskInsert"] call FHQ_TT_isTaskCompleted) then {hint "yes";};
  74. *
  75. *
  76. * 3. Check if a task is successful
  77. * if (["taskDestroy"] call FHQ_TT_isTaskSuccessful) then {hint "yay";};
  78. *
  79. *
  80. * 4. Mark a task and select another task that is not completed yet.
  81. * ["taskDestroySecondary", "succeeded", "taskDestroyPrimary", "taskDestroySecondary", "taskExfiltrate"]
  82. * call FHQ_TT_markTaskAndNext;
  83. *
  84. * This example marks taskDestroySecondary as succesful, and then checks if taskDestroyPrimary is completed.
  85. * If not, it is set to assigned. If it is completed, it continues with the taskDestroySecondary and eventually
  86. * taskExfiltrate.
  87. *
  88. *
  89. *
  90. *
  91. * TODO: Add possibility to change waypoint position
  92. */
  93.  
  94. FHQ_TT_init =
  95. {
  96. FHQ_TT_supressTaskHints = true;
  97.  
  98. /* Check for Arma 3 or 2 */
  99. FHQ_TT_is_arma3 = false;
  100.  
  101. if (isClass (configfile >> "CfgAddons" >> "PreloadAddons" >> "A3")) then {
  102. FHQ_TT_is_arma3 = true;
  103. };
  104.  
  105. if (isServer) then
  106. {
  107. // Global list of tasks kept on the server. Always contains full info:
  108. // [unit filter, description, state]
  109. FHQ_TT_TaskList = [];
  110. };
  111.  
  112. if (!isDedicated) then
  113. {
  114. // Local version of the client
  115. // I wonder, though, why this is necessary, since according to the documentation,
  116. // the effects of createSimpleTask are global
  117. // Anyway, [name, state, list of objects]
  118. FHQ_TT_ClientTaskList = [];
  119.  
  120. if (isNil {player} || isNull player) then
  121. {
  122. FHQ_TT_isJIPPlayer = true;
  123. };
  124.  
  125. [] spawn
  126. {
  127. // Wait for join in progress
  128. waitUntil {!isNil {player}};
  129. waitUntil {!isNull player};
  130.  
  131. // Wait until the task list is ready.
  132. waitUntil {!isNil "FHQ_TT_initialized"};
  133. FHQ_TT_TaskList call FHQ_TT_UpdateTaskList;
  134. FHQ_TT_supressTaskHints = false;
  135. "FHQ_TT_TaskList" addPublicVariableEventHandler {(_this select 1) call FHQ_TT_UpdateTaskList};
  136. };
  137. };
  138. };
  139.  
  140.  
  141. FHQ_TT_filterUnits =
  142. {
  143. private ["_unitsArray", "_inputArray", "_outputArray"];
  144.  
  145. _unitsArray = _this select 1;
  146. _inputArray = _this select 0;
  147. _outputArray = [];
  148.  
  149. switch (typename _inputArray) do
  150. {
  151. case "CODE":
  152. {
  153. // Filter all playable units by comparing them with the code
  154. {if (_x call _inputArray) then {_outputArray = _outputArray + [_x];};} forEach _unitsArray;
  155. };
  156. case "GROUP":
  157. {
  158. // Filter out all objects not in group
  159. {if (_x in units _inputArray) then {_outputArray = _outputArray + [_x];};} forEach _unitsArray;
  160. };
  161. case "OBJECT":
  162. {
  163. // Result is only the array containing the object
  164. _outputArray = [_inputArray];
  165. };
  166. case "SIDE":
  167. {
  168. // Filter out all objects not belonging to side
  169. {if (side _x == _inputArray) then {_outputArray = _outputArray + [_x];};} forEach _unitsArray;
  170. };
  171. case "STRING":
  172. {
  173. // Filer out all objects not belonging to the faction
  174. {if (faction _x == _inputArray) then {_outputArray = _outputArray + [_x];};} forEach _unitsArray;
  175. };
  176. };
  177.  
  178. _outputArray;
  179. };
  180.  
  181. /* FHQ_TT_addBriefingEntry: Add a briefing entry for the given entities
  182. *
  183. * This function adds a briefing entry for the given units. The units can be
  184. * supplied as either a player, a group, a side, a faction, or a piece of code.
  185. * All playable units will receive the given entries if they match the condition.
  186. *
  187. * [_units, _topic, _text] call FHQ_TT_addBriefingEntry;
  188. * [_units, _subject, _topic, _text] call FHQ_TT_addBriefingEntry; (NOT YET IMPLEMENTED)
  189. *
  190. * Parameters:
  191. * _units: A single unit, a group, side faction, or piece of code that will
  192. * be run on all playable units.
  193. * _topic: topic to add to
  194. * _text: text for this subject
  195. * _subject: Subject to file this under. A new subject is created if it does not exist yet.
  196. * (optional, not yet implemented)
  197. *
  198. */
  199.  
  200. FHQ_TT_addBriefingEntry =
  201. {
  202. private ["_units", "_subject", "_topic", "_text", "_unitsArray", "_unitPool"];
  203.  
  204. _units = _this select 0;
  205. _subject = "Diary";
  206. _topic = _this select 1;
  207. _text = _this select 2;
  208. _unitPool = (if (isMultiplayer) then {playableUnits} else {switchableUnits});
  209.  
  210. _unitsArray = [_units, _unitPool] call FHQ_TT_filterUnits;
  211.  
  212. {_x createDiaryRecord [_subject, [_topic, _text]]} forEach _unitsArray;
  213. };
  214.  
  215.  
  216. /* Internally used to add topics to units in reversed order */
  217. FHQ_TT_addBriefingEntries =
  218. {
  219. private ["_units", "_subject", "_topics", "_count", "_i", "_topic", "_text"];
  220.  
  221. _units = _this select 0;
  222. _subject = "Diary";
  223. _topics = _this select 1;
  224.  
  225. _count = count _topics;
  226. if (_count > 0) then
  227. {
  228. for [ {_i = _count - 1}, {_i >= 0}, {_i = _i - 1}] do
  229. {
  230. _topic = (_topics select _i) select 0;
  231. _text = (_topics select _i) select 1;
  232. {_x createDiaryRecord [_subject, [_topic, _text]]} forEach _units;
  233. };
  234. };
  235. };
  236.  
  237. /* FHQ_TT_addBriefing: Add a full briefing to the selected units.
  238. *
  239. * This functions receives an array as input. The elements of the input array
  240. * are interpreted as follows:
  241. * If the element is a two-element array consisting of two strings, the entry is
  242. * interpreted as a new briefing topic.
  243. * If the element is anything else, the following topics will only be presented to
  244. * the units matching the element. For example, if the element is a group, the following
  245. * entries are added to this group only.
  246. * If a new unit match is encountered, the units that have been assigned targets before
  247. * will be removed from the pool of units being considered for future topics.
  248. *
  249. * In other words, you can define briefings from bottom up. If you first define briefing topics
  250. * for a group of players, and then for a side, the side specific topics will not be added to the
  251. * group. This is meant to enable you to go from specific units up to general.
  252. *
  253. * In normal circumstances, you will most likely only define one briefing for a single group of
  254. * players, and thus passing only an array of string pairs.
  255. */
  256.  
  257. FHQ_TT_addBriefing =
  258. {
  259. private ["_unitPool", "_numEntries", "_currentUnits", "_currentTopicList", "_current"];
  260. _unitPool = (if (isMultiplayer) then {playableUnits} else {switchableUnits});
  261. _numEntries = count _this;
  262. _currentUnits = _unitPool;
  263. _currentTopicList = [];
  264.  
  265. for "_i" from 0 to (_numEntries - 1) do
  266. {
  267. _current = _this select _i;
  268.  
  269.  
  270. if (typename _current == "ARRAY") then
  271. {
  272. // Parameter is an entry for the briefing, apply it to the _currentUnits pool
  273. // {_x createDiaryRecord ["Diary", [_current select 0, _current select 1]];} forEach _currentUnits;
  274. _currentTopicList = _currentTopicList + [[_current select 0, _current select 1]];
  275. }
  276. else
  277. {
  278. // Parameter is a filter for the units. Remove the _currentUnits from the pool and select
  279. // units according to the filter. Note: not removing anything on _i = 0
  280. if (_i != 0) then
  281. {
  282. _unitPool = _unitPool - _currentUnits;
  283. };
  284.  
  285. if (count _currentTopicList > 0) then
  286. {
  287. [_currentUnits, _currentTopicList] call FHQ_TT_addBriefingEntries;
  288. _currentTopicList = [];
  289. };
  290.  
  291. _currentUnits = [_current, _unitPool] call FHQ_TT_filterUnits;
  292. };
  293. };
  294.  
  295. // Add any leftovers
  296. if (count _currentTopicList > 0) then
  297. {
  298. [_currentUnits, _currentTopicList] call FHQ_TT_addBriefingEntries;
  299. _currentTopicList = [];
  300. };
  301. };
  302.  
  303.  
  304. /* FHQ_TT_getTaskName
  305. * Internal
  306. */
  307.  
  308. FHQ_TT_getTaskName =
  309. {
  310. private ["_task", "_name"];
  311.  
  312. _task = (_this select 0) select 0;
  313. if (typename _task == "ARRAY") then
  314. {
  315. _name = _task select 0;
  316. }
  317. else
  318. {
  319. _name = _task;
  320. };
  321.  
  322. _name;
  323. };
  324.  
  325. /* FHQ_TT_createSimpleTask:
  326. *
  327. * Internal
  328. */
  329. FHQ_TT_createSimpleTask =
  330. {
  331. private ["_currentUnits", "_currentTask", "_currentTaskState", "_taskObjects", "_taskName"];
  332. _currentUnits = _this select 0;
  333. _currentTask = _this select 1; // [name|[name,parent], text, title, waypoint, object/position]
  334. _currentTaskState = _this select 2;
  335. _taskObjects = [];
  336.  
  337. {
  338. private "_task";
  339. if (typename (_currentTask select 0) == "ARRAY") then
  340. {
  341. private ["_parentTask"];
  342.  
  343. _taskName = (_currentTask select 0) select 0;
  344. _parentTask = (_currentTask select 0) select 1;
  345. _task = _x createSimpleTask [_taskName, _x getVariable format["FHQ_TT_taskname_%1", _parentTask]];
  346. }
  347. else
  348. {
  349. _taskName = _currentTask select 0;
  350. _task = _x createSimpleTask [_currentTask select 0];
  351. };
  352.  
  353. _task setSimpleTaskDescription [_currentTask select 1, _currentTask select 2, _currentTask select 3];
  354.  
  355. if (count _currentTask > 4) then
  356. {
  357. switch (typename (_currentTask select 4)) do
  358. {
  359. case "ARRAY":
  360. {
  361. _task setSimpleTaskDestination (_currentTask select 4);
  362. };
  363. case "OBJECT":
  364. {
  365. _task setSimpleTaskTarget [_currentTask select 4, true];
  366. };
  367. };
  368. };
  369.  
  370. _task setTaskState _currentTaskState;
  371. if (tolower(_currentTaskState) == "assigned") then
  372. {
  373. _x setCurrentTask _task;
  374. };
  375.  
  376. _x setVariable [format["FHQ_TT_taskname_%1", _taskName], _task, true];
  377.  
  378. _taskObjects = _taskObjects + [_task];
  379. } forEach _currentUnits;
  380.  
  381. _taskObjects;
  382. };
  383.  
  384. /* Internal */
  385. FHQ_TT_addTaskEntries =
  386. {
  387. private ["_currentUnits", "_tasks", "_count", "_i", "_current", "_state"];
  388. _currentUnits = _this select 0;
  389. _tasks = _this select 1;
  390. _count = count _tasks;
  391.  
  392. if (_count > 0) then
  393. {
  394. if (FHQ_TT_is_arma3) then
  395. {
  396. for [ {_i = 0}, {_i < _count}, {_i = _i + 1}] do
  397. {
  398. _current = _tasks select _i;
  399. _state = "created";
  400.  
  401. // Optional state
  402. if (count _current >= 6) then
  403. {
  404. _state = _current select 5;
  405. };
  406.  
  407. // fifth element is either an object/position, or a string. In the latter case,
  408. // object/position was ommited but initial state given
  409. if (count _current >= 5) then
  410. {
  411. if (typename (_current select 4) == "STRING") then
  412. {
  413. _state = _current select 4;
  414. };
  415. };
  416.  
  417. FHQ_TT_TaskList = FHQ_TT_TaskList + [[_currentUnits, _current, _state]];
  418. };
  419. }
  420. else
  421. {
  422. for [ {_i = _count - 1}, {_i >= 0}, {_i = _i - 1}] do
  423. {
  424. _current = _tasks select _i;
  425. _state = "created";
  426.  
  427. // Optional state
  428. if (count _current >= 6) then
  429. {
  430. _state = _current select 5;
  431. };
  432.  
  433. // fifth element is either an object/position, or a string. In the latter case,
  434. // object/position was ommited but initial state given
  435. if (count _current >= 5) then
  436. {
  437. if (typename (_current select 4) == "STRING") then
  438. {
  439. _state = _current select 4;
  440. };
  441. };
  442.  
  443. FHQ_TT_TaskList = FHQ_TT_TaskList + [[_currentUnits, _current, _state]];
  444. };
  445. }
  446. };
  447. };
  448.  
  449. /* FHQ_TT_addTasks: Add tasks to the mission
  450. *
  451. * write me
  452. *
  453. */
  454. FHQ_TT_addTasks =
  455. {
  456. private ["_numEntries", "_unitPool", "_currentUnits", "_currentTaskList", "_current"];
  457.  
  458. if (!isServer) exitWith {};
  459.  
  460. _numEntries = count _this;
  461. if (_numEntries <= 0) exitWith {};
  462.  
  463. //_unitPool = (if (isMultiplayer) then {playableUnits} else {switchableUnits});
  464. //_currentUnits = _unitPool;
  465. _currentTaskList = [];
  466.  
  467. for "_i" from 0 to (_numEntries - 1) do
  468. {
  469. _current = _this select _i;
  470.  
  471. if (typename _current == "ARRAY") then
  472. {
  473. _currentTaskList = _currentTaskList + [_current];
  474. }
  475. else
  476. {
  477. // Parameter is a filter for the units.
  478. if (_i != 0) then
  479. {
  480. //_unitPool = _unitPool - _currentUnits;
  481. };
  482.  
  483. if (count _currentTaskList > 0) then
  484. {
  485. [_currentUnits, _currentTaskList] call FHQ_TT_addTaskEntries;
  486. _currentTaskList = [];
  487. };
  488.  
  489. //_currentUnits = [_current, _unitPool] call FHQ_TT_filterUnits;
  490. _currentUnits = _current;
  491. };
  492. };
  493.  
  494. if (count _currentTaskList > 0) then
  495. {
  496. [_currentUnits, _currentTaskList] call FHQ_TT_addTaskEntries;
  497. };
  498.  
  499. // Send task list to clients
  500. publicVariable "FHQ_TT_TaskList";
  501. if (!isDedicated) then
  502. {
  503. FHQ_TT_TaskList call FHQ_TT_UpdateTaskList;
  504. };
  505.  
  506. FHQ_TT_initialized = true;
  507. publicVariable "FHQ_TT_initialized";
  508.  
  509. };
  510.  
  511. FHQ_TT_hasTask =
  512. {
  513. private "_result";
  514.  
  515. _result = false;
  516.  
  517. {
  518. if ((_x call FHQ_TT_getTaskName) == _this) exitWith {_result = true;};
  519. } forEach FHQ_TT_ClientTaskList;
  520.  
  521. _result;
  522. };
  523.  
  524.  
  525. FHQ_TT_taskHint =
  526. {
  527. if (!FHQ_TT_is_arma3) then
  528. {
  529. /* Arma 2 */
  530. private ["_desc", "_state", "_color", "_icon", "_text"];
  531.  
  532. _desc = _this select 0;
  533. _state = _this select 1;
  534.  
  535. _color = [1, 1, 1, 1];
  536. _icon = "taskNew";
  537. _text = "New Task";
  538.  
  539. switch (tolower(_state)) do
  540. {
  541. case "created":
  542. {
  543. _color = [1, 1, 1, 1];
  544. _icon = "taskNew";
  545. _text = localize "str_taskNew";
  546. };
  547. case "assigned":
  548. {
  549. _color = [1, 1, 1, 1];
  550. _icon = "taskCurrent";
  551. _text = localize "str_taskSetCurrent";
  552. };
  553. case "succeeded":
  554. {
  555. _color = [0.600000,0.839215,0.466666,1];
  556. _icon = "taskDone";
  557. _text = localize "str_taskAccomplished";
  558. };
  559. case "canceled":
  560. {
  561. _color = [0.75,0.75,0.75,1];
  562. _icon = "taskFailed";
  563. _text = localize "str_taskCancelled";
  564. };
  565. case "cancelled":
  566. {
  567. _color = [0.75,0.75,0.75,1];
  568. _icon = "taskFailed";
  569. _text = localize "str_taskCancelled";
  570. };
  571. case "failed":
  572. {
  573. _color = [0.972549,0.121568,0,1];
  574. _icon = "taskFailed";
  575. _text = localize "str_taskFailed";
  576. };
  577. };
  578.  
  579. taskHint [format ["%1\n%2", _text, _desc], _color, _icon];
  580. }
  581. else
  582. {
  583. /* Arma 3 */
  584. private ["_notifyTemplate", "_desc", "_state"];
  585.  
  586. _desc = _this select 0;
  587. _state = _this select 1;
  588.  
  589. switch (tolower _state) do
  590. {
  591. case "created":
  592. {
  593. _notifyTemplate = "TaskCreated";
  594. };
  595. case "assigned":
  596. {
  597. _notifyTemplate = "TaskAssigned";
  598. };
  599. case "succeeded":
  600. {
  601. _notifyTemplate = "TaskSucceeded";
  602. };
  603. case "canceled":
  604. {
  605. _notifyTemplate = "TaskCanceled";
  606. };
  607. case "cancelled":
  608. {
  609. _notifyTemplate = "TaskCanceled";
  610. };
  611. case "failed":
  612. {
  613. _notifyTemplate = "TaskFailed";
  614. };
  615. };
  616.  
  617. [_notifyTemplate, ["", _desc]] call BIS_fnc_showNotification;
  618. };
  619. };
  620.  
  621.  
  622. FHQ_TT_UpdateTaskList =
  623. {
  624. if (isDedicated) exitWith {};
  625.  
  626. private ["_count", "_i", "_tasks"];
  627. _tasks = _this;
  628. _count = count _tasks;
  629.  
  630. _unitPool = (if (isMultiplayer) then {playableUnits} else {switchableUnits});
  631.  
  632. if (_count > 0) then
  633. {
  634. for [ {_i = 0}, {_i < _count}, {_i = _i + 1}] do
  635. {
  636. private ["_current", "_currentUnits", "_taskObjects", "_currentTask",
  637. "_currentTaskState", "_currentTaskName", "_currentTaskParent"];
  638. _current = _tasks select _i; // [units, taskDesc, state]
  639. _currentTask = _current select 1; // [name|[name,parent], text, title, waypoint, object/position]
  640. _currentUnits = _current select 0;
  641. _currentTaskState = _current select 2;
  642. _currentTaskName = "";
  643. _currentTaskParent = "";
  644.  
  645. _currentUnits = [_currentUnits, _unitPool] call FHQ_TT_filterUnits;
  646.  
  647. if (typename (_currentTask select 0) == "ARRAY") then
  648. {
  649. _currentTaskName = (_currentTask select 0) select 0;
  650. _currentTaskParent = (_currentTask select 0) select 1;
  651. }
  652. else
  653. {
  654. _currentTaskName = _currentTask select 0;
  655. };
  656.  
  657. if (_currentTaskName call FHQ_TT_hasTask) then
  658. {
  659. private ["_localTask", "_x", "_task"];
  660.  
  661. _localTask = FHQ_TT_ClientTaskList select _i; // [name, state, objects]
  662. diag_log format["_localTask -> %1, _curent -> %2", _localTask select 1, _current select 2];
  663. if ((_current select 2) != (_localTask select 1)) then
  664. {
  665. // Update the task
  666. _localTask set [1, _current select 2];
  667. FHQ_TT_ClientTaskList set [_i, _localTask];
  668.  
  669. if (player in (_currentUnits)) then
  670. {
  671. [_currentTask select 2, _current select 2] call FHQ_TT_taskHint;
  672. };
  673.  
  674. {
  675. _task = _x;
  676. if (_current select 2 == "assigned") then
  677. {
  678. {
  679. if (_task in (simpletasks _x)) then
  680. {
  681. _x setCurrentTask _task;
  682. };
  683. } forEach _currentUnits;
  684. };
  685. _task setTaskState (_current select 2);
  686. } forEach (_localTask select 2);
  687. };
  688. }
  689. else
  690. {
  691. _taskObjects = [_currentUnits, _currentTask, _currentTaskState] call FHQ_TT_createSimpleTask;
  692. FHQ_TT_ClientTaskList set [_i, [(_current select 1), _currentTaskState, _taskObjects]];
  693. if (player in (_currentUnits) && !FHQ_TT_supressTaskHints) then
  694. {
  695. [_currentTask select 2, _currentTaskState] call FHQ_TT_taskHint;
  696. };
  697.  
  698. };
  699. };
  700. };
  701. };
  702.  
  703. /* FHQ_TT_setTaskState: Set state of a specific task
  704. *
  705. * write me
  706. *
  707. * [_taskName, _state] call FHQ_TT_setTaskState;
  708. */
  709.  
  710. FHQ_TT_setTaskState =
  711. {
  712. if (!isServer) exitWith {};
  713.  
  714. private ["_count", "_taskName", "_newState", "_i", "_curTask"];
  715.  
  716. _count = count FHQ_TT_TaskList;
  717. _taskName = _this select 0;
  718. _newState = _this select 1;
  719.  
  720. for [ {_i = 0}, {_i < _count}, {_i = _i + 1}] do
  721. {
  722. _curTask = FHQ_TT_TaskList select _i;
  723. diag_log format["_curTask = %1", _curTask];
  724.  
  725. //if (_taskName == ((_curTask select 1) select 0)) exitWith
  726. if (_taskName == ([_curTask select 1] call FHQ_TT_getTaskName)) exitWith
  727. {
  728. _curTask set [2, _newState];
  729. FHQ_TT_TaskList set [_i, _curTask];
  730. };
  731. };
  732.  
  733. publicVariable "FHQ_TT_TaskList";
  734. if (!isDedicated) then
  735. {
  736. FHQ_TT_TaskList call FHQ_TT_UpdateTaskList;
  737. };
  738. };
  739.  
  740.  
  741. /* FHQ_TT_getTaskState: Get state of a specific task
  742. *
  743. * write me
  744. *
  745. * _result = [_taskName] call FHQ_TT_getTaskState;
  746. */
  747. FHQ_TT_getTaskState =
  748. {
  749. private ["_result", "_taskName"];
  750.  
  751. _result = "";
  752. _taskName = _this select 0;
  753.  
  754. {
  755. // if (((_x select 1) select 0) == _taskname) exitWith
  756. if (([_x select 1] call FHQ_TT_getTaskName) == _taskname) exitWith
  757. {
  758. _result = (_x select 2);
  759. };
  760. } forEach FHQ_TT_TaskList;
  761.  
  762. _result;
  763. };
  764.  
  765. /* FHQ_TT_isTaskCompleted: Check whether a task is canceled, successful or failed
  766. *
  767. * _result = [_taskName] call FHQ_TT_isTaskCompleted;
  768. */
  769. FHQ_TT_isTaskCompleted =
  770. {
  771. private "_result";
  772.  
  773. _result = (tolower(_this call FHQ_TT_getTaskState) in ["succeeded", "canceled", "failed"]);
  774.  
  775. _result;
  776. };
  777.  
  778. /* FHQ_TT_areTasksCompleted: Check for all tasks given whether they are cancelled, successful, or failed
  779. * _result = [_taskName1, _taskName2, ...] call FHQ_TT_areTasksCompleted
  780. */
  781. FHQ_TT_areTasksCompleted =
  782. {
  783. private ["_result", "_x"];
  784.  
  785. _result = true;
  786.  
  787. {
  788. if (!(tolower ([_x] call FHQ_TT_getTaskState) in ["succeeded", "canceled", "failed"])) exitWith
  789. {
  790. _result = false;
  791. };
  792. } forEach _this;
  793.  
  794. _result;
  795. };
  796.  
  797. /* FHQ_TT_isTaskSuccessful: Check whether a task is ended successfully
  798. *
  799. * _result = [_taskName] call FHQ_TT_isTaskSuccessful;
  800. */
  801. FHQ_TT_isTaskSuccessful =
  802. {
  803. private "_result";
  804.  
  805. _result = (tolower(_this call FHQ_TT_getTaskState) == "succeeded");
  806.  
  807. _result;
  808. };
  809.  
  810. /* FHQ_TT_areTasksSuccessful: Check success for all tasks given
  811. * _result = [_taskName1, _taskName2, ...] call FHQ_TT_areTasksSuccessful
  812. */
  813. FHQ_TT_areTasksSuccessful =
  814. {
  815. private ["_result", "_x"];
  816.  
  817. _result = true;
  818.  
  819. {
  820. if (tolower ([_x] call FHQ_TT_getTaskState) != "succeeded") exitWith
  821. {
  822. _result = false;
  823. };
  824. } forEach _this;
  825.  
  826. _result;
  827. };
  828.  
  829.  
  830. /* FHQ_TT_getAllTasksWithState: Get all tasks with a given state
  831. *
  832. * _taskList = [_state] call FHQ_TT_getAllTasksWithState;
  833. */
  834. FHQ_TT_getAllTasksWithState =
  835. {
  836. private ["_result", "_taskState"];
  837.  
  838. _result = [];
  839. _taskState = _this select 0;
  840.  
  841. {
  842. if ((_x select 2) == _taskState) then
  843. {
  844. _result = _result + [(_x select 1) select 0];
  845. };
  846. } forEach FHQ_TT_TaskList;
  847.  
  848. _result;
  849. };
  850.  
  851. /* FHQ_TT_markTaskAndNext: Mark a task as completed, and look for the next
  852. * open task.
  853. *
  854. * ["taskName", "state", ("newTask1", "newTask2" ... )] call FHQ_TT_markTaskAndNext;
  855. */
  856. FHQ_TT_markTaskAndNext =
  857. {
  858. private "_i";
  859. [_this select 0, _this select 1] call FHQ_TT_setTaskState;
  860.  
  861. for [ {_i = 2}, {_i < count _this}, {_i = _i + 1} ] do
  862. {
  863. if (!([_this select _i] call FHQ_TT_isTaskCompleted)) exitWith
  864. {
  865. [_this select _i, "assigned"] call FHQ_TT_setTaskState;
  866. };
  867. };
  868.  
  869. };
  870.  
  871. /* ------------ End of file, calling init ------------ */
  872. call FHQ_TT_init;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement