Jump to content
Sign in to follow this  
leysard

Randomly choose task and assign to all a team

Recommended Posts

Hy,

I want to assign tasks randomly to a team (Multiplayer).

Say that task 00 starts at the beginning of mission.

When task 00 is finisched, I want to assign to all players a task between task N° 1 to N° 4.

Then when that task is succeeded, assign random task not succeeded out of the 3 left,

then again

then again and that makes all 4 tasks finisched but in different order from one time to another.

I did not find a script and complete explanation to manage that.

Can someone help me out ?

Share this post


Link to post
Share on other sites

I assume you are using an editor trigger to complete the first task. The code I wrote below will run in parallel with the trigger until the first task is completed. Then, the function relies on another trigger to complete the next task, and so on. In you init.sqf, define a function like this:

Zen_AssignRandomTask = {
   /*
   *  Loops through the given array of tasks and uses BIS functions to set
   *  a new random task as current when the current task is failed or succeeded
   *  Params:  1. Array of strings, the task names
   *  Return:  Null
   */
   if !(isServer) exitWith {};
   private ["_taskArray", "_task"];

   _taskArray = _this select 0;
   _task = _taskArray select 0;

   _taskArray = _taskArray - [_task];
   0 = [_task] spawn BIS_fnc_taskSetCurrent;

   while {((count _taskArray) > 0)} do {
       waitUntil {
           sleep 2;
           (([_task] call BIS_fnc_taskState) in ["failed", "succeeded"])
       };

       _task = (_taskArray select (floor (random ((count _taskArray) - 0.0001))));
       _taskArray = _taskArray - [_task];
       0 = [_task] spawn BIS_fnc_taskSetCurrent;
   };
};

You could then call the function from any object's init field in the editor like so:

0 = [["task0", "task1", "task2", "task3", "task4"]] spawn Zen_AssignRandomTask;

You will have to change 'task0' etc to the correct names of your tasks, and this function sets the first task a current for you. This is untested in both singleplayer and multiplayer, as I cannot test it in the context of your mission (actually giving the tasks that this script requires). If it does not work in multiplayer, try removing 'if !(isServer) exitWith {};' from the beginning of the function.

I do not use the BIS task functions very much, so I do not know how well they work in multiplayer or if you need that check. I also assume from briefly looking at the BIS functions about tasks, that the units that get the task set as current are given when calling BIS_fnc_taskCreate and not BIS_fnc_taskSetCurrent. If this does not work in multiplayer, consider looking for tasks systems made by community members, as they might be able to manage tasks better than manually calling BIS functions.

Edited by Zenophon

Share this post


Link to post
Share on other sites

Kylania, Sorry, yes I did search, but not found what I was looking for. Thats the reason of my post.

Zenophon, Thanks for your help, but even if removing line, it does not work. Always goes on to task4 and never moves on to next one. Maybe I'm wrong with the way I built my mission. PM'd the zip file of it so that you could have a look. I would really appreciate.

Thanks, Leysard

Share this post


Link to post
Share on other sites

First, I made an obvious mistake in the example of using the function. It should be 'spawn' not 'call' that is used. I have edited my previous post to reflect that.

Next, looking at your mission and poking around the mission.sqm, I saw that you used my function four times in four task modules. That would create four threads that are looping at the same time, causing odd behavior. To clarify, execute the function only once from a single object's init field in the editor.

Also, I did not find a create task module named 'task00', even when searching for that word in the mission.sqm. However, the call to Zen_AssignRandomTask includes 'task00' as an argument. Make sure you create that task with a module or a script.

Then, I tested in an empty mission to confirm that it worked. I set up four task modules synch'd to the player and used my function and BIS functions in the debug console to test. I found an odd issue with BIS_fnc_taskSetCurrent in which the function redefined the local variable '_task'. I am not sure if there is some error in the function itself or it is a bug. There is some issue with variable scope that I cannot track down in the BIS functions. To fix this, I have used 'spawn' instead of 'call' for BIS_fnc_taskSetCurrent; I have made this change in my previous post. Also note, in my tests I used BIS_fnc_taskSetState to complete the tasks, but I assume that a task state module works the same way.

Finally, I did get the function to work in singleplayer, but I still cannot comment on multiplayer performance.

Edited by Zenophon
typo

Share this post


Link to post
Share on other sites

So, I've been trying several different things to get all that working.

I would like to learn to use correctly Arma 3 Scripting and must recognize that I've got a long way to go.

I had my own try to creating a script that I can call when I want with a trigger for example. But, obviously, it does not work. So, here it is and please, could someone help me make that one work ?

At this point, I just want to be able to randomly select a task in my array. I get the error message at the count point. Later, I will use the selected task to open a file with the scripted task.

if (!isServer) exitwith {};

if (Task != "done")

then {Task = "tasks\Task.sqf";};

if (Task_1 != "done")

then {Task_1 = "tasks\Task_1.sqf";};

if (Task_2 != "done")

then {Task_2 = "tasks\Task_2.sqf";};

if (Task_3 != "done")

then {Task_3 = "tasks\Task_3.sqf";};

if (Task != "done") then

{Tasks = Task;};

if (Task_1 != "done") then

{Tasks = Tasks + Task_1;};

if (Task_2 != "done") then

{Tasks = Tasks + Task_2;};

if (Task_3 != "done") then

{Tasks = Tasks + Task_3;};

SelectedTask = Tasks select (floor (random (count Tasks)));

hint SelectedTask;

Share this post


Link to post
Share on other sites

You are using the variable 'Tasks' like it is an array without declaring it as an array. The error likely indicates that 'count' cannot act on a string. Try this method:

Tasks = [];
Tasks set [(count Tasks), Task];

Declare 'Tasks' before checking to add strings to it, then append the string to the array with 'set'. The 'set' command is also faster than binary addition.

Furthermore, 'Task_1' etc are not defined when being compared to 'done'. I assume that since these are global variables they are being declared elsewhere; it would be helpful if you posted where and how.

Share this post


Link to post
Share on other sites

Zenophon,

Thank you very much for your help, the random Task selector now works perfectly. Regarding the "done" of the global variables, I'm now going to look either to put them in triggers in mission or if i'm going to script them.

I'm planning on creating 1 .sqf file per mission/task, that will be called by triggers or by script going to the random file.

Again thanks for the help

Share this post


Link to post
Share on other sites

If you're using the task system you don't need global variables to keep track of if they are done or not. There are functions to check the state, just compare that to "SUCCEEDED" or not.

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×