#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "effects.h"
#include "monsters.h"
#include "weapons.h"
#include "nodes.h"
#include "aura.h"
#include "classes.h"
#include "gamerules.h"
#include "chargedattack.h"
#include "magicattack.h"
#include "explodingattack.h"
#include "player.h"
#include "beamattack.h"

#define PURPLEBALLATTACK_SIZE		70
#define PURPLEBALL_TRAILLENGTH		80
extern int gmsgFlare;
/**
 * Purple ball attack
 * @version 10-12-1004
 * @author Herwin 'harSens' van Welbergen
 */
class CPurpleBallAttack:public CBeamAttack
{	
public:
	/**
	* Create a purple ball attack 
	* @param entvars_t *pevOwner: Monster/Player who shoots it
	* @param Vector vecStart: Origin vector of the attack
	* @param Vector vecVelocity: Velocity of the attack
	* @param damage: the amount of damage to be done
	* @param size: the size of the purpleball sprite
	*/
	static CPurpleBallAttack *ShootPurpleBall( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, int damage, float size,short flarea, short flareb, short trail);
};

CPurpleBallAttack* CPurpleBallAttack::ShootPurpleBall( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, int damage, float size, short flarea, short flareb, short trail)
{	CPurpleBallAttack *pMagicAttack = GetClassPtr( (CPurpleBallAttack *)NULL );
	pMagicAttack->Spawn();	
	
	pMagicAttack->pev->movetype = MOVETYPE_FLY;
	pMagicAttack->pev->solid = SOLID_TRIGGER;	//touches everything

	//set model
	SET_MODEL(ENT(pMagicAttack->pev), "sprites/null.spr");	

	pMagicAttack->m_iExplosionColor = PURPLE_EXPLOSION;
	
	pMagicAttack->m_iRadius = PURPLEBALL_RADIUS;

	pMagicAttack->SetDamage(damage);
	pMagicAttack->pev->velocity=vecVelocity;
	pMagicAttack->m_flSpeed=vecVelocity.Length();
	pMagicAttack->pev->angles=UTIL_VecToAngles(pMagicAttack->pev->velocity);
	pMagicAttack->pev->owner=ENT(pevOwner);
	pMagicAttack->pev->classname = MAKE_STRING( "purpleball" );
	
	float flSize = PURPLEBALLATTACK_SIZE * size;
	float flAttackSize = flSize * 0.25;	//compensate for emptyness in sprites
	UTIL_SetOrigin(pMagicAttack->pev,vecStart + flAttackSize * vecVelocity.Normalize());
	UTIL_SetSize(pMagicAttack->pev, Vector(-flAttackSize, -flAttackSize, -flAttackSize), Vector(flAttackSize, flAttackSize, flAttackSize));
	pMagicAttack->SetTouch( &CPurpleBallAttack::ExplodeTouch );

	MESSAGE_BEGIN( MSG_ALL, gmsgFlare, NULL );
		WRITE_LONG(pMagicAttack->entindex());		//end entity
		WRITE_SHORT(flarea);						//start attachment
		WRITE_SHORT(flareb);						//start sprites
		WRITE_SHORT(flSize * 0.1);					//size in .1's
		WRITE_SHORT(trail);							//trail sprite
		WRITE_SHORT(PURPLEBALL_TRAILLENGTH * size);	//trail length
		WRITE_COORD(vecStart.x);					//start pos
		WRITE_COORD(vecStart.y);
		WRITE_COORD(vecStart.z);
	MESSAGE_END();

	pMagicAttack->SetThink( &CPurpleBallAttack::NormalThink );
	pMagicAttack->pev->nextthink = gpGlobals->time;

	/*DEBUG by harSens: enable bbox	
	extern int gmsgBoundingBox;
	MESSAGE_BEGIN( MSG_ALL, gmsgBoundingBox);
		WRITE_LONG(pMagicAttack->entindex());
	MESSAGE_END();	
	*/
	
	return pMagicAttack;
}
//--------------------------------------------------------------
/**
* Purple ball Weapon
* @version 10-12-2004
* @author Herwin 'harSens' van Welbergen
*/
class CPurpleBall:public CChargedAttack
{	
public:
	/**
	* Init function
	*/
	void Spawn( void );

	/**
	* Precaches sprites and sounds
	*/
	void Precache( void );

	/**
	* Get  purpleball slot
	* return int: the slot, is 5 for purpleball
	*/
	int iItemSlot( void ) { return 5; }

	/**
	* Get purple ball item info
	* @param ItemInfo *p: The ItemInfo gets stored here
	* @return int: Always returns 1 (why???)
	*/
	int GetItemInfo(ItemInfo *p);
private:
	/**
	 * shoots the ball
	 */
	void ShootAttack();

	/**
	 * emits the shooting sound
	 */
	void EmitShootSound();

	/**
	 * emits the charging sound
	 */	
	void EmitChargeSound();
private:
	short m_sFlareA,m_sFlareB,m_sTrail;
};

LINK_ENTITY_TO_CLASS( weapon_purpleball, CPurpleBall );

void CPurpleBall::Spawn( void )
{	Precache();
	m_iId = WEAPON_PURPLEBALL;
	m_iDefaultAmmo = 0;
	m_iClip = -1;

	m_iMaxCharge = PURPLEBALL_MAXCHARGETIME;
	m_iKiCost = PURPLEBALL_KI_COST;
	m_flPlayerSlowDown = PURPLEBALL_PLAYERSLOWDOWN;
	strcpy(m_pAttackName,"purpleball");
	FallInit();// get ready to fall down.
}

void CPurpleBall::Precache( void )
{	m_sFlareA = PRECACHE_MODEL("sprites/purpleballa.spr");
	m_sFlareB = PRECACHE_MODEL("sprites/purpleballb.spr");
	m_sTrail = PRECACHE_MODEL("sprites/purpleballtrail.spr");
	//PRECACHE_SOUND("vegeta/bigbang.wav");
	//PRECACHE_SOUND("vegeta/bigbang_charge.wav");
	//PRECACHE_SOUND("weapons/bigbang_fire.wav");
}

int CPurpleBall::GetItemInfo(ItemInfo *p)
{	p->pszName = STRING(pev->classname);
	p->pszAmmo1 = "ki";
	p->iMaxAmmo1 = -1;	//max ammo is weapon independent
	p->pszAmmo2 = NULL;
	p->iMaxAmmo2 = -1;
	p->iMaxClip = WEAPON_NOCLIP;
	p->iSlot = 4;
	p->iPosition = 8;
	p->iId = m_iId = WEAPON_PURPLEBALL;
	p->iWeight = PURPLEBALL_WEIGHT;
	p->iFlags = 0;
	return 1;
}

void CPurpleBall::EmitShootSound()
{	//make some sounds :-)
	/*
	m_pPlayer->EmitClassSound("bigbang.wav");
	EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/bigbang_fire.wav", 1.0, ATTN_NORM);
	*/
}

void CPurpleBall::EmitChargeSound()
{	//m_pPlayer->EmitClassSound("bigbang_charge.wav");
}

void CPurpleBall::ShootAttack()	
{	//shoot the attack
	UTIL_MakeVectors( m_pPlayer->pev->v_angle );
	Vector vecSrc = m_pPlayer->GetGunPosition() + gpGlobals->v_right * 10 + gpGlobals->v_forward * 10;
	Vector vecThrow = gpGlobals->v_forward * PURPLEBALL_SPEED;
	CPurpleBallAttack::ShootPurpleBall( m_pPlayer->pev, vecSrc, vecThrow, m_iCharge * PURPLEBALL_DAMAGE * GetPowerRatio() , (float)m_iCharge/(float)PURPLEBALL_MAXCHARGETIME,m_sFlareA,m_sFlareB,m_sTrail);
}