﻿const int SKULK_BITE = 2;
const int SKULK_LEAP = 3;

class monster_skulk : ScriptBaseMonsterEntity
{

	bool hidden = false;

	void Spawn()
	{
		Precache( ); 
		g_EntityFuncs.SetModel( self, "models/ns/skulk.mdl" );
		g_EntityFuncs.SetSize( pev, Vector(-16, -16, 0), Vector(16, 16, 32) ); 
		pev.solid = SOLID_SLIDEBOX; 
		pev.movetype = MOVETYPE_STEP; 
		self.m_bloodColor = BLOOD_COLOR_GREEN;
		pev.health = 140;
		pev.view_ofs = Vector ( 0, 0, 10 );
		self.m_flFieldOfView = 0.75; 
		self.m_MonsterState = MONSTERSTATE_NONE; 
		g_EntityFuncs.DispatchKeyValue( self.edict(), "displayname", "Skulk" );

		self.MonsterInit(); 
	}

	void Precache()
	{
		g_Game.PrecacheModel( "models/ns/skulk.mdl" );
		g_SoundSystem.PrecacheSound( "rc/bite.wav" );
	}

	int	Classify ( void )
	{
		return	CLASS_ALIEN_MONSTER; 
	}

	void SetYawSpeed( void )
	{
		pev.yaw_speed = 90; 
	}

	
	void HandleAnimEvent( MonsterEvent@ pEvent )
	{
		switch ( pEvent.event ) 
		{
			case SKULK_BITE:
			{
				CBaseEntity@ pTarget = self.m_hEnemy;
				Vector vecToEnemy = ((pTarget.pev.origin + pTarget.pev.view_ofs) - self.pev.origin).Normalize();
				Vector vecSrc = self.pev.origin + g_Engine.v_forward * 16;
				Vector vecEnd = vecSrc + (vecToEnemy * 160);

				TraceResult tr;
				g_Utility.TraceLine( vecSrc, vecEnd, dont_ignore_monsters, self.edict(), tr );
				
				if ( tr.flFraction >= 1.0 )
				{
					// miss
				}
				else
				{
					// hit			
					g_SoundSystem.EmitSoundDyn( self.edict(), CHAN_VOICE, "rc/bite.wav", 1.0, ATTN_NORM, 0, 95 + Math.RandomLong( 0, 10 ) );
					CBaseEntity@ pHurt = g_EntityFuncs.Instance( tr.pHit ); 
					float flDamage = 25;
					pHurt.TakeDamage( self.pev, self.pev, flDamage, DMG_SLASH ); 			
				
					if ( pHurt !is null )
					{
						pHurt.pev.punchangle.x = 15;
						pHurt.pev.velocity = pHurt.pev.velocity + g_Engine.v_up * -100;
					}
				}
			}
			break;
			case SKULK_LEAP:
			{
				CBaseEntity@ eTarget = self.m_hEnemy;
				Vector enemyPos = eTarget.pev.origin;
				enemyPos.z += eTarget.pev.maxs.z;
				Vector vecToEnemy = (enemyPos - self.pev.origin).Normalize();
				self.pev.basevelocity = g_Engine.v_forward * 1200;
				//self.pev.velocity = g_Engine.v_forward * 2000;
			}
			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 (self.HasConditions( bits_COND_HEAVY_DAMAGE ))
				{
					return BaseClass.GetScheduleOfType ( SCHED_TAKE_COVER_FROM_ENEMY );
				}
			
				if ( distToEnemy < 96 && self.HasConditions( bits_COND_CAN_MELEE_ATTACK1 ))
				{
					return BaseClass.GetScheduleOfType (SCHED_MELEE_ATTACK1);
				}
				else if( distToEnemy >= 96)
				{
					switch ( Math.RandomLong ( 0, 1 ) ) 
					{
						case 0:
						return BaseClass.GetScheduleOfType (SCHED_MELEE_ATTACK2);
						case 1:
						return BaseClass.GetScheduleOfType (SCHED_CHASE_ENEMY);	
					}
				}
								
			}			
		}

		return BaseClass.GetSchedule();
	}
}

string GetSkulkName()
{
	return "monster_skulk";
}

void RegisterSkulk()
{
	g_CustomEntityFuncs.RegisterCustomEntity( "monster_skulk", GetSkulkName() );
}