Schedule

From Valve Developer Community
Revision as of 14:58, 4 August 2005 by Fluxtah (talk | contribs) (terminology error)
Jump to navigation Jump to search


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.

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.

The SelectSchedule() method

In CAI_BaseNPC the method 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; 
} 

The TranslateSchedule() method

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.

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 );
}

Default Schedule List

SCHED_NONE

SCHED_IDLE_STAND

SCHED_IDLE_WALK

SCHED_IDLE_WANDER

SCHED_WAKE_ANGRY

SCHED_ALERT_FACE

--fluxtah 07:27, 4 Aug 2005 (PDT)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