AI Perception Behavior Enhancement: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
m (Syntax highlighting and some cleanup)
No edit summary
Line 3: Line 3:
With the modification below the NPC will investigate the source of the sound instead.
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 <code>SelectAlertSchedule()</code>. Look for the following code:
Open the '''ai_basenpc_schedule.cpp''' file and look for the function <code>SelectIdleSchedule()</code>. Look for the following code:
<source lang=cpp>
<source lang=cpp>
if ( HasCondition ( COND_HEAR_DANGER ) ||
if ( HasCondition( COND_HEAR_DANGER ) ||
  HasCondition ( COND_HEAR_PLAYER ) ||
HasCondition( COND_HEAR_PLAYER ) ||
  HasCondition ( COND_HEAR_WORLD  ) ||
HasCondition( COND_HEAR_WORLD  ) ||
  HasCondition ( COND_HEAR_BULLET_IMPACT ) ||
HasCondition( COND_HEAR_BULLET_IMPACT ) ||
  HasCondition ( COND_HEAR_COMBAT ) )
HasCondition( COND_HEAR_COMBAT ) )
{
{
return SCHED_ALERT_FACE_BESTSOUND;
return SCHED_ALERT_FACE_BESTSOUND;
Line 17: Line 17:
Replace this code with:
Replace this code with:
<source lang=cpp highlight=7>
<source lang=cpp highlight=7>
if ( HasCondition ( COND_HEAR_WORLD  ) ||
HasCondition ( COND_HEAR_PLAYER ) )
{
return SCHED_ALERT_FACE_BESTSOUND;
}
</source>
Look for the function <code>SelectAlertSchedule()</code>. Look for the following code:
<source lang=cpp>
if ( HasCondition( COND_HEAR_DANGER ) ||
if ( HasCondition( COND_HEAR_DANGER ) ||
HasCondition( COND_HEAR_PLAYER ) ||
HasCondition( COND_HEAR_PLAYER ) ||
Line 23: Line 32:
HasCondition( COND_HEAR_COMBAT ) )
HasCondition( COND_HEAR_COMBAT ) )
{
{
return SCHED_INVESTIGATE_SOUND;
return SCHED_ALERT_FACE_BESTSOUND;
}
}
</source>
</source>


Alternate Code:
Replace this code with:
<source lang=cpp>
<source lang=cpp highlight=7>
if ( HasCondition( COND_HEAR_DANGER | COND_HEAR_PLAYER | COND_HEAR_WORLD | COND_HEAR_BULLET_IMPACT | COND_HEAR_COMBAT ) )
if ( HasCondition ( COND_HEAR_BULLET_IMPACT ) ||
    HasCondition ( COND_HEAR_DANGER ) ||  
HasCondition ( COND_HEAR_COMBAT ) )
{
{
return SCHED_INVESTIGATE_SOUND;
return SCHED_INVESTIGATE_SOUND ;
}
}
</source>
Open the '''ai_default.cpp''' file and look for the schedule <code>SCHED_ALERT_FACE_BESTSOUND</code>. Look for the following code:
<source lang=cpp>
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"
);
</source>
Replace this code with:
<source lang=cpp>
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"
);
</source>
Look for the schedule <code>SCHED_INVESTIGATE_SOUND</code>. Look for the following code:
<source lang=cpp>
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"
);
</source>
Replace this code with:
<source lang=cpp>
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"
);
</source>
</source>


==Conclusion==
==Conclusion==
With this code, as soon as NPC hears sounds that meet conditions, they will investigate it.
With this code, NPC will hear sounds and react to them according to their loudness and intensity
{{Warning|This code does not have the changes required to allow AI to hear sounds from prop_physics.}}


[[Category:AI Programming]]
[[Category:AI Programming]]

Revision as of 08:24, 21 November 2021

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.