#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "effects.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"

#define FINGERLASER_BEAMWIDTH 3

extern int gmsgExplosion;

/**
* Finger Laser weapon
* @version 8-9-2001
* @author Herwin 'harSens' van Welbergen
*/
class CFingerLaser:public CBasePlayerWeapon
{	
public:
	/**
	* Init function
	*/
	void Spawn( void );

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

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

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

	/**
	 * Deploys the fingerlaser
	 * @return BOOL: true if succesfully deployed
	 */
	BOOL Deploy( void );

	/**
	 * shoots a piercing fingerlaser attack
	 */	
	void PrimaryAttack(void);

	/**
	 * shoots an exploding fingerlaser attack
	 */
	void SecondaryAttack(void);	

private:
	/**
	* emits the shoot sound
	*/
	void EmitShootSound();	
	bool blSwitchAni;
	CSprite *m_pChargeSprite;
};

LINK_ENTITY_TO_CLASS( weapon_fingerlaser, CFingerLaser );

void CFingerLaser::Spawn( void )
{	Precache();
	m_iId = WEAPON_FINGERLASER;
	m_iDefaultAmmo = 0;
	m_iClip = -1;
	blSwitchAni = false;

	

	FallInit();// get ready to fall down.
}

void CFingerLaser::Precache( void )
{	PRECACHE_SOUND("weapons/fingerlaser.wav");
	PRECACHE_MODEL("sprites/fingerlaserbeam.spr");	
	PRECACHE_MODEL("sprites/fingerlaserstart.spr");	
}

BOOL CFingerLaser::Deploy( void )
{	m_pChargeSprite = CSprite::SpriteCreate( "sprites/fingerlaserstart.spr", m_pPlayer->pev->origin, false);
	m_pChargeSprite->TurnOff();	
	m_pChargeSprite->SetScale(0.00001);
	m_pChargeSprite->SetAttachment(m_pPlayer->edict(),1);
	m_pChargeSprite->SetTransparency( kRenderTransAdd, 255, 255, 255, 254, kRenderFxGlowShell );
	m_pChargeSprite->pev->framerate = 10;
	return DefaultDeploy("fingerlaser");
}

int CFingerLaser::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 = 3;
	p->iPosition = 4;
	p->iId = m_iId = WEAPON_FINGERLASER;
	p->iWeight = FINGERLASER_WEIGHT;
	p->iFlags = 0;
	return 1;
}

void CFingerLaser::EmitShootSound()
{	EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/fingerlaser.wav", 1.0, ATTN_NORM);
}

void CFingerLaser::PrimaryAttack(void)
{
	if (m_pPlayer->UseKi(FINGERLASER_PRIMARYKI_COST))
	{	
		//set the right animation
		// Added by Pcjoe
		if(blSwitchAni)
			m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
		else
			m_pPlayer->SetAnimation( PLAYER_ATTACK2 );

		blSwitchAni = !blSwitchAni;

		EmitShootSound();

		//calculate startpos and speed
		UTIL_MakeVectors(m_pPlayer->pev->v_angle);
		Vector vecAiming = gpGlobals->v_forward;
		Vector vecSrc = m_pPlayer->GetGunPosition();
		TraceResult tr;
		UTIL_TraceLine(vecSrc,vecSrc + vecAiming * 8192, ignore_monsters, ENT(pev), &tr );
		Vector vecEnd = tr.vecEndPos;

		//shoot the laser
		CBeam *beam = CBeam::BeamCreate("sprites/fingerlaserbeam.spr",FINGERLASER_BEAMWIDTH);
		beam->pev->effects = EF_NODRAW;
		beam->PointEntInit( vecEnd, m_pPlayer->entindex());
		beam->SetEndAttachment(1);
		beam->SetColor(255,255,255);
		beam->SetBrightness(255);			
		beam->SetThink(&CBeam::TurnOnThink);
		beam->pev->nextthink = gpGlobals->time+0.1;
		beam->m_flTurnOffTime = 0.25;
				
		m_pChargeSprite->SetScale(0.03);
		m_pChargeSprite->SetThink( &CSprite::TurnOnThink );
		m_pChargeSprite->pev->nextthink = gpGlobals->time+0.1;
		m_pChargeSprite->m_flTurnOffTime = 0.25;
		/*
		CSprite *sprite = CSprite::SpriteCreate("sprites/fingerlaserstart.spr",Vector(0,0,0),TRUE);
		sprite->SetAttachment(m_pPlayer->entindex(),1);
		sprite->SetColor(255,255,255);
		sprite->SetBrightness(255);
		*/

		//do damage to everyone hit
		entvars_s *pIgnoreEnt = m_pPlayer->pev;
		//harSens: removed aura hitting stuff, aura's are SOLID_NOT
		//do
		{	
			UTIL_TraceLine(vecSrc,vecEnd, dont_ignore_monsters, ENT(pIgnoreEnt), &tr );
			
			//do damage if hit a player
			CBaseEntity *pEntity = CBaseEntity::Instance(tr.pHit);
			// Edited by Pcjoe, reduce damage by 50% if the player is being "tossed"
			float flReduction = 1;
			if(pEntity && pEntity->IsPlayer())
			{	CBasePlayer *pPlayer = (CBasePlayer*)pEntity;
				if(pPlayer->m_Melee.InThrow())
				{	if(pPlayer->m_Melee.SpecialLaserReduction())
					{	flReduction = (2/3);
					}
					else
					{	flReduction = .5;
					}
				}
			}
			//don't hit it if you're the owner (so don't hit your aura)
			/*
			if (VARS(pEntity->pev->owner)!=m_pPlayer->pev)
			{
				
			}
			*/
			pEntity->TakeDamage(m_pPlayer->pev,m_pPlayer->pev,FINGERLASER_PRIMARYDAMAGE * GetPowerRatio() * flReduction, DMG_MAGIC);				
			// end of edit by Pcjoe
			//pIgnoreEnt = pEntity->pev;
			//vecSrc = tr.vecEndPos;
		}
		//while (tr.flFraction < 1.0);

		m_flNextPrimaryAttack = m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 3;
	}
}

void CFingerLaser::SecondaryAttack()								  
{	
	if (m_pPlayer->UseKi(FINGERLASER_SECONDARYKI_COST))
	{	//calculate startpos and speed
		UTIL_MakeVectors(m_pPlayer->pev->v_angle);
		Vector vecAiming = gpGlobals->v_forward;
		Vector vecSrc = m_pPlayer->GetGunPosition();
		TraceResult tr;
		entvars_s *pIgnoreEnt = m_pPlayer->pev;
		Vector vecEnd = vecSrc + vecAiming * 8192;

		//ignore aura's
		do
		{
			UTIL_TraceLine(vecSrc, vecEnd, dont_ignore_monsters, ENT(pIgnoreEnt), &tr );
			vecSrc = tr.vecEndPos;
			pIgnoreEnt = VARS(tr.pHit);
		}
		while(VARS(pIgnoreEnt->owner)==m_pPlayer->pev && tr.flFraction<1.0);

		//set the right animation
		// Edited by Pcjoe
		if(blSwitchAni)
			m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
		else
			m_pPlayer->SetAnimation( PLAYER_ATTACK2 );

		blSwitchAni = !blSwitchAni;
		EmitShootSound();
	
		//shoot the laser
		//shoot the laser
		CBeam *beam = CBeam::BeamCreate("sprites/fingerlaserbeam.spr",FINGERLASER_BEAMWIDTH);
		beam->pev->effects = EF_NODRAW;
		beam->PointEntInit( tr.vecEndPos, m_pPlayer->entindex());
		beam->SetEndAttachment(1);
		beam->SetColor(255,255,255);
		beam->SetBrightness(255);			
		beam->SetThink(&CBeam::TurnOnThink);
		beam->pev->nextthink = gpGlobals->time+0.1;
		beam->m_flTurnOffTime = 0.25;
				
		m_pChargeSprite->SetScale(0.02);
		m_pChargeSprite->SetThink( &CSprite::TurnOnThink );
		m_pChargeSprite->pev->nextthink = gpGlobals->time+0.1;
		m_pChargeSprite->m_flTurnOffTime = 0.25;

		// Edited by Pcjoe, reduce damage by 50% if the player is being "tossed"
		float flReduction = 1;
		if(tr.flFraction<1.0 && tr.pHit)
		{	CBaseEntity *pEntity = CBaseEntity::Instance(tr.pHit);
			if(pEntity && pEntity->IsPlayer())
			{	CBasePlayer *pPlayer = (CBasePlayer*)pEntity;
				if(pPlayer->m_Melee.InThrow())
				{	if(pPlayer->m_Melee.SpecialLaserReduction())
					{	flReduction = (2/3);
					}
					else
					{	flReduction = .5;
					}
				}
			}
		}

		int damage = FINGERLASER_SECONDARYDAMAGE * GetPowerRatio() * flReduction;
		RadiusDamage( tr.vecEndPos, m_pPlayer->pev, m_pPlayer->pev, damage, damage * FINGERLASER_RADIUS, CLASS_NONE, DMG_MAGIC );
	
		//make explosion
		MESSAGE_BEGIN( MSG_ALL, gmsgExplosion, NULL );
			WRITE_COORD( tr.vecEndPos.x );	
			WRITE_COORD( tr.vecEndPos.y );
			WRITE_COORD( tr.vecEndPos.z );
			WRITE_LONG (2.5 * damage);	//radius
			WRITE_BYTE(PURPLE_EXPLOSION);			
		MESSAGE_END();
		m_flNextPrimaryAttack = m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.3;
	}
}