Creating a task: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
mNo edit summary
No edit summary
Line 1: Line 1:
{{npc tut}}
{{npc tut}}
Custom tasks may be added to your NPC by first declaring a new enum.


<pre>
A '''Task''' is an action that an NPC can perform. [[Schedule]]s will run a list of tasks. Keep tasks as atomic as possible; don't squeeze two distinct actions into the same one.
 
== Creating a task ==
 
Custom tasks are added by first declaring a new enum value.
 
<source lang=cpp>
enum  
enum  
{
{
TASK_JUMP = LAST_SHARED_TASK,
TASK_JUMP = LAST_SHARED_TASK,
        TASK_FIND_DODGE_DIRECTION,
TASK_FIND_DODGE_DIRECTION,  
LAST_MY_NPC_TASK,
};
};
</pre>
</source>


After that, the task should be declared like this:
After that, the task itself should be declared like this:


<pre>
<source lang=cpp>
DECLARE_TASK(TASK_GOOMBA_WALK_STRAIGHT)
AI_BEGIN_CUSTOM_NPC( npc_custom, CNPC_Custom )
</pre>
DECLARE_TASK( TASK_GOOMBA_WALK_STRAIGHT )
<!--- Someone's been playing Super Mario lately eh? --->
AI_END_CUSTOM_SCHEDULE_PROVIDER()
That line goes under AI_BEGIN_CUSTOM_NPC( npc_custom, CNPC_Custom ).
</source>


Then you add the tasks in your custom schedule in the order you want them to execute. See [[Schedule]] for more details on the following code:


Then you would need to add the tasks in your custom schedule in the order you wish them to execute, notice <code>TASK_FIND_DODGE_DIRECTION</code> has been given a value of 3, you can pass data through with your tasks and use them when the task logic is executed.
<source lang=cpp>
 
<pre>
AI_BEGIN_CUSTOM_NPC( npc_custom, CNPC_Custom )
AI_BEGIN_CUSTOM_NPC( npc_custom, CNPC_Custom )
DEFINE_SCHEDULE
DEFINE_SCHEDULE
Line 30: Line 34:
" Tasks"
" Tasks"
" TASK_FIND_DODGE_DIRECTION 3"
" TASK_FIND_DODGE_DIRECTION 3"
" TASK_JUMP 0"
" TASK_JUMP 0"
""
""
" Interrupts"
" Interrupts"
        "               COND_LIGHT_DAMAGE"
      " COND_LIGHT_DAMAGE"
);
)
AI_END_CUSTOM_NPC()
AI_END_CUSTOM_NPC()
</pre>
</source>
 
== Task logic ==
 
Now that everything is set up it's finally time ''to write some actual AI code''.
 
* Tasks are initiated from <code>StartTask(Task_t *pTask)</code>, which should take the form of a <code>[[W:Switch statement#Examples|switch]]</code> statement that evaluates <code>pTask->iTask</code>. {{note|Remember to have a <code>default</code> case that falls back on <code>BaseClass::StartTask()</code>.}}
* Each task has an associated [[float]] value, <code>pTask->flTaskData</code>, which can be used to change its outcome.
* When the current task is complete, call <code>TaskComplete()</code>.
* If the current task has failed, call <code>TaskFail()</code> with an error message.
 
=== Navigation ===
 
{{todo}}


We need to also provide some logic that will be executed for each task, we can do this by overriding the method <code>StartTask( const Task_t *pTask )</code> and <code>RunTask( const Task_t *pTask )</code> of <code>CAI_BaseNPC</code>. As mentioned you can grab the data passed through with the task in these methods by using <code>pTask->flTaskData</code>. An example is shown below.
=== Animation ===


<pre>
{{todo}}
void CNPC_Custom::StartTask( const Task_t *pTask )
 
{
=== Combat ===
switch ( pTask->iTask )
{
case TASK_FIND_DODGE_DIRECTION:
{
if(!FindBestDodgeDirection(pTask->flTaskData))
                        {
                              TaskFail( "TASK_FIND_DODGE_DIRECTION: Unable to find suitable dodge direction\n" );
                        }
                        else
                        {
                              TaskComplete();
                        }
}
break;


case TASK_JUMP:
{{todo}}
{
Jump();
}
break;


default:
{{navbar|Creating a schedule|Creating an NPC|Giving an NPC Memory}}
{
BaseClass::StartTask( pTask );
}
}
}
</pre>
{{navbar|Creating a condition|Creating an NPC|Creating an activity}}
[[Category:AI Programming]]
[[Category:AI Programming]]

Revision as of 11:18, 15 September 2011

A Task is an action that an NPC can perform. Schedules will run a list of tasks. Keep tasks as atomic as possible; don't squeeze two distinct actions into the same one.

Creating a task

Custom tasks are added by first declaring a new enum value.

enum 
{
	TASK_JUMP = LAST_SHARED_TASK,
	TASK_FIND_DODGE_DIRECTION, 
	LAST_MY_NPC_TASK,
};

After that, the task itself should be declared like this:

AI_BEGIN_CUSTOM_NPC( npc_custom, CNPC_Custom )
	DECLARE_TASK( TASK_GOOMBA_WALK_STRAIGHT )
AI_END_CUSTOM_SCHEDULE_PROVIDER()

Then you add the tasks in your custom schedule in the order you want them to execute. See Schedule for more details on the following code:

AI_BEGIN_CUSTOM_NPC( npc_custom, CNPC_Custom )
	DEFINE_SCHEDULE
	(
		SCHED_DODGE_ENEMY_FIRE,

		"	Tasks"
		"		TASK_FIND_DODGE_DIRECTION	3"
		"		TASK_JUMP	0"
		""
		"	Interrupts"
       	"		COND_LIGHT_DAMAGE"
	)
AI_END_CUSTOM_NPC()

Task logic

Now that everything is set up it's finally time to write some actual AI code.

  • Tasks are initiated from StartTask(Task_t *pTask), which should take the form of a switch statement that evaluates pTask->iTask.
    Note.pngNote:Remember to have a default case that falls back on BaseClass::StartTask().
  • Each task has an associated float value, pTask->flTaskData, which can be used to change its outcome.
  • When the current task is complete, call TaskComplete().
  • If the current task has failed, call TaskFail() with an error message.

Navigation

[Todo]

Animation

[Todo]

Combat

[Todo]