Yes you can make new tasks. I'll try to give a comprehensable explanation of the task system (I'm not very good at that

).
All tasks are in the global/jv_bots folder and are prefixed 'task_'. The layout of these scripts is the following:
setup:
end
getpriority:
end (local.priority::local.parm1::local.parm2.....)
evaluate local.parms local.onlyeval:
// necessary since version 1.1
end local.priority
action:
end
These four threads are needed for
any task. They have specific functions which I'll explain below.
To make the bots 'use' our new task, you have to 'install' it. This is done in the following manner (you can add this anywhere in your map script):
waitthead global/jv_bots/jv_mp_ai.scr::addtask [taskname] [basepriority]
Although I used [ and ] these parameters are compulsory. [taskname] defines the name of the script file associated with this task, namely 'task_[taskname].scr'. [basepriority] is a priority modifier applied to all output priorities (discussed later). The basepriorities for the existing tasks are (to give you an idea):
follow 1.5
health 10.0 // pickup medkits
attackbomb 1.0
defendbomb 1.0
sniper 0.1
camp 0.1
machinegun 0.5
Since the final priority value is calculated by multiplying the basepriority value with the output priority value, it's not a good idea to use negative priorities for invalid tasks (a double negative value would result in a positive value).
Now I'll try to explain the functions of the threads in the task scripts. The setup: thread is run immediately after you issued the 'addtask' command. It's not run again after a bot restart. The setup thread is the place to start any handler threads that your task may require. It's also generally the place where the 'route tracer' is added, but I'll just skip explaining that one for now

(will do later).
The getpriority: thread is probably the most complicated thread. It's called from the taskhandler for 'free' bots (these bots may choose their own task). The function of the thread is to return the best parameters for the task for this particular bot (self) at this very moment. Moreover a priority value should be returned, which defines the likeliness of the bot to switch to this task.
Let's take a closer look

:
Code: Select all
// self is the 'free' bot
// just a simple example
// image the bot has to go to the docs
getpriority:
// if there are multiple docs, find the nearest
local.greatest = 0
local.bestdoc = NULL
for(local.i = 1; local.i <= $doc.size; local.i++)
{
local.doc = $doc[local.i]
local.dist = vector_length(local.doc.origin - self.origin)
// always greater than 0
local.inv_dist = 1.0 / local.dist
// always greater than 0 again :)
local.inv_dist > local.greatest)
{
local.greatest = local.inv_dist
local.bestdoc = local.doc
}
}
// likeliness to perform this task only depends on range
local.priority = local.greatest // the nearer the higher
local.parm = local.bestdoc // set the parameters (can be any number of parms)
// need to return this in an array
local.array[1] = local.priority // compulsory
local.array[2] = local.parm // optional
local.array[3] = .... // if you need more parms
// just return this array, the bot script will take it from here :D
end local.array
This array is returned to the bot script for evaluation. If the priority value is high enough, the bot will switch to this task, entering the action: thread. When entering the action: thread, self.task is set to [taskname] and self.parm[1] is set to the second entry of the array returned by the getpriority thread, self.parm[2] to the third and so on (sorry I know it's confusing

)
Code: Select all
// actual action code goes here
action:
// always cast self.parm to local variables, since they may change
// if the bot switches tasks
local.docs = self.parm[1]
// just run to the docs
// this thread automatically exits if the task or parms have changed
self waitthread level.jvbot_main_script::action_go_to_routed local.docs
end
Now there's only one thing left to explain, which is the (new) evaluate thread. This thread is only called from the bot script when a bot is currently executing the task. The evaluate thread is used to decide if the bot should continue doing this task. Usually you can just move some code from the getpriority thread into the evaluate thread to make this work.
Code: Select all
evaluate local.parm local.onlyeval:
local.doc = local.parm[1]
local.dist = vector_length(local.doc.origin - self.origin)
local.inv_dist = 1.0 / local.dist
end local.inv_dist
local.parm contains the entire self.parm array. local.onlyeval is set to 1 if the thread is called from the bot script (this is an optional variable).
Well that's it more or less. I hope I didn't deliver any headaches
