
///////////////////////////////////////////////////////////////////////////////
//
// File   : AVP_ServerProjectile_GenericProjectile.h
// Author : Chris Wallace
// Date   : 27-June-2007
//
// Copyright (C) 2007 Rebellion, All Rights Reserved.
//
///////////////////////////////////////////////////////////////////////////////

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

#ifndef __AVP_SERVERPROJECTILE_GENERICPROJECTILE_H__
#define __AVP_SERVERPROJECTILE_GENERICPROJECTILE_H__

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

#include "Entity/PhysicalObject/Projectile/AVP_ServerEntity_Projectile.h"

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

class AVP_GenericProjectileData;

////////////////////////////////////////////////////////////////////////////////
// Class        : AVP_ServerProjectile_GenericProjectile
// Author       : Will Plano
// Date         : 20/12/2007
//
// Description  : Class to handle the generic projectile
////////////////////////////////////////////////////////////////////////////////

class AVP_ServerProjectile_GenericProjectile : public AVP_ServerEntity_Projectile
{
public:
	static	AVP_ServerProjectile_GenericProjectile*	Create( const Asura_Message* pxMsg );

	bool			IsEmbedded() const { return m_bEmbedded; }
	bool			IsAvoidedByAI() const;
	bool			IsForwardPredictedByAI() const;

	virtual void	Launch	(const Asura_Vector_3& xPosition, const Asura_Matrix_3x3& xOrientation, const Asura_Vector_3& xVelocity, const Asura_Guid uGuidToIgnore, float fDamageMultiplier);

	virtual	void	Update(void);

	virtual	void	ReadFromChunkStream(Asura_Chunk_Stream& xStream);
	virtual	void	WriteToChunkStream(Asura_Chunk_Stream& xStream) const;
	virtual bool	CanBeSavedToChunk(void) const	{ return(false); }

	// Legacy chunk handling, to be removed as soon as possible...
	virtual	bool	IsFilledFromChunkBuffer(void) const	{ return(false); }

	virtual bool	CheckForCollisionsUsingLOS( const Asura_Vector_3& xPosition, const Asura_Vector_3& xVelocity );

	void			SetTargetGuid(Asura_Guid uGuid) {m_uTargetGuid = uGuid;}

	static	AVP_ServerProjectile_GenericProjectile*								FindEntity(const Asura_Guid uGuid)	{ return(s_xList.FindEntity(uGuid)); }
	static	const Asura_Hashed_List<AVP_ServerProjectile_GenericProjectile>*	GetList(void)						{ return(&s_xList); }

protected:
	AVP_ServerProjectile_GenericProjectile( const Asura_Guid uGuid );
	AVP_ServerProjectile_GenericProjectile( const Asura_Guid uGuid, const Asura_Message* pxMsg );
	virtual ~AVP_ServerProjectile_GenericProjectile();

	virtual void	InitialiseFromBlueprint( const Asura_Blueprint& xBlueprint );

	virtual void	OnImpact( const Asura_Vector_3& xImpactPoint, const Asura_Vector_3& xImpactNormal = Asura_Maths::ZeroVector3 );
	virtual void	OnCollision( const Asura_LOS_InputData& xLOSInputData, const Asura_LOS_OutputData& xLOSOutputData ); 
	virtual void	OnEmbed( const Asura_Vector_3& xImpactPoint, const Asura_Vector_3& xImpactNormal ) { m_bEmbedded = true; }
	
	void			Explode();

	virtual	void	MakeClientUpdateMessage(void);

protected:
	const AVP_GenericProjectileData* m_pxProjectileData;
	bool							 m_bEmbedded;

	Asura_Guid						 m_uTargetGuid;
	float							 m_fTargetSeekingAngle;
	float							 m_fTargetTurningPerSecond;

	u_int							 m_uPhysicsCounter;	// Internal state of physics. Use this counter to stay in sync with physics.... Update projectile flight only when physics has been updated too. Otherwise, there is no point of updating.

private:
	typedef AVP_ServerEntity_Projectile PARENT;

	static Asura_Hashed_List<AVP_ServerProjectile_GenericProjectile> s_xList;

	AVP_ServerProjectile_GenericProjectile(void);
	AVP_ServerProjectile_GenericProjectile(const AVP_ServerProjectile_GenericProjectile& xOther);
	AVP_ServerProjectile_GenericProjectile&	operator=(const AVP_ServerProjectile_GenericProjectile& xOther);
};

#endif   // ifndef __AVP_SERVERPROJECTILE_GENERICPROJECTILE_H__

/// End of file. ///
