AI Perception Behavior Enhancement

From Valve Developer Community
Revision as of 08:24, 21 November 2021 by Catherine (talk | contribs)
Jump to navigation Jump to search

In Half-Life 2, if an idle NPC hears a sound but doesn't see its emitter, it will only turn in the direction of the sound for a bit before returning to its previous action.

With the modification below the NPC will investigate the source of the sound instead.

Open the ai_basenpc_schedule.cpp file and look for the function SelectIdleSchedule(). Look for the following code:

	if ( HasCondition( COND_HEAR_DANGER ) ||
		HasCondition( COND_HEAR_PLAYER ) ||
		HasCondition( COND_HEAR_WORLD  ) ||
		HasCondition( COND_HEAR_BULLET_IMPACT ) ||
		HasCondition( COND_HEAR_COMBAT ) )
	{
		return SCHED_ALERT_FACE_BESTSOUND;
	}

Replace this code with:

if ( HasCondition ( COND_HEAR_WORLD  ) ||
		 HasCondition ( COND_HEAR_PLAYER ) )
	{
		return SCHED_ALERT_FACE_BESTSOUND;
	}

Look for the function SelectAlertSchedule(). Look for the following code:

	if ( HasCondition( COND_HEAR_DANGER ) ||
		HasCondition( COND_HEAR_PLAYER ) ||
		HasCondition( COND_HEAR_WORLD  ) ||
		HasCondition( COND_HEAR_BULLET_IMPACT ) ||
		HasCondition( COND_HEAR_COMBAT ) )
	{
		return SCHED_ALERT_FACE_BESTSOUND;
	}

Replace this code with:

if ( HasCondition ( COND_HEAR_BULLET_IMPACT ) ||	
	     HasCondition ( COND_HEAR_DANGER ) ||		  
		 HasCondition ( COND_HEAR_COMBAT ) ) 	
	{
		return SCHED_INVESTIGATE_SOUND	;
	}

Open the ai_default.cpp file and look for the schedule SCHED_ALERT_FACE_BESTSOUND. Look for the following code:

AI_DEFINE_SCHEDULE
(
	SCHED_ALERT_FACE_BESTSOUND,

	"	Tasks"
	"		TASK_STORE_BESTSOUND_REACTORIGIN_IN_SAVEPOSITION		0"
	"		TASK_STOP_MOVING			0"
	"		TASK_FACE_SAVEPOSITION		0"
	"		TASK_SET_ACTIVITY			ACTIVITY:ACT_IDLE"
	"		TASK_WAIT					1.5"
	"		TASK_FACE_REASONABLE		0"
	""
	"	Interrupts"
	"		COND_NEW_ENEMY"
	"		COND_SEE_FEAR"
	"		COND_LIGHT_DAMAGE"
	"		COND_HEAVY_DAMAGE"
	"		COND_PROVOKED"
);

Replace this code with:

AI_DEFINE_SCHEDULE
(
	SCHED_ALERT_FACE_BESTSOUND,

	"	Tasks"
	"		TASK_STOP_MOVING				0"
	"		TASK_STORE_LASTPOSITION			0"
//	"		TASK_SET_TOLERANCE_DISTANCE		32"
	"		TASK_GET_PATH_TO_BESTSOUND		0"
	"		TASK_FACE_IDEAL					0"
	"		TASK_RUN_PATH					0"
	"		TASK_WAIT_FOR_MOVEMENT			0"
	"		TASK_STOP_MOVING				0"
	"		TASK_WAIT						5"
	"		TASK_GET_PATH_TO_LASTPOSITION	0"
	"		TASK_WALK_PATH					0"
	"		TASK_WAIT_FOR_MOVEMENT			0"
	"		TASK_STOP_MOVING				0"
	"		TASK_CLEAR_LASTPOSITION			0"
	"		TASK_FACE_REASONABLE			0"

	""
	"	Interrupts"
	"		COND_NEW_ENEMY"
	"		COND_SEE_FEAR"
	"		COND_LIGHT_DAMAGE"
	"		COND_HEAVY_DAMAGE"
	"		COND_PROVOKED"
	"		COND_HEAR_BULLET_IMPACT"
	"		COND_HEAR_DANGER"
	"		COND_HEAR_COMBAT"
);

Look for the schedule SCHED_INVESTIGATE_SOUND. Look for the following code:

AI_DEFINE_SCHEDULE
(
	SCHED_INVESTIGATE_SOUND,

	"	Tasks"
	"		TASK_STOP_MOVING				0"
	"		TASK_STORE_LASTPOSITION			0"
//	"		TASK_SET_TOLERANCE_DISTANCE		32"
	"		TASK_GET_PATH_TO_BESTSOUND		0"
	"		TASK_FACE_IDEAL					0"
	"		TASK_RUN_PATH					0"
	"		TASK_WAIT_FOR_MOVEMENT			0"
	"		TASK_STOP_MOVING				0"
	"		TASK_WAIT						5"
	"		TASK_GET_PATH_TO_LASTPOSITION	0"
	"		TASK_WALK_PATH					0"
	"		TASK_WAIT_FOR_MOVEMENT			0"
	"		TASK_STOP_MOVING				0"
	"		TASK_CLEAR_LASTPOSITION			0"
	"		TASK_FACE_REASONABLE			0"
	""
	"	Interrupts"
	"		COND_NEW_ENEMY"
	"		COND_SEE_FEAR"
	"		COND_SEE_ENEMY"
	"		COND_LIGHT_DAMAGE"
	"		COND_HEAVY_DAMAGE"
	"		COND_HEAR_DANGER"
);

Replace this code with:

AI_DEFINE_SCHEDULE
(
	SCHED_INVESTIGATE_SOUND,

	"	Tasks"
	"		TASK_STOP_MOVING				0"
//	"		TASK_SET_TOLERANCE_DISTANCE		32"
	"		TASK_GET_PATH_TO_BESTSOUND		0"
	"		TASK_FACE_IDEAL					0"
	"		TASK_RUN_PATH					0"
	"		TASK_SET_ROUTE_SEARCH_TIME		25"	// Spend 25 seconds trying to build a path if stuck
	"		TASK_GET_PATH_TO_RANDOM_NODE	200"
	"		TASK_RUN_PATH					0"
	"		TASK_TURN_LEFT		45"
	"		TASK_WAIT			2"
	"		TASK_TURN_RIGHT		45"
	"		TASK_WAIT			2"
	
	""
	"	Interrupts"
	"		COND_NEW_ENEMY"
	"		COND_SEE_FEAR"
	"		COND_SEE_ENEMY"
	"		COND_LIGHT_DAMAGE"
	"		COND_HEAVY_DAMAGE"
	"		COND_HEAR_DANGER"
	"		COND_HEAR_COMBAT"
	"		COND_HEAR_PLAYER"
	"		COND_HEAR_BULLET_IMPACT"
);

Conclusion

With this code, NPC will hear sounds and react to them according to their loudness and intensity

Warning.pngWarning:This code does not have the changes required to allow AI to hear sounds from prop_physics.