
#include "data_classlevels_data"
#include "proj_toarrow"

enum arrowAnimation
{
	TOBOW_IDLE,
	TOBOW_LOAD,
	TOBOW_AIM_LOOP,
	TOBOW_SHOOT,
	TOBOW_DEPLOY,
	TOBOW_CANCEL,
};

enum bowstatus
{
	BOW_READY,
	BOW_NOT_READY,
};

const int tobow_DEFAULT_GIVE 	= 10;
const int tobow_MAX_AMMO		= 50;
const int tobow_WEIGHT 		= 15;
const int tobow_DAMAGE1		= 80;
const int tobow_VELOCITY	= 1500;
const float tobow_RADIUS_NONE	= 2.0f;
const float tobow_RADIUS_SECONDARY	= 300.0f;

const string tobow_MODEL_VIEW		= "models/torre/weapons/v_tobow.mdl";
const string tobow_MODEL_WORLD		= "models/torre/weapons/w_tobow.mdl";
const string tobow_MODEL_PLAYER	= "models/torre/weapons/p_tobow.mdl";
const string tobow_MODEL_CLIP		= "models/torre/weapons/arrow.mdl";

const string tobow_SOUND_LOAD = "torre/tobow_load.wav";
const string tobow_SOUND_FIRE = "torre/tobow_fire.wav";

class CWeapontobow : ScriptBasePlayerWeaponEntity
{
	private CBasePlayer@ basePlayer = null;
	int g_iCurrentMode;
	int g_iInSpecialReload;
	int iBowStatus = BOW_NOT_READY;
		
	void Spawn()
	{
		Precache();
		g_EntityFuncs.SetModel( self, tobow_MODEL_WORLD );

		self.m_iDefaultAmmo = tobow_DEFAULT_GIVE;
		g_iCurrentMode = 1;

		self.FallInit();
	}

	void Precache()
	{
		g_Game.PrecacheModel( tobow_MODEL_VIEW );
		g_Game.PrecacheModel( tobow_MODEL_WORLD );
		g_Game.PrecacheModel( tobow_MODEL_PLAYER );
		g_Game.PrecacheModel( tobow_MODEL_CLIP );
		g_Game.PrecacheModel( "models/not_precached2.mdl" );
		g_Game.PrecacheModel( "models/torre/weapons/arrow.mdl" );
		
		g_Game.PrecacheGeneric( "sound/" + tobow_SOUND_FIRE);
		g_Game.PrecacheGeneric( "sound/" + tobow_SOUND_LOAD);
				
		g_SoundSystem.PrecacheSound( "items/9mmclip1.wav" );
		g_SoundSystem.PrecacheSound( "weapons/357_cock1.wav" );
		
		g_SoundSystem.PrecacheSound( tobow_SOUND_FIRE );
		g_SoundSystem.PrecacheSound( tobow_SOUND_LOAD );
	}

	bool GetItemInfo( ItemInfo& out info )
	{
		info.iMaxAmmo1 	= tobow_MAX_AMMO;
		info.iMaxAmmo2 	= -1;
		info.iMaxClip 	= WEAPON_NOCLIP;
		info.iSlot 		= 1;
		info.iPosition 	= 5;
		info.iFlags 	= 0;
		info.iWeight 	= tobow_WEIGHT;

		return true;
	}
	
	bool PlayEmptySound()
	{
		if( self.m_bPlayEmptySound )
		{
			self.m_bPlayEmptySound = false;
			
			CBasePlayer@ basePlayer = cast<CBasePlayer>(self.m_hPlayer.GetEntity());
			g_SoundSystem.EmitSoundDyn( basePlayer.edict(), CHAN_WEAPON, "weapons/357_cock1.wav", 0.8, ATTN_NORM, 0, PITCH_NORM );
		}
		
		return false;
	}

	bool Deploy()
	{
		return self.DefaultDeploy( self.GetV_Model( tobow_MODEL_VIEW ), self.GetP_Model( tobow_MODEL_PLAYER ), TOBOW_DEPLOY, "bowscope" );
	}
	
	void Holster( int skipLocal = 0 )
	{	
		if (iBowStatus == BOW_READY)
		{
			CBasePlayer@ basePlayer = cast<CBasePlayer>(self.m_hPlayer.GetEntity());
			iBowStatus = BOW_NOT_READY;
			basePlayer.pev.noise = "false";
			basePlayer.SetMaxSpeed (basePlayer.GetMaxSpeed() + 90);
		}
		
		BaseClass.Holster( skipLocal );
	}
	
	float WeaponTimeBase()
	{
		return g_Engine.time;
	}

	void PrimaryAttack()
	{
		Vector vecSrc, vecVelocity, vecAngles;
		CBasePlayer@ basePlayer = cast<CBasePlayer>(self.m_hPlayer.GetEntity());
		int iAmmo = basePlayer.m_rgAmmo( self.m_iPrimaryAmmoType );		
			
		if( basePlayer.pev.waterlevel == WATERLEVEL_HEAD || iAmmo <= 0 )
		{
			self.PlayEmptySound();
			self.m_flNextSecondaryAttack = WeaponTimeBase() + 0.15f;
			return;
		}
		
		if (iBowStatus == BOW_NOT_READY)
		{
			self.m_flNextPrimaryAttack = self.m_flNextSecondaryAttack = WeaponTimeBase() + 1.2f;
			self.SendWeaponAnim( TOBOW_LOAD, 0, 0 );
			iBowStatus = BOW_READY;
			g_SoundSystem.EmitSound( basePlayer.edict(), CHAN_WEAPON, tobow_SOUND_LOAD, 1.0f, ATTN_NORM );
			basePlayer.pev.noise = "true";
			basePlayer.SetMaxSpeed (basePlayer.GetMaxSpeed() - 90);
				return;
		}
		
		iBowStatus = BOW_NOT_READY;
				
		--iAmmo;
		
		basePlayer.m_iWeaponVolume = NORMAL_GUN_VOLUME;
		
		basePlayer.SetAnimation( PLAYER_ATTACK1 );

		Math.MakeVectors( basePlayer.pev.v_angle );
		vecSrc = basePlayer.GetGunPosition() + g_Engine.v_forward * 16 + g_Engine.v_up * -6;
		
		ShootArrowProjectile( basePlayer.pev, vecSrc, g_Engine.v_forward * (tobow_VELOCITY/2));
		self.m_flNextPrimaryAttack = self.m_flNextSecondaryAttack = WeaponTimeBase() + 0.05f;
		
		if( iAmmo != 0 )
			self.m_flTimeWeaponIdle = WeaponTimeBase() + 5.0f;
		else
			self.m_flTimeWeaponIdle = WeaponTimeBase() + 0.75f;
		
		g_iInSpecialReload = 0;
		
		g_SoundSystem.EmitSoundDyn( basePlayer.edict(), CHAN_WEAPON, tobow_SOUND_FIRE, 0.9, ATTN_NORM, 0, PITCH_NORM );
		self.SendWeaponAnim( TOBOW_SHOOT, 0, 0 );
		self.m_flNextPrimaryAttack = self.m_flNextSecondaryAttack= WeaponTimeBase() + 0.83f;
		basePlayer.m_rgAmmo(self.m_iPrimaryAmmoType, iAmmo);
		basePlayer.pev.noise = "false";
		basePlayer.SetMaxSpeed (basePlayer.GetMaxSpeed() + 90);
	}
	
	void SecondaryAttack()
	{
		if (iBowStatus == BOW_READY)
		{
			self.m_flNextPrimaryAttack = self.m_flNextSecondaryAttack= WeaponTimeBase() + 0.1f;
			self.SendWeaponAnim( TOBOW_AIM_LOOP, 0, 0 );
			//g_SoundSystem.EmitSound( basePlayer.edict(), CHAN_WEAPON, tobow_SOUND_FIRE, 1.0f, ATTN_NORM );
		}
	
		CBasePlayer@ basePlayer = cast<CBasePlayer>(self.m_hPlayer.GetEntity());
		if (iBowStatus == BOW_NOT_READY)
		{
			basePlayer.pev.noise = "true";
			basePlayer.SetMaxSpeed (basePlayer.GetMaxSpeed() - 90); 
			self.m_flNextPrimaryAttack = self.m_flNextSecondaryAttack = WeaponTimeBase() + 1.2f;
			self.SendWeaponAnim( TOBOW_LOAD, 0, 0 );
			iBowStatus = BOW_READY;
			g_SoundSystem.EmitSound( basePlayer.edict(), CHAN_WEAPON, tobow_SOUND_LOAD, 1.0f, ATTN_NORM );
		}
	}

	void WeaponIdle()
	{
		CBasePlayer@ basePlayer = cast<CBasePlayer>(self.m_hPlayer.GetEntity());
		
		if (iBowStatus == BOW_READY)
		{
			iBowStatus = BOW_NOT_READY;
			self.SendWeaponAnim( TOBOW_CANCEL, 0, 0 );
			basePlayer.pev.noise = "false";
			basePlayer.SetMaxSpeed (basePlayer.GetMaxSpeed() + 90); 
		}
	}
}

class ToArrow : ScriptBasePlayerAmmoEntity
{
	void Spawn()
	{ 
		Precache();
		g_EntityFuncs.SetModel( self, tobow_MODEL_CLIP );
		BaseClass.Spawn();
	}
	
	void Precache()
	{
		g_Game.PrecacheModel( tobow_MODEL_CLIP );
		g_SoundSystem.PrecacheSound( "items/9mmclip1.wav" );
	}
	
	bool AddAmmo( CBaseEntity@ pOther )
	{ 
		int iGive;

		iGive = tobow_DEFAULT_GIVE/2;

		if( pOther.GiveAmmo( iGive, "toarrow", tobow_MAX_AMMO ) != -1)
		{
			g_SoundSystem.EmitSound( self.edict(), CHAN_ITEM, "items/9mmclip1.wav", 1, ATTN_NORM );
			return true;
		}
		return false;
	}
}


void Registertobow()
{
	g_CustomEntityFuncs.RegisterCustomEntity( "CWeapontobow", "weapon_tobow" );
	g_ItemRegistry.RegisterWeapon( "weapon_tobow", "torre", "toarrow" );
}

void RegisterToArrow()
{
	g_CustomEntityFuncs.RegisterCustomEntity( "ToArrow", "ammo_toarrow" );
}
