#include "extdll.h" 
#include "decals.h" 
#include "util.h" 
#include "cbase.h" 
#include "monsters.h" 
#include "weapons.h" 
#include "soundent.h" 
#include "shake.h" 
#include "gamerules.h" 
#include "effects.h"
#include "aura.h"
#include "classes.h"
#include "magicattack.h"
#include "explodingattack.h"
#include "player.h"

Vector g_vecAuraColor[]=
{	Vector(200,200,200),	//WHITE
	Vector(0,200,0),		//GREEN	
	Vector(200,0,200),		//PURPLE
	Vector(200,0,0),		//RED
	Vector(200,200,0),		//YELLOW	
};

const char *g_pAuraColorString[] =
{	"blue",
	"green",
	"purple",
	"red",
	"yellow"
};

LINK_ENTITY_TO_CLASS( aura, CAura );

void CAura::Spawn()
{	Precache();
	SetTouch( NULL );	
	if(m_fDash)
		SET_MODEL(ENT(pev),"models/dash.mdl");
	else
		SET_MODEL(ENT(pev),"models/aura.mdl");
	
	//ingenious tweak by Joe: don't let the aura tough ANYTHING
	pev->solid = SOLID_NOT;
	
	pev->rendermode = kRenderTransAdd;
	pev->renderamt = 100;
	pev->takedamage = DAMAGE_NO;
	
	pev->gaitsequence = 0;
	pev->sequence = 0;
	pev->frame = 0;

	// Removed by Pcjoe, a custom animation is now set in the Create function
//	ResetSequenceInfo ( );	
//	m_fHasTrail = false;
}

void CAura::Precache()
{	PRECACHE_MODEL("models/aura.mdl");
	PRECACHE_MODEL("models/dash.mdl");
	PRECACHE_MODEL("sprites/aura.spr");
	PRECACHE_SOUND("weapons/aura.wav");
	// Added by Pcjoe
	PRECACHE_SOUND("weapons/swoop.wav");
	m_sTrailSprite = PRECACHE_MODEL("sprites/auratrail.spr");
}

void CAura::RemoveThink()
{	entvars_t *pevOwner;
	if (pev->owner)
	{	pevOwner=VARS(pev->owner);
		if (pevOwner->solid == SOLID_NOT)
		{	Destroy();
		}
	}
	else
	{	Destroy();
	}

	
	/* Moved by Pcjoe - trails are on as long as we have an aura, no need to do this in the think function
	if (m_pPlayer->m_fFlying)
	{	pev->angles = m_pPlayer->pev->v_angle;
		// Removed by Pcjoe
		if(!m_fHasTrail)
		{	m_fHasTrail = true;
			Vector vecTrailColor = g_vecAuraColor[pev->skin];
			MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
				WRITE_BYTE  (TE_BEAMFOLLOW);			//create a line of decaying beam segments until entity stops moving
				WRITE_SHORT	(m_pPlayer->entindex());	//entity:attachment to follow)
				WRITE_SHORT	(m_sTrailSprite);			//short (sprite index)
				WRITE_BYTE	(25);						//life in 0.1's) 
				WRITE_BYTE	(6);						//(line width in 0.1's) 
				WRITE_BYTE  (vecTrailColor.x);			//byte,byte,byte (color)
				WRITE_BYTE  (vecTrailColor.y);			
				WRITE_BYTE  (vecTrailColor.z);
				WRITE_BYTE  (50);						//brightness
			MESSAGE_END();
		}
	}*/
	
	// Removed by Pcjoe
/*	if (!m_pPlayer->m_fFlying && m_fHasTrail)
	{	m_fHasTrail = false;
		// remove all trails from entity
		MESSAGE_BEGIN ( MSG_PVS, SVC_TEMPENTITY, pev->origin );
			WRITE_BYTE( TE_KILLBEAM	);	//kill all beams attached to entity
			WRITE_SHORT( m_pPlayer->entindex());	// short (entity)
		MESSAGE_END();	
	}*/

	pev->nextthink=gpGlobals->time + 0.5;
}

void CAura::SetColor()
{
	pev->skin = m_pPlayer->m_pClass->GetAuraSkin();
	pev->rendercolor = Vector(5,5,5);
}

CAura *CAura::Create(CBasePlayer *pevOwner, BOOL fDash)
{	CAura *pAura = GetClassPtr( (CAura *)NULL );
	pAura->m_fDash = fDash;
	pAura->Spawn();
	UTIL_SetOrigin( pAura->pev, pevOwner->pev->origin );
	pAura->m_pPlayer = pevOwner;
	pAura->pev->owner = pevOwner->edict();
	pAura->SetThink(&CAura::RemoveThink);
	pAura->pev->nextthink = gpGlobals->time + 0.5;
	
	pAura->pev->aiment = pevOwner->edict();
	pAura->pev->movetype = MOVETYPE_FOLLOW;
	pAura->SetColor();
	pAura->pev->renderfx = kRenderFxGlowShell;


	pAura->m_pPlayer->pev->rendermode = kRenderTransTexture;
	pAura->m_pPlayer->pev->renderamt = 255;
	
	// Pcjoe : Edited to play the swoop melee sound if your swooping
	if(pAura->m_pPlayer->m_Swoop.m_fSwoop)
	{	EMIT_SOUND(ENT(pAura->m_pPlayer->pev), CHAN_ITEM, "weapons/swoop.wav", 1, ATTN_NORM);
		// Pcjoe: Swooping sequence
		if(pAura->m_fDash)
			pAura->pev->sequence = pAura->LookupSequence("dash");
		else
			pAura->pev->sequence = pAura->LookupSequence("swoop");
		pAura->pev->frame = 0;
		pAura->ResetSequenceInfo( );
	}
	//emit aura sound
	else
	{	EMIT_SOUND(ENT(pAura->m_pPlayer->pev), CHAN_ITEM, "weapons/aura.wav", 1, ATTN_NORM);
		// Pcjoe: Default aura sequence
		pAura->pev->sequence = pAura->LookupSequence("idle");
		pAura->pev->frame = 0;
		pAura->ResetSequenceInfo( );
	}

	// Pcjoe: Aura trail
	if(!pAura->m_fDash)
	{	pAura->AddTrail();
	}

	// Pcjoe: "Bend" aura clientside
	UTIL_Model_AuraBend(pAura->entindex());

	return pAura;	
}

void CAura::Destroy()
{	EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "common/null.wav", 1, ATTN_NORM);

	// Edited by Pcjoe: Removed m_fHasTrail check since we always have a trail
	// remove all trails from entity
	if(!m_fDash)
		RemoveTrail();

	// Pcjoe: Remove the bend for the aura
	UTIL_Model_RemoveAll(entindex());

	UTIL_Remove(this);
	if(!m_pPlayer->m_fSpawnInvulnerable)
	{	m_pPlayer->pev->rendermode = kRenderNormal;	
	}
}

int	CAura::TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType )
{	return m_pPlayer->TakeDamage( pevInflictor, pevAttacker, flDamage, bitsDamageType);
}

/**
* Pcjoe: Add Trail
*/
void CAura::AddTrail( void )
{	Vector vecTrailColor = g_vecAuraColor[pev->skin];
	MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
		WRITE_BYTE  (TE_BEAMFOLLOW);			//create a line of decaying beam segments until entity stops moving
		WRITE_SHORT	(m_pPlayer->entindex());		//entity:attachment to follow)
		WRITE_SHORT	(m_sTrailSprite);			//short (sprite index)
		WRITE_BYTE	(50);						//life in 0.1's) 
		WRITE_BYTE	(8);						//(line width in 0.1's)
		WRITE_BYTE  ((int)vecTrailColor.x);		//byte,byte,byte (color)
		WRITE_BYTE  ((int)vecTrailColor.y);			
		WRITE_BYTE  ((int)vecTrailColor.z);
		WRITE_BYTE  (64);						//brightness
	MESSAGE_END();
}

/**
* Pcjoe: Remove Trail
*/
void CAura::RemoveTrail( void )
{	MESSAGE_BEGIN ( MSG_PVS, SVC_TEMPENTITY, pev->origin );
		WRITE_BYTE( TE_KILLBEAM	);				//kill all beams attached to entity
		WRITE_SHORT( m_pPlayer->entindex());	// short (entity)
	MESSAGE_END();

}
