/*
===========================================================================
Copyright (C) 2000 - 2013, Raven Software, Inc.
Copyright (C) 2001 - 2013, Activision, Inc.
Copyright (C) 2013 - 2015, OpenJK contributors

This file is part of the OpenJK source code.

OpenJK is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>.
===========================================================================
*/

#include "b_local.h"
#include "g_nav.h"

#define	MIN_MELEE_RANGE				320
#define	MIN_MELEE_RANGE_SQR			( MIN_MELEE_RANGE * MIN_MELEE_RANGE )

#define MIN_DISTANCE				128
#define MIN_DISTANCE_SQR			( MIN_DISTANCE * MIN_DISTANCE )

#define TURN_OFF					0x00000100

#define LEFT_ARM_HEALTH				40
#define RIGHT_ARM_HEALTH			40
#define AMMO_POD_HEALTH				40

#define	BOWCASTER_VELOCITY			1300
#define	BOWCASTER_NPC_DAMAGE_EASY	12
#define	BOWCASTER_NPC_DAMAGE_NORMAL	24
#define	BOWCASTER_NPC_DAMAGE_HARD	36
#define BOWCASTER_SIZE				2
#define BOWCASTER_SPLASH_DAMAGE		0
#define BOWCASTER_SPLASH_RADIUS		0

//Local state enums
enum
{
	LSTATE_NONE = 0,
	LSTATE_ASLEEP,
	LSTATE_WAKEUP,
	LSTATE_FIRED0,
	LSTATE_FIRED1,
	LSTATE_FIRED2,
	LSTATE_FIRED3,
	LSTATE_FIRED4,
};

qboolean NPC_CheckPlayerTeamStealth( void );
void Mark1_BlasterAttack(qboolean advance);
void DeathFX( gentity_t *ent );

extern gitem_t *BG_FindItemForAmmo( ammo_t ammo );

/*
-------------------------
NPC_Mark1_Precache
-------------------------
*/
void NPC_Mark1_Precache(void)
{
	G_SoundIndex( "sound/chars/mark1/misc/mark1_wakeup");
	G_SoundIndex( "sound/chars/mark1/misc/shutdown");
	G_SoundIndex( "sound/chars/mark1/misc/walk");
	G_SoundIndex( "sound/chars/mark1/misc/run");
	G_SoundIndex( "sound/chars/mark1/misc/death1");
	G_SoundIndex( "sound/chars/mark1/misc/death2");
	G_SoundIndex( "sound/chars/mark1/misc/anger");
	G_SoundIndex( "sound/chars/mark1/misc/mark1_fire");
	G_SoundIndex( "sound/chars/mark1/misc/mark1_pain");
	G_SoundIndex( "sound/chars/mark1/misc/mark1_explo");

//	G_EffectIndex( "small_chunks");
	G_EffectIndex( "env/med_explode2");
	G_EffectIndex( "explosions/probeexplosion1");
	G_EffectIndex( "blaster/smoke_bolton");
	G_EffectIndex( "bryar/muzzle_flash");
	G_EffectIndex( "explosions/droidexplosion1" );

	RegisterItem( BG_FindItemForAmmo( 	AMMO_METAL_BOLTS));
	RegisterItem( BG_FindItemForAmmo( AMMO_BLASTER ));
	RegisterItem( BG_FindItemForWeapon( WP_BOWCASTER ));
	RegisterItem( BG_FindItemForWeapon( WP_BRYAR_PISTOL ));
}

/*
-------------------------
NPC_Mark1_Part_Explode
-------------------------
*/
void NPC_Mark1_Part_Explode( gentity_t *self, int bolt )
{
	if ( bolt >=0 )
	{
		mdxaBone_t	boltMatrix;
		vec3_t		org, dir;

		trap->G2API_GetBoltMatrix( self->ghoul2, 0,
					bolt,
					&boltMatrix, self->r.currentAngles, self->r.currentOrigin, level.time,
					NULL, self->modelScale );

		BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, org );
		BG_GiveMeVectorFromMatrix( &boltMatrix, NEGATIVE_Y, dir );

		G_PlayEffectID( G_EffectIndex("env/med_explode2"), org, dir );

		G_PlayEffectID( G_EffectIndex("blaster/smoke_bolton"), org, dir );
	}

	//G_PlayEffectID( G_EffectIndex("blaster/smoke_bolton"), self->playerModel, bolt, self->s.number );
}

/*
-------------------------
Mark1_Idle
-------------------------
*/
void Mark1_Idle( void )
{
	NPC_BSIdle();

	NPC_SetAnim( NPCS.NPC, SETANIM_BOTH, BOTH_SLEEP1, SETANIM_FLAG_NORMAL );
}

/*
-------------------------
Mark1Dead_FireRocket
- Shoot the left weapon, the multi-blaster
-------------------------
*/
void Mark1Dead_FireRocket (void)
{
	mdxaBone_t	boltMatrix;
	vec3_t	muzzle1,muzzle_dir;
	gentity_t *missile;
	int	damage	= 50;
	int bolt = trap->G2API_AddBolt(NPCS.NPC->ghoul2, 0, "*flash5");

	trap->G2API_GetBoltMatrix( NPCS.NPC->ghoul2, 0,
				bolt,
				&boltMatrix, NPCS.NPC->r.currentAngles, NPCS.NPC->r.currentOrigin, level.time,
				NULL, NPCS.NPC->modelScale );

	BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, muzzle1 );
	BG_GiveMeVectorFromMatrix( &boltMatrix, NEGATIVE_Y, muzzle_dir );

	G_PlayEffectID( G_EffectIndex("bryar/muzzle_flash"), muzzle1, muzzle_dir );

	G_Sound( NPCS.NPC, CHAN_AUTO, G_SoundIndex("sound/chars/mark1/misc/mark1_fire"));

	missile = CreateMissile( muzzle1, muzzle_dir, BOWCASTER_VELOCITY, 10000, NPCS.NPC, qfalse );

	missile->classname = "bowcaster_proj";
	missile->s.weapon = WP_BOWCASTER;

	VectorSet( missile->r.maxs, BOWCASTER_SIZE, BOWCASTER_SIZE, BOWCASTER_SIZE );
	VectorScale( missile->r.maxs, -1, missile->r.mins );

	missile->damage = damage;
	missile->dflags = DAMAGE_DEATH_KNOCKBACK;
	//missile->methodOfDeath = MOD_ENERGY;
	missile->methodOfDeath = MOD_ROCKET;
	missile->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER;
	missile->splashDamage = BOWCASTER_SPLASH_DAMAGE;
	missile->splashRadius = BOWCASTER_SPLASH_RADIUS;

	// we don't want it to bounce
	missile->bounceCount = 0;

}

/*
-------------------------
Mark1Dead_FireBlaster
- Shoot the left weapon, the multi-blaster
-------------------------
*/
void Mark1Dead_FireBlaster (void)
{
	vec3_t	muzzle1,muzzle_dir;
	gentity_t	*missile;
	mdxaBone_t	boltMatrix;
	int			bolt;

	bolt = trap->G2API_AddBolt(NPCS.NPC->ghoul2, 0, "*flash1");

	trap->G2API_GetBoltMatrix( NPCS.NPC->ghoul2, 0,
				bolt,
				&boltMatrix, NPCS.NPC->r.currentAngles, NPCS.NPC->r.currentOrigin, level.time,
				NULL, NPCS.NPC->modelScale );

	BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, muzzle1 );
	BG_GiveMeVectorFromMatrix( &boltMatrix, NEGATIVE_Y, muzzle_dir );

	G_PlayEffectID( G_EffectIndex("bryar/muzzle_flash"), muzzle1, muzzle_dir );

	missile = CreateMissile( muzzle1, muzzle_dir, 1600, 10000, NPCS.NPC, qfalse );

	G_Sound( NPCS.NPC, CHAN_AUTO, G_SoundIndex("sound/chars/mark1/misc/mark1_fire"));

	missile->classname = "bryar_proj";
	missile->s.weapon = WP_BRYAR_PISTOL;

	missile->damage = 1;
	missile->dflags = DAMAGE_DEATH_KNOCKBACK;
	missile->methodOfDeath = MOD_BRYAR_PISTOL;
	missile->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER;

}

/*
-------------------------
Mark1_die
-------------------------
*/
void Mark1_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod,int dFlags,int hitLoc )
{
	/*
	int	anim;

	// Is he dead already?
	anim = self->client->ps.legsAnim;
	if (((anim==BOTH_DEATH1) || (anim==BOTH_DEATH2)) && (self->client->ps.torsoTimer<=0))
	{	// This is because self->health keeps getting zeroed out. HL_NONE acts as health in this case.
		self->locationDamage[HL_NONE] += damage;
		if (self->locationDamage[HL_NONE] > 50)
		{
			DeathFX(self);
			self->client->ps.eFlags |= EF_NODRAW;
			self->contents = CONTENTS_CORPSE;
			// G_FreeEntity( self ); // Is this safe?  I can't see why we'd mark it nodraw and then just leave it around??
			self->e_ThinkFunc = thinkF_G_FreeEntity;
			self->nextthink = level.time + FRAMETIME;
		}
		return;
	}
	*/

	G_Sound( self, CHAN_AUTO, G_SoundIndex(va("sound/chars/mark1/misc/death%d.wav",Q_irand( 1, 2))));

	// Choose a death anim
	if (Q_irand( 1, 10) > 5)
	{
		NPC_SetAnim( self, SETANIM_BOTH, BOTH_DEATH2, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
	}
	else
	{
		NPC_SetAnim( self, SETANIM_BOTH, BOTH_DEATH1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
	}
}

/*
-------------------------
Mark1_dying
-------------------------
*/
void Mark1_dying( gentity_t *self )
{
	int	num,newBolt;

	if (self->client->ps.torsoTimer>0)
	{
		if (TIMER_Done(self,"dyingExplosion"))
		{
			num = Q_irand( 1, 3);

			// Find place to generate explosion
			if (num == 1)
			{
				num = Q_irand( 8, 10);
				newBolt = trap->G2API_AddBolt( self->ghoul2, 0, va("*flash%d",num) );
				NPC_Mark1_Part_Explode(self,newBolt);
			}
			else
			{
				num = Q_irand( 1, 6);
				newBolt = trap->G2API_AddBolt( self->ghoul2, 0, va("*torso_tube%d",num) );
				NPC_Mark1_Part_Explode(self,newBolt);
				NPC_SetSurfaceOnOff( self, va("torso_tube%d",num), TURN_OFF );
			}

			TIMER_Set( self, "dyingExplosion", Q_irand( 300, 1000 ) );
		}


//		int		dir;
//		vec3_t	right;

		// Shove to the side
//		AngleVectors( self->client->renderInfo.eyeAngles, NULL, right, NULL );
//		VectorMA( self->client->ps.velocity, -80, right, self->client->ps.velocity );

		// See which weapons are there
		// Randomly fire blaster
		if (!trap->G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "l_arm" ))	// Is the blaster still on the model?
		{
			if (Q_irand( 1, 5) == 1)
			{
				SaveNPCGlobals();
				SetNPCGlobals( self );
				Mark1Dead_FireBlaster();
				RestoreNPCGlobals();
			}
		}

		// Randomly fire rocket
		if (!trap->G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "r_arm" ))	// Is the rocket still on the model?
		{
			if (Q_irand( 1, 10) == 1)
			{
				SaveNPCGlobals();
				SetNPCGlobals( self );
				Mark1Dead_FireRocket();
				RestoreNPCGlobals();
			}
		}
	}

}

/*
-------------------------
NPC_Mark1_Pain
- look at what was hit and see if it should be removed from the model.
-------------------------
*/
void NPC_Mark1_Pain(gentity_t *self, gentity_t *attacker, int damage)
{
	int newBolt,i,chance;
	int hitLoc = gPainHitLoc;

	NPC_Pain( self, attacker, damage );

	G_Sound( self, CHAN_AUTO, G_SoundIndex("sound/chars/mark1/misc/mark1_pain"));

	// Hit in the CHEST???
	if (hitLoc==HL_CHEST)
	{
		chance = Q_irand( 1, 4);

		if ((chance == 1) && (damage > 5))
		{
			NPC_SetAnim( self, SETANIM_BOTH, BOTH_PAIN1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
		}
	}
	// Hit in the left arm?
	else if ((hitLoc==HL_ARM_LT) && (self->locationDamage[HL_ARM_LT] > LEFT_ARM_HEALTH))
	{
		if (self->locationDamage[hitLoc] >= LEFT_ARM_HEALTH)	// Blow it up?
		{
			newBolt = trap->G2API_AddBolt( self->ghoul2, 0, "*flash3" );
			if ( newBolt != -1 )
			{
				NPC_Mark1_Part_Explode(self,newBolt);
			}

			NPC_SetSurfaceOnOff( self, "l_arm", TURN_OFF );
		}
	}
	// Hit in the right arm?
	else if ((hitLoc==HL_ARM_RT) && (self->locationDamage[HL_ARM_RT] > RIGHT_ARM_HEALTH))	// Blow it up?
	{
		if (self->locationDamage[hitLoc] >= RIGHT_ARM_HEALTH)
		{
			newBolt = trap->G2API_AddBolt( self->ghoul2, 0, "*flash4" );
			if ( newBolt != -1 )
			{
//				G_PlayEffect( "small_chunks", self->playerModel, self->genericBolt2, self->s.number);
				NPC_Mark1_Part_Explode( self, newBolt );
			}

			NPC_SetSurfaceOnOff( self, "r_arm", TURN_OFF );
		}
	}
	// Check ammo pods
	else
	{
		for (i=0;i<6;i++)
		{
			if ((hitLoc==HL_GENERIC1+i) && (self->locationDamage[HL_GENERIC1+i] > AMMO_POD_HEALTH))	// Blow it up?
			{
				if (self->locationDamage[hitLoc] >= AMMO_POD_HEALTH)
				{
					newBolt = trap->G2API_AddBolt( self->ghoul2, 0, va("*torso_tube%d",(i+1)) );
					if ( newBolt != -1 )
					{
						NPC_Mark1_Part_Explode(self,newBolt);
					}
					NPC_SetSurfaceOnOff( self, va("torso_tube%d",(i+1)), TURN_OFF );
					NPC_SetAnim( self, SETANIM_BOTH, BOTH_PAIN1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
					break;
				}
			}
		}
	}

	// Are both guns shot off?
	if ((trap->G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "l_arm" )>0) &&
		(trap->G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "r_arm" )>0))
	{
		G_Damage(self,NULL,NULL,NULL,NULL,self->health,0,MOD_UNKNOWN);
	}
}

/*
-------------------------
Mark1_Hunt
- look for enemy.
-------------------------`
*/
void Mark1_Hunt(void)
{

	if ( NPCS.NPCInfo->goalEntity == NULL )
	{
		NPCS.NPCInfo->goalEntity = NPCS.NPC->enemy;
	}

	NPC_FaceEnemy( qtrue );

	NPCS.NPCInfo->combatMove = qtrue;
	NPC_MoveToGoal( qtrue );
}

/*
-------------------------
Mark1_FireBlaster
- Shoot the left weapon, the multi-blaster
-------------------------
*/
void Mark1_FireBlaster(void)
{
	vec3_t	muzzle1,enemy_org1,delta1,angleToEnemy1;
	static	vec3_t	forward, vright, up;
//	static	vec3_t	muzzle;
	gentity_t	*missile;
	mdxaBone_t	boltMatrix;
	int			bolt;

	// Which muzzle to fire from?
	if ((NPCS.NPCInfo->localState <= LSTATE_FIRED0) || (NPCS.NPCInfo->localState == LSTATE_FIRED4))
	{
		NPCS.NPCInfo->localState = LSTATE_FIRED1;
		bolt = trap->G2API_AddBolt(NPCS.NPC->ghoul2, 0, "*flash1");
	}
	else if (NPCS.NPCInfo->localState == LSTATE_FIRED1)
	{
		NPCS.NPCInfo->localState = LSTATE_FIRED2;
		bolt = trap->G2API_AddBolt(NPCS.NPC->ghoul2, 0, "*flash2");
	}
	else if (NPCS.NPCInfo->localState == LSTATE_FIRED2)
	{
		NPCS.NPCInfo->localState = LSTATE_FIRED3;
		bolt = trap->G2API_AddBolt(NPCS.NPC->ghoul2, 0, "*flash3");
	}
	else
	{
		NPCS.NPCInfo->localState = LSTATE_FIRED4;
		bolt = trap->G2API_AddBolt(NPCS.NPC->ghoul2, 0, "*flash4");
	}

	trap->G2API_GetBoltMatrix( NPCS.NPC->ghoul2, 0,
				bolt,
				&boltMatrix, NPCS.NPC->r.currentAngles, NPCS.NPC->r.currentOrigin, level.time,
				NULL, NPCS.NPC->modelScale );

	BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, muzzle1 );

	if (NPCS.NPC->health)
	{
		CalcEntitySpot( NPCS.NPC->enemy, SPOT_HEAD, enemy_org1 );
		VectorSubtract (enemy_org1, muzzle1, delta1);
		vectoangles ( delta1, angleToEnemy1 );
		AngleVectors (angleToEnemy1, forward, vright, up);
	}
	else
	{
		AngleVectors (NPCS.NPC->r.currentAngles, forward, vright, up);
	}

	G_PlayEffectID( G_EffectIndex("bryar/muzzle_flash"), muzzle1, forward );

	G_Sound( NPCS.NPC, CHAN_AUTO, G_SoundIndex("sound/chars/mark1/misc/mark1_fire"));

	missile = CreateMissile( muzzle1, forward, 1600, 10000, NPCS.NPC, qfalse );

	missile->classname = "bryar_proj";
	missile->s.weapon = WP_BRYAR_PISTOL;

	missile->damage = 1;
	missile->dflags = DAMAGE_DEATH_KNOCKBACK;
	missile->methodOfDeath = MOD_BRYAR_PISTOL;
	missile->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER;

}

/*
-------------------------
Mark1_BlasterAttack
-------------------------
*/
void Mark1_BlasterAttack(qboolean advance )
{
	int chance;

	if ( TIMER_Done( NPCS.NPC, "attackDelay" ) )	// Attack?
	{
		chance = Q_irand( 1, 5);

		NPCS.NPCInfo->burstCount++;

		if (NPCS.NPCInfo->burstCount<3)	// Too few shots this burst?
		{
			chance = 2;				// Force it to keep firing.
		}
		else if (NPCS.NPCInfo->burstCount>12)	// Too many shots fired this burst?
		{
			NPCS.NPCInfo->burstCount = 0;
			chance = 1;				// Force it to stop firing.
		}

		// Stop firing.
		if (chance == 1)
		{
			NPCS.NPCInfo->burstCount = 0;
			TIMER_Set( NPCS.NPC, "attackDelay", Q_irand( 1000, 3000) );
			NPCS.NPC->client->ps.torsoTimer=0;						// Just in case the firing anim is running.
		}
		else
		{
			if (TIMER_Done( NPCS.NPC, "attackDelay2" ))	// Can't be shooting every frame.
			{
				TIMER_Set( NPCS.NPC, "attackDelay2", Q_irand( 50, 50) );
				Mark1_FireBlaster();
 				NPC_SetAnim( NPCS.NPC, SETANIM_BOTH, BOTH_ATTACK1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
			}
			return;
		}
	}
	else if (advance)
	{
		if ( NPCS.NPC->client->ps.torsoAnim == BOTH_ATTACK1 )
		{
			NPCS.NPC->client->ps.torsoTimer=0;						// Just in case the firing anim is running.
		}
		Mark1_Hunt();
	}
	else	// Make sure he's not firing.
	{
		if ( NPCS.NPC->client->ps.torsoAnim == BOTH_ATTACK1 )
		{
			NPCS.NPC->client->ps.torsoTimer=0;						// Just in case the firing anim is running.
		}
	}
}

/*
-------------------------
Mark1_FireRocket
-------------------------
*/
void Mark1_FireRocket(void)
{
	mdxaBone_t	boltMatrix;
	vec3_t	muzzle1,enemy_org1,delta1,angleToEnemy1;
	static	vec3_t	forward, vright, up;
	int bolt = trap->G2API_AddBolt(NPCS.NPC->ghoul2, 0, "*flash5");
	gentity_t *missile;

	int	damage	= 50;

	trap->G2API_GetBoltMatrix( NPCS.NPC->ghoul2, 0,
				bolt,
				&boltMatrix, NPCS.NPC->r.currentAngles, NPCS.NPC->r.currentOrigin, level.time,
				NULL, NPCS.NPC->modelScale );

	BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, muzzle1 );

//	G_PlayEffect( "blaster/muzzle_flash", muzzle1 );

	CalcEntitySpot( NPCS.NPC->enemy, SPOT_HEAD, enemy_org1 );
	VectorSubtract (enemy_org1, muzzle1, delta1);
	vectoangles ( delta1, angleToEnemy1 );
	AngleVectors (angleToEnemy1, forward, vright, up);

	G_Sound( NPCS.NPC, CHAN_AUTO, G_SoundIndex("sound/chars/mark1/misc/mark1_fire" ));

	missile = CreateMissile( muzzle1, forward, BOWCASTER_VELOCITY, 10000, NPCS.NPC, qfalse );

	missile->classname = "bowcaster_proj";
	missile->s.weapon = WP_BOWCASTER;

	VectorSet( missile->r.maxs, BOWCASTER_SIZE, BOWCASTER_SIZE, BOWCASTER_SIZE );
	VectorScale( missile->r.maxs, -1, missile->r.mins );

	missile->damage = damage;
	missile->dflags = DAMAGE_DEATH_KNOCKBACK;
	missile->methodOfDeath = MOD_ROCKET;
	missile->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER;
	missile->splashDamage = BOWCASTER_SPLASH_DAMAGE;
	missile->splashRadius = BOWCASTER_SPLASH_RADIUS;

	// we don't want it to bounce
	missile->bounceCount = 0;

}

/*
-------------------------
Mark1_RocketAttack
-------------------------
*/
void Mark1_RocketAttack( qboolean advance )
{
	if ( TIMER_Done( NPCS.NPC, "attackDelay" ) )	// Attack?
	{
		TIMER_Set( NPCS.NPC, "attackDelay", Q_irand( 1000, 3000) );
 		NPC_SetAnim( NPCS.NPC, SETANIM_TORSO, BOTH_ATTACK2, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
		Mark1_FireRocket();
	}
	else if (advance)
	{
		Mark1_Hunt();
	}
}

/*
-------------------------
Mark1_AttackDecision
-------------------------
*/
void Mark1_AttackDecision( void )
{
	int blasterTest,rocketTest;
	float		distance;
	distance_e	distRate;
	qboolean	visible;
	qboolean	advance;

	//randomly talk
	if ( TIMER_Done(NPCS.NPC,"patrolNoise") )
	{
		if (TIMER_Done(NPCS.NPC,"angerNoise"))
		{
//			G_Sound( NPC, G_SoundIndex(va("sound/chars/mark1/misc/talk%d.wav",	Q_irand(1, 4))));
			TIMER_Set( NPCS.NPC, "patrolNoise", Q_irand( 4000, 10000 ) );
		}
	}

	// Enemy is dead or he has no enemy.
	if ((NPCS.NPC->enemy->health<1) || ( NPC_CheckEnemyExt(qfalse) == qfalse ))
	{
		NPCS.NPC->enemy = NULL;
		return;
	}

	// Rate our distance to the target and visibility
	distance	= (int) DistanceHorizontalSquared( NPCS.NPC->r.currentOrigin, NPCS.NPC->enemy->r.currentOrigin );
	distRate	= ( distance > MIN_MELEE_RANGE_SQR ) ? DIST_LONG : DIST_MELEE;
	visible		= NPC_ClearLOS4( NPCS.NPC->enemy );
	advance		= (qboolean)(distance > MIN_DISTANCE_SQR);

	// If we cannot see our target, move to see it
	if ((!visible) || (!NPC_FaceEnemy(qtrue)))
	{
		Mark1_Hunt();
		return;
	}

	// See if the side weapons are there
	blasterTest = trap->G2API_GetSurfaceRenderStatus( NPCS.NPC->ghoul2, 0, "l_arm" );
	rocketTest = trap->G2API_GetSurfaceRenderStatus( NPCS.NPC->ghoul2, 0, "r_arm" );

	// It has both side weapons
	if (!blasterTest  && !rocketTest)
	{
		;	// So do nothing.
	}
	else if (blasterTest!=-1
		&&blasterTest)
	{
		distRate = DIST_LONG;
	}
	else if (rocketTest!=-1
		&&rocketTest)
	{
		distRate = DIST_MELEE;
	}
	else	// It should never get here, but just in case
	{
		NPCS.NPC->health = 0;
		NPCS.NPC->client->ps.stats[STAT_HEALTH] = 0;
		//GEntity_DieFunc(NPC, NPC, NPC, 100, MOD_UNKNOWN);
		if (NPCS.NPC->die)
		{
			NPCS.NPC->die(NPCS.NPC, NPCS.NPC, NPCS.NPC, 100, MOD_UNKNOWN);
		}
	}

	// We can see enemy so shoot him if timers let you.
	NPC_FaceEnemy( qtrue );

	if (distRate == DIST_MELEE)
	{
		Mark1_BlasterAttack(advance);
	}
	else if (distRate == DIST_LONG)
	{
		Mark1_RocketAttack(advance);
	}
}

/*
-------------------------
Mark1_Patrol
-------------------------
*/
void Mark1_Patrol( void )
{
	if ( NPC_CheckPlayerTeamStealth() )
	{
		G_Sound( NPCS.NPC, CHAN_AUTO, G_SoundIndex("sound/chars/mark1/misc/mark1_wakeup"));
		NPC_UpdateAngles( qtrue, qtrue );
		return;
	}

	//If we have somewhere to go, then do that
	if (!NPCS.NPC->enemy)
	{
		if ( UpdateGoal() )
		{
			NPCS.ucmd.buttons |= BUTTON_WALKING;
			NPC_MoveToGoal( qtrue );
			NPC_UpdateAngles( qtrue, qtrue );
		}

		//randomly talk
//		if (TIMER_Done(NPC,"patrolNoise"))
//		{
//			G_Sound( NPC, G_SoundIndex(va("sound/chars/mark1/misc/talk%d.wav",	Q_irand(1, 4))));
//
//			TIMER_Set( NPC, "patrolNoise", Q_irand( 2000, 4000 ) );
//		}
	}

}


/*
-------------------------
NPC_BSMark1_Default
-------------------------
*/
void NPC_BSMark1_Default( void )
{
	//NPC->e_DieFunc = dieF_Mark1_die;

	if ( NPCS.NPC->enemy )
	{
		NPCS.NPCInfo->goalEntity = NPCS.NPC->enemy;
		Mark1_AttackDecision();
	}
	else if ( NPCS.NPCInfo->scriptFlags & SCF_LOOK_FOR_ENEMIES )
	{
		Mark1_Patrol();
	}
	else
	{
		Mark1_Idle();
	}
}
