﻿const int robo2_rocket = 1;
const int robo2_laser = 2;
const int robo2_robo = 3;
const int robo2_die = 4;
const int robo2_heal = 5;


class monster_robo2 : ScriptBaseMonsterEntity
{

	int robo_rocketammo = 1;
	int robo_roboammo = 1;
	int g_sModelIndexSmoke;
	int m_iBodyGibs;
	string TURRET_SMOKE = "sprites/steam1.spr";

	void Spawn()
	{
		Precache( ); 
		g_EntityFuncs.SetModel( self, "models/ns/robo2.mdl" );
		g_EntityFuncs.SetSize( pev, Vector(-32, -32, 0), Vector(32, 32, 80) ); 
		pev.solid = SOLID_SLIDEBOX; 
		pev.movetype = MOVETYPE_FLY; 
		self.m_bloodColor = DONT_BLEED;
		pev.health = 3500;
		pev.view_ofs = Vector ( 0, 0, 64 );
		self.m_flFieldOfView = 0.75; 
		self.m_MonsterState = MONSTERSTATE_NONE; 
		g_EntityFuncs.DispatchKeyValue( self.edict(), "displayname", "robo2" );
		
		g_SoundSystem.EmitSoundDyn( self.edict(), CHAN_VOICE, "rc/robo_idle2.wav", 1.0, ATTN_NORM, 0, 95 + Math.RandomLong( 0, 10 ) );

		self.MonsterInit(); 
		
	}

	void Precache()
	{
		g_Game.PrecacheModel( "models/ns/robo2.mdl" );
		g_Game.PrecacheModel( "models/ns/laserprojectile.mdl" );
		g_Game.PrecacheModel( "models/ns/rocketprojectile.mdl" );
		g_Game.PrecacheModel( "models/ns/roboprojectile.mdl" );
		m_iBodyGibs = g_Game.PrecacheModel( "models/computergibs.mdl" );	
		g_sModelIndexSmoke = g_Game.PrecacheModel( TURRET_SMOKE );
		g_Game.PrecacheModel( "sprites/rc/rc_explosionHD.spr" );
		g_Game.PrecacheModel( "sprites/rc/rc_explosion2HD.spr" );
	}

	int	Classify ( void )
	{
		return	CLASS_MACHINE; 
	}

	void SetYawSpeed( void )
	{
		pev.yaw_speed = 90; 
	}
		
	
	void ReloadRockets()
	{
		robo_rocketammo = 1;
	}
	
	void ReloadRobo()
	{
		robo_roboammo = 1;
	}
	
	
	void HandleAnimEvent( MonsterEvent@ pEvent )
	{
		switch ( pEvent.event ) 
		{
			case robo2_laser:
			{
				CBaseEntity@ pTarget = self.m_hEnemy;
				
				Vector vecOffset = ( g_Engine.v_forward * 6 + g_Engine.v_up * 80 + g_Engine.v_right * 32);
				Vector vecSrc = (self.pev.origin + vecOffset);
				Vector vecToEnemy = (pTarget.pev.origin - vecSrc).Normalize();
				
				CBaseEntity@ pLaser = g_EntityFuncs.Create( "ns_laserprojectile", vecSrc, pev.angles, false, null );
				
				pLaser.pev.velocity = vecToEnemy * 1800;
				@pLaser.pev.owner = self.edict();
				pLaser.pev.friction = 0;
			}
			break;
			case robo2_rocket:
			{
				robo_rocketammo -= 1;
				CBaseEntity@ pTarget = self.m_hEnemy;
				
				Vector vecOffset = ( g_Engine.v_forward * 6 + g_Engine.v_up * 80 + g_Engine.v_right * -32);
				Vector vecSrc = (self.pev.origin + vecOffset);
				Vector vecToEnemy = (pTarget.pev.origin - vecSrc).Normalize();
				
				vecToEnemy.x += Math.RandomFloat( -0.01, 0.01 );
				vecToEnemy.y += Math.RandomFloat( -0.01, 0.01 );
				vecToEnemy.z += Math.RandomFloat( -0.01, 0.01 );
				CBaseEntity@ pRocket = g_EntityFuncs.Create( "ns_rocketprojectile", vecSrc, pev.angles, false, null );
				
				pRocket.pev.velocity = vecToEnemy * 600;
				@pRocket.pev.owner = self.edict();
				pRocket.pev.friction = 0;
				
				if(robo_rocketammo <= 0){ g_Scheduler.SetTimeout( @this, "ReloadRockets", 10.0); }
				
			}
			break;
			case robo2_robo:
			{
				robo_roboammo -= 1;
				CBaseEntity@ pTarget = self.m_hEnemy;
				
				Vector vecOffset = ( g_Engine.v_forward * 6 + g_Engine.v_up * 80 + g_Engine.v_right * -32);
				Vector vecSrc = (self.pev.origin + vecOffset);
				Vector vecToEnemy = (pTarget.pev.origin - vecSrc).Normalize();
				
				vecToEnemy.x += Math.RandomFloat( -0.01, 0.01 );
				vecToEnemy.y += Math.RandomFloat( -0.01, 0.01 );
				vecToEnemy.z += Math.RandomFloat( -0.01, 0.01 );
				CBaseEntity@ pRocket = g_EntityFuncs.Create( "ns_roboprojectile", vecSrc, pev.angles, false, null );
				
				pRocket.pev.velocity = vecToEnemy * 600;
				@pRocket.pev.owner = self.edict();
				pRocket.pev.friction = 0;
				
				if(robo_rocketammo <= 0){ g_Scheduler.SetTimeout( @this, "ReloadRobo", 10.0); }
				
			}
			break;
			case robo2_die:
			{	
				g_SoundSystem.StopSound( self.edict(), CHAN_VOICE, "rc/robo_idle.wav" );
				self.pev.dmgtime = g_Engine.time;
				SetThink( ThinkFunction( this.Death ) );
				self.pev.nextthink = g_Engine.time + 0.1;				
			}
			break;
			case robo2_heal:
			{	
				if(self.pev.health > 4000){ self.pev.health = 4000; }
				else{ self.pev.health += 2; }
			}
			break;
			default:
				BaseClass.HandleAnimEvent( pEvent );
				break; 
		}
	}
	
	
	Schedule@ GetSchedule( void )
	{	
	
		switch	(self.m_MonsterState)
		{
			case MONSTERSTATE_COMBAT:
			{	
				if(self.HasConditions(bits_COND_ENEMY_DEAD))
				{
					return BaseClass.GetSchedule();	
				}
			
				pev.movetype = MOVETYPE_STEP;
				CBaseEntity@ pTarget = self.m_hEnemy;
				float distToEnemy = ( pev.origin - pTarget.pev.origin).Length();
			
				if ( distToEnemy < 1500 && self.HasConditions( bits_COND_SEE_ENEMY ))
				{
					if(robo_rocketammo >= 1){
						return BaseClass.GetScheduleOfType ( SCHED_RANGE_ATTACK2 );
					}
					else if(robo_roboammo >= 1){
						return BaseClass.GetScheduleOfType ( SCHED_MELEE_ATTACK1 );
					}
					else {
						return BaseClass.GetScheduleOfType ( SCHED_RANGE_ATTACK1 );
					}
				}
				else {
					return BaseClass.GetScheduleOfType ( SCHED_CHASE_ENEMY );	
				}
			}			
		}

		return BaseClass.GetSchedule();	
	}
	
	
	void Death ( void )
	{
		
		bool iActive = false;

		self.StudioFrameAdvance( );
		self.pev.nextthink = g_Engine.time + 0.1;

		if ( self.pev.deadflag != DEAD_DEAD )
		{
			self.pev.deadflag = DEAD_DEAD;
			g_SoundSystem.EmitSoundDyn( self.edict(), CHAN_VOICE, "turret/tu_die.wav", 1.0, ATTN_NORM, 0, 95 + Math.RandomLong( 0, 10 ) );
		}

		if ( self.pev.dmgtime + Math.RandomFloat( 0, 2 ) > g_Engine.time )
		{			
			// lots of smoke
			NetworkMessage smoke( MSG_PVS, NetworkMessages::SVC_TEMPENTITY );
				smoke.WriteByte( TE_SMOKE );
				smoke.WriteCoord( Math.RandomFloat( self.pev.absmin.x, self.pev.absmax.x ) );
				smoke.WriteCoord( Math.RandomFloat( self.pev.absmin.y, self.pev.absmax.y ) );
				smoke.WriteCoord( self.pev.origin.z );
				smoke.WriteShort( g_sModelIndexSmoke );
				smoke.WriteByte( 25 ); // scale * 10
				smoke.WriteByte( 25); // framerate
			smoke.End();
		}
		
		if ( self.pev.dmgtime + Math.RandomFloat( 0, 5 ) > g_Engine.time )
		{
			Vector vecSrc = Vector( Math.RandomFloat( self.pev.absmin.x, self.pev.absmax.x ), Math.RandomFloat( self.pev.absmin.y, self.pev.absmax.y ), 0 );
			vecSrc = vecSrc + Vector( 0, 0, Math.RandomFloat( self.pev.origin.z, self.pev.absmax.z ) );

			g_Utility.Sparks( vecSrc );
		}
	
		if ( self.pev.dmgtime + 5 < g_Engine.time )
		{	
			//Explodes
			g_WeaponFuncs.RadiusDamage(self.pev.origin, self.pev, self.pev, 1000, 2000, CLASS_NONE, DMG_BLAST);
			
			rc_explosion(self.pev, self.pev, 20);
									
			RoboGibs(100);
			
			self.pev.framerate = 0;
			g_EntityFuncs.Remove( self );
		}
	
	}

	
	void RoboGibs(int vel)
	{

		uint8 shards = 20;
		uint8 durationshard = 5;
		Vector vecSpot = self.pev.origin + (self.pev.mins + self.pev.maxs) * 0.5;

		//Gibs
		NetworkMessage gibs( MSG_PVS, NetworkMessages::SVC_TEMPENTITY, vecSpot );
		gibs.WriteByte( TE_BREAKMODEL );
				
		//Position
		gibs.WriteCoord( vecSpot.x );
		gibs.WriteCoord( vecSpot.y );
		gibs.WriteCoord( vecSpot.z );
				
		//Size
		gibs.WriteCoord( self.pev.size.x );
		gibs.WriteCoord( self.pev.size.y );
		gibs.WriteCoord( self.pev.size.z );
				
		//Velocity
		gibs.WriteCoord( 0 );
		gibs.WriteCoord( 0 );
		gibs.WriteCoord( 2 * vel);
				
		//Randomization
		gibs.WriteByte( 20 );
				
		//Model
		gibs.WriteShort( m_iBodyGibs );
				
		//Number of gibs
		gibs.WriteByte( shards );
				
		//Duration
		gibs.WriteByte( durationshard );
				
		//Flags
		gibs.WriteByte( BREAK_METAL + 16 );
		gibs.End();
		
	}
}




string GetRobo2Name()
{
	return "monster_robo2";
}

void RegisterRobo2()
{
	g_CustomEntityFuncs.RegisterCustomEntity( "monster_robo2", GetRobo2Name() );
}

