bool ServerPhysicsCollisionMgr::StartAIStimulusResponse( CollisionResponse& collisionResponse )
{
	// Get the aistimulus record struct.
	HATTRIBUTE hStruct = DATABASE_CATEGORY( CollisionProperty ).GETSTRUCTSTRUCT( Responses, 
		collisionResponse.GetResponses(), collisionResponse.GetResponsesIndex( ), AIStimulusRecord );
	if( !hStruct )
		return false;

	uint32 nIndexFound;
	uint32 nImpulseFound;
	if( !FindImpulseInTable( collisionResponse.GetImpulse( ), hStruct, AIStimulusRecordImpulseAccessCB, nIndexFound, nImpulseFound ))
		return false;

	// Determine the stimulus type.
	HRECORD hStimulus = DATABASE_CATEGORY( CollisionProperty ).GETSTRUCTATTRIB( AIStimulusRecord, hStruct, nIndexFound, Stimulus );
	if( !hStimulus )
		return false;
	const char* pszStimulus = g_pLTDatabase->GetRecordName( hStimulus );
	if( !pszStimulus || !pszStimulus[0] )
		return false;

	// Bail if stimulus does not exist.
	EnumAIStimulusType eStimulus = (EnumAIStimulusType)g_pAIDB->String2BitFlag( pszStimulus, kStim_Count, s_aszStimulusTypes );
	if( eStimulus == kStim_InvalidType )
		return false;

	// Use the generic object alignment set in GDBEdit under AI/Constants.
	EnumCharacterAlignment eAlignment = g_pCharacterDB->String2Alignment(g_pAIDB->GetAIConstantsRecord()->strObjectAlignmentName.c_str());

	// Interpolate the radius of the stimulus.
	float fRadius = FindStimulusRadius( collisionResponse );

	// Bail if either character has sound disabled.
	// This is a hack to prevent AI from generating stimuli.
	// (e.g. at the begining of the FEAR Docks level, where
	// we have a scripted execution scene, and do not want the
	// AI to start investigating when a body hits the ground).
	HOBJECT hActor = collisionResponse.GetCollisionActor()->GetObject();
	HOBJECT hOtherActor = collisionResponse.GetCollisionActor()->GetOtherCollisionActor()->GetObject();

	if( IsCharacter( hActor ) )
	{
		CCharacter* pChar = (CCharacter*)g_pLTServer->HandleToObject( hActor );
		if( pChar && pChar->GetSoundOuterRadius() == 0.f )
		{
			return false;
		}
	}
	if( IsCharacter( hOtherActor ) )
	{
		CCharacter* pChar = (CCharacter*)g_pLTServer->HandleToObject( hOtherActor );
		if( pChar && pChar->GetSoundOuterRadius() == 0.f )
		{
			return false;
		}
	}

	// Register the stimulus.
	StimulusRecordCreateStruct scs( eStimulus, eAlignment, collisionResponse.GetCollisionPoint( ), hActor );
	scs.m_hStimulusTarget = hOtherActor;
	scs.m_flRadiusScalar = fRadius;
	g_pAIStimulusMgr->RegisterStimulus( scs );

#ifndef _FINAL
	uint32 nStatsLevel;
	bool bServer;
	HRECORD hCollisionPropertyFilter = NULL;
	CollisionStatsLevel( nStatsLevel, bServer, hCollisionPropertyFilter );
	if( nStatsLevel > 0 &&
		( !hCollisionPropertyFilter || hCollisionPropertyFilter == collisionResponse.GetCollisionProperty()))
	{
		g_pLTBase->CPrint( "S:  AIStimulus(%s)", pszStimulus );
	}
#endif // _FINAL

	return true;
}