#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 "magicattack.h"
#include "discattack.h"
#include "chargedattack.h"

/**
 * Destructo disc attack
 * @version 30-3-2002
 * @author Herwin 'harSens' van Welbergen
 */
class CDestructoDiscAttack:public CDiscAttack
{	
public:
	
	/**
	 * Shoots the destructodisc
	 * @param Vector vecOrigin: Origin of the destructodisc
	 * @param Vector vecVelocity: Velocity of the destructodisc
	 */
	void Shoot(Vector vecOrigin,Vector vecVelocity);

	/**
	 * Create magical attack Destructo Disc
	 * @param entvars_t *pevOwner: Monster/Player who shoots it
	 * @param Vector vecStart: Origin vector of the destructodisc
	 * @param float size: size of da disc
	 * @return *CMagicAttack: The created MagicAttack 
	 */
	static CDestructoDiscAttack *ChargeDestructoDisc( entvars_t *pevOwner, Vector vecStart, float size);

	/**
	 * Randomly rotates the roll of magic, used for destructodisc
	 */
	void EXPORT RandomRotateThink ( void );
};

CDestructoDiscAttack* CDestructoDiscAttack::ChargeDestructoDisc(entvars_t *pevOwner, Vector vecStart, float size)
{	CDestructoDiscAttack *pMagicAttack=GetClassPtr( (CDestructoDiscAttack *)NULL );
	pMagicAttack->Spawn();	

	pMagicAttack->pev->movetype=MOVETYPE_NOCLIP;//go through walls
	pMagicAttack->pev->solid=SOLID_TRIGGER;//only touch players
	pMagicAttack->pev->effects &= ~EF_BRIGHTLIGHT;

	//set model and sound
	SET_MODEL(ENT(pMagicAttack->pev), "models/w_destructodisc.mdl");	
	
	pMagicAttack->pev->scale = size;
	
	pMagicAttack->pev->dmg=999; //instant death
	UTIL_SetOrigin(pMagicAttack->pev,vecStart);
	pMagicAttack->pev->owner=ENT(pevOwner);

	//HACK HACK: rendercolor indicates owner to charge to
	pMagicAttack->pev->rendercolor.x=ENTINDEX(ENT(pevOwner));
	
	pMagicAttack->pev->velocity=Vector(0,0,0);
	pMagicAttack->pev->classname = MAKE_STRING( "Destructo Disc" );

	//rotate it
	pMagicAttack->pev->gaitsequence = 0;
	pMagicAttack->pev->sequence = 0;
	pMagicAttack->pev->frame = 0;
	pMagicAttack->ResetSequenceInfo( );	

	//let the weapon handle the removing of the attack
	pMagicAttack->m_fReleased = false;

	pMagicAttack->SetTouch(NULL);
	// Edited by Pcjoe
//	pMagicAttack->SetThink(NULL);
	pMagicAttack->SetThink(&CDiscAttack::AuraCheck);
	pMagicAttack->pev->nextthink = gpGlobals->time;
	pMagicAttack->CDiscAttack::AuraCheck();

	return pMagicAttack;
}

void CDestructoDiscAttack::Shoot(Vector vecOrigin, Vector vecVelocity)
{
	// Added by Pcjoe
	pev->movetype=MOVETYPE_NOCLIP;//go through walls
	pev->aiment = NULL;

	pev->effects |= EF_BRIGHTLIGHT;
	UTIL_SetOrigin(pev,vecOrigin);
	UTIL_SetSize(pev, pev->scale * Vector(-7, -7 , -7), pev->scale * Vector (7, 7, 7));
	
	pev->velocity=vecVelocity;
	m_flSpeed=vecVelocity.Length();
	pev->angles=UTIL_VecToAngles(pev->velocity);
	pev->rendercolor.x = 0;
	pev->scale *=2;	
	SetTouch( &CDestructoDiscAttack::HitTouch );
	SetThink( &CDestructoDiscAttack::RandomRotateThink );	
	
	//emit flying sound
	EMIT_SOUND(ENT(pev), CHAN_WEAPON, "weapons/rotating.wav", 1.0, ATTN_NORM);
	
	pev->nextthink = gpGlobals->time + 0.25;//start flying straight	
}

void CDestructoDiscAttack::RandomRotateThink(void)
{	int new_avelocity = 10 * RANDOM_LONG(-100,100);
	pev->avelocity.z = 0.6 * new_avelocity + pev->avelocity.z * 0.4;
	NormalThink();
}
//----------------------------------------------------------------
/**
* Destructo disc
* @version 27-7-2002
* @author Herwin 'harSens' van Welbergen
*/
class CDestructoDisc:public CChargedAttack
{	
public:
	/**
	* Init function
	*/
	void Spawn( void );

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

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

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

	/**
	 * Deploys the destructodisc
	 * @return true is succesfully deployed
	 */
	BOOL Deploy();

	/**
	 * Holsters the attack
	 * @param int skiplocal:?
	 */
	void Holster(int skiplocal);
	
	/*
	* Pcjoe: Holster when meleed
	*/
	BOOL HolsterWhenMeleed( void ) { return TRUE; }
private:
	/**
	* emits the shoot sound
	*/
	void EmitShootSound();

	/**
	* emits the charge sound
	*/
	void EmitChargeSound();
	
	/**
	* enables the chargesprite
	*/
	void EnableChargeSprite();
	
	/**
	* Grow charge sprite
	*/
	void GrowChargeSprite();
	
	/**
	* shoots a destructodisc
	*/
	void ShootAttack();	
	CDestructoDiscAttack *m_pDisc;
};
LINK_ENTITY_TO_CLASS( weapon_destructodisc, CDestructoDisc );

void CDestructoDisc::Spawn( void )
{	Precache();
	m_iId = WEAPON_DESTRUCTODISC;
	m_iDefaultAmmo = 0;
	m_iClip = -1;
	m_iMaxCharge = DESTRUCTODISC_MAXCHARGETIME;
	m_iKiCost = DESTRUCTODISC_KI_COST;
	m_flPlayerSlowDown = 0.5;
	strcpy(m_pAttackName,"destructodisc");
	FallInit();// get ready to fall down.
}

void CDestructoDisc::Precache( void )
{	PRECACHE_MODEL("sprites/null.spr");
	PRECACHE_MODEL("models/w_destructodisc.mdl");
	PRECACHE_SOUND("krillin/destructodisc.wav");
	PRECACHE_SOUND("krillin/destructodisc_charge.wav");
	PRECACHE_SOUND("weapons/rotating.wav");
	PRECACHE_SOUND("weapons/destructodisc_charge.wav");
	PRECACHE_SOUND("weapons/disc_fire.wav");
	PRECACHE_SOUND("weapons/disckill.wav");
}

BOOL CDestructoDisc::Deploy()
{	m_pDisc = NULL;
	return CChargedAttack::Deploy();
}

void CDestructoDisc::Holster(int skiplocal)
{	if(m_pDisc)
	{	m_pDisc->Remove();	
	}	
	CChargedAttack::Holster(skiplocal);
}

int CDestructoDisc::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 = 0;
	p->iId = m_iId = WEAPON_DESTRUCTODISC;
	p->iWeight = DESTRUCTODISC_WEIGHT;
	p->iFlags = 0;
	return 1;
}


void CDestructoDisc::EnableChargeSprite()
{	Vector vecSrc = m_pPlayer->GetGunPosition();	
	m_pDisc = CDestructoDiscAttack::ChargeDestructoDisc( m_pPlayer->pev, vecSrc, 0.5 *(float)m_iCharge/(float)m_iMaxCharge);
}

void CDestructoDisc::GrowChargeSprite()
{	m_pDisc->pev->scale = 0.5 * (float)m_iCharge / (float)m_iMaxCharge;
}

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

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

void CDestructoDisc::ShootAttack()	
{	UTIL_MakeVectors(m_pPlayer->pev->v_angle);
	Vector vecThrow = gpGlobals->v_forward * DESTRUCTODISC_SPEED;
	m_pDisc->Shoot(m_pPlayer->GetGunPosition(),vecThrow);	
	m_pDisc = NULL;
}
