Schedule: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
m (recategorize)
m (clean up)
Line 1: Line 1:
[[Category:AI Programming]]
[[Category:AI Programming]]
A '''schedule''' is a list of [[Tasks]] the NPC is to perform, a schedule could be to go to a specific location, such as <code>SCHED_FORCED_GO</code> or a schedule to create an attack plan <code>SCHED_PLAN_ATTACK</code>. The NPC's schedule selection is governed by its current [[States|State]] and [[Conditions]].


A Schedule is a list of [[Tasks]] the NPC is to perform, a schedule could be to go to a specific location, such as <code>SCHED_FORCED_GO</code> or a schedule to create an attack plan <code>SCHED_PLAN_ATTACK</code>. The NPC's schedule selection is governed by its current [[States|State]] and [[Conditions]].
==Defining a Schedule==
 
Custom schedules can be added by first declaring a new enum that will define the custom schedules.
Custom schedules can be added by first declaring a new enum that will define the custom schedules.


Line 16: Line 16:
<pre>
<pre>
AI_BEGIN_CUSTOM_NPC( npc_custom, CNPC_Custom )
AI_BEGIN_CUSTOM_NPC( npc_custom, CNPC_Custom )
DEFINE_SCHEDULE
DEFINE_SCHEDULE
(
(
SCHED_DODGE_ENEMY_FIRE,
SCHED_DODGE_ENEMY_FIRE,
 
" Tasks"
" TASK_FIND_DODGE_DIRECTION 3"
" TASK_JUMP 0"
""
" Interrupts"
        "              COND_LIGHT_DAMAGE"
);


" Tasks"
" TASK_FIND_DODGE_DIRECTION 3"
" TASK_JUMP 0"
""
" Interrupts"
        "              COND_LIGHT_DAMAGE"
);
AI_END_CUSTOM_NPC()
AI_END_CUSTOM_NPC()
</pre>
</pre>
Line 37: Line 36:
Some interesting methods are described below that make up <code>CAI_BaseNPC</code> class.
Some interesting methods are described below that make up <code>CAI_BaseNPC</code> class.


==The SelectSchedule() method==  
==SelectSchedule==  


In <code>CAI_BaseNPC</code> the method <code>SelectSchedule()</code> determines what schedule the NPC should run depending on its state and conditions.  
In <code>CAI_BaseNPC</code> the function <code>SelectSchedule()</code> determines what schedule the NPC should run depending on its state and conditions.  


In <code>CAI_BaseNPC</code>, all of the default States are considered, and additional methods are called to select the schedule based on condition, for example, when the NPC is in the <code>NPC_STATE_IDLE</code>, the method <code>SelectIdleSchedule()</code> is called, this method is similar to <code>SelectSchedule()</code>, all it does is select a schedule based on the NPC's state and conditions.  
In <code>CAI_BaseNPC</code>, all of the default States are considered, and additional methods are called to select the schedule based on condition, for example, when the NPC is in the <code>NPC_STATE_IDLE</code>, the method <code>SelectIdleSchedule()</code> is called, this method is similar to <code>SelectSchedule()</code>, all it does is select a schedule based on the NPC's state and conditions.  
Line 55: Line 54:


The following switch statement has been taken from <code>SelectSchedule()</code> in <code>CAI_BaseNPC</code>, it shows how the different variations of schedule selection is chosen depending on the NPC's state.  
The following switch statement has been taken from <code>SelectSchedule()</code> in <code>CAI_BaseNPC</code>, it shows how the different variations of schedule selection is chosen depending on the NPC's state.  


<pre>
<pre>
Line 89: Line 87:
</pre>
</pre>


==The TranslateSchedule() method==
==TranslateSchedule==


This method is called after the schedule selection, it can be used to translate parent NPC schedules to child specific schedules, it's useful if you want to change the default schedules to run your own ones instead.
This function is called after the schedule selection. It can be used to translate parent NPC schedules to child specific schedules. It's useful if you want to change the default schedules to run your own ones instead.


The following code demonstrates how to translate schedules into child specific schedules.
The following code demonstrates how to translate schedules into child specific schedules.
Line 98: Line 96:
int CNPC_Custom::TranslateSchedule( int scheduleType )
int CNPC_Custom::TranslateSchedule( int scheduleType )
{
{
switch( scheduleType )
switch( scheduleType )
{
case SCHED_IDLE_WALK:
{
{
case SCHED_IDLE_WALK:
return SCHED_CUSTOM_IDLE_WALK;
return SCHED_CUSTOM_IDLE_WALK;
break;
break;
}
}
}
return BaseClass::TranslateSchedule( scheduleType );
 
return BaseClass::TranslateSchedule( scheduleType );
}
}
</pre>
</pre>


==Default Schedule List==
==See Also==
SCHED_NONE
* [[Shared schedules]]
 
SCHED_IDLE_STAND
 
SCHED_IDLE_WALK
 
SCHED_IDLE_WANDER
 
SCHED_WAKE_ANGRY
 
SCHED_ALERT_FACE
 
SCHED_ALERT_FACE_BESTSOUND
 
SCHED_ALERT_SCAN
 
SCHED_ALERT_STAND
 
SCHED_ALERT_WALK
 
SCHED_INVESTIGATE_SOUND
 
SCHED_COMBAT_FACE
 
SCHED_COMBAT_SWEEP
 
SCHED_FEAR_FACE
 
SCHED_COMBAT_STAND
 
SCHED_COMBAT_WALK
 
SCHED_CHASE_ENEMY
 
SCHED_CHASE_ENEMY_FAILED
 
SCHED_VICTORY_DANCE
 
SCHED_TARGET_FACE
 
SCHED_TARGET_CHASE
 
SCHED_SMALL_FLINCH
 
SCHED_BIG_FLINCH
 
SCHED_BACK_AWAY_FROM_ENEMY
 
SCHED_BACK_AWAY_FROM_SAVE_POSITION
 
SCHED_TAKE_COVER_FROM_ENEMY
 
SCHED_TAKE_COVER_FROM_BEST_SOUND
 
SCHED_FLEE_FROM_BEST_SOUND
 
SCHED_TAKE_COVER_FROM_ORIGIN
 
SCHED_FAIL_TAKE_COVER
 
SCHED_RUN_FROM_ENEMY
 
SCHED_RUN_FROM_ENEMY_FALLBACK
 
SCHED_MOVE_TO_WEAPON_RANGE
 
SCHED_ESTABLISH_LINE_OF_FIRE
 
SCHED_ESTABLISH_LINE_OF_FIRE_FALLBACK
 
SCHED_PRE_FAIL_ESTABLISH_LINE_OF_FIRE
 
SCHED_FAIL_ESTABLISH_LINE_OF_FIRE
 
SCHED_SHOOT_ENEMY_COVER
 
SCHED_COWER
 
SCHED_MELEE_ATTACK1
 
SCHED_MELEE_ATTACK2
 
SCHED_RANGE_ATTACK1
 
SCHED_RANGE_ATTACK2
 
SCHED_SPECIAL_ATTACK1
 
SCHED_SPECIAL_ATTACK2
 
SCHED_STANDOFF
 
SCHED_ARM_WEAPON
 
SCHED_DISARM_WEAPON
 
SCHED_HIDE_AND_RELOAD
 
SCHED_RELOAD
 
SCHED_AMBUSH
 
SCHED_DIE
 
SCHED_DIE_RAGDOLL
 
SCHED_WAIT_FOR_SCRIPT
 
SCHED_AISCRIPT
 
SCHED_SCRIPTED_WALK
 
SCHED_SCRIPTED_RUN
 
SCHED_SCRIPTED_CUSTOM_MOVE
 
SCHED_SCRIPTED_WAIT
 
SCHED_SCRIPTED_FACE
 
SCHED_SCENE_GENERIC
 
SCHED_NEW_WEAPON
 
SCHED_NEW_WEAPON_CHEAT
 
SCHED_GET_HEALTHKIT
 
SCHED_WAIT_FOR_SPEAK_FINISH
 
 
SCHED_GIVE_WAY
 
SCHED_MOVE_AWAY
 
SCHED_MOVE_AWAY_FAIL
 
SCHED_MOVE_AWAY_END
 
SCHED_FORCED_GO
 
SCHED_FORCED_GO_RUN
 
SCHED_NPC_FREEZE
 
SCHED_PATROL_WALK
 
SCHED_COMBAT_PATROL
 
SCHED_PATROL_RUN
 
SCHED_RUN_RANDOM
 
SCHED_FALL_TO_GROUND
 
SCHED_DROPSHIP_DUSTOFF
 
 
SCHED_FLINCH_PHYSICS
 
 
SCHED_FAIL

Revision as of 18:28, 10 June 2006

A schedule is a list of Tasks the NPC is to perform, a schedule could be to go to a specific location, such as SCHED_FORCED_GO or a schedule to create an attack plan SCHED_PLAN_ATTACK. The NPC's schedule selection is governed by its current State and Conditions.

Defining a Schedule

Custom schedules can be added by first declaring a new enum that will define the custom schedules.

enum
{
     SCHED_DODGE_ENEMY_FIRE = LAST_SHARED_SCHEDULE, 
}

Then we would need to define our custom schedule using the DEFINE_SCHEDULE macro.

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()

When you define a schedule you provide two sections, Tasks and Interrupts.

An Interrupt is a condition that will cause the NPC to break out of the schedule and run a more appropriate one to the given condition and/or state. In this case if the NPC experiences COND_LIGHT_DAMAGE (any damage greater than zero) the NPC will break out of this schedule and play a more appropriate one which would be handled in SelectSchedule() or state specific variants.

Some interesting methods are described below that make up CAI_BaseNPC class.

SelectSchedule

In CAI_BaseNPC the function SelectSchedule() determines what schedule the NPC should run depending on its state and conditions.

In CAI_BaseNPC, all of the default States are considered, and additional methods are called to select the schedule based on condition, for example, when the NPC is in the NPC_STATE_IDLE, the method SelectIdleSchedule() is called, this method is similar to SelectSchedule(), all it does is select a schedule based on the NPC's state and conditions.

Child classes can implement these schedule selection methods to select their own custom schedules based on their own custom conditions.

For instance, we could create our own schedule SCHED_MEDICALPOINT_GO and a condition COND_NEEDS_MEDICAL_ASSISTANCE.

We could implement the schedule selection in SelectSchedule() or a schedule selection method variation as follows

if(HasCondition(COND_NEEDS_MEDICAL_ASSISTANCE)) 
     return SCHED_MEDICALPOINT_GO; 

The following switch statement has been taken from SelectSchedule() in CAI_BaseNPC, it shows how the different variations of schedule selection is chosen depending on the NPC's state.

switch( m_NPCState ) 
{ 
      case NPC_STATE_NONE: 
            DevWarning( 2, "NPC_STATE IS NONE!\n" ); 
            break; 
      
      case NPC_STATE_PRONE: 
            return SCHED_IDLE_STAND; 
      case NPC_STATE_IDLE: 
            AssertMsgOnce( GetEnemy() == NULL, "NPC has enemy but is not in combat state?" ); 
            return SelectIdleSchedule(); 

      case NPC_STATE_ALERT: 
            AssertMsgOnce( GetEnemy() == NULL, "NPC has enemy but is not in combat state?" ); 
            return SelectAlertSchedule(); 

      case NPC_STATE_COMBAT: 
            return SelectCombatSchedule(); 
      
      case NPC_STATE_DEAD: 
            return SelectDeadSchedule(); 

      case NPC_STATE_SCRIPT: 
            return SelectScriptSchedule(); 

      default: 
            DevWarning( 2, "Invalid State for SelectSchedule!\n" ); 
            break; 
} 

TranslateSchedule

This function is called after the schedule selection. It can be used to translate parent NPC schedules to child specific schedules. It's useful if you want to change the default schedules to run your own ones instead.

The following code demonstrates how to translate schedules into child specific schedules.

int CNPC_Custom::TranslateSchedule( int scheduleType )
{
	switch( scheduleType )
	{
		case SCHED_IDLE_WALK:
		{
			return SCHED_CUSTOM_IDLE_WALK;
			break;
		}
	}

	return BaseClass::TranslateSchedule( scheduleType );
}

See Also