Task: Difference between revisions
		
		
		
		
		
		Jump to navigation
		Jump to search
		
				
		
	
		
	
| mNo edit summary | m (Added see also) | ||
| (7 intermediate revisions by 2 users not shown) | |||
| Line 1: | Line 1: | ||
| {{npc tut}} | |||
| {{Seealso|For community tasks, see [[Valve Developer Community:Tasks]]}} | |||
| A ''' | 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  | |||
| { | |||
| 	TASK_JUMP = LAST_SHARED_TASK, | |||
| 	TASK_FIND_DODGE_DIRECTION,  | |||
| 	LAST_MY_NPC_TASK, | |||
| }; | |||
| </source> | |||
| After that, the task itself should be declared like this: | |||
| <source lang=cpp> | |||
| AI_BEGIN_CUSTOM_NPC( npc_custom, CNPC_Custom ) | |||
| 	DECLARE_TASK( TASK_FIND_DODGE_DIRECTION ) | |||
| AI_END_CUSTOM_NPC() | |||
| </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: | |||
| <source lang=cpp> | |||
| 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() | |||
| </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>. The schedule will move on to the next task. | |||
| * If the current task has failed, call <code>TaskFail()</code> with an error message. A new schedule will be selected. | |||
| === Example === | |||
| This code makes the NPC play the <code>ACT_MP_JUMP</code> [[activity]] endlessly. | |||
| <source lang=cpp> | |||
| void CNewNPC::StartTask( const Task_t *pTask ) | |||
| < | |||
| { | { | ||
| 	switch (pTask->iTask) | |||
| 	{ | |||
| 	case TASK_MYCUSTOMTASK: | |||
| 		if (FindGestureLayer(ACT_MP_JUMP) == -1) | |||
| 			AddGesture(ACT_MP_JUMP); | |||
| 		TaskComplete(); | |||
| 		break; | |||
| 	default: | |||
| 		BaseClass::StartTask( pTask ); | |||
| 	} | |||
| } | } | ||
| </ | </source> | ||
| === Navigation === | |||
| {{todo}} | |||
| === Animation === | |||
| * [[Animating a model]] | |||
| === Combat === | |||
| {{todo}} | |||
| === Speech === | |||
| * | * [[Response System]] | ||
| * [[Speech semaphore]] | |||
| * [[Choreography creation]] | |||
| == See also == | |||
| * [[Shared tasks]] | |||
| {{navbar|Creating a schedule|Creating an NPC|Giving an NPC Memory}} | |||
| [[Category:AI Programming]] | [[Category:AI Programming]] | ||
Latest revision as of 10:24, 9 May 2023
See also:  For community tasks, see Valve Developer Community:Tasks
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_FIND_DODGE_DIRECTION )
AI_END_CUSTOM_NPC()
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 aswitchstatement that evaluatespTask->iTask. Note:Remember to have a Note:Remember to have adefaultcase that falls back onBaseClass::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(). The schedule will move on to the next task.
- If the current task has failed, call TaskFail()with an error message. A new schedule will be selected.
Example
This code makes the NPC play the ACT_MP_JUMP activity endlessly.
void CNewNPC::StartTask( const Task_t *pTask )
{
	switch (pTask->iTask)
	{
	case TASK_MYCUSTOMTASK:
		if (FindGestureLayer(ACT_MP_JUMP) == -1)
			AddGesture(ACT_MP_JUMP);
		TaskComplete();
		break;
	default:
		BaseClass::StartTask( pTask );
	}
}
[Todo]
Animation
Combat
[Todo]