//////////////////////////////////////////////////////////////////////////////
//
// AVP_Behaviour_GS2Actor.cpp
//
// Copyright (C) 2008 Rebellion. All Rights Reserved.
//
//////////////////////////////////////////////////////////////////////////////

// I N C L U D E S ///////////////////////////////////////////////////////////

// core
#include "Core/Asura.h"

// header
#include "Behaviour/BehaviourTypes/AVP_Behaviour_GS2Actor.h"

// asura
#include "Animation/Asura_AnimationController_Animation.h"
#include "Entity/Locations/OrientedNode/GamesceneNode/Asura_ServerNode_GS2Node.h"
#include "Entity/Locations/OrientedNode/GamesceneNode/AttractorNode/Asura_ServerNode_GS2Attractor.h"
#include "Entity/Locations/Spline/GamesceneSpline/Asura_ServerNode_GS2Spline.h"
#include "Entity/PhysicalObject/Moves/Asura_Moves.h"
#include "Network/Asura_Message.h"
#include "Rendering/Asura_Font_System.h"

// avp
#include "Actor/AVP_Actor_AIAnimStateMachine.h"
#include "Animation/AVP_AnimFlags.h"
#include "Entity/AVP_Entity_Classification.h"
#include "Entity/AVP_Messages.h"
#include "Entity/Locations/OrientedNode/GamesceneNode/AVP_ServerNode_GS2Node.h"
#include "Entity/Locations/Spline/GamesceneSpline/AVP_ServerNode_GS2Spline.h"
#include "Entity/PhysicalObject/Actor/AVP_ClientEntity_Actor.h"
#include "Entity/PhysicalObject/Actor/AVP_ServerEntity_Actor.h"
#include "Entity/PhysicalObject/Actor/Vertebrates/Human/AVP_ServerActor_Human.h"
#include "Inventory/AVP_Inventory_HashIDs.h"
#include "Inventory/AVP_Inventory_System.h"
#include "Moves/AVP_Movement_System.h"
#include "Moves/AVP_Moves.h"

// axon
#include "AnimTemplates/AVP_GS2_AnimPackage.h"
#include "Behaviour/BehaviourTypes/AVP_Behaviour_Types.h"
#include "Behaviour/BehaviourTypes/Alien/AVP_Behaviour_Alien_Movement.h"
#include "Behaviour/BehaviourTypes/AlienQueen/AVP_Behaviour_AlienQueen_GS2Move.h"
#include "Behaviour/BehaviourTypes/FaceHugger/AVP_Behaviour_FaceHugger_Movement.h"
#include "Behaviour/BehaviourTypes/Human/AVP_Behaviour_Human_Movement.h"
#include "Behaviour/BehaviourTypes/Predator/AVP_Behaviour_Predator_GS2Move.h"
#include "Behaviour/BehaviourTypes/Predalien/AVP_Behaviour_Predalien_GS2Move.h"
#include "Core/BrainTypes/AVP_Brain_Actor_Predator.h"
#include "Core/BrainTypes/AVP_Brain_Actor_Civilian.h"
#include "Core/BrainTypes/AVP_Brain_Actor_Marine.h"

//////////////////////////////////////////////////////////////////////////////
//
// AVP_Behaviour_GS2Actor
//
//////////////////////////////////////////////////////////////////////////////

AVP_Behaviour_GS2Actor::AVP_Behaviour_GS2Actor( AVP_Brain_Actor* pxActorBrain )
: PARENT( pxActorBrain )
, m_xLastPositionForMovementDirection( Asura_Maths::ZeroVector3 )
{
}

static void SetActorUseExternalControl( const AVP_Brain_Actor& xBrain, const bool bUseExternalControl )
{
	AVP_Actor_PhysicsObjectHandler* pxPhysicsHandler = NULL;

	if ( xBrain.GetActor() )
	{
		pxPhysicsHandler = xBrain.GetActor()->GetPhysicsObjectHandler();
	}
	else
	{
		// Fall back to the client if we couldn't find the server. Local players only have client-side
		// physics objects at the moment, but can still go on gamescenes
		AVP_ClientEntity_Actor* const pxClientActor = AVP_ClientEntity_Actor::FindEntity( xBrain.GetOwnerGuid() );
		if ( pxClientActor )
		{
			pxPhysicsHandler = pxClientActor->GetPhysicsObjectHandler();
		}
	}

	if ( pxPhysicsHandler )
	{
		if ( bUseExternalControl )
		{
			pxPhysicsHandler->EnableExternalControlPhysics( AVP_PhysicsObjectHandler::ECREQ_GAMESCENE );
		}
		else
		{
			pxPhysicsHandler->DisableExternalControlPhysics( AVP_PhysicsObjectHandler::ECREQ_GAMESCENE );
		}
	}
}

void AVP_Behaviour_GS2Actor::SetOwnerPhysicsToExtControl()
{
	SetActorUseExternalControl( *GetActorBrain(), true );
	if ( GetActorBrain()->GetActor()->GetAIAnimStateMachine() )
	{
		GetActorBrain()->GetActor()->GetAIAnimStateMachine()->RequestInGamescene();
	}
}

void AVP_Behaviour_GS2Actor::ResetOwnerPhysicsFromExtControl()
{
	SetActorUseExternalControl( *GetActorBrain(), false );
	if ( GetActorBrain()->GetActor()->GetAIAnimStateMachine() )
	{
		GetActorBrain()->GetActor()->GetAIAnimStateMachine()->RequestEndGamescene();
	}
}

bool AVP_Behaviour_GS2Actor::SetOwnerPosition( const Asura_Vector_3& xPosition, bool bShouldIgnoreCollisions /*= false*/ )
{
	bool bOK = PARENT::SetOwnerPosition( xPosition, bShouldIgnoreCollisions );

	if ( m_xLastPositionForMovementDirection.ApproximatelyEquals( Asura_Maths::ZeroVector3 ) )
	{
		m_xLastPositionForMovementDirection = xPosition;	
	}
	else if ( !xPosition.ApproximatelyEquals( m_xLastPositionForMovementDirection, 0.5f ) ) // if we've moved a bit from where we were
	{
		Asura_Vector_3 xDir = xPosition - m_xLastPositionForMovementDirection;
		const Asura_Matrix_3x3& xOurOrientM = GetActorBrain()->GetActor()->GetOrientation();

		xDir = xOurOrientM.ApplyTranspose( xDir );
		xDir.y = 0.0f;
		if (!xDir.ApproximatelyEquals(Asura_Maths::ZeroVector3))
		{
			xDir.Normalise();
			xDir = xDir * xOurOrientM;

			GetActorBrain()->SetMovementDirection( xDir );
		}


		m_xLastPositionForMovementDirection = xPosition;
	}

	return bOK;
}

void AVP_Behaviour_GS2Actor::SetOwnerOrientation( const Asura_Matrix_3x3& xOrientation )
{
	PARENT::SetOwnerOrientation( xOrientation );

	// Make sure our anim state machine knows which way we're pointing also.
	const Asura_Vector_3 xLookDirection( xOrientation.e13, xOrientation.e23, xOrientation.e33 );
	GetActorBrain()->SetAimDirection( xLookDirection );
	GetActorBrain()->SetLookAtPosition( GetActorBrain()->GetActor()->GetPosition() + xLookDirection * 10.0f );
}

bool AVP_Behaviour_GS2Actor::GetOwnerAnimationMovementOffset( Asura_Vector_3& xPosition, Asura_Quat& xQOrient ) const
{
	const AVP_ClientEntity_Actor* const pxClientActor = AVP_ClientEntity_Actor::FindEntity( GetBrain()->GetOwnerGuid() );
	if ( !pxClientActor )
	{
		return false;
	}

	const Asura_AnimationController_Animation* pxAACA = NULL;
	const AVP_Move* pxCurrentGSMove = NULL;
	if ( pxClientActor->GetMovementSystem() && pxClientActor->GetMovementSystem()->GetCurrentMove() && pxClientActor->GetMovementSystem()->GetCurrentMove()->GetHash() == AVP_Move_GS2RigidAnim::GetStaticHash() )
	{
		pxCurrentGSMove = static_cast< const AVP_Move* >( pxClientActor->GetMovementSystem()->GetCurrentMove() );
	}

	if ( pxCurrentGSMove && pxCurrentGSMove->GetAVPAnimationData() )
	{
		pxAACA = pxCurrentGSMove->GetAVPAnimationData()->GetAnimationController();
	}
	else
	{
		const Asura_Animation* const pxClientAnimation = pxClientActor->GetShapeInstance().GetAnimation();
		Asura_Assert( pxClientAnimation, "AVP_Behaviour_GS2Actor::GetOwnerAnimationVelocity - cannot find owner animation" );
		if ( pxClientAnimation )
		{
			pxAACA = pxClientAnimation->GetControllerAnimationFromHash( pxClientActor->GetCurrentGamesceneAnimControllerHash() );
		}
	}

	if ( pxAACA )
	{
		return pxAACA->GetMovementOffset( &xPosition, &xQOrient );
	}
	//else
	return false;
}

Axon_Behaviour* AVP_Behaviour_GS2Actor::CreateGetToBehaviour( const GetToBehaviourParams* pxParams /*= NULL*/ )
{
	AVP_ServerEntity_Actor* const pxServerActor = GetActorBrain()->GetActor();

	GetActorBrain()->EstablishNavData();

	Asura_Vector_3 xGetToPosition = Asura_Maths::ZeroVector3;
	Asura_Guid uGS2Guid = ASURA_GUID_UNREGISTERED;
	if ( pxParams )
	{
		if ( pxParams->Contains( GetToBehaviourParams::NODE ) )
		{
			xGetToPosition = pxParams->m_pxNode->GetPosition();
			uGS2Guid = pxParams->m_pxNode->GetGuid();
		}
		
		if ( pxParams->Contains( GetToBehaviourParams::ATTRACTOR ) )
		{
			xGetToPosition = pxParams->m_pxAttractor->GetPosition();
			uGS2Guid = pxParams->m_pxAttractor->GetGuid();
		}
		
		if ( pxParams->Contains( GetToBehaviourParams::POSITION ) )
		{
			xGetToPosition = pxParams->m_xPosition;
		}
		
		if ( pxParams->Contains( GetToBehaviourParams::LINK ) )
		{
			Asura_Assert( false, "AVP_Behaviour_GS2Actor::CreateGetToBehaviour - is this correct?" );
			pxParams->m_pxLink->GetPositionFromProportion( 1.0f, xGetToPosition );
		}
		
	}

    Axon_Behaviour* pxBehaviour = NULL;
	bool bGotRoute = false;
	switch ( pxServerActor->GetClassification() )
	{
		case AVP_ENTITYCLASS_PREDATOR:
		{
			AVP_Behaviour_Predator_GS2Move* pxPredBehaviour =
				static_cast< AVP_Behaviour_Predator_GS2Move* >( GetBrain()->CreateBehaviour( AVP_BEHAVIOUR_TYPE_PREDATOR_GS2MOVE ) );
			if ( pxPredBehaviour && pxParams )
			{
				bGotRoute = pxPredBehaviour->GetToPosition( xGetToPosition );
			}
			pxBehaviour = pxPredBehaviour;
			break;
		}

		case AVP_ENTITYCLASS_PREDALIEN:
			{
				AVP_Behaviour_Predalien_GS2Move* pxPredalienBehaviour =
					static_cast< AVP_Behaviour_Predalien_GS2Move* >( GetBrain()->CreateBehaviour( AVP_BEHAVIOUR_TYPE_PREDALIEN_GS2MOVE ) );
				if ( pxPredalienBehaviour && pxParams )
				{
					bGotRoute = pxPredalienBehaviour->GetToPosition( xGetToPosition );
				}
				pxBehaviour = pxPredalienBehaviour;
				break;
			}

		case AVP_ENTITYCLASS_ALIEN:
		{
			AVP_Behaviour_Alien_MovementWrapper* pxAlienBehaviour =
				static_cast< AVP_Behaviour_Alien_MovementWrapper* >( GetBrain()->CreateBehaviour( AVP_BEHAVIOUR_TYPE_ALIEN_MOVEMENTWRAPPER ) );
			if ( pxAlienBehaviour && pxParams )
			{
				bGotRoute = pxAlienBehaviour->GetToPosition( xGetToPosition );
			}
			pxBehaviour = pxAlienBehaviour;
			break;
		}

		case AVP_ENTITYCLASS_ALIENQUEEN:
		{
			AVP_Behaviour_AlienQueen_GS2Move* pxAlienQueenBehaviour =
				static_cast<AVP_Behaviour_AlienQueen_GS2Move*>( GetBrain()->CreateBehaviour( AVP_BEHAVIOUR_TYPE_ALIENQUEEN_GS2MOVE ) );
			if ( pxAlienQueenBehaviour && pxParams )
			{
				bGotRoute = pxAlienQueenBehaviour->GetToPosition( xGetToPosition, uGS2Guid );
			}
			pxBehaviour = pxAlienQueenBehaviour;
			break;
		}

		case AVP_ENTITYCLASS_ANDROID:
		case AVP_ENTITYCLASS_CIVILIAN:
		case AVP_ENTITYCLASS_HUMAN:
		case AVP_ENTITYCLASS_MARINE:
		{
			AVP_Behaviour_Human_Movement* pxHumanBehaviour =
				static_cast< AVP_Behaviour_Human_Movement* >( GetBrain()->CreateBehaviour( AVP_BEHAVIOUR_TYPE_HUMAN_MOVEMENT ) );
			if ( pxHumanBehaviour && pxParams )
			{
				pxHumanBehaviour->SetDestinationGS2NodeGuid( uGS2Guid );

/*				AVP_ServerNode_GS2Node*			pxNode			= AVP_ServerNode_GS2Node::FindEntity( uGS2Guid );*/
				AVP_Navigation::MovementMode	uMovementMode	= (AVP_Navigation::MovementMode)( ( AVP_ServerActor_Human* )GetActorBrain()->GetActor() )->GetGS2MoveSpeed();

// 				if ( pxNode )
// 				{
// 					if ( pxNode->GetClassification() == AVP_ENTITYCLASS_GS2ATTRACTOR )
// 					{
// 						uMovementMode = (AVP_Navigation::MovementMode)pxNode->GetMovementMode();
// 					}
// 				}

				bGotRoute = pxHumanBehaviour->GetToPosition( xGetToPosition, uMovementMode, true );
			}

			pxBehaviour = pxHumanBehaviour;
			break;
		}

		case AVP_ENTITYCLASS_ALIENFACEHUGGER:
		{
			AVP_Behaviour_FaceHugger_GS2_Movement* pxFacehuggerBehaviour =
				static_cast< AVP_Behaviour_FaceHugger_GS2_Movement* >( GetBrain()->CreateBehaviour( AVP_BEHAVIOUR_TYPE_FACEHUGGER_GS2_MOVEMENT ) );
			if ( pxFacehuggerBehaviour && pxParams )
			{
				bGotRoute = pxFacehuggerBehaviour->GetToPosition( xGetToPosition );
			}
			pxBehaviour = pxFacehuggerBehaviour;
			break;
		}

		default:
			Asura_Assert( false, "AVP_Behaviour_GS2Actor::CreateGetToBehaviour - unhandled entity classification" );
			return NULL;
	}

#ifdef ASURA_ASSERT
	if ( !bGotRoute && pxParams )
	{
		if ( pxParams->Contains( GetToBehaviourParams::POSITION ) )
		{
			Asura_Assertf( false,
				( "AVP_Behaviour_GS2Actor::CreateGetToBehaviour - could not move entity %u to position %f, %f, %f",
				GetBrain()->GetOwnerGuid(), xGetToPosition.x, xGetToPosition.y, xGetToPosition.z ) );
		}
		else if ( pxParams->Contains( GetToBehaviourParams::NODE ) )
		{
			Asura_Assertf( false,
				( "AVP_Behaviour_GS2Actor::CreateGetToBehaviour - could not move entity %u to node %u",
				GetBrain()->GetOwnerGuid(), pxParams->m_pxNode->GetGuid() ) );
		}
		else if ( pxParams->Contains( GetToBehaviourParams::ATTRACTOR ) )
		{
			Asura_Assertf( false,
				( "AVP_Behaviour_GS2Actor::CreateGetToBehaviour - could not move entity %u to attractor %u",
				GetBrain()->GetOwnerGuid(), pxParams->m_pxNode->GetGuid() ) );
		}
		else if ( pxParams->Contains( GetToBehaviourParams::LINK ) )
		{
			Asura_Assertf( false,
				( "AVP_Behaviour_GS2Actor::CreateGetToBehaviour - could not move entity %u along link %u",
				GetBrain()->GetOwnerGuid(), pxParams->m_pxLink->GetGuid() ) );
		}
	}
#endif

    return pxBehaviour;
}

void AVP_Behaviour_GS2Actor::DestroyGetToBehaviour( Axon_Behaviour* pxBehaviour )
{
	GetBrain()->DestroyBehaviour( pxBehaviour );
}

bool AVP_Behaviour_GS2Actor::HandleMessage(const Asura_Message* pxMessage)
{
	switch (pxMessage->GetMsgID())
	{
		case ASURA_MSG_MOVE_START:
		case AVP_MSGID_MOVESTART_SERVER:
		{
			const AVP_Msg_Move*	pxData = static_cast<const AVP_Msg_Move*>(pxMessage->GetData());

			if (pxData && pxData->GetHasTargetEntity() && pxData->GetTargetEntityIsPuppet())
			{
				const AVP_Msg_MoveWithTargetEntity* pxMoveMsgData = static_cast<const AVP_Msg_MoveWithTargetEntity*>(pxData);

				if (pxMoveMsgData)
				{
					if (pxMoveMsgData->GetTargetGuid() == GetActorBrain()->GetOwnerGuid())
					{
						SwitchToState(Axon_Behaviour_GS2Actor::FINISHED);
						SetFinished();
					}
				}
			}
			return true;
		}

		case AVP_MSGID_PERFORM_AI_OBJECTIVE_ACTION:
		{
			const AVP_Message_PerformObjectiveAction* pxMsgData = static_cast<const AVP_Message_PerformObjectiveAction*>(pxMessage->GetData());

			if (pxMsgData)
			{
				if (pxMsgData->GetActionGuid() != ASURA_GUID_UNREGISTERED)
				{
					AVP_ServerActor_Human* pxHuman = (AVP_ServerActor_Human*)GetActorBrain()->GetActor();

					if (pxHuman)
					{
						pxHuman->SetActionGamesceneGuid( pxMsgData->GetActionGuid() );
					}
				}
			}
			return true;
		}

		default:
		{
			return PARENT::HandleMessage(pxMessage);
		}
	}
}

void AVP_Behaviour_GS2Actor::UpdateAnimFlagEvents()
{
	const AVP_ClientEntity_Actor* const pxClientActor = AVP_ClientEntity_Actor::FindEntity( GetBrain()->GetOwnerGuid() );
	
	if ( !pxClientActor )
	{
		return;
	}

	const Asura_AnimationController_Animation* pxAACA = NULL;
	const AVP_Move* pxCurrentGSMove = NULL;

	if ( pxClientActor->GetMovementSystem() && pxClientActor->GetMovementSystem()->GetCurrentMove() && pxClientActor->GetMovementSystem()->GetCurrentMove()->GetHash() == AVP_Move_GS2RigidAnim::GetStaticHash() )
	{
		pxCurrentGSMove = static_cast< const AVP_Move* >( pxClientActor->GetMovementSystem()->GetCurrentMove() );
	}

	if ( pxCurrentGSMove && pxCurrentGSMove->GetAVPAnimationData() )
	{
		pxAACA = pxCurrentGSMove->GetAVPAnimationData()->GetAnimationController();
	}
	else
	{
		const Asura_Animation* const pxClientAnimation = pxClientActor->GetShapeInstance().GetAnimation();
		Asura_Assert( pxClientAnimation, "AVP_Behaviour_GS2Actor::GetOwnerAnimationVelocity - cannot find owner animation" );
		if ( pxClientAnimation )
		{
			pxAACA = pxClientAnimation->GetControllerAnimationFromHash( pxClientActor->GetCurrentGamesceneAnimControllerHash() );
		}
	}

	if ( pxAACA )
	{
		u_int uAniMFlags = pxAACA->GetFlagsForLastFrame();

		if ( uAniMFlags & AVP_ANIMFLAG_ACTION_1 )
		{
			GetActorBrain()->GetActor()->SendGS2AnimFlagEvent();
		}
	}
}

void AVP_Behaviour_GS2Actor::PerFrameUpdate( const float fTimeslice )
{
	PARENT::PerFrameUpdate( fTimeslice );

	UpdateAnimFlagEvents();

	bool bAllowedToExit = GetIsAllowedToExitOnKnowledge();

	if ( bAllowedToExit )
	{
		AVP_ServerEntity_Actor* pxOurActor = GetActorBrain()->GetActor(); // pointer verified by brain

		switch ( pxOurActor->GetClassification() )
		{
			case AVP_ENTITYCLASS_MARINE:
			case AVP_ENTITYCLASS_ANDROID:
			{
				AVP_Brain_Actor_Marine* pxMarineBrain = ( AVP_Brain_Actor_Marine* )GetActorBrain();

				if ( pxMarineBrain && pxMarineBrain->IsAllowedToExitGS2OnKnowledge() && ( ( pxMarineBrain->DoesHaveThreat() ) || ( pxMarineBrain->DoesHaveAlert() ) ) )
				{
					SwitchToState(Axon_Behaviour_GS2Actor::FINISHED);
					SetFinished();
				}

			}break;

			case AVP_ENTITYCLASS_CIVILIAN:
			{
				AVP_Brain_Actor_Civilian* pxCivilianBrain = ( AVP_Brain_Actor_Civilian* )GetActorBrain();

				if ( pxCivilianBrain && pxCivilianBrain->IsAllowedToExitGS2OnKnowledge() && ( ( pxCivilianBrain->DoesHaveThreat() ) || ( pxCivilianBrain->DoesHaveAlert() ) ) )
				{
					SwitchToState(Axon_Behaviour_GS2Actor::FINISHED);
					SetFinished();
				}

			}break;

			case AVP_ENTITYCLASS_ALIEN:
			{
				// Put Alien conditions here
			}break;

			case AVP_ENTITYCLASS_PREDATOR:
			{
				// Put Predator conditions here
			}break;

			case AVP_ENTITYCLASS_PREDALIEN:
			{
				// Put Predator conditions here
			}break;

			case AVP_ENTITYCLASS_ALIENFACEHUGGER:
			{
				// Put Face Hugger conditions here
			}break;

			default:
			{

			}break;
		}
	}
}

void* AVP_Behaviour_GS2Actor::GetAnimMappingData()
{
	static AVP_GS2_AnimMappingData s_xMappingData;

	// Fill the mapping data in from the current owner.
	s_xMappingData.m_auFactorValues[ AVP_GS2_MF_SKIN ] = GetOwnerPhyObj()->GetSkinID();
	s_xMappingData.m_auFactorValues[ AVP_GS2_MF_WEAPON ] = GetActorBrain()->GetClientActor()->GetInventorySystem()->GetCurrentItemID( uAVP_INVENTORY_GROUPHASH_WEAPON );

	return &s_xMappingData;
}

bool AVP_Behaviour_GS2Actor::GetIsAllowedToExitOnKnowledge() const
{
	switch (GetCurrentState())
	{
		// If we are moving to an attractor and that node has the leave on knowledge flag set.
		case MOVING_TO_ATTRACTOR:
		case AT_NODE:
		{
			AVP_ServerNode_GS2Node* pxNode = AVP_ServerNode_GS2Node::FindEntity( GetCurrentEntityGuid() );

			if ( pxNode && pxNode->ShouldExitGamesceneOnKnowledge() )
			{
				return true;
			}
			else
			{
				return false;
			}
		}

		// On spline
		case ON_LINK:
		{
			AVP_ServerNode_GS2Spline* pxSpline = (AVP_ServerNode_GS2Spline*)AVP_ServerNode_GS2Spline::FindEntity( GetCurrentEntityGuid() );

			if ( pxSpline && pxSpline->ShouldExitGamesceneOnKnowledge() )
			{
				return true;
			}
			else
			{
				return false;
			}
		}

		case UNSET:
		default:
		{
			return false;
		}
	}
}

bool AVP_Behaviour_GS2Actor::Activate()
{
	GetActorBrain()->StartGS2();
	return PARENT::Activate();
}

void AVP_Behaviour_GS2Actor::Deactivate()
{
	GetActorBrain()->EstablishNavData();
	PARENT::Deactivate();
	GetActorBrain()->EndGS2();
}

#ifndef ASURA_NO_DEBUG_OUTPUT
void AVP_Behaviour_GS2Actor::RenderDebugInfo()
{
	PARENT::RenderDebugInfo();

	switch ( GetCurrentState() )
	{
		case MOVING_TO_ATTRACTOR:
		case AT_NODE:
		case ON_LINK:
		{
			Asura_Font_System::Print( GetActorBrain()->GetDebugOutputPos().x, GetActorBrain()->GetDebugOutputPos().y, 0.5f, 0xffffffff,
				ASURA_TEXTFORMAT_CENTREJUSTIFIED | ASURA_TEXTFORMAT_FORMATSTRING, "GS2Actor: %s - %d", GetStateString(), GetCurrentEntityGuid() );
		}
		break;

		case UNSET:
		case FINISHED:
		default:
		{
			Asura_Font_System::Print( GetActorBrain()->GetDebugOutputPos().x, GetActorBrain()->GetDebugOutputPos().y, 0.5f, 0xffffffff,
				ASURA_TEXTFORMAT_CENTREJUSTIFIED | ASURA_TEXTFORMAT_FORMATSTRING, "GS2Actor: %s", GetStateString() );
		}
		break;
	}

	GetActorBrain()->GetDebugOutputPos().y += 10.0f;
}
#endif

AVP_Brain_Actor* AVP_Behaviour_GS2Actor::GetActorBrain() const
{
	return static_cast< AVP_Brain_Actor* >( GetBrain() );
}
