
///////////////////////////////////////////////////////////////////////////////
//
// File   : AVP_Alien_MovesMelee.cpp
// Author : Anthony Gregson
// Date   : 22/02/08
//
// Copyright (C) 2008 Rebellion, All Rights Reserved.
//
///////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Include files...
////////////////////////////////////////////////////////////////////////////////

#include "Core/Asura.h"


// This file's header...
#include "Moves/Vertebrates/Alien/AVP_Alien_MovesMelee.h"

// Asura independent header-files...
#include "Animation/Asura_Hierarchy.h"
#include "Blueprint/Asura_Blueprint.h"
#include "Blueprint/Asura_Blueprint_System.h"
#include "Network/Asura_Message.h"

// Asura platform header-files...

// Game independent header-files...
#include "Actor/AVP_Actor_PhysicsObjectHandler.h"
#include "Actor/Vertebrates/Alien/AVP_Alien_MeleeCounter_System.h"
#include "Actor/Vertebrates/AVP_Vertebrate_Description.h"
#include "Blueprint/AVP_Blueprint_HashIDs.h"
#include "Core/AVP_Settings.h"
#include "Entity/AVP_Messages.h"
#include "Entity/PhysicalObject/Actor/AVP_ServerEntity_Actor.h"
#include "Entity/PhysicalObject/Actor/Vertebrates/AVP_ServerActor_Vertebrate.h"
#include "Entity/PhysicalObject/Actor/Vertebrates/AVP_Vertebrate_Messages.h"
#include "Entity/PhysicalObject/Actor/Vertebrates/Alien/AVP_ClientActor_Alien.h"
#include "Entity/PhysicalObject/Actor/Vertebrates/Human/AVP_ClientActor_Human.h"
#include "Entity/PhysicalObject/Actor/Vertebrates/Predator/AVP_ClientActor_Predator.h"

// Game platform header-files...

// Tools header-files...


////////////////////////////////////////////////////////////////////////////////
// Constant declarations...
////////////////////////////////////////////////////////////////////////////////

static const float g_fTweenInDuration = 0.05f;
static const float g_fTweenOutDuration = 0.1f;


////////////////////////////////////////////////////////////////////////////////
// Static variable declarations...
////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////
// Private functions...
////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////
// Protected functions...
////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////
// Public functions...
////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////
// Class		: AVP_Alien_Move_Melee_JumpSlash_LeftClaw_Start
// Author       : Anthony Gregson
// Date         : 06/03/08
////////////////////////////////////////////////////////////////////////////////

AVP_Alien_Move_Melee_JumpSlash_LeftClaw_Start::AVP_Alien_Move_Melee_JumpSlash_LeftClaw_Start(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, 0xAFEDB38D,//"JumpSlashLeftClawStart",
		 AVP_Alien_Move_Melee_JumpSlash_LeftClaw_Return_Hit::GetStaticHash(), AVP_Alien_Move_Melee_JumpSlash_LeftClaw_Return_Countered::GetStaticHash(), AVP_Alien_Move_Melee_JumpSlash_LeftClaw_Return_Miss::GetStaticHash())
, m_xOrientationForVelocity(Asura_Maths::IdentityQuat)
, m_fVelocityMultiplier(1.0f)
{
	m_bClearQueuedMeleeRequests = true;
	SetGravityIgnored(true);
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	// Remove the default generic start aiming behaviour
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	m_bDisableSurfaceReorientation = true;
}

DEBUGVAR float dbg_fLeapReorientationTime = 0.5f;

bool AVP_Alien_Move_Melee_JumpSlash_LeftClaw_Start::Start(const Asura_Msg_Move* pxStartMsg)
{
	// This has to be started by message.
	if (!pxStartMsg) { return false; }

	// The message has to be a AVP_Msg_MeleeWithTargetPosition_Move.
	const AVP_Msg_MeleeWithTargetPosition_Move* pxMeleeStart = static_cast<const AVP_Msg_MeleeWithTargetPosition_Move*>(pxStartMsg);

	// Ensure the animation data is set up
	SetVariation(pxMeleeStart->GetVariation());

	if (!m_pxAVPAnimationData) { return false; }

	AVP_ClientEntity_Actor& xOwner = GetAVPParentSystem().GetActorOwner();

	// We need to ensure the correct anim hash is set up, as it's about to get used.
	if (xOwner.IsUsingFirstPersonSkin())
	{
		m_pxAVPAnimationData->SetAnimHash(m_uFirstPersonAnimHash);
	}
	else
	{
		m_pxAVPAnimationData->SetAnimHash(m_uThirdPersonAnimHash);
	}

	// Set up our velocity adjustment
	const Asura_Vector_3& xTargetPos = pxMeleeStart->GetTargetPosition();

	Asura_Vector_3 xTargetOffset = xTargetPos - xOwner.GetCurrentPosition();
	Asura_Vector_3 xAnimEndOffset(Asura_Maths::ZeroVector3);
	// The controller hasn't been created yet, so we have to do this manually.
	const Asura_Hierarchy_Anim* pxAnim = m_pxAVPAnimationData->GetHierarchyAnim();
	if (!pxAnim) { return false; }

	pxAnim->GetMovementOffset(m_pxAVPAnimationData->GetHierarchySkin(), 1.0f, &xAnimEndOffset, NULL, false);
	if (xAnimEndOffset.ApproximatelyEquals(Asura_Maths::ZeroVector3)) { return false; }
	// Note the side effect of normalising the offset - it's about to be used to work out the orientation we want to apply our velocity in.
	m_fVelocityMultiplier = xTargetOffset.Normalise() / xAnimEndOffset.Magnitude();

	Asura_Matrix_3x3 xOri;
	Asura_Maths::OrientationFromDirection(xOri, xTargetOffset);
	m_xOrientationForVelocity.FromMatrix(xOri);

	// Also get an upright orientation to interpolate to.
	xTargetOffset.y = 0.0f;
	if (xTargetOffset.ApproximatelyEquals(Asura_Maths::ZeroVector3))
	{
		Asura_Euler_3 xEuler;
		xEuler.FromMatrix(xOwner.GetCurrentOrientation());
		xEuler.x = xEuler.z = 0.0f;
		xEuler.ToMatrix(xOri);
	}
	else
	{
		xTargetOffset.Normalise();
		Asura_Maths::OrientationFromDirection(xOri, xTargetOffset);
	}
	m_xOrientationInterpolationData.SetFinal(xOri);
	m_xOrientationInterpolationData.SetInitial(xOwner.GetCurrentOrientation());
	m_xOrientationInterpolationData.SetDuration(dbg_fLeapReorientationTime);

	InitialiseOrientationInterpolation(m_xOrientationInterpolationData);

	bool bResult = PARENT::Start(pxStartMsg);

	if (bResult && Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(true);
		}
	}

	return bResult;
}

void AVP_Alien_Move_Melee_JumpSlash_LeftClaw_Start::Abort()
{
	EnsureAnimationFinishes();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}

	PARENT::Abort();
}

bool AVP_Alien_Move_Melee_JumpSlash_LeftClaw_Start::CalculateVelocity(const float fTimeStep, Asura_AVector3_OutParam xVelocity) const
{
	xVelocity.Zero();

	if (m_pxAVPAnimationData)
	{
		if(m_pxAVPAnimationData->CalculateVelocity(xVelocity))
		{
			xVelocity *= m_fVelocityMultiplier;
			xVelocity = m_xOrientationForVelocity.RotateVector(xVelocity);
		}
	}

	// Returning false just means the move doesn't wait for this to "finish".
	return false;
}


////////////////////////////////////////////////////////////////////////////////
// Class		: AVP_Alien_Move_Melee_JumpSlash_LeftClaw_Return_Hit
// Author       : Anthony Gregson
// Date         : 06/03/08
////////////////////////////////////////////////////////////////////////////////

AVP_Alien_Move_Melee_JumpSlash_LeftClaw_Return_Hit::AVP_Alien_Move_Melee_JumpSlash_LeftClaw_Return_Hit(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, 0x851C517E)//"JumpSlashLeftClawHit")
{
	m_bClearQueuedMeleeRequests = true;
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	m_bDisableSurfaceReorientation = true;
	SetAIPostMoveMode(AI_MM_MDEIUM);
}

void AVP_Alien_Move_Melee_JumpSlash_LeftClaw_Return_Hit::Finish()
{
	PARENT::Finish();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

void AVP_Alien_Move_Melee_JumpSlash_LeftClaw_Return_Hit::Abort()
{
	PARENT::Abort();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}


////////////////////////////////////////////////////////////////////////////////
// Class		: AVP_Alien_Move_Melee_JumpSlash_LeftClaw_Return_Countered
// Author       : Anthony Gregson
// Date         : 06/03/08
////////////////////////////////////////////////////////////////////////////////

AVP_Alien_Move_Melee_JumpSlash_LeftClaw_Return_Countered::AVP_Alien_Move_Melee_JumpSlash_LeftClaw_Return_Countered(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, 0xA34B3546)//"JumpSlashLeftClawCountered")
{
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	m_bPreventsFlinch = true;
	m_bDisableSurfaceReorientation = true;
}

void AVP_Alien_Move_Melee_JumpSlash_LeftClaw_Return_Countered::Finish()
{
	PARENT::Finish();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

void AVP_Alien_Move_Melee_JumpSlash_LeftClaw_Return_Countered::Abort()
{
	PARENT::Abort();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}
////////////////////////////////////////////////////////////////////////////////
// Class		: AVP_Alien_Move_Melee_JumpSlash_LeftClaw_Return_Miss
// Author       : Anthony Gregson
// Date         : 06/03/08
////////////////////////////////////////////////////////////////////////////////

AVP_Alien_Move_Melee_JumpSlash_LeftClaw_Return_Miss::AVP_Alien_Move_Melee_JumpSlash_LeftClaw_Return_Miss(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, 0x1E702471)//"JumpSlashLeftClawMiss")
{
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	m_bDisableSurfaceReorientation = true;
	SetAIPostMoveMode(AI_MM_MDEIUM);
}

void AVP_Alien_Move_Melee_JumpSlash_LeftClaw_Return_Miss::Finish()
{
	PARENT::Finish();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

void AVP_Alien_Move_Melee_JumpSlash_LeftClaw_Return_Miss::Abort()
{
	PARENT::Abort();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

////////////////////////////////////////////////////////////////////////////////
// Class		: AVP_Alien_Move_Melee_JumpSlash_RightClaw_Start
// Author       : Anthony Gregson
// Date         : 06/03/08
////////////////////////////////////////////////////////////////////////////////

AVP_Alien_Move_Melee_JumpSlash_RightClaw_Start::AVP_Alien_Move_Melee_JumpSlash_RightClaw_Start(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, 0x542AF696,//"JumpSlashRightClawStart",
		 AVP_Alien_Move_Melee_JumpSlash_RightClaw_Return_Hit::GetStaticHash(), AVP_Alien_Move_Melee_JumpSlash_RightClaw_Return_Countered::GetStaticHash(), AVP_Alien_Move_Melee_JumpSlash_RightClaw_Return_Miss::GetStaticHash())
, m_xOrientationForVelocity(Asura_Maths::IdentityQuat)
, m_fVelocityMultiplier(1.0f)
{
	m_bClearQueuedMeleeRequests = true;
	SetGravityIgnored(true);
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	// Remove the default generic start aiming behaviour
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	m_bDisableSurfaceReorientation = true;
}

bool AVP_Alien_Move_Melee_JumpSlash_RightClaw_Start::Start(const Asura_Msg_Move* pxStartMsg)
{
	// This has to be started by message.
	if (!pxStartMsg) { return false; }

	// The message has to be a AVP_Msg_MeleeWithTargetPosition_Move.
	const AVP_Msg_MeleeWithTargetPosition_Move* pxMeleeStart = static_cast<const AVP_Msg_MeleeWithTargetPosition_Move*>(pxStartMsg);

	// Ensure the animation data is set up
	SetVariation(pxMeleeStart->GetVariation());

	if (!m_pxAVPAnimationData) { return false; }

	AVP_ClientEntity_Actor& xOwner = GetAVPParentSystem().GetActorOwner();

	// We need to ensure the correct anim hash is set up, as it's about to get used.
	if (xOwner.IsUsingFirstPersonSkin())
	{
		m_pxAVPAnimationData->SetAnimHash(m_uFirstPersonAnimHash);
	}
	else
	{
		m_pxAVPAnimationData->SetAnimHash(m_uThirdPersonAnimHash);
	}

	// Set up our velocity adjustment
	const Asura_Vector_3& xTargetPos = pxMeleeStart->GetTargetPosition();

	Asura_Vector_3 xTargetOffset = xTargetPos - xOwner.GetCurrentPosition();
	Asura_Vector_3 xAnimEndOffset(Asura_Maths::ZeroVector3);
	// The controller hasn't been created yet, so we have to do this manually.
	const Asura_Hierarchy_Anim* pxAnim = m_pxAVPAnimationData->GetHierarchyAnim();
	if (!pxAnim) { return false; }

	pxAnim->GetMovementOffset(m_pxAVPAnimationData->GetHierarchySkin(), 1.0f, &xAnimEndOffset, NULL, false);
	if (xAnimEndOffset.ApproximatelyEquals(Asura_Maths::ZeroVector3)) { return false; }
	// Note the side effect of normalising the offset - it's about to be used to work out the orientation we want to apply our velocity in.
	m_fVelocityMultiplier = xTargetOffset.Normalise() / xAnimEndOffset.Magnitude();

	Asura_Matrix_3x3 xOri;
	Asura_Maths::OrientationFromDirection(xOri, xTargetOffset);
	m_xOrientationForVelocity.FromMatrix(xOri);

	// Also get an upright orientation to interpolate to.
	xTargetOffset.y = 0.0f;
	if (xTargetOffset.ApproximatelyEquals(Asura_Maths::ZeroVector3))
	{
		Asura_Euler_3 xEuler;
		xEuler.FromMatrix(xOwner.GetCurrentOrientation());
		xEuler.x = xEuler.z = 0.0f;
		xEuler.ToMatrix(xOri);
	}
	else
	{
		xTargetOffset.Normalise();
		Asura_Maths::OrientationFromDirection(xOri, xTargetOffset);
	}
	m_xOrientationInterpolationData.SetFinal(xOri);
	m_xOrientationInterpolationData.SetInitial(xOwner.GetCurrentOrientation());
	m_xOrientationInterpolationData.SetDuration(dbg_fLeapReorientationTime);

	InitialiseOrientationInterpolation(m_xOrientationInterpolationData);

	bool bResult = PARENT::Start(pxStartMsg);

	if (bResult && Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(true);
		}
	}

	return bResult;

}

void AVP_Alien_Move_Melee_JumpSlash_RightClaw_Start::Abort()
{
	EnsureAnimationFinishes();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}

	PARENT::Abort();
}

bool AVP_Alien_Move_Melee_JumpSlash_RightClaw_Start::CalculateVelocity(const float fTimeStep, Asura_AVector3_OutParam xVelocity) const
{
	xVelocity.Zero();

	if (m_pxAVPAnimationData)
	{
		if(m_pxAVPAnimationData->CalculateVelocity(xVelocity))
		{
			xVelocity *= m_fVelocityMultiplier;
			xVelocity = m_xOrientationForVelocity.RotateVector(xVelocity);
		}
	}

	// Returning false just means the move doesn't wait for this to "finish".
	return false;
}


////////////////////////////////////////////////////////////////////////////////
// Class		: AVP_Alien_Move_Melee_JumpSlash_RightClaw_Return_Hit
// Author       : Anthony Gregson
// Date         : 06/03/08
////////////////////////////////////////////////////////////////////////////////

AVP_Alien_Move_Melee_JumpSlash_RightClaw_Return_Hit::AVP_Alien_Move_Melee_JumpSlash_RightClaw_Return_Hit(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, 0xBCB0C2C7)//"JumpSlashRightClawHit")
{
	m_bClearQueuedMeleeRequests = true;
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	m_bDisableSurfaceReorientation = true;
	SetAIPostMoveMode(AI_MM_MDEIUM);
}

void AVP_Alien_Move_Melee_JumpSlash_RightClaw_Return_Hit::Finish()
{
	PARENT::Finish();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

void AVP_Alien_Move_Melee_JumpSlash_RightClaw_Return_Hit::Abort()
{
	PARENT::Abort();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

////////////////////////////////////////////////////////////////////////////////
// Class		: AVP_Alien_Move_Melee_JumpSlash_RightClaw_Return_Countered
// Author       : Anthony Gregson
// Date         : 06/03/08
////////////////////////////////////////////////////////////////////////////////

AVP_Alien_Move_Melee_JumpSlash_RightClaw_Return_Countered::AVP_Alien_Move_Melee_JumpSlash_RightClaw_Return_Countered(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, 0x91ADCBCF)//"JumpSlashRightClawCountered")
{
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	m_bPreventsFlinch = true;
	m_bDisableSurfaceReorientation = true;
}

void AVP_Alien_Move_Melee_JumpSlash_RightClaw_Return_Countered::Finish()
{
	PARENT::Finish();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

void AVP_Alien_Move_Melee_JumpSlash_RightClaw_Return_Countered::Abort()
{
	PARENT::Abort();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

////////////////////////////////////////////////////////////////////////////////
// Class		: AVP_Alien_Move_Melee_JumpSlash_RightClaw_Return_Miss
// Author       : Anthony Gregson
// Date         : 06/03/08
////////////////////////////////////////////////////////////////////////////////

AVP_Alien_Move_Melee_JumpSlash_RightClaw_Return_Miss::AVP_Alien_Move_Melee_JumpSlash_RightClaw_Return_Miss(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, 0xD969DC48)//"JumpSlashRightClawMiss")
{
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	m_bDisableSurfaceReorientation = true;
	SetAIPostMoveMode(AI_MM_MDEIUM);
}

void AVP_Alien_Move_Melee_JumpSlash_RightClaw_Return_Miss::Finish()
{
	PARENT::Finish();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

void AVP_Alien_Move_Melee_JumpSlash_RightClaw_Return_Miss::Abort()
{
	PARENT::Abort();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}



/// ////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////
//
// AVP_Alien_Move_Melee_JumpSlashWall_LeftClaw_Start
//
////////////////////////////////////////////////////////////////////////////////

AVP_Alien_Move_Melee_JumpSlashWall_LeftClaw_Start::AVP_Alien_Move_Melee_JumpSlashWall_LeftClaw_Start(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, 0x8e954983, //JumpSlashWallLeftClawStart
		 AVP_Alien_Move_Melee_JumpSlashWall_LeftClaw_Return_Hit::GetStaticHash(), AVP_Alien_Move_Melee_JumpSlashWall_LeftClaw_Return_Countered::GetStaticHash(), AVP_Alien_Move_Melee_JumpSlashWall_LeftClaw_Return_Miss::GetStaticHash())
, m_xOrientationForVelocity(Asura_Maths::IdentityQuat)
, m_fVelocityMultiplier(1.0f)
{
	m_bClearQueuedMeleeRequests = true;
	SetGravityIgnored(true);
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	// Remove the default generic start aiming behaviour
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	m_bDisableSurfaceReorientation = true;
}

bool AVP_Alien_Move_Melee_JumpSlashWall_LeftClaw_Start::Start(const Asura_Msg_Move* pxStartMsg)
{
	// This has to be started by message.
	if (!pxStartMsg) { return false; }

	// The message has to be a AVP_Msg_MeleeWithTargetPosition_Move.
	const AVP_Msg_MeleeWithTargetPosition_Move* pxMeleeStart = static_cast<const AVP_Msg_MeleeWithTargetPosition_Move*>(pxStartMsg);

	// Ensure the animation data is set up
	SetVariation(pxMeleeStart->GetVariation());

	if (!m_pxAVPAnimationData) { return false; }

	AVP_ClientEntity_Actor& xOwner = GetAVPParentSystem().GetActorOwner();

	// We need to ensure the correct anim hash is set up, as it's about to get used.
	if (xOwner.IsUsingFirstPersonSkin())
	{
		m_pxAVPAnimationData->SetAnimHash(m_uFirstPersonAnimHash);
	}
	else
	{
		m_pxAVPAnimationData->SetAnimHash(m_uThirdPersonAnimHash);
	}

	// Set up our velocity adjustment
	const Asura_Vector_3& xTargetPos = pxMeleeStart->GetTargetPosition();

	Asura_Vector_3 xTargetOffset = xTargetPos - xOwner.GetCurrentPosition();
	Asura_Vector_3 xAnimEndOffset(Asura_Maths::ZeroVector3);
	// The controller hasn't been created yet, so we have to do this manually.
	const Asura_Hierarchy_Anim* pxAnim = m_pxAVPAnimationData->GetHierarchyAnim();
	if (!pxAnim) { return false; }

	pxAnim->GetMovementOffset(m_pxAVPAnimationData->GetHierarchySkin(), 1.0f, &xAnimEndOffset, NULL, false);
	if (xAnimEndOffset.ApproximatelyEquals(Asura_Maths::ZeroVector3)) { return false; }
	// Note the side effect of normalising the offset - it's about to be used to work out the orientation we want to apply our velocity in.
	m_fVelocityMultiplier = xTargetOffset.Normalise() / xAnimEndOffset.Magnitude();

	Asura_Matrix_3x3 xOri;
	Asura_Maths::OrientationFromDirection(xOri, xTargetOffset);
	m_xOrientationForVelocity.FromMatrix(xOri);

	// Also get an upright orientation to interpolate to.
	xTargetOffset.y = 0.0f;
	if (xTargetOffset.ApproximatelyEquals(Asura_Maths::ZeroVector3))
	{
		Asura_Euler_3 xEuler;
		xEuler.FromMatrix(xOwner.GetCurrentOrientation());
		xEuler.x = xEuler.z = 0.0f;
		xEuler.ToMatrix(xOri);
	}
	else
	{
		xTargetOffset.Normalise();
		Asura_Maths::OrientationFromDirection(xOri, xTargetOffset);
	}
	m_xOrientationInterpolationData.SetFinal(xOri);
	m_xOrientationInterpolationData.SetInitial(xOwner.GetCurrentOrientation());
	m_xOrientationInterpolationData.SetDuration(dbg_fLeapReorientationTime);

	InitialiseOrientationInterpolation(m_xOrientationInterpolationData);

	return PARENT::Start(pxStartMsg);
}

void AVP_Alien_Move_Melee_JumpSlashWall_LeftClaw_Start::Abort()
{
	EnsureAnimationFinishes();

	PARENT::Abort();
}

bool AVP_Alien_Move_Melee_JumpSlashWall_LeftClaw_Start::CalculateVelocity(const float fTimeStep, Asura_AVector3_OutParam xVelocity) const
{
	xVelocity.Zero();

	if (m_pxAVPAnimationData)
	{
		if(m_pxAVPAnimationData->CalculateVelocity(xVelocity))
		{
			xVelocity *= m_fVelocityMultiplier;
			xVelocity = m_xOrientationForVelocity.RotateVector(xVelocity);
		}
	}

	// Returning false just means the move doesn't wait for this to "finish".
	return false;
}


////////////////////////////////////////////////////////////////////////////////
//
// AVP_Alien_Move_Melee_JumpSlashWall_LeftClaw_Return_Hit
//
////////////////////////////////////////////////////////////////////////////////

AVP_Alien_Move_Melee_JumpSlashWall_LeftClaw_Return_Hit::AVP_Alien_Move_Melee_JumpSlashWall_LeftClaw_Return_Hit(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, 0xf97cecf4) //JumpSlashWallLeftClawHit
{
	m_bClearQueuedMeleeRequests = true;
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	m_bDisableSurfaceReorientation = true;
}


////////////////////////////////////////////////////////////////////////////////
//
// AVP_Alien_Move_Melee_JumpSlashWall_LeftClaw_Return_Countered
//
////////////////////////////////////////////////////////////////////////////////

AVP_Alien_Move_Melee_JumpSlashWall_LeftClaw_Return_Countered::AVP_Alien_Move_Melee_JumpSlashWall_LeftClaw_Return_Countered(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, 0x17aae03c) //JumpSlashWallLeftClawCountered
{
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	m_bPreventsFlinch = true;
	m_bDisableSurfaceReorientation = true;
}


////////////////////////////////////////////////////////////////////////////////
//
// AVP_Alien_Move_Melee_JumpSlashWall_LeftClaw_Return_Miss
//
////////////////////////////////////////////////////////////////////////////////

AVP_Alien_Move_Melee_JumpSlashWall_LeftClaw_Return_Miss::AVP_Alien_Move_Melee_JumpSlashWall_LeftClaw_Return_Miss(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, 0x3622f7bb) //JumpSlashWallLeftClawMiss
{
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	m_bDisableSurfaceReorientation = true;
}


////////////////////////////////////////////////////////////////////////////////
//
// AVP_Alien_Move_Melee_JumpSlashWall_RightClaw_Start
//
////////////////////////////////////////////////////////////////////////////////

AVP_Alien_Move_Melee_JumpSlashWall_RightClaw_Start::AVP_Alien_Move_Melee_JumpSlashWall_RightClaw_Start(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, 0x4a761f60, //JumpSlashWallRightClawStart
		 AVP_Alien_Move_Melee_JumpSlashWall_RightClaw_Return_Hit::GetStaticHash(), AVP_Alien_Move_Melee_JumpSlashWall_RightClaw_Return_Countered::GetStaticHash(), AVP_Alien_Move_Melee_JumpSlashWall_RightClaw_Return_Miss::GetStaticHash())
, m_xOrientationForVelocity(Asura_Maths::IdentityQuat)
, m_fVelocityMultiplier(1.0f)
{
	m_bClearQueuedMeleeRequests = true;
	SetGravityIgnored(true);
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	// Remove the default generic start aiming behaviour
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	m_bDisableSurfaceReorientation = true;
}

bool AVP_Alien_Move_Melee_JumpSlashWall_RightClaw_Start::Start(const Asura_Msg_Move* pxStartMsg)
{
	// This has to be started by message.
	if (!pxStartMsg) { return false; }

	// The message has to be a AVP_Msg_MeleeWithTargetPosition_Move.
	const AVP_Msg_MeleeWithTargetPosition_Move* pxMeleeStart = static_cast<const AVP_Msg_MeleeWithTargetPosition_Move*>(pxStartMsg);

	// Ensure the animation data is set up
	SetVariation(pxMeleeStart->GetVariation());

	if (!m_pxAVPAnimationData) { return false; }

	AVP_ClientEntity_Actor& xOwner = GetAVPParentSystem().GetActorOwner();

	// We need to ensure the correct anim hash is set up, as it's about to get used.
	if (xOwner.IsUsingFirstPersonSkin())
	{
		m_pxAVPAnimationData->SetAnimHash(m_uFirstPersonAnimHash);
	}
	else
	{
		m_pxAVPAnimationData->SetAnimHash(m_uThirdPersonAnimHash);
	}

	// Set up our velocity adjustment
	const Asura_Vector_3& xTargetPos = pxMeleeStart->GetTargetPosition();

	Asura_Vector_3 xTargetOffset = xTargetPos - xOwner.GetCurrentPosition();
	Asura_Vector_3 xAnimEndOffset(Asura_Maths::ZeroVector3);
	// The controller hasn't been created yet, so we have to do this manually.
	const Asura_Hierarchy_Anim* pxAnim = m_pxAVPAnimationData->GetHierarchyAnim();
	if (!pxAnim) { return false; }

	pxAnim->GetMovementOffset(m_pxAVPAnimationData->GetHierarchySkin(), 1.0f, &xAnimEndOffset, NULL, false);
	if (xAnimEndOffset.ApproximatelyEquals(Asura_Maths::ZeroVector3)) { return false; }
	// Note the side effect of normalising the offset - it's about to be used to work out the orientation we want to apply our velocity in.
	m_fVelocityMultiplier = xTargetOffset.Normalise() / xAnimEndOffset.Magnitude();

	Asura_Matrix_3x3 xOri;
	Asura_Maths::OrientationFromDirection(xOri, xTargetOffset);
	m_xOrientationForVelocity.FromMatrix(xOri);

	// Also get an upright orientation to interpolate to.
	xTargetOffset.y = 0.0f;
	if (xTargetOffset.ApproximatelyEquals(Asura_Maths::ZeroVector3))
	{
		Asura_Euler_3 xEuler;
		xEuler.FromMatrix(xOwner.GetCurrentOrientation());
		xEuler.x = xEuler.z = 0.0f;
		xEuler.ToMatrix(xOri);
	}
	else
	{
		xTargetOffset.Normalise();
		Asura_Maths::OrientationFromDirection(xOri, xTargetOffset);
	}
	m_xOrientationInterpolationData.SetFinal(xOri);
	m_xOrientationInterpolationData.SetInitial(xOwner.GetCurrentOrientation());
	m_xOrientationInterpolationData.SetDuration(dbg_fLeapReorientationTime);

	InitialiseOrientationInterpolation(m_xOrientationInterpolationData);

	return PARENT::Start(pxStartMsg);
}

void AVP_Alien_Move_Melee_JumpSlashWall_RightClaw_Start::Abort()
{
	EnsureAnimationFinishes();

	PARENT::Abort();
}

bool AVP_Alien_Move_Melee_JumpSlashWall_RightClaw_Start::CalculateVelocity(const float fTimeStep, Asura_AVector3_OutParam xVelocity) const
{
	xVelocity.Zero();

	if (m_pxAVPAnimationData)
	{
		if(m_pxAVPAnimationData->CalculateVelocity(xVelocity))
		{
			xVelocity *= m_fVelocityMultiplier;
			xVelocity = m_xOrientationForVelocity.RotateVector(xVelocity);
		}
	}

	// Returning false just means the move doesn't wait for this to "finish".
	return false;
}


////////////////////////////////////////////////////////////////////////////////
//
// AVP_Alien_Move_Melee_JumpSlashWall_RightClaw_Return_Hit
//
////////////////////////////////////////////////////////////////////////////////

AVP_Alien_Move_Melee_JumpSlashWall_RightClaw_Return_Hit::AVP_Alien_Move_Melee_JumpSlashWall_RightClaw_Return_Hit(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, 0xd4639611) //JumpSlashWallRightClawHit
{
	m_bClearQueuedMeleeRequests = true;
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	m_bDisableSurfaceReorientation = true;
}


////////////////////////////////////////////////////////////////////////////////
//
// AVP_Alien_Move_Melee_JumpSlashWall_RightClaw_Return_Countered
//
////////////////////////////////////////////////////////////////////////////////

AVP_Alien_Move_Melee_JumpSlashWall_RightClaw_Return_Countered::AVP_Alien_Move_Melee_JumpSlashWall_RightClaw_Return_Countered(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, 0xa9437f99) //JumpSlashWallRightClawCountered
{
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	m_bPreventsFlinch = true;
	m_bDisableSurfaceReorientation = true;
}


////////////////////////////////////////////////////////////////////////////////
//
// AVP_Alien_Move_Melee_JumpSlashWall_RightClaw_Return_Miss
//
////////////////////////////////////////////////////////////////////////////////

AVP_Alien_Move_Melee_JumpSlashWall_RightClaw_Return_Miss::AVP_Alien_Move_Melee_JumpSlashWall_RightClaw_Return_Miss(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, 0xb811723e) //JumpSlashWallRightClawMiss
{
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	m_bDisableSurfaceReorientation = true;
}


///  /////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////
// Class        : AVP_Alien_Move_Melee_StandingClawAttack_Start
// Author       : Anthony Gregson
// Date         : 10/03/08
////////////////////////////////////////////////////////////////////////////////

AVP_Alien_Move_Melee_StandingClawAttack_Start::AVP_Alien_Move_Melee_StandingClawAttack_Start(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Alien_Move_Melee_StandingClawAttack_Return_Hit::GetStaticHash(), AVP_Alien_Move_Melee_StandingClawAttack_Return_Countered::GetStaticHash(), AVP_Alien_Move_Melee_StandingClawAttack_Return_Miss::GetStaticHash())
{
	SetAlwaysCheckNextMoves(false);
	m_bForceStanding = true;

	const Asura_Blueprint* pxFirstPersonBlueprint = Asura_Blueprint_System::GetBlueprintByHashID(uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash);
	const Asura_Blueprint* pxThirdPersonBlueprint = Asura_Blueprint_System::GetBlueprintByHashID(uAVP_BLUEPRINT_TYPE_MELEE, uThirdPersonBlueprintHash);
	if ( pxFirstPersonBlueprint || pxThirdPersonBlueprint )
	{
		Asura_Value xValue;
		// Go through each of the parameter types

		if (pxFirstPersonBlueprint)
		{
			AVP_Blueprint_ParameterEnumerator_MeleeVariations_MultipleParameters xFPEnumerator(*this, false);

			pxFirstPersonBlueprint->EnumerateParameters(AVP_Alien_MeleeCounter_System::GetStandingLeftSlashAttackBaseParameterName(), 2, xFPEnumerator);
			pxFirstPersonBlueprint->EnumerateParameters(AVP_Alien_MeleeCounter_System::GetStandingRightSlashAttackBaseParameterName(), 2, xFPEnumerator);

			xFPEnumerator.EnumeratedAllParameters();
		}

		if (pxThirdPersonBlueprint)
		{
			AVP_Blueprint_ParameterEnumerator_MeleeVariations_MultipleParameters xTPEnumerator(*this, true);

			pxThirdPersonBlueprint->EnumerateParameters(AVP_Alien_MeleeCounter_System::GetStandingLeftSlashAttackBaseParameterName(), 2, xTPEnumerator);
			pxThirdPersonBlueprint->EnumerateParameters(AVP_Alien_MeleeCounter_System::GetStandingRightSlashAttackBaseParameterName(), 2, xTPEnumerator);

			xTPEnumerator.EnumeratedAllParameters();
		}

		SetVariation(0);
	}

	if (m_pxAVPAnimationData)
	{
		m_pxAVPAnimationData->SetTweenData(g_fTweenInDuration, 0.0f, true);
		m_pxAVPAnimationData->SetLeaveAnimAtEnd(true);
		m_pxAVPAnimationData->SetDontCalculateVelocity(true);
		m_pxAVPAnimationData->SetDontCalculateAngularVelocity(true);
	}
}

////////////////////////////////////////////////////////////////////////////////
// Class        : AVP_Alien_Move_Melee_StandingClawAttack_Return_Hit
// Author       : Anthony Gregson
// Date         : 10/03/08
////////////////////////////////////////////////////////////////////////////////

const char* AVP_Alien_Move_Melee_StandingClawAttack_Return_Hit::s_szParameterNameLeft = "StandingClawHitLeft";
const char* AVP_Alien_Move_Melee_StandingClawAttack_Return_Hit::s_szParameterNameRight = "StandingClawHitRight";

AVP_Alien_Move_Melee_StandingClawAttack_Return_Hit::AVP_Alien_Move_Melee_StandingClawAttack_Return_Hit(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash())
{
	m_bForceStanding = true;

	const Asura_Blueprint* pxFirstPersonBlueprint = Asura_Blueprint_System::GetBlueprintByHashID(uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash);
	const Asura_Blueprint* pxThirdPersonBlueprint = Asura_Blueprint_System::GetBlueprintByHashID(uAVP_BLUEPRINT_TYPE_MELEE, uThirdPersonBlueprintHash);
	if ( pxFirstPersonBlueprint || pxThirdPersonBlueprint )
	{
		Asura_Value xValue;
		// Go through each of the parameter types

		if (pxFirstPersonBlueprint)
		{
			AVP_Blueprint_ParameterEnumerator_MeleeVariations_MultipleParameters xFPEnumerator(*this, false);

			pxFirstPersonBlueprint->EnumerateParameters(s_szParameterNameLeft, 2, xFPEnumerator);
			pxFirstPersonBlueprint->EnumerateParameters(s_szParameterNameRight, 2, xFPEnumerator);

			xFPEnumerator.EnumeratedAllParameters();
		}

		if (pxThirdPersonBlueprint)
		{
			AVP_Blueprint_ParameterEnumerator_MeleeVariations_MultipleParameters xTPEnumerator(*this, true);

			pxThirdPersonBlueprint->EnumerateParameters(s_szParameterNameLeft, 2, xTPEnumerator);
			pxThirdPersonBlueprint->EnumerateParameters(s_szParameterNameRight, 2, xTPEnumerator);

			xTPEnumerator.EnumeratedAllParameters();
		}

		SetVariation(0);
	}

	if (m_pxAVPAnimationData)
	{
		m_pxAVPAnimationData->SetTweenData(g_fTweenInDuration, g_fTweenOutDuration, true);
		m_pxAVPAnimationData->SetLeaveAnimAtEnd(true);
	}

	m_bClearQueuedMeleeRequests = true;
}

////////////////////////////////////////////////////////////////////////////////
// Class        : AVP_Alien_Move_Melee_StandingClawAttack_Return_Countered
// Author       : Anthony Gregson
// Date         : 10/03/08
////////////////////////////////////////////////////////////////////////////////

const char* AVP_Alien_Move_Melee_StandingClawAttack_Return_Countered::s_szParameterNameLeft = "StandingClawCounteredLeft";
const char* AVP_Alien_Move_Melee_StandingClawAttack_Return_Countered::s_szParameterNameRight = "StandingClawCounteredRight";

AVP_Alien_Move_Melee_StandingClawAttack_Return_Countered::AVP_Alien_Move_Melee_StandingClawAttack_Return_Countered(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash())
{
	m_bForceStanding = true;

	const Asura_Blueprint* pxFirstPersonBlueprint = Asura_Blueprint_System::GetBlueprintByHashID(uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash);
	const Asura_Blueprint* pxThirdPersonBlueprint = Asura_Blueprint_System::GetBlueprintByHashID(uAVP_BLUEPRINT_TYPE_MELEE, uThirdPersonBlueprintHash);
	if ( pxFirstPersonBlueprint || pxThirdPersonBlueprint )
	{
		Asura_Value xValue;
		// Go through each of the parameter types

		if (pxFirstPersonBlueprint)
		{
			AVP_Blueprint_ParameterEnumerator_MeleeVariations_MultipleParameters xFPEnumerator(*this, false);

			pxFirstPersonBlueprint->EnumerateParameters(s_szParameterNameLeft, 2, xFPEnumerator);
			pxFirstPersonBlueprint->EnumerateParameters(s_szParameterNameRight, 2, xFPEnumerator);

			xFPEnumerator.EnumeratedAllParameters();
		}

		if (pxThirdPersonBlueprint)
		{
			AVP_Blueprint_ParameterEnumerator_MeleeVariations_MultipleParameters xTPEnumerator(*this, true);

			pxThirdPersonBlueprint->EnumerateParameters(s_szParameterNameLeft, 2, xTPEnumerator);
			pxThirdPersonBlueprint->EnumerateParameters(s_szParameterNameRight, 2, xTPEnumerator);

			xTPEnumerator.EnumeratedAllParameters();
		}

		SetVariation(0);
	}

	if (m_pxAVPAnimationData)
	{
		m_pxAVPAnimationData->SetTweenData(g_fTweenInDuration, g_fTweenOutDuration, true);
		m_pxAVPAnimationData->SetLeaveAnimAtEnd(true);
	}

	m_bClearQueuedMeleeRequests = true;
}

////////////////////////////////////////////////////////////////////////////////
// Class        : AVP_Alien_Move_Melee_StandingClawAttack_Return_Miss
// Author       : Anthony Gregson
// Date         : 10/03/08
////////////////////////////////////////////////////////////////////////////////

const char* AVP_Alien_Move_Melee_StandingClawAttack_Return_Miss::s_szParameterNameLeft = "StandingClawMissLeft";
const char* AVP_Alien_Move_Melee_StandingClawAttack_Return_Miss::s_szParameterNameRight = "StandingClawMissRight";

AVP_Alien_Move_Melee_StandingClawAttack_Return_Miss::AVP_Alien_Move_Melee_StandingClawAttack_Return_Miss(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash())
{
	m_bForceStanding = true;

	const Asura_Blueprint* pxFirstPersonBlueprint = Asura_Blueprint_System::GetBlueprintByHashID(uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash);
	const Asura_Blueprint* pxThirdPersonBlueprint = Asura_Blueprint_System::GetBlueprintByHashID(uAVP_BLUEPRINT_TYPE_MELEE, uThirdPersonBlueprintHash);
	if ( pxFirstPersonBlueprint || pxThirdPersonBlueprint )
	{
		Asura_Value xValue;
		// Go through each of the parameter types

		if (pxFirstPersonBlueprint)
		{
			AVP_Blueprint_ParameterEnumerator_MeleeVariations_MultipleParameters xFPEnumerator(*this, false);

			pxFirstPersonBlueprint->EnumerateParameters(s_szParameterNameLeft, 2, xFPEnumerator);
			pxFirstPersonBlueprint->EnumerateParameters(s_szParameterNameRight, 2, xFPEnumerator);

			xFPEnumerator.EnumeratedAllParameters();
		}

		if (pxThirdPersonBlueprint)
		{
			AVP_Blueprint_ParameterEnumerator_MeleeVariations_MultipleParameters xTPEnumerator(*this, true);

			pxThirdPersonBlueprint->EnumerateParameters(s_szParameterNameLeft, 2, xTPEnumerator);
			pxThirdPersonBlueprint->EnumerateParameters(s_szParameterNameRight, 2, xTPEnumerator);

			xTPEnumerator.EnumeratedAllParameters();
		}

		SetVariation(0);
	}

	if (m_pxAVPAnimationData)
	{
		m_pxAVPAnimationData->SetTweenData(g_fTweenInDuration, g_fTweenOutDuration, true);
		m_pxAVPAnimationData->SetLeaveAnimAtEnd(true);
		m_pxAVPAnimationData->SetDontCalculateVelocity(true);
		m_pxAVPAnimationData->SetDontCalculateAngularVelocity(true);
	}

	m_bClearQueuedMeleeRequests = true;
}


////////////////////////////////////////////////////////////////////////////////
// Class        : AVP_Alien_Move_Melee_CrouchingClawAttack_Start
// Author       : Anthony Gregson
// Date         : 26/09/08
////////////////////////////////////////////////////////////////////////////////

AVP_Alien_Move_Melee_CrouchingClawAttack_Start::AVP_Alien_Move_Melee_CrouchingClawAttack_Start(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "CrouchingClawAttackStart",
		 AVP_Alien_Move_Melee_CrouchingClawAttack_Return_Hit::GetStaticHash(), AVP_Alien_Move_Melee_CrouchingClawAttack_Return_Countered::GetStaticHash(), AVP_Alien_Move_Melee_CrouchingClawAttack_Return_Miss::GetStaticHash())
{
	m_bAllowSuckToEnemy = false;

	if (m_pxAVPAnimationData)
	{
		m_pxAVPAnimationData->SetDontCalculateVelocity(true);
		m_pxAVPAnimationData->SetDontCalculateAngularVelocity(true);
	}
}

////////////////////////////////////////////////////////////////////////////////
// Class        : AVP_Alien_Move_Melee_CrouchingClawAttack_Return_Hit
// Author       : Anthony Gregson
// Date         : 26/09/08
////////////////////////////////////////////////////////////////////////////////
static const char* g_szCrouchingClawAttackReturnParameterName = "CrouchingClawAttackReturn";

AVP_Alien_Move_Melee_CrouchingClawAttack_Return_Hit::AVP_Alien_Move_Melee_CrouchingClawAttack_Return_Hit(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, g_szCrouchingClawAttackReturnParameterName)
{
	m_bClearQueuedMeleeRequests = true;

	if (m_pxAVPAnimationData)
	{
		m_pxAVPAnimationData->SetDontCalculateVelocity(true);
		m_pxAVPAnimationData->SetDontCalculateAngularVelocity(true);
	}
}

////////////////////////////////////////////////////////////////////////////////
// Class        : AVP_Alien_Move_Melee_CrouchingClawAttack_Return_Countered
// Author       : Anthony Gregson
// Date         : 26/09/08
////////////////////////////////////////////////////////////////////////////////

AVP_Alien_Move_Melee_CrouchingClawAttack_Return_Countered::AVP_Alien_Move_Melee_CrouchingClawAttack_Return_Countered(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, g_szCrouchingClawAttackReturnParameterName)
{
	if (m_pxAVPAnimationData)
	{
		m_pxAVPAnimationData->SetDontCalculateVelocity(true);
		m_pxAVPAnimationData->SetDontCalculateAngularVelocity(true);
	}
}

////////////////////////////////////////////////////////////////////////////////
// Class        : AVP_Alien_Move_Melee_CrouchingClawAttack_Return_Miss
// Author       : Anthony Gregson
// Date         : 26/09/08
////////////////////////////////////////////////////////////////////////////////

AVP_Alien_Move_Melee_CrouchingClawAttack_Return_Miss::AVP_Alien_Move_Melee_CrouchingClawAttack_Return_Miss(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, g_szCrouchingClawAttackReturnParameterName)
{
	if (m_pxAVPAnimationData)
	{
		m_pxAVPAnimationData->SetDontCalculateVelocity(true);
		m_pxAVPAnimationData->SetDontCalculateAngularVelocity(true);
	}
}


////////////////////////////////////////////////////////////////////////////////
// Class        : AVP_Alien_Move_Melee_Headbite
// Author       : Anthony Gregson
// Date         : 08/04/08
////////////////////////////////////////////////////////////////////////////////

AVP_Alien_Move_Melee_Headbite::AVP_Alien_Move_Melee_Headbite(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash())
{
	const Asura_Blueprint* pxFirstPersonBlueprint = Asura_Blueprint_System::GetBlueprintByHashID(uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash);
	const Asura_Blueprint* pxThirdPersonBlueprint = Asura_Blueprint_System::GetBlueprintByHashID(uAVP_BLUEPRINT_TYPE_MELEE, uThirdPersonBlueprintHash);
	if ( pxFirstPersonBlueprint || pxThirdPersonBlueprint )
	{
		SetupAnimHashesFromBlueprint(pxFirstPersonBlueprint, pxThirdPersonBlueprint, 0xBD8502D8);	//"Headbite");
	}

	if (m_pxAVPAnimationData)
	{
		m_pxAVPAnimationData->SetTweenData(g_fTweenInDuration, g_fTweenOutDuration, true);
		m_pxAVPAnimationData->SetLeaveAnimAtEnd(true);
		m_pxAVPAnimationData->SetAnimPriority(AVP_AAPC_BITE_ANIM);
	}

	m_bClearQueuedMeleeRequests = true;
	m_bDisableMovement = true;
}

//DEBUGVAR float dbg_fMaxHeadbiteMoveDistanceSquared = 36.0f;
//DEBUGVAR float dbg_fHeadbiteDistance = 1.2f;
//DEBUGVAR float dbg_fHeadbiteInterpolationMultiplier = 0.2f;
//DEBUGVAR float dbg_fHeadbiteAimDirectionLerpTimeScale = 0.1f;

bool AVP_Alien_Move_Melee_Headbite::Start(const Asura_Msg_Move* pxStartMsg)
{
	// Headbites only start from message.
	if (!pxStartMsg) { return false; }

	SetVariation(0);

	//const AVP_Msg_Melee_Move* pxMeleeStart = static_cast<const AVP_Msg_Melee_Move*>(pxStartMsg);

	//const AVP_ClientEntity_Actor& xOwner = GetAVPParentSystem().GetActorOwner();
	//const Asura_Matrix_3x3& xOri = xOwner.GetCurrentOrientation();
	//m_xAimDirection = Asura_AVector3(xOri.e13, xOri.e23, xOri.e33);
	//m_uTargetGuid = pxMeleeStart->GetTargetGuid();
	//// If we have a target, aim towards it.
	//const AVP_ClientEntity_Actor* pxEnemy = AVP_ClientEntity_Actor::FindEntity(m_uTargetGuid);
	//if (pxEnemy)
	//{
	//	if (m_pxAVPAnimationData)
	//	{
	//		// We need to ensure the correct anim hash is set up, as it's about to get used.
	//		if (xOwner.IsUsingFirstPersonSkin())
	//		{
	//			m_pxAVPAnimationData->SetAnimHash(m_uFirstPersonAnimHash);
	//		}
	//		else
	//		{
	//			m_pxAVPAnimationData->SetAnimHash(m_uThirdPersonAnimHash);
	//		}
	//	}
	//	bool bHasAnimation = m_pxAVPAnimationData && m_pxAVPAnimationData->HasValidAnimation();
	//	float fDuration = bHasAnimation ? m_pxAVPAnimationData->GetAnimationDuration() : 0.3f;

	//	Asura_Vector_3 xTargetPos;
	//	Asura_Vector_3 xCameraPos;
	//	bool bGotTargetPos = pxEnemy->GetMarkerLocationFromHash(AVP_Vertebrate_Description::GetMarkerPointHashID(AVP_Vertebrate_Description::MPID_TARGET_2), &xTargetPos, NULL);
	//	if (xOwner.GetMarkerLocationFromHash(AVP_Vertebrate_Description::GetMarkerPointHashID(AVP_Vertebrate_Description::MPID_EYES), &xCameraPos, NULL)
	//		&& bGotTargetPos)
	//	{
	//		m_xAimDirection = Asura_AVector3(xTargetPos - xCameraPos);
	//		m_xAimDirection.Normalise();
	//		SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_SET_DIRECTLY);
	//	}
	//	else
	//	{
	//		SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	//	}

	//	SetAimDirectionLerpTimeScale(dbg_fHeadbiteAimDirectionLerpTimeScale);

	//	// Move to a sensible distance from the enemy
	//	if (bGotTargetPos)
	//	{
	//		const Asura_Vector_3& xOwnerPos = xOwner.GetCurrentPosition();
	//		// Move the target position to the same level as the alien, based on the alien's down vector.
	//		const Asura_Vector_3 xDown(xOri.e12, xOri.e22, xOri.e32);
	//		Asura_Vector_3 xFromEnemy = xOwnerPos - xTargetPos;
	//		Asura_Vector_3 xAdjustment = xDown * (xDown * xFromEnemy);
	//		xFromEnemy -= xAdjustment;
	//		xTargetPos += xAdjustment;
	//		const float fMagSquared = xFromEnemy.MagnitudeSquared();

	//		if (fMagSquared <= dbg_fMaxHeadbiteMoveDistanceSquared)
	//		{
	//			xFromEnemy.Normalise();
	//			xTargetPos = xTargetPos + (xFromEnemy * dbg_fHeadbiteDistance);
	//			m_xPositionInterpolation.SetInitial(xOwnerPos);
	//			m_xPositionInterpolation.SetFinal(xTargetPos);

	//			m_xPositionInterpolation.SetDuration(fDuration * dbg_fHeadbiteInterpolationMultiplier);

	//			m_xParentSystem.SetCurrentMovePosition(xOwnerPos);
	//			InitialisePositionInterpolation(m_xPositionInterpolation);
	//			// We just want to use the velocity.
	//			SetPositionUsage(POSITION_SET_FROM_VELOCITY);

	//			Asura_Matrix_3x3 xOri;
	//			Asura_Maths::OrientationFromDirection(xOri, -xFromEnemy);
	//			m_xOrientationInterpolation.SetFinal(xOri);
	//			m_xOrientationInterpolation.SetDuration(fDuration * dbg_fHeadbiteInterpolationMultiplier);

	//			InitialiseOrientationInterpolation(m_xOrientationInterpolation);
	//		}
	//	}
	//}
	//else
	//{
	//	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	//}

	return PARENT::Start(pxStartMsg);
}

void AVP_Alien_Move_Melee_Headbite::UpdateStates(const float fTimeStep)
{
	// Update to look at our target entity's head.
	//const AVP_ClientEntity_Actor& xOwner = GetAVPParentSystem().GetActorOwner();
	//const AVP_ClientEntity_Actor* pxEnemy = AVP_ClientEntity_Actor::FindEntity(m_uTargetGuid);
	//if (pxEnemy)
	//{
	//	Asura_Vector_3 xTargetPos;
	//	Asura_Vector_3 xOwnerPos;
	//	if (xOwner.GetMarkerLocationFromHash(AVP_Vertebrate_Description::GetMarkerPointHashID(AVP_Vertebrate_Description::MPID_EYES), &xOwnerPos, NULL)
	//		&& pxEnemy->GetMarkerLocationFromHash(AVP_Vertebrate_Description::GetMarkerPointHashID(AVP_Vertebrate_Description::MPID_TARGET_2), &xTargetPos, NULL))
	//	{
	//		m_xAimDirection = Asura_AVector3(xTargetPos - xOwnerPos);
	//		m_xAimDirection.Normalise();
	//	}
	//}

	//if (m_xPositionInterpolation.IsFinished())
	//{
	//	SetPositionUsage(POSITION_NOT_USED);
	//}

	PARENT::UpdateStates(fTimeStep);
}

//////////////////////////////////////////////////////////////////////////////
//
// Crawl to stand attack classes.
// (Claw slash attack for the AI that starts from the crawl pose.)
//
//////////////////////////////////////////////////////////////////////////////

DEBUGVAR float dbg_fWalkSwipeAnimDistance = 3.2f;
DEBUGVAR float dbg_fOptimalDisatnceFromPlayer = 0.75f;
DEBUGVAR float dbg_fStandAttackMaxTurnSpeed = Asura_Maths::Pi / 8.0f;
//DEBUGVAR float dbg_fStandAttackMaxSpeedMultiplier = 1.5f;

// Right.

AVP_Alien_Move_Melee_CrawlToStandAttackR_Base_Start::AVP_Alien_Move_Melee_CrawlToStandAttackR_Base_Start( Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uMoveHash, Asura_Hash_ID uThirdPersonBlueprintHash, const char* szBaseParameterName )
: PARENT( xParentSystem, uMoveHash,
		  uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, szBaseParameterName,
		  AVP_Alien_Move_Melee_CrawlToStandAttackR_Return_Hit::GetStaticHash(),
		  AVP_Alien_Move_Melee_CrawlToStandAttackR_Return_Countered::GetStaticHash(),
		  AVP_Alien_Move_Melee_CrawlToStandAttackR_Return_Miss::GetStaticHash() )
, m_fAnimTime(0.0f)
, m_xTargetStartPosition(Asura_Maths::ZeroVector3)
, m_uTarget(ASURA_GUID_UNREGISTERED)
, m_fVelocityMultiplier(1.0f)
{
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetLookAtPositionUsage(AVP_ClientEntity_Actor::LOOK_AT_POSITION_RESET);
	m_bDisableSurfaceReorientation = true;

	if (m_pxAVPAnimationData)
	{
		m_pxAVPAnimationData->SetTweenData(g_fTweenInDuration, 0.0f, false);
		m_pxAVPAnimationData->SetLeaveAnimAtEnd(true);
	}

}

DEBUGVAR float dbg_fCTSAttackReorientationTime = 0.25f;

bool AVP_Alien_Move_Melee_CrawlToStandAttackR_Base_Start::Start( const Asura_Msg_Move* pxStartMsg )
{
	if (!pxStartMsg) { return false; }

	bool bResult = PARENT::Start(pxStartMsg);

	const AVP_Msg_Melee_Move* pxMeleeStart = static_cast< const AVP_Msg_Melee_Move* >( pxStartMsg );

	AVP_ClientEntity_Actor& xOwner = GetAVPParentSystem().GetActorOwner();

	// Get an upright orientation to interpolate to.
	m_uTarget = pxMeleeStart->GetTargetGuid();
	const AVP_ClientEntity_Actor* pxTarget = AVP_ClientEntity_Actor::FindEntity( m_uTarget );
	if ( !pxTarget ) { return false; }

	Asura_Matrix_3x3 xOri;
	Asura_Vector_3 xTargetOffset = pxTarget->GetCurrentPosition() - xOwner.GetCurrentPosition();
	xTargetOffset.y = 0.0f;	
	if (m_pxAVPAnimationData && m_pxAVPAnimationData->HasValidAnimation())
	{
		m_fAnimTime = m_pxAVPAnimationData->GetAnimationDuration();
	}
	else
	{
		m_fAnimTime = 1.0f;
	}
	m_xTargetStartPosition =  pxTarget->GetCurrentPosition();
	if (xTargetOffset.ApproximatelyEquals(Asura_Maths::ZeroVector3))
	{
		Asura_Euler_3 xEuler;
		xEuler.FromMatrix(xOwner.GetCurrentOrientation());
		xEuler.x = xEuler.z = 0.0f;
		xEuler.ToMatrix(xOri);
		m_fVelocityMultiplier = 1.0f;
	}
	else
	{
		float fTargetOffset = xTargetOffset.Normalise();
		m_fVelocityMultiplier = (fTargetOffset - dbg_fOptimalDisatnceFromPlayer) / dbg_fWalkSwipeAnimDistance;
		if (m_fVelocityMultiplier < 1.0f)
		{
			m_fVelocityMultiplier = 1.0;
		}
		 
		Asura_Maths::OrientationFromDirection(xOri, xTargetOffset);
	}
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);

	if (bResult && Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(true);
		}
	}

	return bResult;
}

void AVP_Alien_Move_Melee_CrawlToStandAttackR_Base_Start::Abort()
{
	EnsureAnimationFinishes();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}

	PARENT::Abort();
}

bool AVP_Alien_Move_Melee_CrawlToStandAttackR_Base_Start::CalculateVelocity(const float fTimeStep, Asura_AVector3_OutParam xVelocity) const
{
	Asura_AVector3 xRefVelocity;
	bool bResult = PARENT::CalculateVelocity(fTimeStep, xRefVelocity);
	float fRefVelocity = xRefVelocity.Magnitude();

	if (xRefVelocity.ApproximatelyEquals(Asura_Maths::ZeroAVector3))
	{
		xVelocity = xRefVelocity; 
		return bResult;
	}

	xRefVelocity /= fRefVelocity;
	xRefVelocity *= m_fVelocityMultiplier;

	const AVP_ClientEntity_Actor* pxTarget = AVP_ClientEntity_Actor::FindEntity( m_uTarget );

	if ( !pxTarget || m_fAnimTime <= 0.0f ) 
	{
		xVelocity = xRefVelocity * fRefVelocity;
		return bResult; 
	}

	Asura_Vector_3 xTargetVelocity = (pxTarget->GetCurrentPosition() - m_xTargetStartPosition) / fTimeStep;
	m_xTargetStartPosition =  pxTarget->GetCurrentPosition();
	float fTargetVelocity = xTargetVelocity.Normalise();

	if ((Asura_Vector_3(xRefVelocity) * xTargetVelocity) <= 0.0f) // target moving towards us - return the animation velocity
	{
		xVelocity = xRefVelocity * fRefVelocity;
		return bResult; 
	}

	xVelocity = xRefVelocity * (fRefVelocity + fTargetVelocity * (Asura_Vector_3(xRefVelocity) * xTargetVelocity));

	return bResult;
}

bool AVP_Alien_Move_Melee_CrawlToStandAttackR_Base_Start::CalculateOrientation(const float fTimeStep, Asura_Quat& xOrientation) const
{
	const AVP_ClientEntity_Actor* pxTarget = AVP_ClientEntity_Actor::FindEntity( m_uTarget );
	const AVP_ClientEntity_Actor& xOwner = GetAVPParentSystem().GetActorOwner();
	const Asura_Matrix_3x3& xOwnerOri = xOwner.GetCurrentOrientation();

	if ( !pxTarget ) 
	{
		xOrientation.FromMatrix(xOwnerOri); // keep current orientation
		return false; 
	}

	Asura_Vector_3 xTargetOffset = pxTarget->GetCurrentPosition() - xOwner.GetCurrentPosition();
	xTargetOffset.y = 0.0f;	
	if (xTargetOffset.ApproximatelyEquals(Asura_Maths::ZeroVector3))
	{
		xOrientation.FromMatrix(xOwnerOri); // keep current orientation
	}
	else
	{
		const Asura_Vector_3 xForward(xOwnerOri.e13, xOwnerOri.e23, xOwnerOri.e33);
		xTargetOffset.Normalise();
		if (xForward * xTargetOffset > fTimeStep * dbg_fStandAttackMaxTurnSpeed) // small enough turn - just set new orientation
		{
			Asura_Matrix_3x3 xNewOrientation;
			Asura_Maths::OrientationFromDirection(xNewOrientation, xTargetOffset);
			xOrientation.FromMatrix(xNewOrientation);
		}
		else // turn is too much - turn as much as possible
		{
			const Asura_Vector_3 xRight(xOwnerOri.e12, xOwnerOri.e22, xOwnerOri.e32);
			const Asura_Vector_3 xUp(0.0f, -1.0f, 0.0f);
			float fTurnDirection = xRight * xTargetOffset > 0.0f ? 1.0f : -1.0f;
			Asura_Quat xTurn;
			
			xTurn.FromRotation(fTurnDirection* fTimeStep * dbg_fStandAttackMaxTurnSpeed, xUp);
			Asura_Vector_3 xNewDirection = xTurn.RotateVector(xForward);
			Asura_Matrix_3x3 xNewOrientation;
			Asura_Maths::OrientationFromDirection(xNewOrientation, xNewDirection);
			xOrientation.FromMatrix(xNewOrientation);
		}
	}
	// don't wait for this to finish
	return false;
}

void AVP_Alien_Move_Melee_CrawlToStandAttackR_Base_Start::UpdateStates(const float fTimeStep)
{
	Asura_Quat xOrientation;
	CalculateOrientation(false, xOrientation);
	m_xParentSystem.SetCurrentMoveOrientation(xOrientation);
	PARENT::UpdateStates(fTimeStep);

}

AVP_Alien_Move_Melee_CrawlToStandAttackR_Start::AVP_Alien_Move_Melee_CrawlToStandAttackR_Start(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, uFirstPersonBlueprintHash, GetStaticHash(), uThirdPersonBlueprintHash, "CrawlToStandAttackRStart")
{
}

AVP_Alien_Move_Melee_CrawlToStandAttackShortR_Start::AVP_Alien_Move_Melee_CrawlToStandAttackShortR_Start(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, uFirstPersonBlueprintHash, GetStaticHash(), uThirdPersonBlueprintHash, "CrawlToStandAttackShortRStart")
{
}



AVP_Alien_Move_Melee_CrawlToStandAttackR_Return_Hit::AVP_Alien_Move_Melee_CrawlToStandAttackR_Return_Hit( Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash )
: PARENT( xParentSystem, GetStaticHash(),
		  uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "CrawlToStandAttackRReturnHit" ) 
{
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetLookAtPositionUsage(AVP_ClientEntity_Actor::LOOK_AT_POSITION_RESET);
	m_bDisableSurfaceReorientation = true;
	SetAIPostMoveMode(AI_MM_MDEIUM);
}

void AVP_Alien_Move_Melee_CrawlToStandAttackR_Return_Hit::Finish()
{
	PARENT::Finish();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

void AVP_Alien_Move_Melee_CrawlToStandAttackR_Return_Hit::Abort()
{
	PARENT::Abort();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

AVP_Alien_Move_Melee_CrawlToStandAttackR_Return_Countered::AVP_Alien_Move_Melee_CrawlToStandAttackR_Return_Countered( Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash )
: PARENT( xParentSystem, GetStaticHash(),
		  uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "CrawlToStandAttackRReturnCountered" ) 
{
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetLookAtPositionUsage(AVP_ClientEntity_Actor::LOOK_AT_POSITION_RESET);
	m_bDisableSurfaceReorientation = true;

}

void AVP_Alien_Move_Melee_CrawlToStandAttackR_Return_Countered::Finish()
{
	PARENT::Finish();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

void AVP_Alien_Move_Melee_CrawlToStandAttackR_Return_Countered::Abort()
{
	PARENT::Abort();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

AVP_Alien_Move_Melee_CrawlToStandAttackR_Return_Miss::AVP_Alien_Move_Melee_CrawlToStandAttackR_Return_Miss( Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash )
: PARENT( xParentSystem, GetStaticHash(),
		  uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "CrawlToStandAttackRReturnMiss" ) 
{
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetLookAtPositionUsage(AVP_ClientEntity_Actor::LOOK_AT_POSITION_RESET);
	m_bDisableSurfaceReorientation = true;
	SetAIPostMoveMode(AI_MM_MDEIUM);
}

bool AVP_Alien_Move_Melee_CrawlToStandAttackR_Return_Miss::ShouldStart() const
{
	if (GetParentSystem().GetCurrentMove()->GetHash() == AVP_Alien_Move_Melee_CrawlToStandAttackR_Start::GetStaticHash())
	{
		return PARENT::ShouldStart();
	}
	else
	{
		return true;
	}
}

bool AVP_Alien_Move_Melee_CrawlToStandAttackR_Return_Miss::Start(const Asura_Msg_Move* pxStartMsg)
{
	if (GetParentSystem().GetCurrentMove()->GetHash() == AVP_Alien_Move_Melee_CrawlToStandAttackR_Start::GetStaticHash())
	{
		return PARENT::Start(pxStartMsg);
	}
	else
	{
		return GRANDPARENT::Start(pxStartMsg); // this is not regular melee anymore but a puppet ending 
	}
}

void AVP_Alien_Move_Melee_CrawlToStandAttackR_Return_Miss::Finish()
{
	PARENT::Finish();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

void AVP_Alien_Move_Melee_CrawlToStandAttackR_Return_Miss::Abort()
{
	PARENT::Abort();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

// Left.
AVP_Alien_Move_Melee_CrawlToStandAttackL_Base_Start::AVP_Alien_Move_Melee_CrawlToStandAttackL_Base_Start( Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uMoveHash, Asura_Hash_ID uThirdPersonBlueprintHash, const char* szBaseParameterName )
: PARENT( xParentSystem, uMoveHash,
		  uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "CrawlToStandAttackLStart", 
		  AVP_Alien_Move_Melee_CrawlToStandAttackL_Return_Hit::GetStaticHash(),
		  AVP_Alien_Move_Melee_CrawlToStandAttackL_Return_Countered::GetStaticHash(),
		  AVP_Alien_Move_Melee_CrawlToStandAttackL_Return_Miss::GetStaticHash() )
//, m_xOrientationInterpolationData()
, m_fAnimTime(0.0f)
, m_xTargetStartPosition(Asura_Maths::ZeroVector3)
, m_uTarget(ASURA_GUID_UNREGISTERED)
, m_fVelocityMultiplier(1.0f)

{
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetLookAtPositionUsage(AVP_ClientEntity_Actor::LOOK_AT_POSITION_RESET);
	m_bDisableSurfaceReorientation = true;

	if (m_pxAVPAnimationData)
	{
		m_pxAVPAnimationData->SetTweenData(g_fTweenInDuration, 0.0f, false);
		m_pxAVPAnimationData->SetLeaveAnimAtEnd(true);
	}

}

bool AVP_Alien_Move_Melee_CrawlToStandAttackL_Base_Start::Start( const Asura_Msg_Move* pxStartMsg )
{
	if (!pxStartMsg) { return false; }

	bool bResult = PARENT::Start(pxStartMsg);

	const AVP_Msg_Melee_Move* pxMeleeStart = static_cast< const AVP_Msg_Melee_Move* >( pxStartMsg );

	AVP_ClientEntity_Actor& xOwner = GetAVPParentSystem().GetActorOwner();

	// Get an upright orientation to interpolate to.
	m_uTarget = pxMeleeStart->GetTargetGuid();
	const AVP_ClientEntity_Actor* pxTarget = AVP_ClientEntity_Actor::FindEntity( m_uTarget );
	if ( !pxTarget ) { return false; }

	Asura_Matrix_3x3 xOri;
	Asura_Vector_3 xTargetOffset = pxTarget->GetCurrentPosition() - xOwner.GetCurrentPosition();
	xTargetOffset.y = 0.0f;
	if (m_pxAVPAnimationData && m_pxAVPAnimationData->HasValidAnimation())
	{
		m_fAnimTime = m_pxAVPAnimationData->GetAnimationDuration();
	}
	else
	{
		m_fAnimTime = 1.0f;
	}
	m_xTargetStartPosition = pxTarget->GetCurrentPosition();

	if (xTargetOffset.ApproximatelyEquals(Asura_Maths::ZeroVector3))
	{
		Asura_Euler_3 xEuler;
		xEuler.FromMatrix(xOwner.GetCurrentOrientation());
		xEuler.x = xEuler.z = 0.0f;
		xEuler.ToMatrix(xOri);
		m_fVelocityMultiplier = 1.0f;
	}
	else
	{
		float fTargetOffset = xTargetOffset.Normalise();
		m_fVelocityMultiplier = (fTargetOffset - dbg_fOptimalDisatnceFromPlayer) / dbg_fWalkSwipeAnimDistance;
		if (m_fVelocityMultiplier < 1.0f)
		{
			m_fVelocityMultiplier = 1.0;
		}
		Asura_Maths::OrientationFromDirection(xOri, xTargetOffset);
	}
// 	m_xOrientationInterpolationData.SetFinal(xOri);
// 	m_xOrientationInterpolationData.SetInitial(xOwner.GetCurrentOrientation());
// 	m_xOrientationInterpolationData.SetDuration(dbg_fCTSAttackReorientationTime);
// 
// 	InitialiseOrientationInterpolation(m_xOrientationInterpolationData);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);

	if (bResult && Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(true);
		}
	}

	return bResult;
}

void AVP_Alien_Move_Melee_CrawlToStandAttackL_Base_Start::Abort()
{
	EnsureAnimationFinishes();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}

	PARENT::Abort();
}

bool AVP_Alien_Move_Melee_CrawlToStandAttackL_Base_Start::CalculateVelocity(const float fTimeStep, Asura_AVector3_OutParam xVelocity) const
{
	Asura_AVector3 xRefVelocity;
	bool bResult = PARENT::CalculateVelocity(fTimeStep, xRefVelocity);
	const AVP_ClientEntity_Actor* pxTarget = AVP_ClientEntity_Actor::FindEntity( m_uTarget );
	float fRefVelocity = xRefVelocity.Magnitude();

	if (xRefVelocity.ApproximatelyEquals(Asura_Maths::ZeroAVector3))
	{
		xVelocity = xRefVelocity; 
		return bResult;
	}

	xRefVelocity /= fRefVelocity;
	xRefVelocity *= m_fVelocityMultiplier;

	if ( !pxTarget || m_fAnimTime <= 0.0f ) 
	{
		xVelocity = xRefVelocity * fRefVelocity;
		return bResult; 
	}

	Asura_Vector_3 xTargetVelocity = (pxTarget->GetCurrentPosition() - m_xTargetStartPosition) / fTimeStep;
	m_xTargetStartPosition =  pxTarget->GetCurrentPosition();
	float fTargetVelocity = xTargetVelocity.Normalise();

	if ((Asura_Vector_3(xRefVelocity) * xTargetVelocity) <= 0.0f) // target moving towards us - return the animation velocity
	{
		xVelocity = xRefVelocity * fRefVelocity;
		return bResult; 
	}


	xVelocity = xRefVelocity * (fRefVelocity + fTargetVelocity * (Asura_Vector_3(xRefVelocity) * xTargetVelocity));

// 	
// 
// 
// 
// 	float fVelocity;
// 
// 	const AVP_ClientEntity_Actor& xOwner = GetAVPParentSystem().GetActorOwner();
// 	Asura_Vector_3 xTargetOffset = pxTarget->GetCurrentPosition() - xOwner.GetCurrentPosition();
// 	float fTargetOffset = xTargetOffset.Magnitude();
// 	fVelocity = Asura_Maths::ClampToRange(fTargetOffset / m_fAnimTime, fRefVelocity, fRefVelocity * dbg_fStandAttackMaxSpeedMultiplier);
// 	xVelocity = xRefVelocity * fVelocity;
// 	m_fAnimTime -= fTimeStep;
	return bResult;
}

bool AVP_Alien_Move_Melee_CrawlToStandAttackL_Base_Start::CalculateOrientation(const float fTimeStep, Asura_Quat& xOrientation) const
{
	const AVP_ClientEntity_Actor* pxTarget = AVP_ClientEntity_Actor::FindEntity( m_uTarget );
	const AVP_ClientEntity_Actor& xOwner = GetAVPParentSystem().GetActorOwner();
	const Asura_Matrix_3x3& xOwnerOri = xOwner.GetCurrentOrientation();

	if ( !pxTarget ) 
	{
		xOrientation.FromMatrix(xOwnerOri); // keep current orientation
		return false; 
	}

	Asura_Vector_3 xTargetOffset = pxTarget->GetCurrentPosition() - xOwner.GetCurrentPosition();
	xTargetOffset.y = 0.0f;	
	if (xTargetOffset.ApproximatelyEquals(Asura_Maths::ZeroVector3))
	{
		xOrientation.FromMatrix(xOwnerOri); // keep current orientation
	}
	else
	{
		const Asura_Vector_3 xForward(xOwnerOri.e13, xOwnerOri.e23, xOwnerOri.e33);
		xTargetOffset.Normalise();
		if (xForward * xTargetOffset > fTimeStep * dbg_fStandAttackMaxTurnSpeed) // small enough turn - just set new orientation
		{
			Asura_Matrix_3x3 xNewOrientation;
			Asura_Maths::OrientationFromDirection(xNewOrientation, xTargetOffset);
			xOrientation.FromMatrix(xNewOrientation);
		}
		else // turn is too much - turn as much as possible
		{
			const Asura_Vector_3 xRight(xOwnerOri.e12, xOwnerOri.e22, xOwnerOri.e32);
			const Asura_Vector_3 xUp(0.0f, -1.0f, 0.0f);
			float fTurnDirection = xRight * xTargetOffset > 0.0f ? 1.0f : -1.0f;
			Asura_Quat xTurn;

			xTurn.FromRotation(fTurnDirection* fTimeStep * dbg_fStandAttackMaxTurnSpeed, xUp);
			Asura_Vector_3 xNewDirection = xTurn.RotateVector(xForward);
			Asura_Matrix_3x3 xNewOrientation;
			Asura_Maths::OrientationFromDirection(xNewOrientation, xNewDirection);
			xOrientation.FromMatrix(xNewOrientation);
		}
	}
	// don't wait for this to finish
	return false;
}

void AVP_Alien_Move_Melee_CrawlToStandAttackL_Base_Start::UpdateStates(const float fTimeStep)
{
	Asura_Quat xOrientation;
	CalculateOrientation(false, xOrientation);
	m_xParentSystem.SetCurrentMoveOrientation(xOrientation);
	PARENT::UpdateStates(fTimeStep);

}


AVP_Alien_Move_Melee_CrawlToStandAttackL_Start::AVP_Alien_Move_Melee_CrawlToStandAttackL_Start(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, uFirstPersonBlueprintHash, GetStaticHash(), uThirdPersonBlueprintHash, "CrawlToStandAttackLStart")
{
}

AVP_Alien_Move_Melee_CrawlToStandAttackShortL_Start::AVP_Alien_Move_Melee_CrawlToStandAttackShortL_Start(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, uFirstPersonBlueprintHash, GetStaticHash(), uThirdPersonBlueprintHash, "CrawlToStandAttackShortLStart")
{
}


AVP_Alien_Move_Melee_CrawlToStandAttackL_Return_Hit::AVP_Alien_Move_Melee_CrawlToStandAttackL_Return_Hit( Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash )
: PARENT( xParentSystem, GetStaticHash(),
		  uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "CrawlToStandAttackLReturnHit" ) 
{
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetLookAtPositionUsage(AVP_ClientEntity_Actor::LOOK_AT_POSITION_RESET);
	m_bDisableSurfaceReorientation = true;
	SetAIPostMoveMode(AI_MM_MDEIUM);

}

void AVP_Alien_Move_Melee_CrawlToStandAttackL_Return_Hit::Finish()
{
	PARENT::Finish();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

void AVP_Alien_Move_Melee_CrawlToStandAttackL_Return_Hit::Abort()
{
	PARENT::Abort();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

AVP_Alien_Move_Melee_CrawlToStandAttackL_Return_Countered::AVP_Alien_Move_Melee_CrawlToStandAttackL_Return_Countered( Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash )
: PARENT( xParentSystem, GetStaticHash(),
		  uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "CrawlToStandAttackLReturnCountered" ) 
{
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetLookAtPositionUsage(AVP_ClientEntity_Actor::LOOK_AT_POSITION_RESET);
	m_bDisableSurfaceReorientation = true;

}

void AVP_Alien_Move_Melee_CrawlToStandAttackL_Return_Countered::Finish()
{
	PARENT::Finish();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

void AVP_Alien_Move_Melee_CrawlToStandAttackL_Return_Countered::Abort()
{
	PARENT::Abort();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

AVP_Alien_Move_Melee_CrawlToStandAttackL_Return_Miss::AVP_Alien_Move_Melee_CrawlToStandAttackL_Return_Miss( Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash )
: PARENT( xParentSystem, GetStaticHash(),
		  uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "CrawlToStandAttackLReturnMiss" ) 
{
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetLookAtPositionUsage(AVP_ClientEntity_Actor::LOOK_AT_POSITION_RESET);
	m_bDisableSurfaceReorientation = true;
	SetAIPostMoveMode(AI_MM_MDEIUM);

}

bool AVP_Alien_Move_Melee_CrawlToStandAttackL_Return_Miss::ShouldStart() const
{
	if (GetParentSystem().GetCurrentMove()->GetHash() == AVP_Alien_Move_Melee_CrawlToStandAttackL_Start::GetStaticHash())
	{
		return PARENT::ShouldStart();
	}
	else
	{
		return true;
	}
}

bool AVP_Alien_Move_Melee_CrawlToStandAttackL_Return_Miss::Start(const Asura_Msg_Move* pxStartMsg)
{
	if (GetParentSystem().GetCurrentMove()->GetHash() == AVP_Alien_Move_Melee_CrawlToStandAttackL_Start::GetStaticHash())
	{
		return PARENT::Start(pxStartMsg);
	}
	else
	{
		return GRANDPARENT::Start(pxStartMsg); // this is not regular melee anymore but a puppet ending 
	}
}

void AVP_Alien_Move_Melee_CrawlToStandAttackL_Return_Miss::Finish()
{
	PARENT::Finish();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

void AVP_Alien_Move_Melee_CrawlToStandAttackL_Return_Miss::Abort()
{
	PARENT::Abort();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

//////////////////////////////////////////////////////////////////////////////
//
// Stand attack loop classes.
// (Standing claw slash attacks for the AI that can be chained after the initial crawl to stand attack.)
//
//////////////////////////////////////////////////////////////////////////////

// Right.
AVP_Alien_Move_Melee_StandAttackLoopR_Start::AVP_Alien_Move_Melee_StandAttackLoopR_Start( Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash )
: PARENT( xParentSystem, GetStaticHash(),
		  uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "CTStandAttackLoopRStart", 
		  AVP_Alien_Move_Melee_StandAttackLoopR_Return_Hit::GetStaticHash(),
		  AVP_Alien_Move_Melee_StandAttackLoopR_Return_Countered::GetStaticHash(),
		  AVP_Alien_Move_Melee_StandAttackLoopR_Return_Miss::GetStaticHash() )
{
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetLookAtPositionUsage(AVP_ClientEntity_Actor::LOOK_AT_POSITION_RESET);
	m_bDisableSurfaceReorientation = true;

	if (m_pxAVPAnimationData)
	{
		m_pxAVPAnimationData->SetTweenData(g_fTweenInDuration, 0.0f, false);
		m_pxAVPAnimationData->SetLeaveAnimAtEnd(true);
	}

}

bool AVP_Alien_Move_Melee_StandAttackLoopR_Start::Start( const Asura_Msg_Move* pxStartMsg )
{
	if (!pxStartMsg) { return false; }

	const AVP_Msg_Melee_Move* pxMeleeStart = static_cast< const AVP_Msg_Melee_Move* >( pxStartMsg );

	AVP_ClientEntity_Actor& xOwner = GetAVPParentSystem().GetActorOwner();

	// Get an upright orientation to interpolate to.
	const AVP_ClientEntity_Actor* pxTarget = AVP_ClientEntity_Actor::FindEntity( pxMeleeStart->GetTargetGuid() );
	if ( !pxTarget ) { return false; }

	Asura_Matrix_3x3 xOri;
	Asura_Vector_3 xTargetOffset = pxTarget->GetCurrentPosition() - xOwner.GetCurrentPosition();
	xTargetOffset.y = 0.0f;
	if (xTargetOffset.ApproximatelyEquals(Asura_Maths::ZeroVector3))
	{
		Asura_Euler_3 xEuler;
		xEuler.FromMatrix(xOwner.GetCurrentOrientation());
		xEuler.x = xEuler.z = 0.0f;
		xEuler.ToMatrix(xOri);
	}
	else
	{
		xTargetOffset.Normalise();
		Asura_Maths::OrientationFromDirection(xOri, xTargetOffset);
	}
	m_xOrientationInterpolationData.SetFinal(xOri);
	m_xOrientationInterpolationData.SetInitial(xOwner.GetCurrentOrientation());
	m_xOrientationInterpolationData.SetDuration(dbg_fCTSAttackReorientationTime);

	InitialiseOrientationInterpolation(m_xOrientationInterpolationData);
	
	bool bResult = PARENT::Start(pxStartMsg);

	if (bResult && Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(true);
		}
	}

	return bResult;
}

void AVP_Alien_Move_Melee_StandAttackLoopR_Start::Abort()
{
	EnsureAnimationFinishes();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}

	PARENT::Abort();
}

AVP_Alien_Move_Melee_StandAttackLoopR_Return_Hit::AVP_Alien_Move_Melee_StandAttackLoopR_Return_Hit( Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash )
: PARENT( xParentSystem, GetStaticHash(),
		  uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "CTStandAttackLoopRReturnHit" ) 
{
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetLookAtPositionUsage(AVP_ClientEntity_Actor::LOOK_AT_POSITION_RESET);
	m_bDisableSurfaceReorientation = true;
	SetAIPostMoveMode(AI_MM_MDEIUM);
}

void AVP_Alien_Move_Melee_StandAttackLoopR_Return_Hit::Finish()
{
	PARENT::Finish();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

void AVP_Alien_Move_Melee_StandAttackLoopR_Return_Hit::Abort()
{
	PARENT::Abort();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

AVP_Alien_Move_Melee_StandAttackLoopR_Return_Countered::AVP_Alien_Move_Melee_StandAttackLoopR_Return_Countered( Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash )
: PARENT( xParentSystem, GetStaticHash(),
		  uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "CTStandAttackLoopRReturnCountered" ) 
{
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetLookAtPositionUsage(AVP_ClientEntity_Actor::LOOK_AT_POSITION_RESET);
	m_bDisableSurfaceReorientation = true;

	AddNextMove(AVP_Alien_Move_Melee_StandAttackLoopR_Return_Miss::GetStaticHash());
}

void AVP_Alien_Move_Melee_StandAttackLoopR_Return_Countered::Finish()
{
	PARENT::Finish();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

void AVP_Alien_Move_Melee_StandAttackLoopR_Return_Countered::Abort()
{
	PARENT::Abort();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

AVP_Alien_Move_Melee_StandAttackLoopR_Return_Miss::AVP_Alien_Move_Melee_StandAttackLoopR_Return_Miss( Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash )
: PARENT( xParentSystem, GetStaticHash(),
		  uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "CTStandAttackLoopRReturnMiss" )
{
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetLookAtPositionUsage(AVP_ClientEntity_Actor::LOOK_AT_POSITION_RESET);
	m_bDisableSurfaceReorientation = true;
	SetAIPostMoveMode(AI_MM_MDEIUM);
}

bool AVP_Alien_Move_Melee_StandAttackLoopR_Return_Miss::ShouldStart() const
{
	if (GetParentSystem().GetCurrentMove()->GetHash() == AVP_Alien_Move_Melee_StandAttackLoopR_Return_Countered::GetStaticHash())
	{
		return true;
	}
	else
	{
		return PARENT::ShouldStart();
	}
}

void AVP_Alien_Move_Melee_StandAttackLoopR_Return_Miss::Finish()
{
	PARENT::Finish();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

void AVP_Alien_Move_Melee_StandAttackLoopR_Return_Miss::Abort()
{
	PARENT::Abort();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

// Left.
AVP_Alien_Move_Melee_StandAttackLoopL_Start::AVP_Alien_Move_Melee_StandAttackLoopL_Start( Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash )
: PARENT( xParentSystem, GetStaticHash(),
		  uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "CTStandAttackLoopLStart", 
		  AVP_Alien_Move_Melee_StandAttackLoopL_Return_Hit::GetStaticHash(),
		  AVP_Alien_Move_Melee_StandAttackLoopL_Return_Countered::GetStaticHash(),
		  AVP_Alien_Move_Melee_StandAttackLoopL_Return_Miss::GetStaticHash() )
{
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetLookAtPositionUsage(AVP_ClientEntity_Actor::LOOK_AT_POSITION_RESET);
	m_bDisableSurfaceReorientation = true;

	if (m_pxAVPAnimationData)
	{
		m_pxAVPAnimationData->SetTweenData(g_fTweenInDuration, 0.0f, false);
		m_pxAVPAnimationData->SetLeaveAnimAtEnd(true);
	}

}

bool AVP_Alien_Move_Melee_StandAttackLoopL_Start::Start( const Asura_Msg_Move* pxStartMsg )
{
	if (!pxStartMsg) { return false; }

	const AVP_Msg_Melee_Move* pxMeleeStart = static_cast< const AVP_Msg_Melee_Move* >( pxStartMsg );

	AVP_ClientEntity_Actor& xOwner = GetAVPParentSystem().GetActorOwner();

	// Get an upright orientation to interpolate to.
	const AVP_ClientEntity_Actor* pxTarget = AVP_ClientEntity_Actor::FindEntity( pxMeleeStart->GetTargetGuid() );
	if ( !pxTarget ) { return false; }

	Asura_Matrix_3x3 xOri;
	Asura_Vector_3 xTargetOffset = pxTarget->GetCurrentPosition() - xOwner.GetCurrentPosition();
	xTargetOffset.y = 0.0f;
	if (xTargetOffset.ApproximatelyEquals(Asura_Maths::ZeroVector3))
	{
		Asura_Euler_3 xEuler;
		xEuler.FromMatrix(xOwner.GetCurrentOrientation());
		xEuler.x = xEuler.z = 0.0f;
		xEuler.ToMatrix(xOri);
	}
	else
	{
		xTargetOffset.Normalise();
		Asura_Maths::OrientationFromDirection(xOri, xTargetOffset);
	}
	m_xOrientationInterpolationData.SetFinal(xOri);
	m_xOrientationInterpolationData.SetInitial(xOwner.GetCurrentOrientation());
	m_xOrientationInterpolationData.SetDuration(dbg_fCTSAttackReorientationTime);

	InitialiseOrientationInterpolation(m_xOrientationInterpolationData);
	
	bool bResult = PARENT::Start(pxStartMsg);

	if (bResult && Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(true);
		}
	}

	return bResult;
}


void AVP_Alien_Move_Melee_StandAttackLoopL_Start::Abort()
{
	EnsureAnimationFinishes();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
	PARENT::Abort();
}

AVP_Alien_Move_Melee_StandAttackLoopL_Return_Hit::AVP_Alien_Move_Melee_StandAttackLoopL_Return_Hit( Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash )
: PARENT( xParentSystem, GetStaticHash(),
		  uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "CTStandAttackLoopLReturnHit" )
{
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetLookAtPositionUsage(AVP_ClientEntity_Actor::LOOK_AT_POSITION_RESET);
	m_bDisableSurfaceReorientation = true;
	SetAIPostMoveMode(AI_MM_MDEIUM);
}

void AVP_Alien_Move_Melee_StandAttackLoopL_Return_Hit::Finish()
{
	PARENT::Finish();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

void AVP_Alien_Move_Melee_StandAttackLoopL_Return_Hit::Abort()
{
	PARENT::Abort();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

AVP_Alien_Move_Melee_StandAttackLoopL_Return_Countered::AVP_Alien_Move_Melee_StandAttackLoopL_Return_Countered( Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash )
: PARENT( xParentSystem, GetStaticHash(),
		  uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "CTStandAttackLoopLReturnCountered" )
{
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetLookAtPositionUsage(AVP_ClientEntity_Actor::LOOK_AT_POSITION_RESET);
	m_bDisableSurfaceReorientation = true;

	AddNextMove(AVP_Alien_Move_Melee_StandAttackLoopL_Return_Miss::GetStaticHash());
}

void AVP_Alien_Move_Melee_StandAttackLoopL_Return_Countered::Finish()
{
	PARENT::Finish();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

void AVP_Alien_Move_Melee_StandAttackLoopL_Return_Countered::Abort()
{
	PARENT::Abort();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

AVP_Alien_Move_Melee_StandAttackLoopL_Return_Miss::AVP_Alien_Move_Melee_StandAttackLoopL_Return_Miss( Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash )
: PARENT( xParentSystem, GetStaticHash(),
		  uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "CTStandAttackLoopLReturnMiss" )
{
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetLookAtPositionUsage(AVP_ClientEntity_Actor::LOOK_AT_POSITION_RESET);
	m_bDisableSurfaceReorientation = true;
	SetAIPostMoveMode(AI_MM_MDEIUM);
}

bool AVP_Alien_Move_Melee_StandAttackLoopL_Return_Miss::ShouldStart() const
{
	if (GetParentSystem().GetCurrentMove()->GetHash() == AVP_Alien_Move_Melee_StandAttackLoopL_Return_Countered::GetStaticHash())
	{
		return true;
	}
	else
	{
		return PARENT::ShouldStart();
	}
}

void AVP_Alien_Move_Melee_StandAttackLoopL_Return_Miss::Finish()
{
	PARENT::Finish();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

void AVP_Alien_Move_Melee_StandAttackLoopL_Return_Miss::Abort()
{
	PARENT::Abort();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

//////////////////////////////////////////////////////////////////////////////
//
// Walk attack classes.
// (Claw slash attack for the AI that starts from the crawl pose.)
//
//////////////////////////////////////////////////////////////////////////////

DEBUGVAR float dbg_fWalkAttackLoopAnimDistance = 1.678f;
// Right.
AVP_Alien_Move_Melee_WalkAttackLoopR_Start::AVP_Alien_Move_Melee_WalkAttackLoopR_Start( Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash )
: PARENT( xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "WalkAttackRStart", 
		 AVP_Alien_Move_Melee_WalkAttackLoopR_Return_Hit::GetStaticHash(),
		 AVP_Alien_Move_Melee_WalkAttackLoopR_Return_Countered::GetStaticHash(),
		 AVP_Alien_Move_Melee_WalkAttackLoopR_Return_Miss::GetStaticHash() )
, m_xOrientationInterpolationData()
, m_fVelocityMultiplier(1.0f)
{
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetLookAtPositionUsage(AVP_ClientEntity_Actor::LOOK_AT_POSITION_RESET);
	m_bDisableSurfaceReorientation = true;

	if (m_pxAVPAnimationData)
	{
		m_pxAVPAnimationData->SetTweenData(g_fTweenInDuration, 0.0f, false);
		m_pxAVPAnimationData->SetLeaveAnimAtEnd(true);
	}
}

DEBUGVAR float dbg_fWalkAttackReorientationTime = 0.4f;

bool AVP_Alien_Move_Melee_WalkAttackLoopR_Start::Start( const Asura_Msg_Move* pxStartMsg )
{
	if (!pxStartMsg) { return false; }

	const AVP_Msg_Melee_Move* pxMeleeStart = static_cast< const AVP_Msg_Melee_Move* >( pxStartMsg );

	AVP_ClientEntity_Actor& xOwner = GetAVPParentSystem().GetActorOwner();

	// Get an upright orientation to interpolate to.
	const AVP_ClientEntity_Actor* pxTarget = AVP_ClientEntity_Actor::FindEntity( pxMeleeStart->GetTargetGuid() );
	if ( !pxTarget ) { return false; }

	Asura_Matrix_3x3 xOri;
	Asura_Vector_3 xTargetOffset = pxTarget->GetCurrentPosition() - xOwner.GetCurrentPosition();
	xTargetOffset.y = 0.0f;
	if (xTargetOffset.ApproximatelyEquals(Asura_Maths::ZeroVector3))
	{
		Asura_Euler_3 xEuler;
		xEuler.FromMatrix(xOwner.GetCurrentOrientation());
		xEuler.x = xEuler.z = 0.0f;
		xEuler.ToMatrix(xOri);
		m_fVelocityMultiplier = 1.0f;
	}
	else
	{
		float fTargetDistance = xTargetOffset.Normalise();
		m_fVelocityMultiplier = (fTargetDistance - dbg_fOptimalDisatnceFromPlayer) / dbg_fWalkAttackLoopAnimDistance;
		if (m_fVelocityMultiplier < 1.0f)
		{
			m_fVelocityMultiplier = 1.0;
		}
		Asura_Maths::OrientationFromDirection(xOri, xTargetOffset);
	}
	m_xOrientationInterpolationData.SetFinal(xOri);
	m_xOrientationInterpolationData.SetInitial(xOwner.GetCurrentOrientation());
	m_xOrientationInterpolationData.SetDuration(dbg_fWalkAttackReorientationTime);

	InitialiseOrientationInterpolation(m_xOrientationInterpolationData);
	
	bool bResult = PARENT::Start(pxStartMsg);

	if (bResult && Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(true);
		}
	}

	return bResult;
}

void AVP_Alien_Move_Melee_WalkAttackLoopR_Start::Abort()
{
	EnsureAnimationFinishes();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}

	PARENT::Abort();
}

bool AVP_Alien_Move_Melee_WalkAttackLoopR_Start::CalculateVelocity(const float fTimeStep, Asura_AVector3_OutParam xVelocity) const
{
	bool bResult = PARENT::CalculateVelocity(fTimeStep, xVelocity);
	xVelocity *= m_fVelocityMultiplier;
	return bResult;
}

AVP_Alien_Move_Melee_WalkAttackLoopR_Return_Hit::AVP_Alien_Move_Melee_WalkAttackLoopR_Return_Hit( Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash )
: PARENT( xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "WalkAttackRReturnHit" ) 
{
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetLookAtPositionUsage(AVP_ClientEntity_Actor::LOOK_AT_POSITION_RESET);
	m_bDisableSurfaceReorientation = true;
	SetAIPostMoveMode(AI_MM_MDEIUM);
}

void AVP_Alien_Move_Melee_WalkAttackLoopR_Return_Hit::Finish()
{
	PARENT::Finish();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

void AVP_Alien_Move_Melee_WalkAttackLoopR_Return_Hit::Abort()
{
	PARENT::Abort();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}


AVP_Alien_Move_Melee_WalkAttackLoopR_Return_Countered::AVP_Alien_Move_Melee_WalkAttackLoopR_Return_Countered( Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash )
: PARENT( xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "WalkAttackRReturnCountered" )
{
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetLookAtPositionUsage(AVP_ClientEntity_Actor::LOOK_AT_POSITION_RESET);
	m_bDisableSurfaceReorientation = true;

	AddNextMove(AVP_Alien_Move_Melee_WalkAttackLoopR_Return_Miss::GetStaticHash());
}

void AVP_Alien_Move_Melee_WalkAttackLoopR_Return_Countered::Finish()
{
	PARENT::Finish();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

void AVP_Alien_Move_Melee_WalkAttackLoopR_Return_Countered::Abort()
{
	PARENT::Abort();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

AVP_Alien_Move_Melee_WalkAttackLoopR_Return_Miss::AVP_Alien_Move_Melee_WalkAttackLoopR_Return_Miss( Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash )
: PARENT( xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "WalkAttackRReturnMiss" ) 
{
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetLookAtPositionUsage(AVP_ClientEntity_Actor::LOOK_AT_POSITION_RESET);
	m_bDisableSurfaceReorientation = true;
	SetAIPostMoveMode(AI_MM_MDEIUM);
}

bool AVP_Alien_Move_Melee_WalkAttackLoopR_Return_Miss::ShouldStart() const
{
	if (GetParentSystem().GetCurrentMove()->GetHash() == AVP_Alien_Move_Melee_WalkAttackLoopR_Return_Countered::GetStaticHash())
	{
		return true;
	}
	else
	{
		return PARENT::ShouldStart();
	}
}

void AVP_Alien_Move_Melee_WalkAttackLoopR_Return_Miss::Finish()
{
	PARENT::Finish();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

void AVP_Alien_Move_Melee_WalkAttackLoopR_Return_Miss::Abort()
{
	PARENT::Abort();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

// Left.
AVP_Alien_Move_Melee_WalkAttackLoopL_Start::AVP_Alien_Move_Melee_WalkAttackLoopL_Start( Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash )
: PARENT( xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "WalkAttackLStart", 
		 AVP_Alien_Move_Melee_WalkAttackLoopL_Return_Hit::GetStaticHash(),
		 AVP_Alien_Move_Melee_WalkAttackLoopL_Return_Countered::GetStaticHash(),
		 AVP_Alien_Move_Melee_WalkAttackLoopL_Return_Miss::GetStaticHash() )
, m_xOrientationInterpolationData()
, m_fVelocityMultiplier(1.0f)
{
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetLookAtPositionUsage(AVP_ClientEntity_Actor::LOOK_AT_POSITION_RESET);
	m_bDisableSurfaceReorientation = true;

	if (m_pxAVPAnimationData)
	{
		m_pxAVPAnimationData->SetTweenData(g_fTweenInDuration, 0.0f, false);
		m_pxAVPAnimationData->SetLeaveAnimAtEnd(true);
	}
}

bool AVP_Alien_Move_Melee_WalkAttackLoopL_Start::Start( const Asura_Msg_Move* pxStartMsg )
{
	if (!pxStartMsg) { return false; }

	const AVP_Msg_Melee_Move* pxMeleeStart = static_cast< const AVP_Msg_Melee_Move* >( pxStartMsg );

	AVP_ClientEntity_Actor& xOwner = GetAVPParentSystem().GetActorOwner();

	// Get an upright orientation to interpolate to.
	const AVP_ClientEntity_Actor* pxTarget = AVP_ClientEntity_Actor::FindEntity( pxMeleeStart->GetTargetGuid() );
	if ( !pxTarget ) { return false; }

	Asura_Matrix_3x3 xOri;
	Asura_Vector_3 xTargetOffset = pxTarget->GetCurrentPosition() - xOwner.GetCurrentPosition();
	xTargetOffset.y = 0.0f;
	if (xTargetOffset.ApproximatelyEquals(Asura_Maths::ZeroVector3))
	{
		Asura_Euler_3 xEuler;
		xEuler.FromMatrix(xOwner.GetCurrentOrientation());
		xEuler.x = xEuler.z = 0.0f;
		xEuler.ToMatrix(xOri);
		m_fVelocityMultiplier = 1.0f;
	}
	else
	{
		float fTargetDistance = xTargetOffset.Normalise();
		m_fVelocityMultiplier = (fTargetDistance - dbg_fOptimalDisatnceFromPlayer) / dbg_fWalkAttackLoopAnimDistance;
		if (m_fVelocityMultiplier < 1.0f)
		{
			m_fVelocityMultiplier = 1.0;
		}
		Asura_Maths::OrientationFromDirection(xOri, xTargetOffset);
	}
	m_xOrientationInterpolationData.SetFinal(xOri);
	m_xOrientationInterpolationData.SetInitial(xOwner.GetCurrentOrientation());
	m_xOrientationInterpolationData.SetDuration(dbg_fWalkAttackReorientationTime);

	InitialiseOrientationInterpolation(m_xOrientationInterpolationData);
	
	bool bResult = PARENT::Start(pxStartMsg);

	if (bResult && Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(true);
		}
	}

	return bResult;
}

void AVP_Alien_Move_Melee_WalkAttackLoopL_Start::Abort()
{
	EnsureAnimationFinishes();

	PARENT::Abort();
}

bool AVP_Alien_Move_Melee_WalkAttackLoopL_Start::CalculateVelocity(const float fTimeStep, Asura_AVector3_OutParam xVelocity) const
{
	bool bResult = PARENT::CalculateVelocity(fTimeStep, xVelocity);
	xVelocity *= m_fVelocityMultiplier;
	return bResult;
}

AVP_Alien_Move_Melee_WalkAttackLoopL_Return_Hit::AVP_Alien_Move_Melee_WalkAttackLoopL_Return_Hit( Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash )
: PARENT( xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "WalkAttackLReturnHit" ) 
{
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetLookAtPositionUsage(AVP_ClientEntity_Actor::LOOK_AT_POSITION_RESET);
	m_bDisableSurfaceReorientation = true;
	SetAIPostMoveMode(AI_MM_MDEIUM);
}

void AVP_Alien_Move_Melee_WalkAttackLoopL_Return_Hit::Finish()
{
	PARENT::Finish();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

void AVP_Alien_Move_Melee_WalkAttackLoopL_Return_Hit::Abort()
{
	PARENT::Abort();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

AVP_Alien_Move_Melee_WalkAttackLoopL_Return_Countered::AVP_Alien_Move_Melee_WalkAttackLoopL_Return_Countered( Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash )
: PARENT( xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "WalkAttackLReturnCountered" )
{
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetLookAtPositionUsage(AVP_ClientEntity_Actor::LOOK_AT_POSITION_RESET);
	m_bDisableSurfaceReorientation = true;

	AddNextMove(AVP_Alien_Move_Melee_WalkAttackLoopR_Return_Miss::GetStaticHash());
}

void AVP_Alien_Move_Melee_WalkAttackLoopL_Return_Countered::Finish()
{
	PARENT::Finish();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

void AVP_Alien_Move_Melee_WalkAttackLoopL_Return_Countered::Abort()
{
	PARENT::Abort();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

AVP_Alien_Move_Melee_WalkAttackLoopL_Return_Miss::AVP_Alien_Move_Melee_WalkAttackLoopL_Return_Miss( Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash )
: PARENT( xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "WalkAttackLReturnMiss" )
{
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);
	SetOrientationUsage(ORIENTATION_SET_DIRECTLY);
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
	SetLookAtPositionUsage(AVP_ClientEntity_Actor::LOOK_AT_POSITION_RESET);
	m_bDisableSurfaceReorientation = true;
	SetAIPostMoveMode(AI_MM_MDEIUM);
}

bool AVP_Alien_Move_Melee_WalkAttackLoopL_Return_Miss::ShouldStart() const
{
	if (GetParentSystem().GetCurrentMove()->GetHash() == AVP_Alien_Move_Melee_WalkAttackLoopL_Return_Countered::GetStaticHash())
	{
		return true;
	}
	else
	{
		return PARENT::ShouldStart();
	}
}

void AVP_Alien_Move_Melee_WalkAttackLoopL_Return_Miss::Finish()
{
	PARENT::Finish();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

void AVP_Alien_Move_Melee_WalkAttackLoopL_Return_Miss::Abort()
{
	PARENT::Abort();

	if (Asura_Network::IsServer())
	{
		AVP_ServerActor_Vertebrate* pxOwner = AVP_ServerActor_Vertebrate::FindEntity(GetAVPParentSystem().GetOwnerGuid());
		AVP_PhysicsObjectHandler* pxPhyHandler = pxOwner ? pxOwner->GetPhysicsObjectHandler() : NULL;
		if (pxPhyHandler)
		{
			pxPhyHandler->SetWalkWalkingDisabled(false);
		}
	}
}

// Headbites


AVP_Alien_Move_Melee_PickupHuman_Start::AVP_Alien_Move_Melee_PickupHuman_Start(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "PickupHumanAttack",
		 AVP_Alien_Move_Melee_PickupHuman_Return_Hit::GetStaticHash(), AVP_Alien_Move_Melee_PickupHuman_Return_Countered::GetStaticHash(), AVP_Alien_Move_Melee_PickupHuman_Return_Miss::GetStaticHash())
{
	AddNextMove(AVP_Alien_Move_Melee_Headbite_Human_Start::GetStaticHash());
	AddNextMove(AVP_Alien_Move_Melee_BackHeadbite_Human_Start::GetStaticHash());
	AddNextMove(AVP_Alien_Move_Melee_StealthKill_Human_Start::GetStaticHash());
	AddNextMove(AVP_Alien_Move_Melee_Headbite_Predator_Start::GetStaticHash());
	AddNextMove(AVP_Alien_Move_Melee_BackHeadbite_Predator_Start::GetStaticHash());
	AddNextMove(AVP_Alien_Move_Melee_StealthKill_Predator_Start::GetStaticHash());

	m_bClearQueuedMeleeRequests = true;
	m_bForceStanding = true;
	m_bDisableSurfaceReorientation = true;
}


// Currently hit and miss both use the same animation, set up with just one parameter.
static const char* g_szHumanPickupMissParameterName = "PickupHumanMiss";

AVP_Alien_Move_Melee_PickupHuman_Return_Hit::AVP_Alien_Move_Melee_PickupHuman_Return_Hit(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, g_szHumanPickupMissParameterName)
{
	m_bClearQueuedMeleeRequests = true;
	m_bForceStanding = true;
	m_bDisableSurfaceReorientation = true;
}

bool AVP_Alien_Move_Melee_PickupHuman_Return_Hit::ShouldStart() const
{
	// If the parent says we can start, check that the entity is of a type that we don't attach on to.
	if (!PARENT::ShouldStart()) { return false; }

	// There's only one move we can have come from.
	const AVP_Alien_Move_Melee_PickupHuman_Start* pxCurrentMove = static_cast<const AVP_Alien_Move_Melee_PickupHuman_Start*>(GetParentSystem().GetCurrentMove());
	if (!pxCurrentMove) { return false; }

	const AVP_ClientEntity_Actor* pxVictim = AVP_ClientEntity_Actor::FindEntity(pxCurrentMove->GetHitEntity());
	// TODO - These next two checks take the safe option of using this move if our victim has gone missing or died, but we should possibly be going into miss in that case.
	if (!pxVictim) { return true; }
	if (pxVictim->IsDead()) { return true; }

	switch (pxVictim->GetClassification())
	{
	default:
		return true;

		// These entity classifications are attached to, so don't start this move.
	case AVP_ENTITYCLASS_MARINE:
	case AVP_ENTITYCLASS_CIVILIAN:
	case AVP_ENTITYCLASS_PREDATOR:
	case AVP_ENTITYCLASS_PREDALIEN:
		return false;
	}
}


AVP_Alien_Move_Melee_PickupHuman_Return_Countered::AVP_Alien_Move_Melee_PickupHuman_Return_Countered(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "PickupHumanCountered")
{
	m_bForceStanding = true;
	m_bDisableSurfaceReorientation = true;
}


AVP_Alien_Move_Melee_PickupHuman_Return_Miss::AVP_Alien_Move_Melee_PickupHuman_Return_Miss(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, g_szHumanPickupMissParameterName)
{
	m_bForceStanding = true;
	m_bDisableSurfaceReorientation = true;
}


AVP_Alien_Move_Melee_Headbite_Human_Start::AVP_Alien_Move_Melee_Headbite_Human_Start(Asura_Movement_System& xParentSystem)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Settings::AVP_SPECIES_ALIEN, AVP_Settings::AVP_SPECIES_HUMAN, uAVP_BLUEPRINT_NAME_ALIENHEADBITE_HUMANVICTIM,
		 AVP_Alien_Move_Melee_Headbite_Human_Kill::GetStaticHash(), AVP_Alien_Move_Melee_Headbite_Human_Countered::GetStaticHash())
{
}

bool AVP_Alien_Move_Melee_Headbite_Human_Start::ShouldStart() const
{
	// If the parent succeeds, make sure the enemy is facing roughly towards us.
	if (PARENT::ShouldStart())
	{
		const AVP_Move_Melee* pxCurrentMove = static_cast<const AVP_Move_Melee*>(GetParentSystem().GetCurrentMove());
		if (pxCurrentMove)
		{
			const AVP_ClientActor_Human* pxVictim = AVP_ClientActor_Human::FindEntity(pxCurrentMove->GetHitEntity());
			if (pxVictim)
			{
				const AVP_ClientEntity_Actor& xOwner = GetAVPParentSystem().GetActorOwner();

				const Asura_Matrix_3x3& xVictimOri = pxVictim->GetCurrentOrientation();
				const Asura_Matrix_3x3& xOwnerOri = xOwner.GetCurrentOrientation();
				const Asura_Vector_3 xVictimDir(xVictimOri.e13, xVictimOri.e23, xVictimOri.e33);
				const Asura_Vector_3 xOwnerDir(xOwnerOri.e13, xOwnerOri.e23, xOwnerOri.e33);

				if ((xVictimDir * xOwnerDir) >= 0.0f) { return false; }
			}
			else
			{
				return false;
			}
		}

		return true;
	}
	else
	{
		return false;
	}
}


AVP_Alien_Move_Melee_Headbite_Human_Kill::AVP_Alien_Move_Melee_Headbite_Human_Kill(Asura_Movement_System& xParentSystem)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Settings::AVP_SPECIES_ALIEN, AVP_Settings::AVP_SPECIES_HUMAN, uAVP_BLUEPRINT_NAME_ALIENHEADBITE_HUMANVICTIM)
{
	m_bAlwaysFatal = true;
}


AVP_Alien_Move_Melee_Headbite_Human_Countered::AVP_Alien_Move_Melee_Headbite_Human_Countered(Asura_Movement_System& xParentSystem)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Settings::AVP_SPECIES_ALIEN, AVP_Settings::AVP_SPECIES_HUMAN, uAVP_BLUEPRINT_NAME_ALIENHEADBITE_HUMANVICTIM)
{
}


AVP_Alien_Move_Melee_BackHeadbite_Human_Start::AVP_Alien_Move_Melee_BackHeadbite_Human_Start(Asura_Movement_System& xParentSystem)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Settings::AVP_SPECIES_ALIEN, AVP_Settings::AVP_SPECIES_HUMAN, uAVP_BLUEPRINT_NAME_ALIENBACKHEADBITE_HUMANVICTIM,
		 AVP_Alien_Move_Melee_BackHeadbite_Human_Kill::GetStaticHash(), AVP_Alien_Move_Melee_BackHeadbite_Human_Countered::GetStaticHash())
{
}

bool AVP_Alien_Move_Melee_BackHeadbite_Human_Start::ShouldStart() const
{
	// If the parent succeeds, make sure the enemy is facing roughly away from us.
	if (PARENT::ShouldStart())
	{
		const AVP_Move_Melee* pxCurrentMove = static_cast<const AVP_Move_Melee*>(GetParentSystem().GetCurrentMove());
		if (pxCurrentMove)
		{
			if ((pxCurrentMove->GetPendingAttackType() != AVP_ALIEN_MELEEATTACK_TYPE_PICKUPENEMY_HEADBITE) && (pxCurrentMove->GetPendingAttackType() != AVP_MELEEATTACK_TYPE_GRAPPLEPOUNCE)) { return false; }

			const AVP_ClientActor_Human* pxVictim = AVP_ClientActor_Human::FindEntity(pxCurrentMove->GetHitEntity());
			if (pxVictim)
			{
				const AVP_ClientEntity_Actor& xOwner = GetAVPParentSystem().GetActorOwner();

				const Asura_Matrix_3x3& xVictimOri = pxVictim->GetCurrentOrientation();
				const Asura_Matrix_3x3& xOwnerOri = xOwner.GetCurrentOrientation();
				const Asura_Vector_3 xVictimDir(xVictimOri.e13, xVictimOri.e23, xVictimOri.e33);
				const Asura_Vector_3 xOwnerDir(xOwnerOri.e13, xOwnerOri.e23, xOwnerOri.e33);

				if ((xVictimDir * xOwnerDir) < 0.0f) { return false; }
			}
			else
			{
				return false;
			}
		}

		return true;
	}
	else
	{
		return false;
	}
}

bool AVP_Alien_Move_Melee_BackHeadbite_Human_Start::Start(const Asura_Msg_Move* pxStartMsg)
{
	bool bSuccess = PARENT::Start(pxStartMsg);

	if (bSuccess)
	{
		// Unusually, we need to rotate the enemy to face away from us.
		m_xPuppetOrientationInterpolation.SetFinal(Asura_Maths::IdentityQuat);
	}

	return bSuccess;
}


AVP_Alien_Move_Melee_BackHeadbite_Human_Kill::AVP_Alien_Move_Melee_BackHeadbite_Human_Kill(Asura_Movement_System& xParentSystem)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Settings::AVP_SPECIES_ALIEN, AVP_Settings::AVP_SPECIES_HUMAN, uAVP_BLUEPRINT_NAME_ALIENBACKHEADBITE_HUMANVICTIM)
{
	m_bAlwaysFatal = true;
}


AVP_Alien_Move_Melee_BackHeadbite_Human_Countered::AVP_Alien_Move_Melee_BackHeadbite_Human_Countered(Asura_Movement_System& xParentSystem)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Settings::AVP_SPECIES_ALIEN, AVP_Settings::AVP_SPECIES_HUMAN, uAVP_BLUEPRINT_NAME_ALIENBACKHEADBITE_HUMANVICTIM)
{
}


AVP_Alien_Move_Melee_StealthKill_Human_Start::AVP_Alien_Move_Melee_StealthKill_Human_Start(Asura_Movement_System& xParentSystem)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Settings::AVP_SPECIES_ALIEN, AVP_Settings::AVP_SPECIES_HUMAN, uAVP_BLUEPRINT_NAME_ALIENSTEALTHKILL_HUMANVICTIM,
		 AVP_Alien_Move_Melee_StealthKill_Human_Kill::GetStaticHash(), AVP_Alien_Move_Melee_StealthKill_Human_Countered::GetStaticHash())
{
}

bool AVP_Alien_Move_Melee_StealthKill_Human_Start::ShouldStart() const
{
	// If the parent succeeds, make sure the enemy is facing roughly away from us.
	if (PARENT::ShouldStart())
	{
		const AVP_Move_Melee* pxCurrentMove = static_cast<const AVP_Move_Melee*>(GetParentSystem().GetCurrentMove());
		if (pxCurrentMove)
		{
			if (pxCurrentMove->GetPendingAttackType() != AVP_ALIEN_MELEEATTACK_TYPE_PICKUPENEMY) { return false; }

			const AVP_ClientActor_Human* pxVictim = AVP_ClientActor_Human::FindEntity(pxCurrentMove->GetHitEntity());
			if (pxVictim)
			{
				const AVP_ClientEntity_Actor& xOwner = GetAVPParentSystem().GetActorOwner();

				const Asura_Matrix_3x3& xVictimOri = pxVictim->GetCurrentOrientation();
				const Asura_Matrix_3x3& xOwnerOri = xOwner.GetCurrentOrientation();
				const Asura_Vector_3 xVictimDir(xVictimOri.e13, xVictimOri.e23, xVictimOri.e33);
				const Asura_Vector_3 xOwnerDir(xOwnerOri.e13, xOwnerOri.e23, xOwnerOri.e33);

				if ((xVictimDir * xOwnerDir) < 0.0f) { return false; }
			}
			else
			{
				return false;
			}
		}

		return true;
	}
	else
	{
		return false;
	}
}

bool AVP_Alien_Move_Melee_StealthKill_Human_Start::Start(const Asura_Msg_Move* pxStartMsg)
{
	bool bSuccess = PARENT::Start(pxStartMsg);

	if (bSuccess)
	{
		// Unusually, we need to rotate the enemy to face away from us.
		m_xPuppetOrientationInterpolation.SetFinal(Asura_Maths::IdentityQuat);
	}

	return bSuccess;
}


AVP_Alien_Move_Melee_StealthKill_Human_Kill::AVP_Alien_Move_Melee_StealthKill_Human_Kill(Asura_Movement_System& xParentSystem)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Settings::AVP_SPECIES_ALIEN, AVP_Settings::AVP_SPECIES_HUMAN, uAVP_BLUEPRINT_NAME_ALIENSTEALTHKILL_HUMANVICTIM)
{
	m_bAlwaysFatal = true;
}


AVP_Alien_Move_Melee_StealthKill_Human_Countered::AVP_Alien_Move_Melee_StealthKill_Human_Countered(Asura_Movement_System& xParentSystem)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Settings::AVP_SPECIES_ALIEN, AVP_Settings::AVP_SPECIES_HUMAN, uAVP_BLUEPRINT_NAME_ALIENSTEALTHKILL_HUMANVICTIM)
{
}


// Predator versions of the above.
AVP_Alien_Move_Melee_Headbite_Predator_Start::AVP_Alien_Move_Melee_Headbite_Predator_Start(Asura_Movement_System& xParentSystem)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Settings::AVP_SPECIES_ALIEN, AVP_Settings::AVP_SPECIES_PREDATOR, uAVP_BLUEPRINT_NAME_ALIENHEADBITE_PREDATORVICTIM,
		 AVP_Alien_Move_Melee_Headbite_Predator_Kill::GetStaticHash(), AVP_Alien_Move_Melee_Headbite_Predator_Countered::GetStaticHash())
{
}

bool AVP_Alien_Move_Melee_Headbite_Predator_Start::ShouldStart() const
{
	// If the parent succeeds, make sure the enemy is facing roughly towards us.
	if (PARENT::ShouldStart())
	{
		const AVP_Move_Melee* pxCurrentMove = static_cast<const AVP_Move_Melee*>(GetParentSystem().GetCurrentMove());
		if (pxCurrentMove)
		{
			const AVP_ClientActor_Predator* pxVictim = AVP_ClientActor_Predator::FindEntity(pxCurrentMove->GetHitEntity());
			if (pxVictim)
			{
				const AVP_ClientEntity_Actor& xOwner = GetAVPParentSystem().GetActorOwner();

				const Asura_Matrix_3x3& xVictimOri = pxVictim->GetCurrentOrientation();
				const Asura_Matrix_3x3& xOwnerOri = xOwner.GetCurrentOrientation();
				const Asura_Vector_3 xVictimDir(xVictimOri.e13, xVictimOri.e23, xVictimOri.e33);
				const Asura_Vector_3 xOwnerDir(xOwnerOri.e13, xOwnerOri.e23, xOwnerOri.e33);

				if ((xVictimDir * xOwnerDir) >= 0.0f) { return false; }
			}
			else
			{
				return false;
			}
		}

		return true;
	}
	else
	{
		return false;
	}
}


AVP_Alien_Move_Melee_Headbite_Predator_Kill::AVP_Alien_Move_Melee_Headbite_Predator_Kill(Asura_Movement_System& xParentSystem)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Settings::AVP_SPECIES_ALIEN, AVP_Settings::AVP_SPECIES_PREDATOR, uAVP_BLUEPRINT_NAME_ALIENHEADBITE_PREDATORVICTIM)
{
	m_bAlwaysFatal = true;
}


AVP_Alien_Move_Melee_Headbite_Predator_Countered::AVP_Alien_Move_Melee_Headbite_Predator_Countered(Asura_Movement_System& xParentSystem)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Settings::AVP_SPECIES_ALIEN, AVP_Settings::AVP_SPECIES_PREDATOR, uAVP_BLUEPRINT_NAME_ALIENHEADBITE_PREDATORVICTIM)
{
}


AVP_Alien_Move_Melee_BackHeadbite_Predator_Start::AVP_Alien_Move_Melee_BackHeadbite_Predator_Start(Asura_Movement_System& xParentSystem)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Settings::AVP_SPECIES_ALIEN, AVP_Settings::AVP_SPECIES_PREDATOR, uAVP_BLUEPRINT_NAME_ALIENBACKHEADBITE_PREDATORVICTIM,
		 AVP_Alien_Move_Melee_BackHeadbite_Predator_Kill::GetStaticHash(), AVP_Alien_Move_Melee_BackHeadbite_Predator_Countered::GetStaticHash())
{
}

bool AVP_Alien_Move_Melee_BackHeadbite_Predator_Start::ShouldStart() const
{
	// If the parent succeeds, make sure the enemy is facing roughly away from us.
	if (PARENT::ShouldStart())
	{
		const AVP_Move_Melee* pxCurrentMove = static_cast<const AVP_Move_Melee*>(GetParentSystem().GetCurrentMove());
		if (pxCurrentMove)
		{
			if ((pxCurrentMove->GetPendingAttackType() != AVP_ALIEN_MELEEATTACK_TYPE_PICKUPENEMY_HEADBITE) && (pxCurrentMove->GetPendingAttackType() != AVP_MELEEATTACK_TYPE_GRAPPLEPOUNCE)) { return false; }

			const AVP_ClientActor_Predator* pxVictim = AVP_ClientActor_Predator::FindEntity(pxCurrentMove->GetHitEntity());
			if (pxVictim)
			{
				const AVP_ClientEntity_Actor& xOwner = GetAVPParentSystem().GetActorOwner();

				const Asura_Matrix_3x3& xVictimOri = pxVictim->GetCurrentOrientation();
				const Asura_Matrix_3x3& xOwnerOri = xOwner.GetCurrentOrientation();
				const Asura_Vector_3 xVictimDir(xVictimOri.e13, xVictimOri.e23, xVictimOri.e33);
				const Asura_Vector_3 xOwnerDir(xOwnerOri.e13, xOwnerOri.e23, xOwnerOri.e33);

				if ((xVictimDir * xOwnerDir) < 0.0f) { return false; }
			}
			else
			{
				return false;
			}
		}

		return true;
	}
	else
	{
		return false;
	}
}

bool AVP_Alien_Move_Melee_BackHeadbite_Predator_Start::Start(const Asura_Msg_Move* pxStartMsg)
{
	bool bSuccess = PARENT::Start(pxStartMsg);

	if (bSuccess)
	{
		// Unusually, we need to rotate the enemy to face away from us.
		m_xPuppetOrientationInterpolation.SetFinal(Asura_Maths::IdentityQuat);
	}

	return bSuccess;
}


AVP_Alien_Move_Melee_BackHeadbite_Predator_Kill::AVP_Alien_Move_Melee_BackHeadbite_Predator_Kill(Asura_Movement_System& xParentSystem)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Settings::AVP_SPECIES_ALIEN, AVP_Settings::AVP_SPECIES_PREDATOR, uAVP_BLUEPRINT_NAME_ALIENBACKHEADBITE_PREDATORVICTIM)
{
	m_bAlwaysFatal = true;
}


AVP_Alien_Move_Melee_BackHeadbite_Predator_Countered::AVP_Alien_Move_Melee_BackHeadbite_Predator_Countered(Asura_Movement_System& xParentSystem)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Settings::AVP_SPECIES_ALIEN, AVP_Settings::AVP_SPECIES_PREDATOR, uAVP_BLUEPRINT_NAME_ALIENBACKHEADBITE_PREDATORVICTIM)
{
	m_bForceStanding = false;
}


AVP_Alien_Move_Melee_StealthKill_Predator_Start::AVP_Alien_Move_Melee_StealthKill_Predator_Start(Asura_Movement_System& xParentSystem)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Settings::AVP_SPECIES_ALIEN, AVP_Settings::AVP_SPECIES_PREDATOR, uAVP_BLUEPRINT_NAME_ALIENSTEALTHKILL_PREDATORVICTIM,
		 AVP_Alien_Move_Melee_StealthKill_Predator_Kill::GetStaticHash(), AVP_Alien_Move_Melee_StealthKill_Predator_Countered::GetStaticHash())
{
}

bool AVP_Alien_Move_Melee_StealthKill_Predator_Start::ShouldStart() const
{
	// If the parent succeeds, make sure the enemy is facing roughly away from us.
	if (PARENT::ShouldStart())
	{
		const AVP_Move_Melee* pxCurrentMove = static_cast<const AVP_Move_Melee*>(GetParentSystem().GetCurrentMove());
		if (pxCurrentMove)
		{
			if (pxCurrentMove->GetPendingAttackType() != AVP_ALIEN_MELEEATTACK_TYPE_PICKUPENEMY) { return false; }

			const AVP_ClientActor_Predator* pxVictim = AVP_ClientActor_Predator::FindEntity(pxCurrentMove->GetHitEntity());
			if (pxVictim)
			{
				const AVP_ClientEntity_Actor& xOwner = GetAVPParentSystem().GetActorOwner();

				const Asura_Matrix_3x3& xVictimOri = pxVictim->GetCurrentOrientation();
				const Asura_Matrix_3x3& xOwnerOri = xOwner.GetCurrentOrientation();
				const Asura_Vector_3 xVictimDir(xVictimOri.e13, xVictimOri.e23, xVictimOri.e33);
				const Asura_Vector_3 xOwnerDir(xOwnerOri.e13, xOwnerOri.e23, xOwnerOri.e33);

				if ((xVictimDir * xOwnerDir) < 0.0f) { return false; }
			}
			else
			{
				return false;
			}
		}

		return true;
	}
	else
	{
		return false;
	}
}

bool AVP_Alien_Move_Melee_StealthKill_Predator_Start::Start(const Asura_Msg_Move* pxStartMsg)
{
	bool bSuccess = PARENT::Start(pxStartMsg);

	if (bSuccess)
	{
		// Unusually, we need to rotate the enemy to face away from us.
		m_xPuppetOrientationInterpolation.SetFinal(Asura_Maths::IdentityQuat);
	}

	return bSuccess;
}


AVP_Alien_Move_Melee_StealthKill_Predator_Kill::AVP_Alien_Move_Melee_StealthKill_Predator_Kill(Asura_Movement_System& xParentSystem)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Settings::AVP_SPECIES_ALIEN, AVP_Settings::AVP_SPECIES_PREDATOR, uAVP_BLUEPRINT_NAME_ALIENSTEALTHKILL_PREDATORVICTIM)
{
	m_bAlwaysFatal = true;
}


AVP_Alien_Move_Melee_StealthKill_Predator_Countered::AVP_Alien_Move_Melee_StealthKill_Predator_Countered(Asura_Movement_System& xParentSystem)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Settings::AVP_SPECIES_ALIEN, AVP_Settings::AVP_SPECIES_PREDATOR, uAVP_BLUEPRINT_NAME_ALIENSTEALTHKILL_PREDATORVICTIM)
{
	m_bForceStanding = false;
}

// Injured Alien

AVP_Alien_Move_Melee_2Arms_Injured_Human_Start::AVP_Alien_Move_Melee_2Arms_Injured_Human_Start(Asura_Movement_System& xParentSystem)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Settings::AVP_SPECIES_ALIEN, AVP_Settings::AVP_SPECIES_HUMAN, uAVP_BLUEPRINT_NAME_ALIENINJURED2ARMS_HUMANVICTIM,
		 AVP_Alien_Move_Melee_2Arms_Injured_Human_Kill::GetStaticHash(), AVP_Alien_Move_Melee_2Arms_Injured_Human_Countered::GetStaticHash())
{
	m_bForceStanding = false;
}

bool AVP_Alien_Move_Melee_2Arms_Injured_Human_Start::ShouldStart() const
{
	return PARENT::ShouldStart();
}

DEBUGVAR float dbg_fReorientDuration(0.3f);

bool AVP_Alien_Move_Melee_2Arms_Injured_Human_Start::Start(const Asura_Msg_Move* pxStartMsg)
{
	// injured alien only attack from message
	if (!pxStartMsg) { return false; }

	AVP_ClientEntity_Actor& xOwner = GetAVPParentSystem().GetActorOwner();
	const Asura_Matrix_3x3& xStartOri = xOwner.GetCurrentOrientation();
	Asura_Matrix_3x3 xFinalOri;

	Asura_Maths::OrientationFromDirection(xFinalOri, Asura_Vector_3(xStartOri.e13, 0.0f, xStartOri.e33 ));
	m_xOrientationInterpolationData.SetFinal(xFinalOri);
	m_xOrientationInterpolationData.SetDuration(dbg_fReorientDuration);

	InitialiseOrientationInterpolation(m_xOrientationInterpolationData);
	
	return PARENT::Start(pxStartMsg);
}

AVP_Alien_Move_Melee_2Arms_Injured_Human_Kill::AVP_Alien_Move_Melee_2Arms_Injured_Human_Kill(Asura_Movement_System& xParentSystem)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Settings::AVP_SPECIES_ALIEN, AVP_Settings::AVP_SPECIES_HUMAN, uAVP_BLUEPRINT_NAME_ALIENINJURED2ARMS_HUMANVICTIM)
{
	m_bForceStanding = false;
	m_bAlwaysFatal = true;
}


AVP_Alien_Move_Melee_2Arms_Injured_Human_Countered::AVP_Alien_Move_Melee_2Arms_Injured_Human_Countered(Asura_Movement_System& xParentSystem)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Settings::AVP_SPECIES_ALIEN, AVP_Settings::AVP_SPECIES_HUMAN, uAVP_BLUEPRINT_NAME_ALIENINJURED2ARMS_HUMANVICTIM)
{
	m_bForceStanding = false;
	m_bForceUprightPuppet = true;
}


AVP_Alien_Move_Melee_2Arms_Injured_Predator_Start::AVP_Alien_Move_Melee_2Arms_Injured_Predator_Start(Asura_Movement_System& xParentSystem)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Settings::AVP_SPECIES_ALIEN, AVP_Settings::AVP_SPECIES_PREDATOR, uAVP_BLUEPRINT_NAME_ALIENINJURED2ARMS_PREDATORVICTIM,
		 AVP_Alien_Move_Melee_2Arms_Injured_Predator_Kill::GetStaticHash(), AVP_Alien_Move_Melee_2Arms_Injured_Predator_Countered::GetStaticHash())
{
	m_bForceStanding = false;
}

bool AVP_Alien_Move_Melee_2Arms_Injured_Predator_Start::ShouldStart() const
{
	return PARENT::ShouldStart();
}

bool AVP_Alien_Move_Melee_2Arms_Injured_Predator_Start::Start(const Asura_Msg_Move* pxStartMsg)
{
	// injured alien only attack from message
	if (!pxStartMsg) { return false; }

	AVP_ClientEntity_Actor& xOwner = GetAVPParentSystem().GetActorOwner();
	const Asura_Matrix_3x3& xStartOri = xOwner.GetCurrentOrientation();
	Asura_Matrix_3x3 xFinalOri;

	Asura_Maths::OrientationFromDirection(xFinalOri, Asura_Vector_3(xStartOri.e13, 0.0f, xStartOri.e33 ));
	m_xOrientationInterpolationData.SetFinal(xFinalOri);
	m_xOrientationInterpolationData.SetDuration(dbg_fReorientDuration);

	InitialiseOrientationInterpolation(m_xOrientationInterpolationData);

	return PARENT::Start(pxStartMsg);
}

AVP_Alien_Move_Melee_2Arms_Injured_Predator_Kill::AVP_Alien_Move_Melee_2Arms_Injured_Predator_Kill(Asura_Movement_System& xParentSystem)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Settings::AVP_SPECIES_ALIEN, AVP_Settings::AVP_SPECIES_PREDATOR, uAVP_BLUEPRINT_NAME_ALIENINJURED2ARMS_PREDATORVICTIM)
{																			  
	m_bForceStanding = false;
	m_bAlwaysFatal = true;
}


AVP_Alien_Move_Melee_2Arms_Injured_Predator_Countered::AVP_Alien_Move_Melee_2Arms_Injured_Predator_Countered(Asura_Movement_System& xParentSystem)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Settings::AVP_SPECIES_ALIEN, AVP_Settings::AVP_SPECIES_PREDATOR, uAVP_BLUEPRINT_NAME_ALIENINJURED2ARMS_PREDATORVICTIM)
{
	m_bForceStanding = false;
	m_bForceUprightPuppet = true;
}


// Pounce Grapple

AVP_Alien_Move_Melee_JumpToGrappleHuman_Start::AVP_Alien_Move_Melee_JumpToGrappleHuman_Start(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "JumpToGrappleHumanStart",
		 AVP_Alien_Move_Melee_JumpToGrappleHuman_Return_Hit::GetStaticHash(), AVP_Alien_Move_Melee_JumpToGrappleHuman_Return_Countered::GetStaticHash(), AVP_Alien_Move_Melee_JumpToGrappleHuman_Return_Miss::GetStaticHash())
, m_uTargetGuid(ASURA_GUID_UNREGISTERED)
, m_fAnimationTime(0.0f)
{
	AddNextMove(AVP_Move_Melee_Grapple_Start::GetStaticHash());

	m_bClearQueuedMeleeRequests = true;
	// Remove the default generic start aiming behaviour
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_NOT_USED);
	SetDisableSurfaceReorientation(true);
	SetPositionUsage(POSITION_SET_FROM_VELOCITY);

}

bool AVP_Alien_Move_Melee_JumpToGrappleHuman_Start::Start(const Asura_Msg_Move* pxStartMsg)
{
	// There's not really much we can do without the message in this case, as we need a target position.
	if(!pxStartMsg) { return false; }

	const AVP_Msg_Melee_Move* pxMeleeStart = static_cast<const AVP_Msg_Melee_Move*>(pxStartMsg);
	m_uTargetGuid = pxMeleeStart->GetTargetGuid();
	const AVP_ClientEntity_PhysicalObject* pxTarget = AVP_ClientEntity_PhysicalObject::FindEntity(pxMeleeStart->GetTargetGuid());
	if (!pxTarget) { return false; }

	const AVP_ClientActor_Alien& xOwner = static_cast<AVP_ClientActor_Alien&>(GetAVPParentSystem().GetActorOwner());

	SetVariation(pxMeleeStart->GetVariation());

	Asura_Vector_3 xTargetPosition = pxTarget->GetCurrentPosition();
	Asura_Vector_3 xDirection = xTargetPosition - xOwner.GetCurrentPosition();
	xDirection.y = 0.0f;
	Asura_Matrix_3x3 xTargetOri;

	if (xDirection.ApproximatelyEquals(Asura_Maths::ZeroVector3))
	{
		Asura_Euler_3 xEuler;
		xEuler.FromMatrix(xOwner.GetCurrentOrientation());
		xEuler.x = xEuler.z = 0.0f;
		xEuler.ToMatrix(xTargetOri);
	}
	else
	{
		xDirection.Normalise();
		Asura_Maths::OrientationFromDirection(xTargetOri, xDirection);
	}

	// m_xPositionInterpolationData.SetFinal(xTargetPosition - xDirection * 1.0f);
	m_xOrientationInterpolationData.SetFinal(xTargetOri);

	if (m_pxAVPAnimationData)
	{
		// We need to ensure the correct anim hash is set up, as it's about to get used.
		if (xOwner.IsUsingFirstPersonSkin())
		{
			m_pxAVPAnimationData->SetAnimHash(m_uFirstPersonAnimHash);
		}
		else
		{
			m_pxAVPAnimationData->SetAnimHash(m_uThirdPersonAnimHash);
		}
	}

	bool bHasAnimation = m_pxAVPAnimationData && m_pxAVPAnimationData->HasValidAnimation();
	float fDuration = bHasAnimation ? m_pxAVPAnimationData->GetAnimationDuration() : 1.000f;
	m_fAnimationTime = m_pxAVPAnimationData->GetAnimationDuration();


// 	if(bHasAnimation)
// 	{
// 		m_xPositionInterpolationData.SetMovementOffsetOperation(Asura_MoveData_PositionInterpolation::STRETCH_MOVEMENT_OFFSET);
// 	}
// 
// 	m_xPositionInterpolationData.SetDuration(fDuration);
	m_xOrientationInterpolationData.SetDuration(fDuration - 0.1f);

	// InitialisePositionInterpolation(m_xPositionInterpolationData);
	InitialiseOrientationInterpolation(m_xOrientationInterpolationData);


	return PARENT::Start(pxStartMsg);
}

DEBUGVAR float dbg_fStartGrappleOptimalDistance = 0.85f;
bool AVP_Alien_Move_Melee_JumpToGrappleHuman_Start::CalculateVelocity(const float fTimeStep, Asura_AVector3_OutParam xVelocity) const
{

	const AVP_ServerEntity_Actor* pxTarget = AVP_ServerEntity_Actor::FindEntity(m_uTargetGuid);
	if (!pxTarget)
	{
		xVelocity =  Asura_Maths::ZeroVector3;
		return false;
	}

	Asura_Vector_3 xToTargetDirection = pxTarget->GetPosition() - GetAVPParentSystem().GetActorOwner().GetCurrentPosition();
	float fToTargetDistance = xToTargetDirection.Normalise();

	float fToTarget = Asura_Maths::Max(fToTargetDistance - dbg_fStartGrappleOptimalDistance, 0.0f);

	if ( m_fAnimationTime < 0.08f)
	{
		xVelocity = Asura_Maths::ZeroVector3;
	}
	else
	{
		xVelocity = xToTargetDirection * fToTarget / m_fAnimationTime;			
	}

	m_fAnimationTime = Asura_Maths::Max ( m_fAnimationTime - fTimeStep, 0.0f); 

	return false;
}

AVP_Alien_Move_Melee_JumpToGrappleHuman_Return_Hit::AVP_Alien_Move_Melee_JumpToGrappleHuman_Return_Hit(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "JumpToGrappleHumanHit")
{
}

bool AVP_Alien_Move_Melee_JumpToGrappleHuman_Return_Hit::ShouldStart() const
{

	// If the parent says we can start, check that the entity is of a type that we don't attach on to.
	if (!PARENT::ShouldStart()) { return false; }

	// There's only one move we can have come from.
	const AVP_Move_Melee* pxCurrentMove = static_cast<const AVP_Move_Melee*>(GetParentSystem().GetCurrentMove());
	if (!pxCurrentMove) { return false; }

	const AVP_ClientEntity_Actor* pxVictim = AVP_ClientEntity_Actor::FindEntity(pxCurrentMove->GetHitEntity());
	// TODO - These next two checks take the safe option of using this move if our victim has gone missing or died, but we should possibly be going into miss in that case.
	if (!pxVictim) { return true; }
	if (pxVictim->IsDead()) { return true; }

	switch (pxVictim->GetClassification())
	{
	default:
		return PARENT::ShouldStart();
		// These entity classifications are attached to, so don't start this move.
	case AVP_ENTITYCLASS_MARINE:
		return false;
	}
}

AVP_Alien_Move_Melee_JumpToGrappleHuman_Return_Miss::AVP_Alien_Move_Melee_JumpToGrappleHuman_Return_Miss(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "JumpToGrappleHumanMiss")
{
	SetAimDirectionUsage(AVP_ClientEntity_Actor::AIM_DIRECTION_RESET);
}

AVP_Alien_Move_Melee_JumpToGrappleHuman_Return_Countered::AVP_Alien_Move_Melee_JumpToGrappleHuman_Return_Countered(Asura_Movement_System& xParentSystem, Asura_Hash_ID uFirstPersonBlueprintHash, Asura_Hash_ID uThirdPersonBlueprintHash)
: PARENT(xParentSystem, GetStaticHash(),
		 uAVP_BLUEPRINT_TYPE_MELEE, uFirstPersonBlueprintHash, uThirdPersonBlueprintHash, "JumpToGrappleHumanCountered")
{
}

AVP_Alien_Move_Melee_MarineGrapple_Start::AVP_Alien_Move_Melee_MarineGrapple_Start(Asura_Movement_System& xParentSystem)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Settings::AVP_SPECIES_ALIEN, AVP_Settings::AVP_SPECIES_HUMAN, uAVP_BLUEPRINT_NAME_ALIENPOUNCE_HUMANVICTIM,
		 AVP_Alien_Move_Melee_MarineGrapple_Kill::GetStaticHash(), AVP_Alien_Move_Melee_MarineGrapple_Countered::GetStaticHash())
{
}

AVP_Alien_Move_Melee_MarineGrapple_Kill::AVP_Alien_Move_Melee_MarineGrapple_Kill(Asura_Movement_System& xParentSystem)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Settings::AVP_SPECIES_ALIEN, AVP_Settings::AVP_SPECIES_HUMAN, uAVP_BLUEPRINT_NAME_ALIENPOUNCE_HUMANVICTIM)
{
	m_bAlwaysFatal = true;
}

AVP_Alien_Move_Melee_MarineGrapple_Countered::AVP_Alien_Move_Melee_MarineGrapple_Countered(Asura_Movement_System& xParentSystem)
: PARENT(xParentSystem, GetStaticHash(),
		 AVP_Settings::AVP_SPECIES_ALIEN, AVP_Settings::AVP_SPECIES_HUMAN, uAVP_BLUEPRINT_NAME_ALIENPOUNCE_HUMANVICTIM)
{
}



//////////////////////////////////////////////////////////////////////////////
//
// 
//
//////////////////////////////////////////////////////////////////////////////
