#ifndef PLAYER_MELEE_H
#define PLAYER_MELEE_H

// STL
#pragma warning (disable:4530)
/*
#include <list>
#include <vector>
#include <map>
#include <string>
*/

#include "classes.h"
#define MAX_COMBOHITS		32
#define MIN_SWITCH_RATIO	0.2
#define BACK_TRACE_DIST		5.5
#define MELEE_RECOVER_COST	150
#define MELEE_WALLSTICK_RECOVER_COST 100
#define PREPUNCH_STUN_COST	15
#define PREPUNCH_AFTER_COST	25
#define MELEE_END_OFFSET	68
#define THROW_ORIGIN_OFFSET	80
#define UPDATE_PS_MSG	(float)0.05
#define MAX_STRUGGLE_CHARGE	(float)30
#define MAX_STRUGGLE_DIFF (float)60
#define STRUGGLE_CHARGE_RATE (float)20
#define STRUGGLE_SLOWDOWN_RATE (float)6
#define STRUGGLE_MINTELE_TIME (float)2
#define STRUGGLE_MAXTELE_ATTEMPTS 6
#define PUSHBACK_RANGE	350
#define PUSHBACK_FORCE	900
#define BLOCKSTUN_WEAK		0
#define BLOCKSTUN_MEDIUM	1
#define BLOCKSTUN_STRONG	2
#define PREPUNCH_BEHIND_BLOCKSTUN	1
#define MAX_PL_DIFF_BLKFLASH	10
#define CHARGE_MIN_LASTMOVE	1
#define MAX_DELAY_MOVES	3
#define MIN_SLICE_PERCNT 0.2	// 20%
#define TOSS_LAYTIME	1.25
#define LANDRECOVER_TIME 1
#define LANDRECOVER_HOP_FORCE	900
#define CONSECUTIVE_MELEEHITS	2
#define MIN_RATIO 0.5
#define MAX_RATIO 2.0
#define PREPUNCH_KI_BLK_COST	20
#define MAX_PREPUNCH_THROW	8

// Extern cvars
extern cvar_t simplemelee;
extern cvar_t melee_skill;
extern cvar_t melee_percentblocked;
extern cvar_t melee_prepunch_delay;
extern cvar_t melee_prepunch_delaystruggle;
extern cvar_t melee_prepunch_driftspeed;
extern cvar_t melee_prepunch_max;
extern cvar_t melee_prepunch_maxstun;
extern cvar_t melee_prepunch_mincombo;
extern cvar_t melee_maxextanges;
extern cvar_t melee_wallstick_canstick;
extern cvar_t melee_wallstick_mintime;
extern cvar_t melee_wallstick_maxtime;
extern cvar_t melee_struggle_maxarrows;
extern cvar_t melee_struggle_arrowtime;
extern cvar_t melee_struggle_startdelay;
extern cvar_t melee_struggle_enddelay;
extern cvar_t melee_struggle_maxextanges;

// Messages
extern int gmsgMeleeAtkHud;
extern int gmsgMeleeTxtHud;
extern int gmsgCharge;
extern int gmsgPowerStruggle;
extern int gmsgMeleeFX;

/*
* Simple Melee
*/

// Enums
typedef enum
{	UP=0,
	DOWN,
	LEFT,
	RIGHT,
	FRONT,
	BACK,
} MELEE_DIRECTION;

typedef enum
{	THROW_DISABLE = 0,	// Disabled
	THROW_TOSS,			// Traveling through the air
	THROW_ROLL,			// Rolling
	THROW_WALLSTICK,	// Wallstick
	THROW_LAY,			// Lay
	THROW_LANDRECOVER,	// Land on all 4's and recover
	THROW_RECOVER,		// Recover
} THROW_STATUS;

/*
* Advanced Melee
*/
typedef enum
{	DISABLED = 0,
	PREPUNCH_ATTACK,	// Agressive attacker
	PREPUNCH_DEFEND,	// Taking prepunch hits
	CHARGE_ATTACK,		// Charging combos
	CHARGE_DEFEND,		// Blocking / defending queued combos
	GRAB_ATTACK,		// Grabbing attack
	GRAB_DEFEND,		// Being grabbed
	EXE_ATTACK,			// Executing combo
	EXE_DEFEND,			// Defending Executing combo
	STRUGGLE_ATTACK,	// Melee Powerstruggle attacker
	STRUGGLE_BURST_ATTACK,	// Melee Powerstruggle BURST attacker
	STRUGGLE_DEFEND,	// Melee Powerstruggle defender
	KNOCKPRE_STRUGGLE_ATTACK,// Knockback - Prepunch struggle attack
	KNOCKPRE_STRUGGLE_DEFEND,// Knockback - Prepunch struggle attack

} ADV_MELEE_STATUS;

typedef enum
{	WEAK_HIT = 0,
	MEDIUM_HIT,
	STRONG_HIT 
} MELEE_STRENGTH;

typedef enum
{	COMBO_NONE,
	COMBO_START,
	COMBO_IDLE,
	COMBO_END
} MELEE_COMBO_STATUS;

typedef enum
{	BLOCK_NONE=0,
	BLOCK_TRUE,
	BLOCK_FAIL
} BLOCK_STATUS;

// Advanced Melee Directions
typedef enum
{	PUNCH_UP = 0,
	PUNCH_UPPERLEFT,
	PUNCH_LEFT,
	PUNCH_LOWERLEFT,
	PUNCH_DOWN,
	PUNCH_LOWERRIGHT,
	PUNCH_RIGHT,
	PUNCH_UPPERRIGHT,
	KICK_UP,
	KICK_UPPERLEFT,
	KICK_LEFT,
	KICK_LOWERLEFT,
	KICK_DOWN,
	KICK_LOWERRIGHT,
	KICK_RIGHT,
	KICK_UPPERRIGHT,
	PUNCH_NODIR,
	KICK_NODIR,
} ADV_MELEE_DIRECTION;

typedef enum
{	ANIM_PRIORITY_HIGH=0,
	ANIM_PRIORITY_MEDIUM_HIGH,
	ANIM_PRIORITY_MEDIUM,
	ANIM_PRIORITY_LOW,
} ANIM_PRIORITY;

typedef enum
{	MELEETXT_HIT=0,
	MELEETXT_HITS,
	MELEETXT_COMBO,
	MELEETXT_DAMAGE,
	MELEETXT_SWORDKILL,
	MELEETXT_CRITICAL,
	MELEETXT_PERDAMAGE,
	MELEETXT_LOWKI,
	MELEETXT_LOWHP,
	MELEETXT_DEEPSHIT,
	MELEETXT_DODGED,
	MELEETXT_BLOCKBREAK,
	MELEETXT_WINNER,
	MELEETXT_LOOSER,
	MELEETXT_TIE,
	MELEETXT_HEADON,
	MELEETXT_KNOCKBACK,
	MELEETXT_PREPUNCH
}MELEETXT;

#ifndef CLIENT_DLL
struct melee_settings_s;
#endif

// Types of melee hud elements
#define M_ARROW_HUD			1
#define M_FLASH_HUD			2
#define M_FLASHUPDATE_HUD	3
#define M_INIT_HUD			4
#define M_ARROW_HUD_END		5
#define M_ARROW_HUD_SWITCH	6
#define M_ARROW_HUD_DEL		7

#define KI_UPDATE_TIME	0.20
#define MAX_LINKED_ANIM	16

// Added by Rick
class CBuddy;
// end add by Rick
struct plrmelee_anim_s
{	
	char	szAnim[MAX_LINKED_ANIM][32];	// Name of animation
	Activity IdealActivity[32];		// Ideal Activity
	ANIM_PRIORITY eAnimPriority;	// Anim Priority (Default = HIGH)		
	int		iNumAnims;		// Number of animations
	int		iCurrentAnim;	// Animation we are currently on
	float	flTime;			// Time to display
	BOOL	fLooping;		// Loop
	BOOL	fExecution;		// Combo Execution
	BOOL	fAngleFix;		// Angle fix animation
	BOOL	fInit;			// Initilized animation
	BOOL	fStartOnGround;	// Start anim on ground

	plrmelee_anim_s *pNext;	// Next link in list
};

struct melee_combo_hit_s
{	int		iAttackNum;	// Attack number
	float	flHitTime;	// Hit Time
	float	flDamage;	// Damage
	BOOL	fEmitDamage;// Has damage been emitted?
	BOOL	fExecute;	// If we should "Execute" this move eventually
	void (*pComboCallBack) (CBasePlayer *pAttacker, CBasePlayer *pDefender);	// Function callback for each attack
};

struct melee_execution_s
{
	char	szAnim[32];				// Animation name
	int		iFlags;					// Flags
	int		iComboID;				// Combo number
	int		iComboHits;				// Amount of hit sequences in combo
	int		iComboCurrent;			// Current combo we're on
	int		iNum;					// Melee Move #X in linked list
	float	flStartTime;			// Start Time
	float	flEmitDamage;			// Time we should emit damage after animation is played
	BOOL	fBlockStun;				// unblocked by blockstun
	BOOL	fEmitDamage;			// If we emitted the damage(and sounds)
	BOOL	fCombo;					// "Combo" move, if so ignore everything and strictly use combohit
	BOOL	fForceZStrait;			// Force Z axis to zero out on last hit melee moves
	MELEE_COMBO_STATUS eComboStatus;// Combo Status ( if any )
	MELEE_STRENGTH	eStrength;		// Strength of move
	BLOCK_STATUS	eBlock;			// Block Status
	melee_combo_hit_s combohit[MAX_COMBOHITS]; // Combohit array

	melee_execution_s *pNext;
	melee_execution_s *pPrev;
};

struct melee_move_s
{
	int		iNumID;			// Arrow number ( only used with blocking )
	int		iFlags;			// Directions pressed
	float	flTimeStart;	// Time start
	float	flTimeEnd;		// Time end
	BOOL	fFinished;		// Is the move 'done'?

	// Only used for comob execution
	int		iComboID;				// Combo number
	MELEE_COMBO_STATUS eComboStatus;	// Combo Status ( if any )

	melee_move_s *pPrev;	// Previous link
	melee_move_s *pNext;	// Next link
};

struct melee_c_move_s
{	int	iFlags;			// Directions pressed
	MELEE_STRENGTH eStrength;
};

struct combo_move_s
{
	int	iNumDirections;
	int iComboID;
	melee_c_move_s	directions[8];

	combo_move_s *pNext;
	combo_move_s *pPrev;
};

/*
* Melee Attack System
* @version 5-2-2003
* @author Joseph 'Pcjoe' Florencio
*/
class CPlayerMelee
{
public:
	CPlayerMelee();

	/*
	* Reset varibles
	*/
	virtual void Reset( void );

#ifndef CLIENT_DLL
	/*
	* Get Skill Varibles
	*/
	virtual melee_settings_s *GetSkillValues( void );
#endif


	/*
	* ======================================
	* Animation System
	*
	* ======================================
	*/


	/*
	* Manage animation list, deletes out-of-date anims
	*/
	void ManageList( void );

	/*
	* Set Anim Priority
	*/
	void SetAnimPriority( ANIM_PRIORITY ePriority, plrmelee_anim_s *pAnim );

	/*
	* Can Play Medium Priority Anims
	*/
	BOOL PlayMedPriorityAnim( void );

	/*
	* Can Play Low Priority Anims
	*/
	BOOL PlayLowPriorityAnim( void );

	/*
	* Manage Priority
	*/
	void ManagePriority( void );

	/*
	* Adds animation to list
	* @param char blLooping: Loop the animation?
	* @param float flTime: Time animation will play
	* @param int iNum: Number of anims we are sending over
	* @param ... : Name(s) of animations. Set in pairs - "Name of anim", Activity, ...
	*/
	plrmelee_anim_s *AddAnimation( bool blLooping, float flTime, int iNum, ... );
	plrmelee_anim_s *AddAnimationAFix( Vector vecNormal, bool blLooping, float flTime, const char *szString );
	plrmelee_anim_s *AddToCurAnim( bool blLooping, char *szString );
	plrmelee_anim_s *AddAnimationExe( float flTime, char *szString );

	/*
	* Gets current animation playing in the melee system
	* @return plrmelee_anim_s: player animation struct
	*/
	plrmelee_anim_s *GetCurrentAnim( void );

	/*
	* Gets current execution animation playing in the melee system
	* @return plrmelee_anim_s: player animation struct
	*/
	plrmelee_anim_s *GetCurrentExeAnim( void );

	/*
	* Get an animation name for a combo move
	*/
	void GetAnimForMove( melee_move_s *pMove, char *pAnim );
	void GetAnimForMove( int iFlags, MELEE_STRENGTH eStrength, char *pAnim );

	/*
	* Can we play an aniamtion?
	* @return BOOL: True - Can play animation
	*/
	BOOL CanPlayAnimation( void );

	/*
	* Melee Frame Advanced (frame rate of player.mdl)
	*/
	void MeleeFrameAdvance( void );

	/*
	* Removes aniamtion from list
	* @param char *pName: Name of animation(s) to remove
	* @return plrmelee_anim_s: Next animation on list
	*/
	plrmelee_anim_s *RemoveAnim( plrmelee_anim_s *pAnim );

	/*
	* Removes aniamtion from list
	* @param plrmelee_anim_s *pAnim: Struct of animation to remove
	*/
	void RemoveAnim( char *pName );

	/*
	* Removes all animations
	*/
	void RemoveAllAnims( void );

	/*
	* ======================================
	* End of Animation System
	*
	* ======================================
	*/

	
	/*
	* ======================================
	* Toss System
	*
	* ======================================
	*/

	/*
	* Manage Toss
	*/
	void ManageToss( void );

	/*
	* In Throw
	*/
	BOOL InThrow( void ) { return (m_eThrowStatus != THROW_DISABLE); }

	/*
	* Special Laser Reduction
	*/
	BOOL SpecialLaserReduction( void ) { return (m_eThrowStatus == THROW_WALLSTICK || m_eThrowStatus == THROW_LANDRECOVER || m_eThrowStatus == THROW_LAY); }

	
	/*
	* Get Throw Direction (ENUM)
	* @param BOOL fUseUpDown: Use up and down directions
	*/
	int GetThrowDirection( BOOL fUseUpDown );
	
	/*
	* Get Throw Anim Direction
	* @param BOOL fUseUpDown: Use up and down directions
	* @param int iDirection: Direction of throw
	* @param char *pAnim: Animation
	*/
	void GetThrowAnimDirection( int null, int iDirection, char *pAnim );
	void GetThrowAnimDirection( BOOL fUseUpDown, char *pAnim );

	/*
	* Get Throw Activity (Animation)
	*/
	Activity GetThrowActivity( void );

	/*
	* Set Throw Anim
	* @param char *pAnim: Animation
	* @param Activity &IdealActivity: Ideal Activity
	*/
	void SetThrowAnim( char *pAnim, Activity &IdealActivity );

	/*
	* Make Creater
	*/
	void MakeCreater( void );

	/*
	* Apply Velocity
	*/
	void ApplyVelocity( void );

	/*
	* Start "Toss"
	* @param CBasePlayer *pThrower: Player who is "tossing" this player
	* @param BOOL fDmgOnCollision: Take Damage on Collision. If false we will just stop the player
	* @param Vector vecDirection: Normalized Vector in direction we're traveling
	* @param float flMaxSpeed: Max/Starting speed of the throw
	* @param float flMinSpeed: Min speed of the throw, auto-recover if under this speed
	* @param float flDeacceleration: Rate at which we deaccelerate
	* @param float flMinRecoverTime: The soonest we can force recover
	*/
	void StartToss( CBasePlayer *pThrower, BOOL fDmgOnCollision, Vector vecDirection, float flMaxSpeed, float flMinSpeed, float flDeacceleration, float flMinRecoverTime );


	// Added by Rick: buddy version
	/*
	* Start "Toss"
	* @param CBuddy *pThrower: Buddy who is "tossing" this player
	* @param BOOL fDmgOnCollision: Take Damage on Collision. If false we will just stop the player
	* @param Vector vecDirection: Normalized Vector in direction we're traveling
	* @param float flMaxSpeed: Max/Starting speed of the throw
	* @param float flMinSpeed: Min speed of the throw, auto-recover if under this speed
	* @param float flDeacceleration: Rate at which we deaccelerate
	* @param float flMinRecoverTime: The soonest we can force recover
	*/
	void StartToss( CBuddy *pThrower, BOOL fDmgOnCollision, Vector vecDirection, float flMaxSpeed, float flMinSpeed, float flDeacceleration, float flMinRecoverTime );

	/*
	* DeaccelerateToss (Using frametime)
	* @return BOOL: If we deaccelerated below the min speed
	*/
	BOOL DeaccelerateToss( void );

	/*
	* Check for obsticales
	* @return BOOL: If we hit BSP and changed toss mode
	*/
	BOOL CheckForObsticales( void );

	/*
	* Handle Toss
	*/
	void HandleToss( void );

	/*
	* Handle Recover
	* @return BOOL: Recovered successfully
	*/
	BOOL HandleRecover( void );

	/*
	* Start Roll
	*/
	void StartRoll( void );

	/*
	* Handle Roll
	*/
	void HandleRoll( void );

	/*
	* Check Creater
	*/
	void CheckCreater( void );

	/*
	* Start Land Recover ( land on all 4's, hop away )
	*/
	void StartLandRecover( void );

	/*
	* Handle Land Recover
	*/
	void HandleLandRecover( void );

	/*
	* Land Recover Dash
	*/
	void LandRecoverDash( void );

	/*
	* Start Lay
	*/
	void StartLay( void );

	/*
	* Handle Lay
	*/
	void HandleLay( void );

	/*
	* Inflict Wallhit Dmg
	* @param BOOL fObjectStick: If we're sticking to the wall/ground
	* @return BOOL: If we lived
	*/
	BOOL InflictWallhitDmg( BOOL fObjectStick );

	/*
	* Stop Throw
	* @param BOOL fMultiHit: Multi hit
	*/
	void StopThrow( BOOL fMultiHit );
	void StopThrow( void );

	/*
	* Recover
	*/
	void Recover( void );

	/*
	* Start Wallstick
	*/
	void StartWallStick( Vector vecOrigin, Vector vecNormal );

	/*
	* Handle Wallstick
	*/
	void HandleWallStick( void );

	/*
	* Update Struggle Bar
	*/
	void UpdateStruggleBar( int iUpdate );

	/*
	* Remove Struggle Bar
	*/
	void RemoveStruggleBar( void );


	int				m_iConsecutiveHits;		// Consecutive simple melee hits
	float			m_flMaxSpeed;			// Max Speed
	float			m_flCurSpeed;			// Current Speed
	float			m_flMinSpeed;			// Speed that we autorecover at
	float			m_flDeacceleration;		// Deacceleration rate
	float			m_flMinRecoverTime;		// Min time we can force recover
	float			m_flLayStart;			// Time we start laying down
	float			m_flLandRecoverStart;	// Ground recover start time
	float			m_flStartWallStick;		// time we started sticking to the wall
	float			m_flLastRecoverTime;	// Last time we recovered
	BOOL			m_fThrown;				// Are we being thrown?
	BOOL			m_fTakeDmgOnCollision;	// Take damage on collision? If false, Autorecover if we hit the wall
	BOOL			m_fOnGround;			// Used to create creaters with THROW_ROLL
	BOOL			m_fFlyRecover;			// If we're in the air while recovering
	BOOL			m_fStruggleBar;			// Struggle bar active?
	BOOL			m_fEndAdvMeleeToss;		// End adv melee toss
	Vector			m_vecDirection;			// Direction we're being thrown (used in THROW_TOSS)
	Vector			m_vecWallStickNormal;	// Surface normal for wallstick
	Vector			m_vecLandRecoverAngles;	// Land recover angles
	THROW_STATUS	m_eThrowStatus;			// Throw status
	CBasePlayer		*m_pThrower;			// Player that threw us
	// Added by Rick
	CBuddy			*m_pBuddyThrower;		// Buddy that threw us
	
	/*
	* ======================================
	* End of Toss System
	*
	* ======================================
	*/

	/*
	* ======================================
	* Combo System
	*
	* ======================================
	*/

	/*
	* Basic Melee calls ( Handle...Attack/Handle...Defend )
	*/
	void ManageMelee( void );

	/*
	* Manage Invulnerability
	*/
	void ManageInvulnerability( void );

	/*
	* Add Combo Moves
	*/
	void AddComboMoves( void );

	/*
	* Set Combo Moves
	* @return BOOL: False if we should quit melee
	*/
	BOOL SetComboMoves( void );

	/*
	* Add Move
	* @param int character: character we're adding moves for
	* @param int comboid: ID of combo
	* @param int num: number of moves in this combo
	* @param ...: strength(enum), directions for move(int), ...
	*/
	void AddMove( int character, int comboid, int num, ... );

	/*
	* Get power ratio between local player and other player
	*/
	float GetPowerRatio( CBasePlayer *pOther );

	/* Added by Rick
	*
	* Get power ratio between local player and enemy buddy
	*/
	float GetPowerRatio( CBuddy *pOther );

	/*
	* Can Inflict Damage
	* @param CBasePlayer *pInflictor: Inflictor of damage
	* @param int iDmgBits: Damage Bits
	* @return BOOL: If we can inflict damage
	*/
	BOOL CanInflictDamage( CBasePlayer *pInflictor, int iDmgBits );

	/*
	* Execute Combo
	*/
	void ExecuteCombo( );

	/*
	* Set directions
	* @return BOOL: Execute combo sequence if true
	*/
	BOOL SetDirections( void );

	/*
	* Set Blocking directions
	*/
	void SetBlockingDirections( void );

	/*
	* Can Add Direction
	*/
	BOOL CanAddDirection( void );

	/*
	* Add Direction
	*/
	void AddDirection( int iFlags );

	/*
	* Is Directionless?
	* @param int iFlags: Attack flags
	* @return BOOL: True if we only have an attack flag set with no directions
	*/
	BOOL IsDirectionless( int iFlags );

	/*
	* Set Direction, unsets Directionless, sets flags
	* @param int iFlags: Attack flags
	*/
	void SetDirection( melee_move_s *pMove, int iFlags );

	/*
	* Remove Direction
	* @return melee_move_s: next pointer in linked list
	*/
	melee_move_s *RemoveDir( melee_move_s *remove );

	/*
	* Set Attack Flags
	* return BOOL: return true if we're holding onto primary / secondary fire
	*/
	BOOL SetAttackFlags( int &iFlags );

	/*
	* Set Movement Flags
	*/
	void SetMovementFlags( int &iFlags );

	/*
	* Let Go Direction
	* @return BOOL: True if we should execute the combo
	*/
	BOOL LetGoDirection( melee_move_s *pMove );

	/*
	* Can let go?
	* @return BOOL: If we can let go of the direction
	*/
	BOOL CanLetGo( melee_move_s *pMove );
	
	/*
	* Delete all directions for attacker
	*/
	void DelAllDirectionsAttacker( void );

	/*
	* Delete all directions for defender
	*/
	void DelAllDirectionsDefender( void );

	/*
	* Delete all directions ( for both )
	*/
	void DelAllDirections( void );

	/*
	* Hold direction
	* @return BOOL: True if we should execute the combo
	*/
	BOOL HoldDirection( melee_move_s *pMove );

	/*
	* Reset Direction
	* @return BOOL: Was the direction reset?
	*/
	BOOL ResetDirection( int iFlags, melee_move_s *pMove );

	/*
	* Get total combo time
	*/
	float TotalCmbTime( void );

	/*
	* Get total combo time not including the current direction
	*/
	float TotalCmbTimeNC( void );

	/*
	* Get Combo Time
	*/
	float GetCmbTime( melee_move_s *pMove );

	/*
	* Get Move Strength
	*/
	int GetMoveStrength( melee_move_s *pMove );

	/*
	* Get current direction
	*/
	melee_move_s *GetCurrentDirection( void );

	/*
	* Get move count
	*/
	int GetMoveCount( void );
	int GetMoveCountFinishedOnly( void );

	/*
	* Get move count ( specific )
	*/
	int GetMoveCount( melee_move_s *pMove );
	int GetMoveCountFinishedOnly( melee_move_s *pMove );

	/*
	* Use Attacker Moveset
	*/
	BOOL UseAttackerMoves( void );

	/*
	* Send Block Flashes
	* @param CBasePlayer *pOther: Player that we're sending the block flashes to
	* @param melee_move_s *pMove: Move we're using to send the block flashes
	*/
	void SendBlockFlash( CBasePlayer *pOther, melee_move_s *pMove );

	/*
	* Melee Hud
	* @param int iType: Type of melee hud: arrows, blocking flashes, or words ( sprites )
	* @param int iDirection: Arrows + Blocking flashes - Direction, Combo - number representing sprites
	*/
	void MeleeHud( int iType, int iDirection );

	/*
	* Melee Text output
	* @param int iType: Type of melee text
	* @param int iNum: Number associated with type ( 0 if none )
	*/
	void MeleeText( int iType, int iNum );

	/*
	* Melee Hud
	* @param int iType: Type of melee hud: arrows, blocking flashes, or words ( sprites )
	*/
	void MeleeHudRemove( int iType );

	/*
	* Flags to directions
	* @param int iFlags: Flags
	* @return int: Directions
	*/
	int FlagsToDirections( int iFlags );

	/*
	* Directions to flags
	* @param int iFlags: Flags
	* @return int: Directions
	*/
	int DirectionsToFlags( int iDirections );

	/*
	* Melee Hud Flags ( turns flags into directions )
	* @param int iType: Type of melee hud: arrows, blocking flashes, or words ( sprites )
	* @param int iFlags: Directions
	*/
	void MeleeHudFlags( int iType, int iFlags );

	/*
	* Update Block Client
	* @param melee_move_s *pBlock: New move we imputted and are testing for block
	*/
	void UpdateBlockClient( melee_move_s *pBlock );

	/*
	* Melee Hud Flags ( turns flags into directions ), only used for M_ARROW_HUD_END
	* @param int iType: Type of melee hud: arrows, blocking flashes, or words ( sprites )
	* @param int iFlags: Directions
	* @param float flDurration: Total time for this direction
	*/
	void MeleeHudFlags( int iType, int iFlags, float flDurration );

	/*
	* Switch Melee Attack Flags ( client side )
	*/
	void MeleeHudSwitchAtk( melee_move_s *pMove );

	/*
	* Send varibles to client so we can predict correctly
	*/
	void SendPredictVars( float flStunTime );

	/*
	* Disable Melee Hud
	*/
	void MeleeHudDisable( void );

	/*
	* ======================================
	* End of Combo System
	*
	* ======================================
	*/

	/*
	* ======================================
	* Advanced Melee System
	*
	* ======================================
	*/

	/*
	* Get Attacker
	* @return CBasePlayer: attacker
	*/
	CBasePlayer *GetAttacker( void ) { return m_pAttacker; }

	/*
	* Get Attacker Other ( person attacking defender )
	* @return CBasePlayer: attacker
	*/
	CBasePlayer *GetAttackerOther( void ) { return m_pAttackerOther; }

	/*
	* Get Attacker
	* @return CBasePlayer: attacker
	*/
	CBasePlayer *GetDefender( void ) { return m_pDefender; }

	/*
	* Get Original Defender
	* @return CBasePlayer: Original Defender
	*/
	CBasePlayer *GetOrigDefender( void );

	/*
	* Get Attacker Moves
	*/
	melee_move_s *GetAttackerMoves( void ) { return m_pAttackerMoves; }

	/*
	* Get Defender Moves
	*/
	melee_move_s *GetDefenderMoves( void ) { return m_pDefenderMoves; }

	/*
	* Get Sound Edict
	*/
	edict_t *GetSoundEdict( void );

	/*
	* Are we a attacker?
	* @return BOOL: If we're a attacker
	*/
	BOOL IsAttacker( void ) { return m_fAttacker; }

	/*
	* Are we a defender?
	* @return BOOL: If we're a defender
	*/
	BOOL IsDefender( void ) { return m_fDefender; }

	/*
	* Are we in a advanced melee battle?
	* @return BOOL: If we're in a adv melee battle
	*/
	BOOL InAdvMeleeBattle( void ) { return m_fFighting; }

	/*
	* Set Attacker
	* @param CBasePlayer *pPlayer: Player we are setting as attacker
	*/
	void SetAttacker( CBasePlayer *pPlayer );

	/*
	* Set Attacker Other ( person attacking defender )
	* @param CBasePlayer *pPlayer: Player we are setting as attacker other
	*/
	void SetAttackerOther( CBasePlayer *pPlayer );

	/*
	* Set Enemy
	* @param CBasePlayer *pOther: Player we are setting as defender
	*/
	void SetDefender( CBasePlayer *pOther );

	/*
	* Set mode
	* @param ADV_MELEE_STATUS: Melee Status
	*/
	void SetMode( ADV_MELEE_STATUS eMode );

	/*
	* Init Melee
	* @param CBasePlayer *pOther: Player we are setting as defender
	*/
	void InitMelee( CBasePlayer *pOther );

	/*
	* Stop Melee
	*/
	void StopMelee( void );
	
	/*
	* Stop Melee
	* @param BOOL fKnockBack: Knock back after fight is done
	*/
	void StopMelee( BOOL fKnockBack );

	/*
	* Pushback Surrounding Players
	*/
	void PushAwayOtherPlayers( void );

	/*
	* Check defender stuntime
	*/
	void CheckStunTime( void );

	/*
	* Get Stun time
	*/
	float GetStunTime( void );

	/*
	* Set Active Stun Time
	*/
	void SetActiveStunTime( float flStunTime );

	/*
	* Set Total Stun Time
	*/
	void SetTotalStunTime( float flStunTime );

	/*
	* Start PrePunch Attack
	*/
	void StartPrePunchAttack( void );

	/*
	* Attack From Behind and Blocking prepunches
	*/
	void SetAtkBehindAndBlocking( void );

	/*
	* Stop Prepunche Attack
	*/
	void StopPrepunchAttack( void );

	/*
	* Get enemy in prepunching area
	* @return CBasePlayer: Pointer of closest punchable player (NULL if none)
	*/
	CBasePlayer *GetEnemyPrepunch( CBasePlayer *pStruggle );

	// Added by Rick : Buddy version
	/*
	* Get enemy in prepunching area
	* @return CBasePlayer: Pointer of closest punchable player (NULL if none)
	*/
	CBuddy *GetBuddyEnemyPrepunch( CBuddy *pStruggle );
	// End add by Rick

	/*
	* Handle attacking prepunch
	*/
	void HandlePrepunchAttack( void );

	/*
	* Get Stun Per Punch
	* @return float: stun per punch
	*/
	float GetStunPerPunch( void );

	/*
	* Get Dmg Per Punch
	* @return float: dmg per punch
	*/
	float GetDmgPerPunch( void );

	/*
	* Handle defending prepunch
	*/
	void HandlePrepunchDefend( void );

	/*
	* Start Charged Attack
	*/
	void StartChargedAttack( void );

	/*
	* Start Charged Attack (Retaliate In EXE)
	*/
	void StartChargedAttackRetaliate( void );

	/*
	* Stop Charged Attack
	*/
	void StopChargedAttack( void );

	/*
	* Set Delay End Block
	*/
	BOOL SetDelayEndBlock( melee_move_s *pAtk, melee_move_s *pDfd );

	/*
	* Handle Delayed Block
	*/
	BOOL HandleDelayedBlock( melee_move_s *pAtk, melee_move_s *pDfd );

	/*
	* Handle charge combo
	*/
	void HandleChargeAttack( void );

	/*
	* Handle charge defend ( block combos )
	*/
	void HandleChargeDefend( void );

	/*
	* Start Grabbed Attack
	*/
	void StartGrabbedAttack( void );

	/*
	* Stop Grabbed Attack
	*/
	void StopGrabbedAttack( void );

	/*
	* Handle Combo Execution
	*/
	void HandleExeAttack( void );

	/*
	* Handle Combo Execution (defender)
	*/
	void HandleExeDefend( void );

	/*
	* Start Combo Execution Attack
	*/
	void StartExeAttack( void );

	/*
	* Stop Combo Execution Attack
	*/
	void StopExeAttack( void );

	/*
	* Start Struggle Attack
	*/
	void StartStruggleAttack( void );

	/*
	* Retry Struggle Attack ( tie )
	*/
	void RetryStruggleAttack( void );

	/*
	* Start Burst Struggle Attac
	*/
	void StartBurstStruggleAttack( void );

	/*
	* Stop Struggle Attack
	*/
	void StopStruggleAttack( void );

	/*
	* Manage Struggle Arrows
	*/
	void ManageStruggleArrows( void );

	/*
	* Check Struggle Arrows ( when the struggle is complete and ready to execute )
	*/
	void CheckStruggleArrows( void );
	
	/*
	* Struggle Win Knockback
	*/
	void WinStruggle( void );

	/*
	* Handle Struggle Attack
	*/
	void HandleStruggleAttack( void );

	/*
	* Handle Burst Struggle Attack
	*/
	void HandleBurstStruggleAttack( void );

	/*
	* Handle Struggle defend
	*/
	void HandleStruggleDefend( void );

	/*
	* Start Knockback - prepunch Attack
	*/
	void StartKnockPreStruggle( void );

	/*
	* Handle Knockback - prepunch attack
	*/
	void HandleKnockPreStruggleAttack ( void );

	/*
	* Blowback struggle ( knocback vs knockback )
	* @param vec3_t vecDirection: Direction
	* @param float flPlayerSwoop: Player swoop time
	* @param float flOtherSwoop: Other players swoop time
	* @param CBasePlayer *pOther: Player we're "struggling" with
	*/
	void BlowbackStruggle( vec3_t vecDirection, float flPlayerSwoop, float flOtherSwoop, CBasePlayer *pOther );


	/*
	* Struggle Varibles
	*/
	int			m_iStrugArrowCount;
	float		m_flStrugArrow;
	BOOL		m_fStopStruggle;
	BOOL		m_fForceAtkDirs;
	BOOL		m_fForceDfdDirs;


	// Struggle end


	/*
	* Can Use Trunks Sword
	* @param CBasePlayer *pDefender: Defender
	* @return BOOL: If we can use the sword
	*/
	BOOL CanUseTrunksSword( CBasePlayer *pDefender );

	/*
	* Emit Damage
	*/
	void EmitDamage( void );

	/*
	* Emit combo damage
	* @param melee_combo_hit_s *pComboHit: Combo that's emitting dmg
	*/
	void EmitComboDamage( melee_combo_hit_s *pComboHit );

	/*
	* Push player back after death
	*/
	void PushAfterDeath( void );

	/*
	* Copy Combo Move to Execution
	*/
	void CopyMoveToExe( void );

	/*
	* Reset Combo Array
	*/
	void ResetComboArray( melee_execution_s *pExe );

	/*
	* Add Exe Move
	*/
	melee_execution_s *AddExeMove( melee_execution_s *pExe );

	/*
	* Create Exe Move
	*/
	melee_execution_s *CreateExeMove( int iFlags, int iComboID, float flDamageDelay, int iNumMove, MELEE_COMBO_STATUS eComboStatus, MELEE_STRENGTH eStrength, char *pAnim );

	/*
	* Get Melee Strength
	*/
	MELEE_STRENGTH GetMeleeStrength( melee_move_s *pMove );
	MELEE_STRENGTH GetMeleeStrength( float flCmbTime );
	
	/*
	* Get damage on current exe move ( damage infliction )
	*/
	float GetDamage( void );

	/*
	* Get Exe Sound on current exe move
	* @param edict_t *ed: Edict emitting sound
	*/
	void EmitExeSound( edict_t *ed );

	/*
	* Emit Client Sound
	*/
	void EmitClientSound( edict_t *ed, int iChannel, int iSound );

	/*
	* Get damage delay ( when executing attack )
	*/
	float GetDamageDelay( melee_move_s *pMove );

	/*
	* Get Animation For Combo
	*/
	void GetAnimForCombo( int iComboID, char *pAnim );

	/*
	* Add Exe Combo Move
	* @param melee_execution_s *pExe: Exe move we're adding this move to
	* @param float flDmg: Damage inflicted
	* @param float flHitTime: How delayed this hit will be
	* @param void (*pCallBack)(CBasePlayer*,CBasePlayer*): Function pointer for manual callback
	*/
	void AddExeCombo( melee_execution_s *pExe, float flDmg, float flHitTime, void (*pCallBack)(CBasePlayer*,CBasePlayer*));

	/*
	* Setup Combo
	*/
	melee_execution_s *SetupCombo( int iComboID );

	/*
	* Add Combo
	*/
	void AddCombo( melee_execution_s *pCurrent, int iComboID );

	/*
	* Can Execute Combo
	*/
	BOOL CanEXECombo( melee_execution_s *pExe );

	/*
	* Get Next EXE move
	*/
	melee_execution_s *GetNextExe( void );

	/*
	* Next EXE move
	*/
	void NextExeMove( void );

	/*
	* New Exe Move Post
	*/
	void NewExeMovePost( void );

	/*
	* Block
	* @param int iAttackerFlags: Attacker flags
	* @param int iDefenderFlags: Defender flags
	* @return BOOL: Is the direction blocked?
	*/
	BOOL Block( int iAttackerFlags, int iDefenderFlags );

	/*
	* Get Block Ratio
	*/
	float GetBlockRatio( int iBlocked, int iTotal );

	/*
	* Predict Blocking Ratio
	* @param melee_execution_s *pAttack: Attack moves
	* @param melee_move_s *pDefend: Block moves
	* @param float flStunTime: Stun time
	* @return float: new stun time w/ ratio
	*/
	float PredictBlockRatio( melee_execution_s *pAttack, melee_move_s *pDefend, float flStunTime );
	float PredictBlockRatio( melee_move_s *pAttack, melee_move_s *pDefend, float flStunTime );

	/*
	* Can Retaliate ( called in HandleExeDefend )
	*/
	BOOL CanRetaliate( void );

	/*
	* Set Block
	* @param melee_execution_s *pExe: Exe struct
	* @return BLOCK_STATUS
	*/
	BLOCK_STATUS SetBlock( melee_execution_s *pExe );

	/*
	* Get Block Stun Move amt
	*/
	int GetBlockStunAmt( MELEE_STRENGTH eStrength );

	/*
	* Continue Block Stun
	*/
	BOOL ContinueBlockStun( int &iCurrentStun, MELEE_STRENGTH eStartStrength, MELEE_STRENGTH eStrength );

	/*
	* Set Block Stun 
	* (dont allow the player to block if he's been hit by a heavy punch for the next x moves...)
	* @param melee_execution_s *pExe: Exe struct
	*/
	void SetBlockStun( melee_execution_s *pExe );

	/*
	* Can Throw
	* @param int iOriginOffset: When 'deattaching' models, the enemys origin will be this distance
	*							away from the player ( so we're not stuck in eachother )
	* @param Vector &vecOrigin: Origin for other player
	*/
	BOOL CanThrow( int iOriginOffset, Vector &vecOrigin );

	/*
	* Throw
	* @param CBasePlayer *pOther: Player we're throwing
	* @param int iSpeed: Speed of throw
	* @param float flMinBlowTime: Min amount of time to recover
	* @param Vector vecOrigin: Origin for other player
	*/
	void Throw( CBasePlayer *pOther, int iSpeed, float flMinBlowTime, Vector vecOrigin );

	/*
	* Handle grabs
	*/
	void HandleGrabAttack( void );

	/*
	* Handle defending/being grabbed
	*/
	void HandleGrabDefend( void );

	/*
	* Set Grabbed Origin ( while in toss )
	*/
	void SetGrabbedOrigin( void );

	/*
	* Emit Shockwave
	*/
	void EmitShockwave( void );

	/*
	* Emit Explosion Rocks
	* @param Vector vecSrc: Origin of rock gib spawn
	* @param Vector vecVelocity: Velocity of rock gibs
	* @param float flSize: Size of rocks
	* @param int iRandom: Random velocity ( in 10's )
	* @param it iCount: Amount of rocks
	*/
	void EmitExplosionRocks( Vector vecSrc, Vector vecVelocity, float flSize, int iRandom, int iCount );

		
	/*
	* Can Block Attack
	*/
	BOOL BlocksAttack( CBasePlayer *pPlayer );

	/* Added by Rick
	*
	* Can Block Attack, buddy version
	*/
	BOOL BlocksAttack( CBuddy *pBuddy );

	/*
	* Set Powerhit Anim
	*/
	void SetPowerhitAnim( Vector vecDirection, int iDirection );

	/*
	* Powerhit
	* @return BOOL: If attack is blocked
	*/
	BOOL Powerhit( CBasePlayer *pOther, Vector vecDirection, int iDirection, float flDamage, float flMaxSpeed, float flMinSpeed, float flDeacceleration, float flMinRecoverTime );
	BOOL Powerhit( BOOL fPlayAnim, CBasePlayer *pOther, Vector vecDirection, int iDirection, float flDamage, float flMaxSpeed, float flMinSpeed, float flDeacceleration, float flMinRecoverTime );

	// Added by Rick : Buddy version of Powerhit
	BOOL Powerhit( BOOL fPlayAnim, CBuddy *pOther, Vector vecDirection, int iDirection, float flDamage, float flMaxSpeed, float flMinSpeed, float flDeacceleration, float flMinRecoverTime );
	/*
	* Default Powerhit
	* @return BOOL: If attack is blocked
	*/
	BOOL Powerhit( CBasePlayer *pOther, Vector vecDirection, int iDirection );

	/* Added by Rick
	*
	* Default Powerhit, buddy version
	* @return BOOL: If attack is blocked
	*/
	BOOL Powerhit( CBuddy *pOther, Vector vecDirection, int iDirection );

	/*
	* Simple Melee Powerhit
	*/
	void SimpleMeleePowerhit( CBasePlayer *pOther, Vector vecDirection, int iDirection );

	// Added by Rick : Buddy version of Simple Melee Powerhit
	void SimpleMeleePowerhit( CBuddy *pOther, Vector vecDirection, int iDirection );

	/*
	* Can Switch Attack and Defender places
	*/
	BOOL CanSwitch( void );

	/*
	* Simple Switch
	* @param CPlayerMelee *pOther: Player we're switching rolls with
	* @param float flStunTime: Stun time
	* @param ADV_MELEE_STATUS eMeleeMode: Melee mode to switch to after switching rolls
	*/
	void SimpleSwitch( CPlayerMelee *pOther );
	void SimpleSwitch( CPlayerMelee *pOther, float flStunTime, ADV_MELEE_STATUS eMeleeMode );

	/*
	* Switch Attack and Defender places
	*/
	void Switch( void );


	/*
	* General Varibles
	*/
	BOOL				m_fSimpleMelee;		// Is Simple or Advanced melee set?
	plrmelee_anim_s		*m_pMeleeAnim;		// Start of Melee Animation linked list


	/*
	* Advanced Melee
	*/
	float				m_flStunnedTime;	// Stime stunned
	float				m_flTotalStun;		// Total stun time
	float				m_flStartPrePunch;	// Time start of prepunches
	float				m_flLastPrePunch;	// Last time a prepunch dmg point was added
	float				m_flStartHoldGrab;	// Time we started the hold grab
	float				m_flChargeGrab;		// Charge progress of grab
	float				m_flKiUpdate;		// Time of last ki update
	float				m_flPSBarUpdate;	// Power struggle bar update
	float				m_flPreKnockStrug;	// Preknock struggle time
	float				m_flEndArrowTime;	// Time of the last arrow, used to calculate delays before execution
	float				m_flFrameTime;		// Frame time
	float				m_flInvulnerableTime;// Invul time
	int					m_iNumPrepunches;	// Number of prepunches throw
	int					m_iTotalMoves;		// Total amount of moves to be executed
	int					m_iBlockedMoves;	// Amount of moves that were blocked
	int					m_iSwitch;			// How many times have we switched rolls
	int					m_iCurAtkID;		// Current attacking direction ID
	int					m_iCurDfdID;		// Current defending direction ID
	BOOL				m_fPrepunchPinned;	// Pinned to a wall with prepunches
	BOOL				m_fPrepunchBlock;	// Defender blocks the attack
	BOOL				m_fPrepunchBehind;	// Defender gets attacked from behind
	BOOL				m_fDrainStun;		// Start draining stun
	BOOL				m_fStunned;			// Stunned?
	BOOL				m_fHoldGrab;		// Charge bar is full and we're 'holding' the enemy, take no ki
	BOOL				m_fSpinSound;		// Spin Sound
	BOOL				m_fRetaliateEXE;	// Charging combo while defending in a execution
	BOOL				m_fWaitRetal;		// We finished charging our combo within the combo exe, wait
	BOOL				m_fSwitching;		// In the middle of switching attacking/defender rolls
	BOOL				m_fPowerhit;		// Secondary Powerhit
	BOOL				m_fEndComboPower;	// Ending combo with powerhit
	BOOL				m_fPreKnockStrug;	// If we're prepunching from a prepunch/knock strug ( used to change prepunches )
	BOOL				m_fManualExe;		// Dont end melee as soon as we init exe mode, manually enter moves
	BOOL				m_fDelayMelee;		// If we're delaying melee to give a blocker a chance to block the last direction
	BOOL				m_fInvulnerable;	// Melee Invulnerable
	Vector				m_vecPrepunchDir;	// Velocity / angle we will be cruising at with prepunches
	ADV_MELEE_STATUS	m_eAdvMeleeStatus;	// Melee Status
	CBasePlayer			*m_pInvulException; // Invul exception ( ending melee battles )

private:
	CBasePlayer			*m_pAttacker;			// Owner of this melee
	CBasePlayer			*m_pDefender;			// Enemy your fighting
	CBasePlayer			*m_pAttackerOther;		// Person attacking the defender ( only set for defender )
	CPlayerMelee		*m_pDefenderMelee;		// Defender's melee struct
	CPlayerMelee		*m_pAttackerMelee;		// Attackers's melee struct ( only set for the defender )
	BOOL				m_fAttacker;		// Attacker
	BOOL				m_fDefender;		// Defender
	BOOL				m_fOrigDefender;	// Original Defender
	BOOL				m_fFighting;		// Fighting - Advanced melee

	// Combo moves
	melee_move_s		*m_pAttackerMoves;
	melee_move_s		*m_pDefenderMoves;
	combo_move_s		*m_pComboMoves[PC_LAST];
	melee_execution_s	*m_pExeStart;
	melee_execution_s	*m_pExeCurrent;
};


#endif
