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

/**
* Death ball attack
* @version 30-3-2002
* @author Herwin 'harSens' van Welbergen
*/
class CDeathBallAttack:public CBeamAttack
{	
public:
	/**
	* Shoots the deathball
	* @param entvars_t *pevOwner: monster/player who shoots it	
	* @param Vector vecVelocity: velocity of the spiritbomb
	* @param int damage: damage of the spiritbomb
	* @param float size: the size of the deathball
	* @param sprite the db sprite
	* @return *CMagicAttack: The created MagicAttack 
	*/
	static CDeathBallAttack *ShootDeathBall(entvars_t *pevOwner,Vector vecSrc, Vector vecVelocity, int damage, float size, short sprite);
};

CDeathBallAttack *CDeathBallAttack::ShootDeathBall(entvars_t *pevOwner,Vector vecSrc,Vector vecVelocity, int damage, float size,short sprite)
{	CDeathBallAttack *pMagicAttack=GetClassPtr( (CDeathBallAttack *)NULL );
	pMagicAttack->Spawn();
	
	//set model
	extern int gmsgBall;
	MESSAGE_BEGIN( MSG_ALL, gmsgBall, NULL );
		WRITE_SHORT(pMagicAttack->entindex());
		WRITE_SHORT(sprite);
		WRITE_SHORT(26);
	MESSAGE_END();
	SET_MODEL(ENT(pMagicAttack->pev), "sprites/null.spr");
	
	pMagicAttack->m_iRadius = DEATHBALL_RADIUS;
	
	pMagicAttack->m_iExplosionColor = RED_EXPLOSION;
	
	pMagicAttack->pev->owner = ENT(pevOwner);
	pMagicAttack->pev->classname = MAKE_STRING( "Death Ball" );	
	
	pMagicAttack->pev->movetype = MOVETYPE_FLY;
	pMagicAttack->pev->solid = SOLID_TRIGGER;	//touches everything	
	pMagicAttack->SetDamage(damage);
	pMagicAttack->pev->velocity = vecVelocity;
	pMagicAttack->m_flSpeed = vecVelocity.Length();
	pMagicAttack->pev->angles = UTIL_VecToAngles(pMagicAttack->pev->velocity);
	pMagicAttack->pev->scale = size;
	
	float flAttackSize = (size * DEATHBALL_SIZE)/2;
	vecSrc = vecSrc + flAttackSize * vecVelocity.Normalize();
	UTIL_SetOrigin(pMagicAttack->pev,vecSrc);	
	UTIL_SetSize(pMagicAttack->pev, Vector(-flAttackSize, -flAttackSize, -flAttackSize), Vector(flAttackSize, flAttackSize, flAttackSize));
	pMagicAttack->SetTouch( &CDeathBallAttack::ExplodeTouch );

	pMagicAttack->SetThink( &CDeathBallAttack::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;
}
//----------------------------------------------------------------

/**
* DeathballWeapon
* @version 31-10-2001
* @author Herwin 'harSens' van Welbergen
*/
class CDeathBall:public CChargedAttack
{	
public:
	/**
	* Init function
	*/
	void Spawn( void );

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

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

	/**
	* Get spirit bomb item info
	* @param ItemInfo *p: The ItemInfo gets stored here
	* @return int: Always returns 1 (why???)
	*/
	int GetItemInfo(ItemInfo *p);	

private:
	/**
	 * Initializes chargesprite
	 */
	void InitChargeSprite();
	/**
	 * Removes chargesprite
	 */
	void RemoveChargeSprite();
	/**
	 * Disables chargesprite
	 */
	void DisableChargeSprite();
	/**
	 * Enables chargesprite
	 */
	void EnableChargeSprite();
	/**
	 * Grows the charge sprite
	 */
	void GrowChargeSprite();
	/**
	 * Shoot a deathball
	 */
	void ShootAttack();

	/**
	 * Play shoot sound
	 */
	void EmitShootSound();

	/**
	 * play charge sound
	 */	
	void EmitChargeSound();

	CSprite *m_pChargeSprite;		//the sprites wich appears after charging
	short m_sSprite;
};

LINK_ENTITY_TO_CLASS( weapon_deathball, CDeathBall );

void CDeathBall::Spawn( void )
{	Precache();
	m_iId = WEAPON_DEATHBALL;
	m_iDefaultAmmo = 0;
	m_iClip = -1;

	m_iMaxCharge = DEATHBALL_MAXCHARGETIME;
	m_iKiCost = DEATHBALL_KI_COST;
	m_flPlayerSlowDown = 0.5;
	strcpy(m_pAttackName,"deathball");	
	FallInit();// get ready to fall down.
}

void CDeathBall::Precache( void )
{	m_sSprite = PRECACHE_MODEL("sprites/deathball.spr");
	PRECACHE_SOUND("weapons/deathball_fire.wav");
	PRECACHE_SOUND("weapons/deathball_charge.wav");
	PRECACHE_SOUND("frieza/deathball.wav");
}

int CDeathBall::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 = 5;
	p->iPosition = 3;
	p->iId = m_iId = WEAPON_DEATHBALL;
	p->iWeight = DEATHBALL_WEIGHT;
	p->iFlags = 0;
	return 1;
}

void CDeathBall::InitChargeSprite()
{	m_pChargeSprite = CSprite::SpriteCreate( "sprites/deathball.spr", m_pPlayer->pev->origin, true);
	m_pChargeSprite->TurnOff();	
	m_pChargeSprite->SetScale(0.00001);
	m_pChargeSprite->SetAttachment(m_pPlayer->edict(),3);
	m_pChargeSprite->SetTransparency( kRenderTransAdd, 255, 255, 255, 254, kRenderFxGlowShell );
	m_pChargeSprite->pev->framerate = 10;	
}

void CDeathBall::RemoveChargeSprite()
{	UTIL_Remove(m_pChargeSprite);
}

void CDeathBall::EnableChargeSprite()
{	GrowChargeSprite();
	m_pChargeSprite->TurnOn();	
}

void CDeathBall::DisableChargeSprite()	
{	m_pChargeSprite->TurnOff();
}

void CDeathBall::GrowChargeSprite()
{	float flMinCharge = (float)DEATHBALL_MAXCHARGETIME/3.0-1;
	m_pChargeSprite->SetScale(0.4*((float)m_iCharge-flMinCharge)/((float)DEATHBALL_MAXCHARGETIME-flMinCharge));
}
	
void CDeathBall::ShootAttack()
{	//calculate startpos and speed
	UTIL_MakeVectors( m_pPlayer->pev->v_angle );
	Vector vecSrc = m_pPlayer->GetGunPosition()+Vector(0,0,30) + gpGlobals->v_forward * 10;
	Vector vecThrow = gpGlobals->v_forward * DEATHBALL_SPEED;
	
	CDeathBallAttack::ShootDeathBall(m_pPlayer->pev, vecSrc, vecThrow, m_iCharge * GetPowerRatio() * DEATHBALL_DAMAGE, m_pChargeSprite->pev->scale,m_sSprite);
}

void CDeathBall::EmitShootSound()
{	m_pPlayer->EmitClassSound("deathball.wav");
	EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/deathball_fire.wav", 1.0, ATTN_NORM);
}

void CDeathBall::EmitChargeSound()
{	EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/deathball_charge.wav", 1.0, ATTN_NORM);
}

