// NextBotIntentionInterface.cpp
// Interface for intentional thinking
// Author: Michael Booth, November 2007
//========= Copyright Valve Corporation, All rights reserved. ============//

#include "cbase.h"

#include "NextBotInterface.h"
#include "NextBotIntentionInterface.h"

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"


//------------------------------------------------------------------------------------------------------------------------
/**
 * Given a subject, return the world space position we should aim at
 */
Vector IIntention::SelectTargetPoint( const INextBot *me, const CBaseCombatCharacter *subject ) const
{
	for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) )
	{
		const IContextualQuery *query = dynamic_cast< const IContextualQuery * >( sub );
		if ( query )
		{
			// return the response of the first responder that gives a definitive answer
			Vector result = query->SelectTargetPoint( me, subject );
			if ( result != vec3_origin )
			{
				return result;
			}
		}
	}	

	// no answer, use a reasonable position
	Vector threatMins, threatMaxs;
	subject->CollisionProp()->WorldSpaceAABB( &threatMins, &threatMaxs );
	Vector targetPoint = subject->GetAbsOrigin();
	targetPoint.z += 0.7f * ( threatMaxs.z - threatMins.z );

	return targetPoint;
}


//------------------------------------------------------------------------------------------------------------------------
/**
 * Given two threats, decide which one is more dangerous
 */
const CKnownEntity *IIntention::SelectMoreDangerousThreat( const INextBot *me, const CBaseCombatCharacter *subject, const CKnownEntity *threat1, const CKnownEntity *threat2 ) const
{
	if ( !threat1 || threat1->IsObsolete() )
	{
		if ( threat2 && !threat2->IsObsolete() )
			return threat2;

		return NULL;
	}
	else if ( !threat2 || threat2->IsObsolete() )
	{
		return threat1;
	}

	for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) )
	{
		const IContextualQuery *query = dynamic_cast< const IContextualQuery * >( sub );
		if ( query )
		{
			// return the response of the first responder that gives a definitive answer
			const CKnownEntity *result = query->SelectMoreDangerousThreat( me, subject, threat1, threat2 );
			if ( result )
			{
				return result;
			}
		}
	}

	// no specific decision was made - return closest threat as most dangerous
	float range1 = ( subject->GetAbsOrigin() - threat1->GetLastKnownPosition() ).LengthSqr();
	float range2 = ( subject->GetAbsOrigin() - threat2->GetLastKnownPosition() ).LengthSqr();

	if ( range1 < range2 )
	{
		return threat1;
	}

	return threat2;
}