ZZEZ 10 Posted March 1, 2011 Hey. I am trying to create a mission similar to domination where you complete objectives and then you get the next one. How can I create a system that takes all the templates I created[each is a script with units/triggers/end condition in it], randomly select one and then remove it from the system of eligible missions?I am really clueless here - I looked at the domination files and I was overwhelmed by it It really doesn't have to be something complex, just selecting a random script from a folder that are all named "missionXX.sqf" with XX being numbers..any ideas? Share this post Link to post Share on other sites
shuko 45 Posted March 1, 2011 (edited) There are many ways to do this. So, let's start with one. Example mission init.sqf or wherever you want to start it if isserver then { ["_tasks","_rnd","_tsk","_sh"]; _tasks = ["killgeneral","blowupcar","killspy"]; while {count _tasks > 0} do { _rnd = floor random count _tasks; _tsk = _tasks select _rnd; _tsk = _tsk + ".sqf"; _tasks set [_rnd,0]; _tasks = _tasks - [0]; _sh = execvm _tsk; waituntil {scriptdone _sh}; }; }; The tasks are the filenames, they can be whatever you want. An sqf extension will be added to them. So, "blowupcar" will actually be a file named "blowupcar.sqf". Here's an example what it could contain: car = "Lada1" createvehicle (getpos player); waituntil {damage car > 0.7}; deletevehicle car; The key here is to have the waituntil, which acts as an end/complete trigger. PS. I know you will next wonder how the hell you are going to get the (briefing) tasks to show up. ;) Edited March 1, 2011 by Shuko Share this post Link to post Share on other sites
ZZEZ 10 Posted March 1, 2011 Thanks I got that working, now about the briefing/tasks...how do I go about doing that?:) Share this post Link to post Share on other sites
shuko 45 Posted March 1, 2011 There as well you have options. Either use a script to handle them: Multiplayer Framework by BIS Multitask by Deadfast (with LazyTasks by TangoCharlie) Taskmaster by me Or just do something like this: if !isdedicated then { ZEZZ_fnc_RandomTask = { switch (tolower _this) do { case "killgeneral": { tskKillgeneral = player createsimpletask ["killgeneral"]; tskKillgeneral setsimpletaskdescription ["kill general","kill general",""]; }; case "blowupcar": { tskBlowupcar = player createsimpletask ["blowupcar"]; tskBlowupcar setsimpletaskdescription ["blowup car","blowup car",""]; }; case "killspy": { tskKillspy = player createsimpletask ["killspy"]; tskKillspy setsimpletaskdescription ["kill spy","kill spy",""]; }; }; }; "ZEZZ_RandomTask" addpublicvariableeventhandler { (_this select 1) call ZEZZ_fnc_RandomTask; }; }; if isserver then { ["_tasks","_rnd","_tsk","_sh"]; _tasks = ["killgeneral","blowupcar","killspy"]; while {count _tasks > 0} do { _rnd = floor random count _tasks; _tsk = _tasks select _rnd; ZEZZ_RandomTask = _tsk; _tsk = _tsk + ".sqf"; _tasks set [_rnd,"DELETE"]; _tasks = _tasks - ["DELETE"]; _sh = execvm _tsk; publicvariable "ZEZZ_RandomTask"; if !isdedicated then { ZEZZ_RandomTask call ZEZZ_fnc_RandomTask; }; waituntil {scriptdone _sh}; }; }; task.sqf car = "Lada1" createvehicle (getpos player); waituntil {damage car > 0.7}; deletevehicle car; tskBlowupcar settaskstate "succeeded"; Share this post Link to post Share on other sites
ZZEZ 10 Posted March 1, 2011 Er I'm overwhelmed again sorry to keep bothering you but...for the sake of standardization, "modular" how can I add the task settings to the mission file itself?I'm planning on having something like 25 mini-missions and it would be easier to edit 1 file for the entire mission instead of spreading it if you know what I mean. Right now my init.con calls for start.sqf which is this: if isserver then { ["_tasks","_rnd","_tsk","_sh"]; _tasks = ["missions\mission1","missions\mission2","missions\mission3"]; while {count _tasks > 0} do { _rnd = floor random count _tasks; _tsk = _tasks select _rnd; _tsk = _tsk + ".sqf"; _tasks set [_rnd,"DELETE"]; _tasks = _tasks - ["DELETE"]; _sh = execvm _tsk; waituntil {scriptdone _sh}; }; }; example of mission2, bottom is end conditions //======WMD container around mid-city setAccTime 0.0; _this = createCenter east; _center_0 = _this; _group_0 = createGroup _center_0; _unit_0 = objNull; if (true) then { _this = _group_0 createUnit ["TK_INS_Soldier_AA_EP1", [4899.6626, 4611.8809], [], 0, "CAN_COLLIDE"]; _unit_0 = _this; _this setVehicleInit "nul=[this,""fortify2"",""fortify"",""spawned"",""delete:"",600] execvm ""scripts\UPSMON.sqf"";"; _this setUnitAbility 0.60000002; if (true) then {_group_0 selectLeader _this;}; }; _unit_1 = objNull; if (true) then { _this = _group_0 createUnit ["TK_INS_Soldier_AR_EP1", [4900.3032, 4614.1289], [], 0, "CAN_COLLIDE"]; _unit_1 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_0 selectLeader _this;}; }; _unit_2 = objNull; if (true) then { _this = _group_0 createUnit ["TK_INS_Bonesetter_EP1", [4897.6172, 4610.626], [], 0, "CAN_COLLIDE"]; _unit_2 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_0 selectLeader _this;}; }; _unit_3 = objNull; if (true) then { _this = _group_0 createUnit ["TK_INS_Soldier_MG_EP1", [4895.394, 4611.2754], [], 0, "CAN_COLLIDE"]; _unit_3 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_0 selectLeader _this;}; }; _unit_4 = objNull; if (true) then { _this = _group_0 createUnit ["TK_INS_Soldier_2_EP1", [4903.2227, 4613.9854], [], 0, "CAN_COLLIDE"]; _unit_4 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_0 selectLeader _this;}; }; _unit_5 = objNull; if (true) then { _this = _group_0 createUnit ["TK_INS_Soldier_EP1", [4893.6499, 4612.8516], [], 0, "CAN_COLLIDE"]; _unit_5 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_0 selectLeader _this;}; }; _unit_6 = objNull; if (true) then { _this = _group_0 createUnit ["TK_INS_Soldier_4_EP1", [4898.6177, 4614.5078], [], 0, "CAN_COLLIDE"]; _unit_6 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_0 selectLeader _this;}; }; _unit_7 = objNull; if (true) then { _this = _group_0 createUnit ["TK_INS_Soldier_3_EP1", [4902.4351, 4616.4971], [], 0, "CAN_COLLIDE"]; _unit_7 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_0 selectLeader _this;}; }; _unit_8 = objNull; if (true) then { _this = _group_0 createUnit ["TK_INS_Soldier_AAT_EP1", [4895.0933, 4616.9961], [], 0, "CAN_COLLIDE"]; _unit_8 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_0 selectLeader _this;}; }; _unit_9 = objNull; if (true) then { _this = _group_0 createUnit ["TK_INS_Soldier_AT_EP1", [4900.061, 4618.502], [], 0, "CAN_COLLIDE"]; _unit_9 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_0 selectLeader _this;}; }; _unit_10 = objNull; if (true) then { _this = _group_0 createUnit ["TK_INS_Warlord_EP1", [4902.4697, 4610.2222], [], 0, "CAN_COLLIDE"]; _unit_10 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_0 selectLeader _this;}; }; _vehicle_0 = objNull; if (true) then { _this = createVehicle ["Land_Misc_Cargo2E_EP1", [4903.0615, 4621.8687, 4.529953e-005], [], 0, "CAN_COLLIDE"]; _vehicle_0 = _this; _this setDir 86.722115; _this setVehicleVarName "container1"; container1 = _this; _this setPos [4903.0615, 4621.8687, 4.529953e-005]; }; _vehicle_3 = objNull; if (true) then { _this = createVehicle ["DSHKM_Ins", [4898.3481, 4606.7627, 3.4809113e-005], [], 0, "CAN_COLLIDE"]; _vehicle_3 = _this; _this setDir 187.20621; _this setPos [4898.3481, 4606.7627, 3.4809113e-005]; }; _vehicle_5 = objNull; if (true) then { _this = createVehicle ["DSHKM_Ins", [4889.854, 4617.2217, 2.0980835e-005], [], 0, "CAN_COLLIDE"]; _vehicle_5 = _this; _this setDir 92.154259; _this setPos [4889.854, 4617.2217, 2.0980835e-005]; }; _group_1 = createGroup _center_0; _unit_11 = objNull; if (true) then { _this = _group_1 createUnit ["TK_INS_Soldier_AA_EP1", [4882.7275, 4618, 0], [], 0, "CAN_COLLIDE"]; _unit_11 = _this; _this setVehicleInit "nul=[this,""patrol2"",""spawned"",""delete:"",600] execvm ""scripts\UPSMON.sqf"";"; _this setUnitAbility 0.60000002; if (true) then {_group_1 selectLeader _this;}; }; _unit_12 = objNull; if (true) then { _this = _group_1 createUnit ["TK_INS_Soldier_AR_EP1", [4879.7305, 4616.0977, 0], [], 0, "CAN_COLLIDE"]; _unit_12 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_1 selectLeader _this;}; }; _unit_13 = objNull; if (true) then { _this = _group_1 createUnit ["TK_INS_Bonesetter_EP1", [4879.8457, 4618.9795, 0], [], 0, "CAN_COLLIDE"]; _unit_13 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_1 selectLeader _this;}; }; _unit_14 = objNull; if (true) then { _this = _group_1 createUnit ["TK_INS_Soldier_MG_EP1", [4883.3613, 4615.3486, 0], [], 0, "CAN_COLLIDE"]; _unit_14 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_1 selectLeader _this;}; }; _unit_15 = objNull; if (true) then { _this = _group_1 createUnit ["TK_INS_Soldier_2_EP1", [4884.8604, 4618, 0], [], 0, "CAN_COLLIDE"]; _unit_15 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_1 selectLeader _this;}; }; _unit_16 = objNull; if (true) then { _this = _group_1 createUnit ["TK_INS_Soldier_EP1", [4878.001, 4618.5762, 0], [], 0, "CAN_COLLIDE"]; _unit_16 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_1 selectLeader _this;}; }; _unit_17 = objNull; if (true) then { _this = _group_1 createUnit ["TK_INS_Soldier_4_EP1", [4882.7275, 4622.0923, 0], [], 0, "CAN_COLLIDE"]; _unit_17 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_1 selectLeader _this;}; }; _unit_18 = objNull; if (true) then { _this = _group_1 createUnit ["TK_INS_Soldier_3_EP1", [4883.8228, 4620.4204, 0], [], 0, "CAN_COLLIDE"]; _unit_18 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_1 selectLeader _this;}; }; _unit_19 = objNull; if (true) then { _this = _group_1 createUnit ["TK_INS_Soldier_AAT_EP1", [4880.0762, 4621.458, 0], [], 0, "CAN_COLLIDE"]; _unit_19 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_1 selectLeader _this;}; }; _unit_20 = objNull; if (true) then { _this = _group_1 createUnit ["TK_INS_Soldier_AT_EP1", [4877.7705, 4621.228, 0], [], 0, "CAN_COLLIDE"]; _unit_20 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_1 selectLeader _this;}; }; _this = createMarker ["fortify2", [4901.1519, 4613.3667, 0]]; _this setMarkerShape "RECTANGLE"; _this setMarkerType "Flag"; _this setMarkerBrush "Solid"; _this setMarkerSize [70, 70]; _marker_0 = _this; _this = createMarker ["patrol2", [4912.2881, 4620.6465, 0]]; _this setMarkerShape "RECTANGLE"; _this setMarkerType "Flag"; _this setMarkerBrush "Solid"; _this setMarkerSize [150, 150]; _marker_1 = _this; _this = createTrigger ["EmptyDetector", [4906.0273, 4625.5317, 0]]; _this setTriggerArea [0, 0, 0, false]; _this setTriggerStatements ["!alive container1", "execVM ""missionend\mission2complete.sqf""; deleteVehicle mission2trig;", ""]; mission2trig = _this; _trigger_0 = _this; _this = createMarker ["mission2marker", [4903.0029, 4618.5093]]; _this setMarkerText "WMD Container"; _this setMarkerType "Flag"; _this setMarkerBrush "Solid"; _marker_2 = _this; processInitCommands;setAccTime 1; waituntil {sleep 3; !alive mission2trig}; Share this post Link to post Share on other sites
shuko 45 Posted March 1, 2011 Yeah, as I said you have plenty of options. :P One of the reasons why I made Taskmaster was to be able to control all the tasks easily from server only. init.sqf [] call compile preprocessfile "shk_taskmaster.sqf"; if isserver then { ["_path","_tasks","_rnd","_tsk","_sh"]; _path = "missions\"; _tasks = ["mission1","mission2","mission3"]; while {count _tasks > 0} do { _rnd = floor random count _tasks; _tsk = _tasks select _rnd; _tsk = _path + _tsk + ".sqf"; _tasks set [_rnd,"DELETE"]; _tasks = _tasks - ["DELETE"]; _sh = execvm _tsk; waituntil {scriptdone _sh}; }; }; mission1.sqf ["mission1","mission 1","kill general"] call SHK_Taskmaster_add; createcenter east; general = (creategroup east) createunit ["RU_Soldier_Officer", getpos player, [], 0, "FORM"]; waituntil {!alive general}; deletevehicle general; ["mission1","succeeded"] call SHK_Taskmaster_upd; shk_taskmaster.sqf Seems that the webserver or something as having problems, so here it is for copy-paste: /* == TASKMASTER =============================================================================== Version 0.30 Author: Shuko (shuko@quakenet, miika@miikajarvinen.fi) == Creating a briefing ======================================================================= Tasks and notes are given in the init.sqf. Syntax: [[[Task1Data],[Task2Data]],[[Note1Data],[Note2Data]]] execvm "shk_taskmaster.sqf"; Example: [[ ["Task1","Task1Title","Task1Desc"], ["Task2","Task2Title","Task2Desc",true,["markerTask2",getpos obj2]] ],[ ["Note1","Hello West",WEST], ["Note2","Hello East",EAST], ["Credits","<br />Made by: Shuko of LDD Kyllikki<br />Contact: shuko@Quakenet<br />www.kyllikki.fi"] ]] execvm "shk_taskmaster.sqf"; -- Task Data --------------------------------------------------------------------------------- ["TaskName","Title","Description",Condition,[Marker],"State"] Required parameters: TaskName string Name used to refer to the task Title string Task name shown in the in/game task list Description string Task description, the actual text body Optional parameters: Condition boolean/side/faction/unit/group/string Units the task is added to. Default is everyone Marker array Marker related to the task. It will be created only for the units who have the task. Marker will be hidden after task is completed. Name string Name of the marker to create. Position string Position of the marker. Type string Marker type. Optional, default is "selector_selectedMission". Color string Marker color. Optional, default is red. State string Task state of the newly created task. Default is "created". Destination object/position/marker Place to create task destination (game's built-in waypoint/marker). If an object is given, setSimpleTaskTarget command is used, attaching the destination to it. - Condition - It's possible to specify which units (groups, side etc) you want to create the tasks/notes for. Examples: [...,WEST] All playable units on BLUFOR (WEST) [...,"USMC"] Faction USMC [...,grpMarine1] Units that belong to group named grpMarine1 [...,myDude] Unit named myDude Then there is the IF syntax, so you can create a condition anyway you want, where _x is the unit (=player). Examples: "((group _x == grpScouts) OR (_x == pilot1))" Members of grpScouts and unit named pilot1 "(typeof _x == ""CDF_Soldier_Sniper"")" All CDF snipers -- Note Data --------------------------------------------------------------------------------- [NoteTitle,NoteText,Condition] Required parameters: NoteTitle string Text shown in the list NoteText string The actual note text body Optional parameters: Condition boolean/side/faction/unit/group/string Units the note is added to. Default is everyone. == Updating tasks ============================================================================ Task states are updated by calling a function. Possible states are: succeeded/failed/canceled/assigned/created. Example: ["Task1","succeeded"] call SHK_Taskmaster_upd; It's possible to set state of one task and set another as assigned using an optional 3rd parameter. Example: ["Task1","succeeded","Task2"] call SHK_Taskmaster_upd; This will make task state of task Task1 to succeeded and the state of the task Task2 as assigned. Another optional 3rd parameter can be used to add a new task after updating another task. Example: ["Task1","succeeded",["Task2","Title","Desc"]] call SHK_Taskmaster_upd; This will make task Task1 as succeeded and create a new task Task2. Same set of parameters is used for the creation as in init.sqf or SHK_Taskmaster_add. == Creating tasks during a mission =========================================================== Tasks can be added after briefing with the add function. Same set of parameters is used as in creating a briefing. Example: ["Task2","Extraction","Get to teh choppa!"] call SHK_Taskmaster_add; == Checking task status ====================================================================== SHK_Taskmaster_isCompleted This function can be used to check if a task is completed. Task is considered completed with states succeeded, failed and canceled. Function returns a boolean (true/false) value. Example: "Task1" call SHK_Taskmaster_isCompleted SHK_Taskmaster_getAssigned Returns list of tasks which have "assigned" as their state. Example: call SHK_Taskmaster_getAssigned Example result: ["Task1","Task4"] SHK_Taskmaster_getState Returns the task state (succeeded/failed/canceled/assigned/created). Example: "Task1" call SHK_Taskmaster_getState SHK_Taskmaster_hasState Checks if a task's state matches the given state. Function returns a boolean value. Example: ["Task1","succeeded"] call SHK_Taskmaster_hasState SHK_Taskmaster_hasTask Checks if a task with the given name has been created. Returns boolean. Example: "Task1" call SHK_Taskmaster_hasTask SHK_Taskmaster_addNote (client only) Creates a briefing note. This can only be used on client side, and it's not boardcasted for other players. Parameters: ["Title","TextBody",Condition] Condition is optional. Example: Example: ["Enemy forces","Oh noes, there will be enemy soldiers in the area of operation."] call SHK_Taskmaster_addNote == Version history ====================================================================== 0.30 Added: Parameter to create task destination. 0.29 Added: Last task to be added will be made current task automatically. 0.28 Fixed: Markers of completed tasks were not hidden for JIPs. 0.27 Fixed: Attempt to prevent double tasks from being added when the add parameter is used with the update function. 0.26 Added: Script can be called without parameters, just to load the functions for later use. 0.25 Changed: 1.55 patch changed note addition order to same as tasks. Code changed to keep the old way of adding them. 0.24 Changed: Marker handling. Hiding/showing has been removed and replaced with local marker creation. 0.23 Added: Support for Single Player missions. Mainly to enable tasks in the SP mission editor preview. 0.22 Changed: Made add, assign and update functions useable in triggers without getting undefined variable error on clients. 0.21 Changed: Script can now be started with call as well as execvm. 0.20 Added: Support for non-dedicated servers. 0.13 Added: SHK_Taskmaster_initDone variable will be set to true once tasks are processed and functions loaded. 0.12 Fixed: Task updates now wait for player to be alive (after respawn etc). 0.11 Fixed: Missed !isnull player check, which caused problems in marker handling. */ DEBUG = false; /* == COMMON =================================================================================== */ SHK_Taskmaster_initDone = false; SHK_Taskmaster_add = { /* Take a task data array, apply default params if needed, save to the task list. Send to clients. In: array ["Name","Title","Desc",[Marker],"State",Destination] Out: */ if isserver then { private ["_name","_short","_long","_cond","_marker","_state","_dest"]; _name = _this select 0; _short = _this select 1; _long = _this select 2; if (count _this > 3) then { _cond = _this select 3 } else { _cond = true }; if (count _this > 4) then { _marker = _this select 4 } else { _marker = [] }; if (count _this > 5) then { _state = _this select 5 } else { _state = "created" }; if (count _this > 6) then { _dest = _this select 6 } else { _dest = 0 }; SHK_Taskmaster_Tasks set [count SHK_Taskmaster_Tasks, [_name,_short,_long,_cond,_marker,_state,_dest]]; publicvariable "SHK_Taskmaster_Tasks"; /* Update for host of the non-dedicated server. */ if (!isdedicated && SHK_Taskmaster_initDone) then { SHK_Taskmaster_Tasks spawn SHK_Taskmaster_handleEvent; }; }; }; SHK_Taskmaster_addNote = { /* Creates a briefing note. In: array ["Title","TextBody",Condition] Out: */ private "_cond"; if (count _this > 2) then { _cond = _this select 2 } else { _cond = true }; { if ( [_x,_cond] call SHK_Taskmaster_checkCond ) then { _x creatediaryrecord ["Diary",[_this select 0,_this select 1]]; if (time > 10) then{ hintsilent "Diary note added." }; }; } foreach (if ismultiplayer then {playableunits} else {switchableunits}); }; SHK_Taskmaster_addTask = { /* Creates the given task for each playableunit and saves the handles. Adds a task array with name, state and handles to the local task list. If marker exists, it will be shown or hidden depending if the unit has the task. In: array ["Name","Title","Desc",[Marker],"State",Destination] */ private ["_handle","_handles","_name","_state","_marker","_dest"]; _handles = []; _name = _this select 0; _marker = _this select 4; _state = _this select 5; _dest = _this select 6; if DEBUG then { diag_log format ["SHK_Taskmaster> addTask: %1, %2, %3, %4",_name,_marker,_state,_dest]}; { if ( [_x,(_this select 3)] call SHK_Taskmaster_checkCond ) then { _handle = _x createsimpletask [_name]; _handle setsimpletaskdescription [(_this select 2),(_this select 1),""]; _handle settaskstate _state; _x setcurrenttask _handle; switch (toupper(typename _dest)) do { case "OBJECT": { _handle setsimpletasktarget [_dest,true] }; case "STRING": { _handle setsimpletaskdestination (getmarkerpos _dest) }; case "ARRAY": { _handle setsimpletaskdestination _dest }; }; _handles set [count _handles,_handle]; if (_x == player) then { if (SHK_Taskmaster_showHints) then { [_handle,_state] call SHK_Taskmaster_showHint }; if (count _marker > 0) then { if !(_state in ["succeeded","failed","canceled"]) then { private ["_m","_t","_c"]; _m = createmarkerlocal [(_marker select 0),(_marker select 1)]; _m setmarkershapelocal "ICON"; _t = if (count _marker > 2) then {(_marker select 2)} else {"selector_selectedMission"}; _m setmarkertypelocal _t; _c = if (count _marker > 3) then {(_marker select 3)} else {"ColorRed"}; _m setmarkercolorlocal _c; }; }; }; }; } foreach (if ismultiplayer then {playableunits} else {switchableunits}); SHK_Taskmaster_TasksLocal set [count SHK_Taskmaster_TasksLocal,[_name,_state,_handles]]; }; SHK_Taskmaster_assign = { /* Changes task's state to assigned. In: string "Name" Out: */ if isserver then { private "_task"; for "_i" from 0 to (count SHK_Taskmaster_Tasks - 1) do { if (_this == ((SHK_Taskmaster_Tasks select _i) select 0)) then { _task =+ SHK_Taskmaster_Tasks select _i; _task set [5,"assigned"]; SHK_Taskmaster_Tasks set [_i,_task]; }; }; publicvariable "SHK_Taskmaster_Tasks"; /* Update for host of the non-dedicated server. */ if (!isdedicated && SHK_Taskmaster_initDone) then { SHK_Taskmaster_Tasks spawn SHK_Taskmaster_handleEvent; }; }; }; SHK_Taskmaster_checkCond = { /* Checks if given unit fulfills the requirement. In: array [unit,Condition] Out: boolean */ private ["_unit","_cond"]; _unit = _this select 0; _cond = _this select 1; if (!isNil "_cond") then { if DEBUG then { diag_log format ["SHK_Taskmaster> typename condition: %1",typename _cond]}; switch (typename _cond) do { case (typename grpNull): { (_unit in (units _cond)) }; case (typename objNull): { _unit == _cond }; case (typename WEST): { (side _unit == _cond) }; case (typename true): { _cond }; case (typename ""): { if (_cond in ["USMC","INS","CDF","RU","CIV","GUE","CIV_RU"]) then { (faction _unit == _cond) } else { (call compile format ["%1",_cond]) }; }; default { false }; }; } else { false }; }; SHK_Taskmaster_getAssigned = { /* Returns list of tasks which have "assigned" as their state. In: Out: array ["TaskName","TaskName"] */ private "_l"; _l = []; { if ((_x select 5) == "assigned") then { _l set [count _l,(_x select 0)]; }; } foreach SHK_Taskmaster_Tasks; _l; }; SHK_Taskmaster_getState = { /* Returns state of the given task. In: string "Name" Out: string "State" */ private "_s"; { if (_this == (_x select 0)) exitwith { _s = (_x select 5); }; } foreach SHK_Taskmaster_Tasks; _s; }; SHK_Taskmaster_handleEvent = { /* Takes the pubvar'd task array and determines if a task needs to be added or updated. In: array SHK_Taskmaster_Tasks from pubvar eventhandler Out: */ waituntil {alive player}; private "_name"; { _name = _x select 0; if (_name call SHK_Taskmaster_hasTaskLocal) then { if ([_name,(_x select 5)] call SHK_Taskmaster_hasStateChanged) then { if DEBUG then { diag_log format ["SHK_Taskmaster> handleEvent calling updateTask: %1",_name]}; _x call SHK_Taskmaster_updateTask; }; } else { if DEBUG then { diag_log format ["SHK_Taskmaster> handleEvent calling addTask: %1",_name]}; _x call SHK_Taskmaster_addTask; }; } foreach _this; }; SHK_Taskmaster_hasState = { /* Checks if given task has a specific state. In: array ["Name","State"] Out: boolean */ private "_b"; _b = false; { if ((_this select 0) == (_x select 0)) then { if (((_this select 0) call SHK_Taskmaster_getState) == (_this select 1)) then { _b = true; }; }; } foreach SHK_Taskmaster_Tasks; _b; }; SHK_Taskmaster_hasStateChanged = { /* Checks if the task state of the given task has changed. In: array ["TaskName","TaskState"] Out: boolean */ private "_b"; _b = false; { if ((_this select 0) == (_x select 0)) then { if ((_this select 1) != (_x select 1)) exitwith { _b = true; }; }; } foreach SHK_Taskmaster_TasksLocal; _b; }; SHK_Taskmaster_hasTask = { /* Checks if task with given name already exists. In: string Task name Out: boolean */ private "_b"; _b = false; { if (_this == (_x select 0)) exitwith { _b = true }; } foreach SHK_Taskmaster_Tasks; _b; }; SHK_Taskmaster_hasTaskLocal = { /* Checks if task with given name already exists. In: string Task name Out: boolean */ private "_b"; _b = false; { if (_this == (_x select 0)) exitwith { _b = true }; } foreach SHK_Taskmaster_TasksLocal; _b; }; SHK_Taskmaster_isCompleted = { private "_b"; _b = false; { if (_this == (_x select 0)) then { if ((_x select 5) in ["succeeded","failed","canceled"]) then { _b = true; }; }; } foreach SHK_Taskmaster_Tasks; _b; }; SHK_Taskmaster_showHint = { private "_p"; _p = switch (tolower (_this select 1)) do { case "created": { [localize "str_taskNew", [1,1,1,1], "taskNew"] }; case "current": { [localize "str_taskSetCurrent", [1,1,1,1], "taskCurrent"] }; case "assigned": { [localize "str_taskSetCurrent", [1,1,1,1], "taskCurrent"] }; case "succeeded": { [localize "str_taskAccomplished", [0.600000,0.839215,0.466666,1.000000], "taskDone"] }; case "failed": { [localize "str_taskFailed", [0.972549,0.121568,0.000000,1.000000], "taskFailed"] }; case "canceled": { [localize "str_taskCancelled", [0.750000,0.750000,0.750000,1.000000], "taskFailed"] }; }; taskHint [format [(_p select 0) + "\n%1", ((taskDescription (_this select 0)) select 1)], (_p select 1), (_p select 2)]; }; SHK_Taskmaster_upd = { /* Take a task data array, update the task list. Send to clients. In: array ["Name","Title","Desc",[Marker],"State"] Out: */ if isserver then { private ["_task","_state"]; _state = (_this select 1); for "_i" from 0 to (count SHK_Taskmaster_Tasks - 1) do { _task =+ (SHK_Taskmaster_Tasks select _i); if ((_task select 0) == (_this select 0)) then { _task set [5,_state]; }; SHK_Taskmaster_Tasks set [_i,_task]; }; if (count _this > 2) then { switch (typename (_this select 2)) do { case (typename ""): { (_this select 2) call SHK_Taskmaster_assign }; case (typename []): { (_this select 2) spawn { sleep 1; _this call SHK_Taskmaster_add} }; }; }; publicvariable "SHK_Taskmaster_Tasks"; /* Update for host of the non-dedicated server. */ if (!isdedicated && SHK_Taskmaster_initDone) then { SHK_Taskmaster_Tasks spawn SHK_Taskmaster_handleEvent; }; }; }; SHK_Taskmaster_updateTask = { /* Updates task state for all playableunits and local task list. Delete marker of completed task. In: array ["Name","Title","Desc",[Marker],"State"] Out: */ private ["_task","_name","_state","_handle","_marker"]; for "_i" from 0 to (count SHK_Taskmaster_TasksLocal - 1) do { _task =+ SHK_Taskmaster_TasksLocal select _i; _name = _task select 0; if (_name == (_this select 0)) then { _marker = _this select 4; _state = _this select 5; _task set [1,_state]; SHK_Taskmaster_TasksLocal set [_i,_task]; { _handle = _x; { if (_handle in (simpletasks _x)) then { _handle settaskstate _state; if (_x == player) then { if (SHK_Taskmaster_showHints) then { [_handle,_state] call SHK_Taskmaster_showHint }; if (count _marker > 0) then { if (_state in ["succeeded","failed","canceled"]) then { if DEBUG then { diag_log format ["SHK_Taskmaster> updateTask deleting marker: %1, state: %2",_marker,_state]}; deletemarkerlocal (_marker select 0); }; }; }; }; } foreach (if ismultiplayer then {playableunits} else {switchableunits}); } foreach (_task select 2); }; }; }; /* == SERVER =================================================================================== */ if isserver then { SHK_Taskmaster_Tasks = []; // Array member: ["Name","Title","Desc","Marker","State"] /* Iterate through the tasks received from init.sqf and add them to an array. Then send it to clients. */ if (!isnil "_this") then { if (count _this > 0) then { private ["_task","_tasks","_i"]; _tasks = _this select 0; for [{_i=(count _tasks - 1)},{_i>-1},{_i=_i-1}] do { (_tasks select _i) call SHK_Taskmaster_add; }; }; }; publicvariable "SHK_Taskmaster_Tasks"; if DEBUG then { diag_log "-- SHK_Taskmaster_Tasks --"; diag_log SHK_Taskmaster_Tasks; }; }; /* == CLIENT =================================================================================== */ if !isdedicated then { SHK_Taskmaster_showHints = false; SHK_Taskmaster_TasksLocal = []; // Array member: ["TaskName","TaskState",TaskHandles] /* If any notes given in init.sqf, simply add them. */ if (!isnil "_this") then { if (count _this > 1) then { private ["_notes","_i"]; _notes = _this select 1; for [{_i=(count _notes - 1)},{_i>-1},{_i=_i-1}] do { (_notes select _i) call SHK_Taskmaster_addNote; }; }; }; /* Initially wait for server to send the task list for briefing. After briefing is created, add an eventhandler to catch the updated task list server might send. Wait for briefing tasks to be created before enabling taskhints. This prevents hints from briefing tasks from being spammed at the start of the mission. */ [] spawn { waituntil {!isnull player}; waituntil {!isnil "SHK_Taskmaster_Tasks"}; private "_sh"; _sh = SHK_Taskmaster_Tasks spawn SHK_Taskmaster_handleEvent; waituntil {scriptdone _sh}; SHK_Taskmaster_showHints = true; SHK_Taskmaster_initDone = true; "SHK_Taskmaster_Tasks" addpublicvariableeventhandler { (_this select 1) spawn SHK_Taskmaster_handleEvent; }; }; }; Share this post Link to post Share on other sites
ZZEZ 10 Posted March 1, 2011 Exactly what I needed - many thanks for your help and patience :) Share this post Link to post Share on other sites
cool=azroul13 12 Posted March 1, 2011 Nice :cool: , It's what I need!! But I have an issue: I launch the sqf which contain your script via my init.sqf. I launch my mission, one of my side mission begin, I go to the location when the same mission is launched. it's like the script don't wait and continue to choose a side mission. :( Aze Share this post Link to post Share on other sites
shuko 45 Posted March 1, 2011 Could you be a bit more specific about whats happening? The script in the form it's above will choose one mission right at the start, when that is completed it creates another without delay. Share this post Link to post Share on other sites
ZZEZ 10 Posted March 2, 2011 I just added a sleep 60; at the start of each mission file for smoothness, make sure you have waituntill condition thats actually valid Share this post Link to post Share on other sites
ZZEZ 10 Posted March 2, 2011 shk I just finished testing on dedicated server, the tasks won't show up at all, not at startup or after completing them...any ideas? init calling start.sqf which is this [] call compile preprocessfile "shk_taskmaster.sqf"; if isserver then { ["_path","_tasks","_rnd","_tsk","_sh"]; _path = "missions\"; _tasks = ["mission1","mission2","mission3","mission4","mission5"]; while {count _tasks > 0} do { _rnd = floor random count _tasks; _tsk = _tasks select _rnd; _tsk = _path + _tsk + ".sqf"; _tasks set [_rnd,"DELETE"]; _tasks = _tasks - ["DELETE"]; _sh = execvm _tsk; waituntil {scriptdone _sh}; }; }; mission example: sleep 60; //============grad truck at gas station ["mission5","Insurgent held park","The insurgents have occupied a local park, clear it from insurgents in order to reclaim it"] call SHK_Taskmaster_add; setAccTime 0.0; _this = createCenter east; _center_0 = _this; _group_0 = createGroup _center_0; _unit_0 = objNull; if (true) then { _this = _group_0 createUnit ["TK_INS_Soldier_AA_EP1", [3589.7229, 5312.5596], [], 0, "CAN_COLLIDE"]; _unit_0 = _this; _this setVehicleInit "nul=[this,""fortify5"",""fortify"",""spawned"",""delete:"",600] execvm ""scripts\UPSMON.sqf"";"; _this setUnitAbility 0.60000002; if (true) then {_group_0 selectLeader _this;}; }; _unit_1 = objNull; if (true) then { _this = _group_0 createUnit ["TK_INS_Soldier_AR_EP1", [3592.2351, 5312.2769, -2.5272369e-005], [], 0, "CAN_COLLIDE"]; _unit_1 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_0 selectLeader _this;}; }; _unit_2 = objNull; if (true) then { _this = _group_0 createUnit ["TK_INS_Soldier_AR_EP1", [3595.5427, 5312.3008, -1.4305115e-006], [], 0, "CAN_COLLIDE"]; _unit_2 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_0 selectLeader _this;}; }; _unit_3 = objNull; if (true) then { _this = _group_0 createUnit ["TK_INS_Bonesetter_EP1", [3594.356, 5316.418, 1.6689301e-005], [], 0, "CAN_COLLIDE"]; _unit_3 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_0 selectLeader _this;}; }; _unit_4 = objNull; if (true) then { _this = _group_0 createUnit ["TK_INS_Soldier_MG_EP1", [3594.4648, 5318.1196, 1.6212463e-005], [], 0, "CAN_COLLIDE"]; _unit_4 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_0 selectLeader _this;}; }; _unit_5 = objNull; if (true) then { _this = _group_0 createUnit ["TK_INS_Soldier_2_EP1", [3591.4585, 5316.9424, 1.0490417e-005], [], 0, "CAN_COLLIDE"]; _unit_5 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_0 selectLeader _this;}; }; _unit_6 = objNull; if (true) then { _this = _group_0 createUnit ["TK_INS_Soldier_2_EP1", [3592.6047, 5315.4902, 7.1525574e-006], [], 0, "CAN_COLLIDE"]; _unit_6 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_0 selectLeader _this;}; }; _unit_7 = objNull; if (true) then { _this = _group_0 createUnit ["TK_INS_Soldier_EP1", [3597.2141, 5316.29, -3.3378601e-006], [], 0, "CAN_COLLIDE"]; _unit_7 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_0 selectLeader _this;}; }; _unit_8 = objNull; if (true) then { _this = _group_0 createUnit ["TK_INS_Soldier_EP1", [3599.1047, 5315.8169, -3.5762787e-005], [], 0, "CAN_COLLIDE"]; _unit_8 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_0 selectLeader _this;}; }; _unit_9 = objNull; if (true) then { _this = _group_0 createUnit ["TK_INS_Soldier_EP1", [3599.373, 5312.4326, -5.2452087e-006], [], 0, "CAN_COLLIDE"]; _unit_9 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_0 selectLeader _this;}; }; _unit_10 = objNull; if (true) then { _this = _group_0 createUnit ["TK_INS_Soldier_EP1", [3595.0732, 5310.5825, 5.7220459e-006], [], 0, "CAN_COLLIDE"]; _unit_10 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_0 selectLeader _this;}; }; _unit_11 = objNull; if (true) then { _this = _group_0 createUnit ["TK_INS_Soldier_EP1", [3592.9707, 5310.5454, -6.1988831e-006], [], 0, "CAN_COLLIDE"]; _unit_11 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_0 selectLeader _this;}; }; _unit_12 = objNull; if (true) then { _this = _group_0 createUnit ["TK_INS_Soldier_AT_EP1", [3593.5457, 5309.1538, -4.7683716e-007], [], 0, "CAN_COLLIDE"]; _unit_12 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_0 selectLeader _this;}; }; _unit_13 = objNull; if (true) then { _this = _group_0 createUnit ["TK_INS_Soldier_AT_EP1", [3591.6531, 5310.6855, -4.7683716e-006], [], 0, "CAN_COLLIDE"]; _unit_13 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_0 selectLeader _this;}; }; _this = createTrigger ["EmptyDetector", [3600.6663, 5320.4233]]; _this setTriggerArea [300, 300, 0, false]; _this setTriggerActivation ["EAST", "NOT PRESENT", false]; _this setTriggerStatements ["this", "execVM ""missionend\mission5complete.sqf""; deleteVehicle mission5trig", ""]; mission5trig = _this; _trigger_0 = _this; _group_1 = createGroup _center_0; _unit_15 = objNull; if (true) then { _this = _group_1 createUnit ["TK_INS_Warlord_EP1", [3651.9268, 5346.2979, 0], [], 0, "CAN_COLLIDE"]; _unit_15 = _this; _this setVehicleInit "nul=[this,""patrol5"",""spawned"",""delete:"",600] execvm ""scripts\UPSMON.sqf"";"; _this setUnitAbility 0.60000002; if (true) then {_group_1 selectLeader _this;}; }; _unit_16 = objNull; if (true) then { _this = _group_1 createUnit ["TK_INS_Soldier_AT_EP1", [3657.0874, 5347.3823, 0], [], 0, "CAN_COLLIDE"]; _unit_16 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_1 selectLeader _this;}; }; _unit_17 = objNull; if (true) then { _this = _group_1 createUnit ["TK_INS_Soldier_AT_EP1", [3652.6907, 5341.5938, 0], [], 0, "CAN_COLLIDE"]; _unit_17 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_1 selectLeader _this;}; }; _unit_18 = objNull; if (true) then { _this = _group_1 createUnit ["TK_INS_Soldier_4_EP1", [3656.428, 5344.3789, 0], [], 0, "CAN_COLLIDE"]; _unit_18 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_1 selectLeader _this;}; }; _unit_19 = objNull; if (true) then { _this = _group_1 createUnit ["TK_INS_Soldier_4_EP1", [3647.7813, 5342.4731, 0], [], 0, "CAN_COLLIDE"]; _unit_19 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_1 selectLeader _this;}; }; _unit_20 = objNull; if (true) then { _this = _group_1 createUnit ["TK_INS_Soldier_2_EP1", [3645.2168, 5345.8438, 0], [], 0, "CAN_COLLIDE"]; _unit_20 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_1 selectLeader _this;}; }; _unit_21 = objNull; if (true) then { _this = _group_1 createUnit ["TK_INS_Soldier_AR_EP1", [3648.9536, 5354.2705, 0], [], 0, "CAN_COLLIDE"]; _unit_21 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_1 selectLeader _this;}; }; _unit_22 = objNull; if (true) then { _this = _group_1 createUnit ["TK_INS_Soldier_AR_EP1", [3642.2854, 5353.3911, 0], [], 0, "CAN_COLLIDE"]; _unit_22 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_1 selectLeader _this;}; }; _unit_23 = objNull; if (true) then { _this = _group_1 createUnit ["TK_INS_Soldier_AR_EP1", [3647.488, 5350.3135, 0], [], 0, "CAN_COLLIDE"]; _unit_23 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_1 selectLeader _this;}; }; _unit_24 = objNull; if (true) then { _this = _group_1 createUnit ["TK_INS_Soldier_AR_EP1", [3655.4019, 5352.439, 0], [], 0, "CAN_COLLIDE"]; _unit_24 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_1 selectLeader _this;}; }; _unit_25 = objNull; if (true) then { _this = _group_1 createUnit ["TK_INS_Soldier_AR_EP1", [3653.79, 5354.1235, 0], [], 0, "CAN_COLLIDE"]; _unit_25 = _this; _this setUnitAbility 0.60000002; if (false) then {_group_1 selectLeader _this;}; }; _this = createMarker ["fortify5", [3607.5349, 5300.8101]]; _this setMarkerShape "RECTANGLE"; _this setMarkerType "Flag"; _this setMarkerBrush "Solid"; _this setMarkerSize [170, 100]; _this setMarkerDir 82.254807; _marker_2 = _this; _this = createMarker ["patrol5", [3606.5471, 5316.8262]]; _this setMarkerShape "ELLIPSE"; _this setMarkerType "Flag"; _this setMarkerBrush "Solid"; _this setMarkerSize [300, 300]; _marker_3 = _this; _this = createMarker ["mission5marker", [3616.5964, 5308.6582, 0]]; _this setMarkerType "Flag"; _this setMarkerBrush "Solid"; _marker_4 = _this; processInitCommands;setAccTime 1; waituntil {sleep 3; !alive mission5trig;}; //set task complete ["mission5","succeeded"] call SHK_Taskmaster_upd; Share this post Link to post Share on other sites
shuko 45 Posted March 2, 2011 Well, what can I say. These work fine for me on dedi: Test mission [] call compile preprocessfile "shk_taskmaster.sqf"; if isserver then { ["_path","_tasks","_rnd","_tsk","_sh"]; _path = "missions\"; _tasks = ["mission1","mission2","mission3"]; while {count _tasks > 0} do { _rnd = floor random count _tasks; _tsk = _tasks select _rnd; _tsk = _path + _tsk + ".sqf"; _tasks set [_rnd,"DELETE"]; _tasks = _tasks - ["DELETE"]; _sh = execvm _tsk; waituntil {scriptdone _sh}; }; }; sleep 1; ["mission1","mission 1","kill general"] call SHK_Taskmaster_add; createcenter east; general = (creategroup east) createunit ["RU_Soldier_Officer", getpos posHpad, [], 0, "FORM"]; waituntil {!alive general}; deletevehicle general; ["mission1","succeeded"] call SHK_Taskmaster_upd; sleep 1; ["mission2","mission 2","car must go boom"] call SHK_Taskmaster_add; car = "Lada1" createvehicle (getpos posHpad); waituntil {damage car > 0.7}; deletevehicle car; ["mission2","succeeded"] call SHK_Taskmaster_upd; sleep 1; ["mission3","mission 3","kill the damn spy"] call SHK_Taskmaster_add; spy = (creategroup west) createunit ["USMC_Soldier_Light", getpos posHpad, [], 0, "FORM"]; waituntil {!alive spy}; deletevehicle spy; ["mission3","succeeded"] call SHK_Taskmaster_upd; Share this post Link to post Share on other sites
ZZEZ 10 Posted March 2, 2011 I did some tests and found out the problem. It seems if you use the following lines not in the init.con it will cause the tasks not to show up [] call compile preprocessfile "shk_taskmaster.sqf"; if isserver then { ["_path","_tasks","_rnd","_tsk","_sh"]; _path = "missions\"; _tasks = ["mission1","mission2","mission3","mission4","mission5"]; while {count _tasks > 0} do { _rnd = floor random count _tasks; _tsk = _tasks select _rnd; _tsk = _path + _tsk + ".sqf"; _tasks set [_rnd,"DELETE"]; _tasks = _tasks - ["DELETE"]; _sh = execvm _tsk; waituntil {scriptdone _sh}; }; }; I placed it in init.con instead of start.sqf[init.con calling it with isserver check] and the tasks are now showing. Oh well...the init.con will now be less tidy :) Share this post Link to post Share on other sites
shuko 45 Posted March 2, 2011 [] call compile preprocessfile "shk_taskmaster.sqf"; Needs to be run on server AND on clients. Rest can be on server only, just make sure that line is run before you start selecting missions. Share this post Link to post Share on other sites
ZZEZ 10 Posted March 2, 2011 aha..so thats why it was working on local, got it. Share this post Link to post Share on other sites
cool=azroul13 12 Posted May 14, 2011 if isserver then { ["_tasks","_rnd","_tsk","_sh"]; _tasks = ["killgeneral","blowupcar","killspy"]; while {count _tasks > 0} do { _rnd = floor random count _tasks; _tsk = _tasks select _rnd; _tsk = _tsk + ".sqf"; _tasks set [_rnd,0]; _tasks = _tasks - [0]; _sh = execvm _tsk; waituntil {scriptdone _sh}; }; }; Hi Shuko, Is there a possibility to add a condition like only two mission can be choose in the array ? And when the two side missions is finished the "general mission" is finished too? Thanks Aze Share this post Link to post Share on other sites