Jump to content
blackout_sti

How to Properly Code Tasks in SQF

Recommended Posts

Hi guys!

So I am desperate. I have been trying for three days to figure out how to make a mission from start to finish using as little of the GUI as possible, while trying to use SQF scripts for as much as possible. Most of the things I have done have gone smoothly. There is a fair amount of documentation provided via the wiki, but there is still quite a few holes (speaking primarily in regards to examples of usage). One of the things that I am having a very hard time figuring out is tasks. I believe all task tutorials I have found have a 'kill target- then yay!'. I have not been able to find hardly anything that explains how to 'chain' tasks, nor have I found much about task notifications (onAssign if you will).

What I want to do:

- Create a task (with setTaskDescription, setTaskDestination, setTaskState, setCurrentTask)

I found a tutorial that used 'createSimpleTask, setSimpleTaskDescription, setSimpleTaskDestination, setTaskState, and setCurrentTask (not sure what this last one does, as it does not seem to have any affect on the mission). In order to achieve this, I had to use the GUI and a series of modules. When I attempted to do this via scripting, I was unable to get the waypoint to display and I could never get the 'task completed' notification to show, nor would it register as being 'complete'.

- Change the task to 'Completed'

I have gotten this far. This is the only part of this process that I was able to do with a script as opposed to the GUI.

- Assign or create a new task when the previous one is 'complete'

Plain and simple, I want the next task to show when I finish the first.

Again, I wish to learn to accomplish this using (exclusively) script. Ideally, I would be able to create the entire mission with scripts... Why, because I'm a programmer, and GUIs are the devil :)

Let's say that it is not possible to do everything I wish to... There is one thing that I really must know- how do I notify the player that a task is assigned? I saw "bis_fnc_shownotification", but it is unclear to me how to use it. (This is one of the things in the wiki that is missing intuitive examples...)

Additional Requirements:

Notifications must display when

- A task is assigned

- A task is succeeded/failed

Please note: The following script does not work 100% the way I expected it to...

//// Create Diary entry (Briefing)
player createDiaryRecord ["Diary", ["Broken Arrow", "Some hooplah here..."]];

//// Task 1 - Rearm (Optional) at AmmoBox_1

Task_1 = player createSimpleTask ["Rearm"];
Task_1 setSimpleTaskDescription ["To be successful in this example task you need to...","Example Task",""];
Task_1 setSimpleTaskDestination (getPos AmmoBox_1);
Task_1 setTaskState "Assigned";
player setCurrentTask Task_1; // This doesn't seem to do anything

// How to complete "Task_1" - Use "AmmoBox_1" to resupply
AmmoBox_1 addEventHandler
[
 "ContainerClosed",
 {
     _taskID = "Task_1";
     [[_taskID,"Succeeded"],"BIS_fnc_taskSetState",side (_this select 1),false,false] call BIS_fnc_MP;
     (_this select 0) removeEventHandler ["ContainerClosed",0];
 }
];

Let's say for the second task, I want to have the player's group "get to da choppa!". I don't know how to create that task (a "get in the ___" task), but if I did, how would I say "Once 'Task_1' is 'complete' then assign 'Task_2'"?

And, furthermore, what is the correct way to to the aforementioned? Should the "Create Tasks" be put in a function (is that even possible?).

I know I seem to keep expanding on my original question, but to be clear, the question is: "How do you properly create and handle tasks in Arma 3 via scripting?

I really appreciate any help available. Thanks for taking the time to read, and thanks in advance for the knowledge!

Share this post


Link to post
Share on other sites

https://community.bistudio.com/wiki/BIS_fnc_setTask

https://community.bistudio.com/wiki/BIS_fnc_taskState

https://community.bistudio.com/wiki/BIS_fnc_taskSetState

Should work:

[
"Rearm",
true,
[
	"To be successful in this example task you need to...",
	"Example Task",
	""
],
(getPos AmmoBox_1),
"AUTOASSIGNED",
5,
true,
true
] call BIS_fnc_setTask;

AmmoBox_1 addEventHandler
[
"ContainerClosed",
{
	[["Rearm","Succeeded"],"BIS_fnc_taskSetState",(side (_this select 1)),false,false] call BIS_fnc_MP;
	(_this select 0) removeEventHandler ["ContainerClosed",0];
}
];

waitUntil {["Rearm"] call BIS_fnc_taskState isEqualTo "Succeeded"};//wait until the first task is complete, then make the second.

[
"Task2",
true,
[
	"To be successful in this example task you need to...",
	"Example Task",
	""
],
(getPos Something),
"CREATED",
5,
true,
true
] call BIS_fnc_setTask;

To answer the bolded question, it's really up to you how to handle them, there are many ways TBH, here are a couple of scripts that do task managing for you:

http://www.armaholic.com/page.php?id=19774

http://www.armaholic.com/page.php?id=21970

EDIT: Quick note, BIS_fnc_setTask has a notification parameter for you to use, reference the wiki I linked above, it also handles all the other needed information as well, it's a great "one-stop-shop" in my opinion.

Edited by JShock

Share this post


Link to post
Share on other sites

JShock, my man, here to help me out again! Right on... Thanks dude. I'll try this stuff out :)

---------- Post added at 06:30 ---------- Previous post was at 06:07 ----------

+1 on the "BIS_fnc_setTask". I really, really wish this was linked on the wiki page (when viewing "createTask"). I though (naturally) that that was how a person would create a task... Go figure.

---------- Post added at 06:40 ---------- Previous post was at 06:30 ----------

Real quick- you are missing a "," after "Example Task" on line 6 (and on the same line later in the script). Also, I see that you have set "showNotification" to "true", yet, there is no notification (that the task is assigned/active/current/whatever). How can I show that notification? I see i in the campaign all the time... The "Task Succeeded" works great. Do I need to call the "bis_fnc_shownotification" to do this? It seems like it would occur with the snippet you gave me :( Is it broken lol?

---------- Post added at 06:44 ---------- Previous post was at 06:40 ----------

Nevermind (unless there is a better way to do this same thing), I found this little gem...

[] spawn { 
 sleep 2; 
 ["TaskAssigned",["","Rearm (Optional)"]] call bis_fnc_showNotification; 
};

Share this post


Link to post
Share on other sites

Sorry about the missing comma (fixed above for future readers), kinda threw it together, where are you calling this script, because if your doing it via the init.sqf the notification may "show" prior to you actually being in game, if that's the issue there should be an easy fix for that (example below), if it isn't called via init.sqf try trying "AUTOASSIGNED" to just assigned/created to see if that solves it.

//put before the call to the script in the init.sqf
waitUntil {!isNull player && time > 3};

I haven't actually look at it, but I'm almost certain BIS_fnc_setTask uses BIS_fnc_showNotification when that parameter is set to true, so it shouldn't be any different.

Edited by JShock

Share this post


Link to post
Share on other sites
Sorry about the missing comma (fixed above for future readers), kinda threw it together, where are you calling this script, because if your doing it via the init.sqf the notification may "show" prior to you actually being in game, if that's the issue there should be an easy fix for that (example below), if it isn't called via init.sqf try trying "AUTOASSIGNED" to just assigned/created to see if that solves it.

//put before the call to the script in the init.sqf
waitUntil {!isNull player && time > 3};

I haven't actually look at it, but I'm almost certain BIS_fnc_setTask uses BIS_fnc_showNotification when that parameter is set to true, so it shouldn't be any different.

I currently have all the different types of scripts separated. Each called from the init.sqf via 'execVM "blah.sqf";'... I did look at the wiki, and you did set the showNotification to 'true'. I was confused as to why it wasn't showing... I just assumed it was another lack of formality in the game engine... But, I bet you are right. I need to insert the code you gave me to make it wait. I have had to do some delaying here and there so that the scripts wait for the mission to load. Is the script above the '$(document).ready()' of SQF (+3 seconds)? It would be great if there was a "BIS_fnc_onAllReady" or something like that... Anyways-

Here is my tasks.sqf:

[
 "Rearm",
 true,
 [
   "Change your loadout at the resupply area",
   "Rearm",
   "Rearm" // Shows above waypoint indicator arrow
 ],
 (getPos AmmoBox_1),
 "AUTOASSIGNED",
 5,
 true,
 true
] call BIS_fnc_setTask;

[] spawn {
 sleep 2;
 ["TaskAssigned",["Make Love","Rearm"]] call bis_fnc_showNotification;
};

AmmoBox_1 addEventHandler
[
   "ContainerClosed",
   {
       [["Rearm","Succeeded"],"BIS_fnc_taskSetState",(side (_this select 1)),false,false] call BIS_fnc_MP;
       (_this select 0) removeEventHandler ["ContainerClosed",0];
   }
];

waitUntil {["Rearm"] call BIS_fnc_taskState isEqualTo "Succeeded"};//wait until the first task is complete, then make the second.

[] spawn {
 ["TaskAssigned",["Ewowgh","Get to da choppa!"]] call bis_fnc_showNotification;
};

[
   "Task2",
   true,
   [
       "Catch a ride to Oreokastro",
       "Get to da choppa!",
       "Move B***h"
   ],
   (getPos Helo_1),
   "CREATED",
   5,
   true,
   true
] call BIS_fnc_setTask;

And my init.sqf:

/// Init for Operation: Broken Arrow

/// Set global counter (with a unique variable name)
bsCounter = 0;

// Environment (Object Positions)
execVM "environment.sqf";

// Tasks
execVM "tasks.sqf";

// Remove fatigue
execVM "removeFatigue.sqf";

// Dialogue
execVM "dialogue.sqf";

// Movements
execVM "movements.sqf";

// onDeath
execVM "onDeath.sqf";

---------- Post added at 05:48 ---------- Previous post was at 05:44 ----------

So if I put the 'waitUntil {!isNull player && time > 3};' at the top of init.sqf, will it delay all the 'execVM' calls, or just the one that immediately follows the 'waitUntil'? I know the answer (I think), just want to check...

Example:

/// Init for Operation: Broken Arrow

waitUntil {!isNull player && time > 3};

/// Set global counter (with a unique variable name)
bsCounter = 0;

// Environment (Object Positions)
execVM "environment.sqf";

// Tasks
execVM "tasks.sqf";

// Remove fatigue
execVM "removeFatigue.sqf";

// Dialogue
execVM "dialogue.sqf";

// Movements
execVM "movements.sqf";

// onDeath
execVM "onDeath.sqf";

Share this post


Link to post
Share on other sites

It will suspend (stop) the script at the line that the waitUntil is at, so anything after it will not be executed until the waitUntil condition is true, anything before it will be executed.

Share this post


Link to post
Share on other sites

@jshock, what about the locality of all of this?  Because the BIKI page doesn't indicate whether you have to call this clientside or serverside.  I know that when I try to do createDiaryLog or whatever the command is, if I do it in the wrong context then it will either not appear or appear twice.  I think that you're supposed to do this all clientside only?

Share this post


Link to post
Share on other sites
31 minutes ago, 4 said:

@jshock, what about the locality of all of this?  Because the BIKI page doesn't indicate whether you have to call this clientside or serverside.  I know that when I try to do createDiaryLog or whatever the command is, if I do it in the wrong context then it will either not appear or appear twice.  I think that you're supposed to do this all clientside only?

Locality of which part, BIS_fnc_setTask?

Share this post


Link to post
Share on other sites
1 hour ago, jshock said:

Locality of which part, BIS_fnc_setTask?

Yeah -- do you call BIS_fnc_setTask serverside (initServer.sqf), clientside (initPlayerLocal.sqf), or what?

Share this post


Link to post
Share on other sites

If you look at this page: https://community.bistudio.com/wiki/BIS_fnc_setTask

 

There is a "isGlobal" option (true by defualt), so it can be ran from any locality, so long as that is set true it will be broadcasted to everyone. It's important to know the targets of the tasks as well.

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

×