
///////////////////////////////////////////////////////////////////////////////
//
// File   : AVP_Vertebrate_Messages.h
// Author : Chris Wallace
// Date   : 8-Aug-2007
//
// Copyright (C) 2007 Rebellion, All Rights Reserved.
//
///////////////////////////////////////////////////////////////////////////////

#ifdef ASURA_USE_PRAGMA_ONCE
	#pragma once
#endif   // ifdef ASURA_USE_PRAGMA_ONCE

#ifndef __AVP_VERTEBRATE_MESSAGES_H__
#define __AVP_VERTEBRATE_MESSAGES_H__

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

// asura
#include "Core/Asura_Maths.h"
#include "Entity/PhysicalObject/Actor/AVP_Actor_Messages.h"
#include "Entity/PhysicalObject/Moves/Asura_Movement_System.h"

// avp
#include "Entity/PhysicalObject/Actor/Vertebrates/AVP_ClientActor_Vertebrate.h"


////////////////////////////////////////////////////////////////////////////////
// Forward class declarations...
////////////////////////////////////////////////////////////////////////////////

class Asura_NetMsg;
class Asura_BitPacker; 
class Asura_BitUnpacker; 
class AVP_ServerActor_Vertebrate;

////////////////////////////////////////////////////////////////////////////////
// Class declaration...
////////////////////////////////////////////////////////////////////////////////

class AVP_Message_Vertebrate_ClientUpdate : public AVP_Message_Actor_ClientUpdate
{
public:
    void					FillVertebrate( const AVP_ServerActor_Vertebrate& xVertebrate );

	bool					GetEnemyInMeleeRange() const { return m_bEnemyInMeleeRange; }

	u_int GetDestroyedSkinElementFlags() const { return m_uDestroyedSkinElementFlags; }

#ifdef ASURA_SUPPORT_NETMSG_SYSTEM
	// No way to create this class directly, so no need to register this entity type.
	static void RegisterFields(Asura_NetMsg* pxNetMsg);
	static u_char GetNumFields() { return static_cast<u_char>(2 + AVP_Message_Actor_ClientUpdate::GetNumFields()); }
#endif//#ifdef ASURA_SUPPORT_NETMSG_SYSTEM

protected:

	struct
	{
		bool	m_bEnemyInMeleeRange;
	};

	u_int m_uDestroyedSkinElementFlags;

private:
	typedef AVP_Message_Actor_ClientUpdate PARENT;
};

class AVP_Message_VertebratePlayerCommands : public AVP_Message_ActorPlayerCommands
{
public:
	// Constructor
	AVP_Message_VertebratePlayerCommands( const AVP_ClientActor_Vertebrate& xVert );
	
	void FillVertebrate( const AVP_ClientActor_Vertebrate& xVert );

	// Accessor functions...
	Asura_Guid GetCurrentMeleeTarget() const { return m_uCurrentMeleeTarget; }

	// Compression
	void Pack( Asura_BitPacker& xPacker ) const; 
	void Unpack( Asura_BitUnpacker& xUnpacker ); 

protected:
	AVP_Message_VertebratePlayerCommands() {}

private:
	typedef AVP_Message_ActorPlayerCommands PARENT;

	Asura_Guid		m_uCurrentMeleeTarget;

	// Private functions...
	AVP_Message_VertebratePlayerCommands( const AVP_Message_VertebratePlayerCommands& xOther );
	AVP_Message_VertebratePlayerCommands& operator=( const AVP_Message_VertebratePlayerCommands& xOther );

};   // End of class 'AVP_Message_PredatorPlayerCommands'.

class AVP_Message_Vertebrate_RequestMelee
{
public:
	void SetType(u_int uType) { m_uType = uType; }
	u_int GetType() const { return m_uType; }

	void SetTargetGuid(Asura_Guid uTargetGuid) { m_uTargetGuid = uTargetGuid; }
	Asura_Guid GetTargetGuid() const { return m_uTargetGuid; }

private:
	u_int m_uType;
	Asura_Guid m_uTargetGuid; // Leave as unregistered to let the melee system choose.
};   // End of class 'AVP_Message_Vertebrate_RequestMelee'.

class AVP_Message_Vertebrate_RequestMelee_Ex : public AVP_Message_Vertebrate_RequestMelee
{
public:

	void SetForceMiss(bool bMiss) { m_bMiss = bMiss; }
	bool GetForceMiss() const { return m_bMiss; }
	void SetDamageMultiplier(float fDmgMultiplier) { m_fDmgMultiplier = fDmgMultiplier;}
	float GetDamageMultiplier() const { return m_fDmgMultiplier;}

private:
	bool m_bMiss;
	float m_fDmgMultiplier;

};   // End of class 'AVP_Message_Vertebrate_RequestMelee_Ex'.



class AVP_Msg_Melee_Attack_Hit
{
public:
	Asura_Guid GetHitEntity() const				{ return m_uHitEntity; }
	void SetHitEntity(Asura_Guid uHitEntity)	{ m_uHitEntity = uHitEntity; }

	u_int GetPendingVariation() const					{ return m_uPendingVariation; }
	void SetPendingVariation(u_int uPendingVariation)	{ m_uPendingVariation = uPendingVariation; }

	u_int GetPendingAttackType() const					{ return m_uPendingAttackType; }
	void SetPendingAttackType(u_int uPendingAttackType)	{ m_uPendingAttackType = uPendingAttackType; }

	u_int GetDamageType() const							{ return m_uDamageType; }
	void SetDamageType(u_int uDamageType)				{ m_uDamageType = uDamageType; }

	bool GetIsRightHanded() const						{ return m_bRightHand; }
	void SetIsRightHanded(bool bRightHand)				{ m_bRightHand = bRightHand; }

private:
	Asura_Guid m_uHitEntity;
	u_int m_uPendingVariation;
	u_int m_uPendingAttackType;
	u_int m_uDamageType;
	bool m_bRightHand;
};


// Alternative hit message designed for moves which transition to the new type of grapples.
class AVP_Msg_Melee_Attack_PrepareGrapple
{
public:
	Asura_Guid GetHitEntity() const				{ return m_uHitEntity; }
	void SetHitEntity(Asura_Guid uHitEntity)	{ m_uHitEntity = uHitEntity; }

	Asura_Hash_ID GetGrappleDescriptionBlueprint() const	{ return m_uGrappleDescriptionBlueprint; }
	void SetGrappleDescriptionBlueprint(u_int uBlueprint)	{ m_uGrappleDescriptionBlueprint = uBlueprint; }

private:
	Asura_Guid m_uHitEntity;
	Asura_Hash_ID m_uGrappleDescriptionBlueprint;
};


class AVP_Msg_Melee_Attack_FailedToStart
{
public:
	void SetType(u_int uType) { m_uType = uType; }
	u_int GetType() const { return m_uType; }
private:
	u_int m_uType;
};

// This is sent from client to server. It will tell server result of players attempt to hit sweet spot when grapple is initialized
class AVP_Message_Vertebrate_ActiveGrappleValue
{
public:
	void SetValue( float fActiveGrappleValue )	{ m_fActiveGrappleValue = fActiveGrappleValue; }
	float GetValue() const						{ return m_fActiveGrappleValue; }

private:
	float m_fActiveGrappleValue;
};   // End of class 'AVP_Message_Vertebrate_ActiveGrappleValue'.


// This is sent back to clients after receipt of the above in order to let them know who won. This will often be sent twice in multiplayer - once when each player's value is received - the first time being a prediction, the second time finalising it (and correcting a client if they've wrongly used the prediction).
class AVP_Message_Vertebrate_ActiveGrappleResult
{
public:
	void SetAttackerVictorious(bool bAttackerWin)	{ m_bAttackerVictorious = bAttackerWin; }
	bool GetAttackerVictorious() const				{ return m_bAttackerVictorious; }

	void SetCriticalVictory(bool bCritical)			{ m_bCriticalVictory = bCritical; }
	bool GetCriticalVictory() const					{ return m_bCriticalVictory; }

	void SetFinalResult(bool bFinal)				{ m_bFinalResult = bFinal; }
	bool IsFinalResult() const						{ return m_bFinalResult; }

private:
	bool m_bAttackerVictorious;
	bool m_bCriticalVictory;
	bool m_bFinalResult;
};


// Multiple moves may send the animations in the message, so they can all use this.
class AVP_Msg_Move_Start_AnimationData : public Asura_Msg_Move
{
public:
	void SetAnimHashes(Asura_Hash_ID uFirstPersonAnim, Asura_Hash_ID uThirdPersonAnim) { m_uFirstPersonAnim = uFirstPersonAnim; m_uThirdPersonAnim = uThirdPersonAnim; }

	Asura_Hash_ID GetFirstPersonAnim() const { return m_uFirstPersonAnim; }
	Asura_Hash_ID GetThirdPersonAnim() const { return m_uThirdPersonAnim; }

protected:
	Asura_Hash_ID m_uFirstPersonAnim;
	Asura_Hash_ID m_uThirdPersonAnim;
};

// This is sent from the server to the client to tell them to start a flinch. This won't always start a move, but if it does...
class AVP_Msg_Flinch
{
public:
	void ResetFlags() { m_uFlags = 0; }
	void SetAnimHashes(Asura_Hash_ID uFirstPersonAnim, Asura_Hash_ID uThirdPersonAnim) { m_uFirstPersonAnim = uFirstPersonAnim; m_uThirdPersonAnim = uThirdPersonAnim; }
	void SetTargetHeading(float fHeading) { m_fTargetHeading = fHeading; }
	void SetUseFlinchMove(bool bUseMove) { m_uFlags = bUseMove ? (m_uFlags | FLAG_USEFLINCHMOVE) : (m_uFlags & ~FLAG_USEFLINCHMOVE); }
	void SetAttackBlocked(bool bBlocked) { m_uFlags = bBlocked ? (m_uFlags | FLAG_ATTACKBLOCKED) : (m_uFlags & ~FLAG_ATTACKBLOCKED); }
	void SetDisableSurfaceReorientation(bool bDisable) { m_uFlags = bDisable ? (m_uFlags | FLAG_DISABLESURFACEREORIENTATION) : (m_uFlags & ~FLAG_DISABLESURFACEREORIENTATION); }
	void SetResetAimDirection(bool bReset) { m_uFlags = bReset ? (m_uFlags | FLAG_RESETAIMDIRECTION) : (m_uFlags & ~FLAG_RESETAIMDIRECTION); }
	void SetOrientateToImpactDirection(bool bReorientate) { m_uFlags = bReorientate ? (m_uFlags | FLAG_ORIENTATETOIMPACTDIRECTION) : (m_uFlags & ~FLAG_ORIENTATETOIMPACTDIRECTION); }

	Asura_Hash_ID GetFirstPersonAnim() const { return m_uFirstPersonAnim; }
	Asura_Hash_ID GetThirdPersonAnim() const { return m_uThirdPersonAnim; }
	float GetTargetHeading() const { return m_fTargetHeading; }
	bool GetUseFlinchMove() const { return (m_uFlags & FLAG_USEFLINCHMOVE) != 0; }
	bool GetAttackBlocked() const { return (m_uFlags & FLAG_ATTACKBLOCKED) != 0; }
	bool GetDisableSurfaceReorientation() const { return (m_uFlags & FLAG_DISABLESURFACEREORIENTATION) != 0; }
	bool GetResetAimDirection() const { return (m_uFlags & FLAG_RESETAIMDIRECTION) != 0; }
	bool GetOrientateToImpactDirection() const { return (m_uFlags & FLAG_ORIENTATETOIMPACTDIRECTION) != 0; }

private:
	Asura_Hash_ID m_uFirstPersonAnim;
	Asura_Hash_ID m_uThirdPersonAnim;
	float m_fTargetHeading; // Euler y value, only relevant if FLAG_ORIENTATETOIMPACTDIRECTION is set.
	u_int m_uFlags;

	enum
	{
		FLAG_USEFLINCHMOVE = 0x00000001,
		FLAG_ATTACKBLOCKED = 0x00000002,
		FLAG_DISABLESURFACEREORIENTATION = 0x00000004,
		FLAG_RESETAIMDIRECTION = 0x00000008,
		FLAG_ORIENTATETOIMPACTDIRECTION = 0x00000010,
	};
};

// ...we'll locally create and handle a message using this class, which will use the normal move start handling with the extra data taken from the message above used to fill out the move's details.
class AVP_Msg_Flinch_Move_Start : public AVP_Msg_Move_Start_AnimationData
{
public:
	void SetTargetOrientation(const Asura_Matrix_3x3& xTargetOrientation) { m_xTargetOrientation = xTargetOrientation; }
	void SetDisableSurfaceReorientation(bool bDisable) { m_bDisableSurfaceReorientation = bDisable; }
	void SetResetAimDirection(bool bReset) { m_bResetAimDirection = bReset; }

	void GetTargetOrientation(Asura_Matrix_3x3& xTargetOrientation) const { xTargetOrientation = m_xTargetOrientation; }
	bool GetDisableSurfaceReorientation() const { return m_bDisableSurfaceReorientation; }
	bool GetResetAimDirection() const { return m_bResetAimDirection; }

protected:
	Asura_Matrix_3x3 m_xTargetOrientation;
	bool m_bDisableSurfaceReorientation;
	bool m_bResetAimDirection;
};

//////////////////////////////////////////////////////////////////////////////
//
// AVP_Message_HealthOverride
//
//////////////////////////////////////////////////////////////////////////////

class AVP_Message_HealthOverride
{
public:
	// Public functions...
	AVP_Message_HealthOverride(void) {}
	float m_fHealth;
};

class AVP_Msg_CreateSound
{
	public:
		AVP_Msg_CreateSound()	
		{ 
			m_bOriginatesFromPlayer = true;
		}

		void	SetOriginatesFromPlayer( bool bOriginatesFromPlayer )	{ m_bOriginatesFromPlayer = bOriginatesFromPlayer; }
		bool	GetOriginatesFromPlayer( void )	const					{ return m_bOriginatesFromPlayer; }

		void			SetSoundHashId( Asura_Hash_ID uSoundID )		{ m_uSoundHashId = uSoundID; }
		Asura_Hash_ID	GetSoundHashId( void ) const					{ return m_uSoundHashId; }

	private:
		bool			m_bOriginatesFromPlayer;		// bool to say if the sounds originated from the players location. 
		Asura_Hash_ID	m_uSoundHashId;					// Sounds name Hash Id to Look up from blueprints
};

class AVP_Msg_DistractAI
{
public:
	AVP_Msg_DistractAI()	
	{ 
		m_bReconDistraction = false; 
	}

	void SetTargetGuid(Asura_Guid uTargetGuid) { m_uTargetGuid = uTargetGuid; }
	Asura_Guid GetTargetGuid() const { return m_uTargetGuid; }

	void	SetReconBool( bool bRecon )	{ m_bReconDistraction = bRecon; }
	bool	GetReconBool() const		{ return m_bReconDistraction; }

private:
	Asura_Guid	m_uTargetGuid;

	bool	m_bReconDistraction;
};

#endif   // ifndef __AVP_VERTEBRATE_MESSAGES_H__

/// End of file. ///
