/*
	++++++++++++++++++++++++++++++++
	+ DarkEye Guided Missile v0.03 +
	++++++++++++++++++++++++++++++++

	Author: Michael R. Bethany
		  aka Dark1 (dark1@microhouse.com)
		  http://www.microhouse.com/darkland
	
	Revision History:

	v0.03 19Sept96;
	 Changed name to DarkEye (shameless self promotion)
	 Fixed weapon cycling endless loop bug
	 Cleaned up, put in own .qc file
	 Fixed more repawn on player death problems

	v0.02 18Sept96;
	 Fixed some no respawn on player death problems.
	 Fixed refire rate.
	 Added player screen changes (made the view like a TV, kind of)
	 Kludged weapon cycling endless loop bug
	 Removed a really stupid bug on my part.
	
	v0.01 16Sept96;
	 Wow!  It works... kind of. Well not very well but...
	

	I received great beginning help by examining:

	Homing Missile v.005 by
	Lynx (briggsj@lurch.ball.com) &
	Dumont (pjsmith@ix.netcom.com)
       
	Which, in turn, was based on:
	Homing Missiles v.001
	by Vhold <vhold@netwizards.net> 
	http://netwizards.net/~vhold/

	Thanx guys.

	================
*/
void()   drk1_Aim_GMissile;

void() drk1_W_FireGMissile =
{
//	local   entity gmissile, mpuff; //why mpuff? not used?
	local   entity gmissile;

	//If not enough ammo for guided, try to fire the rocket launcher
      if (self.ammo_rockets < 5)
	{         
		self.drk1_wpn_type = 0;
		self.weapon = IT_ROCKET_LAUNCHER;
		W_FireRocket ();
		self.attack_finished = time + 0.8;
		return;
	}
	
	//Subtract ammo used
	self.currentammo = self.ammo_rockets = self.ammo_rockets - 5;
	
	//Make fire sound
	sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);

	//Create the gmissile
	gmissile = spawn ();
	gmissile.owner = self;
	gmissile.movetype = MOVETYPE_FLYMISSILE;
	gmissile.solid = SOLID_BBOX;
		
	// Aim the gmissile, and give it an intitial velocity    
	makevectors (self.v_angle);
	gmissile.velocity = aim(self, 400);
	gmissile.velocity = gmissile.velocity * 400;
	gmissile.angles = vectoangles(gmissile.velocity);
	
	//Tell the missile what to do if it touches something
	gmissile.touch = drk1_T_MissileTouch;

	//Fuel the rocket
	gmissile.drk1_gm_fuel = 20;

	//Put the missile in the world
	setmodel (gmissile, "progs/missile.mdl");
	setsize (gmissile, '0 0 0', '0 0 0');            
	setorigin (gmissile, self.origin + v_forward*8 + '0 0 16');

	//Make the user look thru the eyes of the rocket
	msg_entity = self;
  	WriteByte (MSG_ONE, SVC_SETVIEWPORT);
  	WriteEntity( MSG_ONE, gmissile);
	
	/* Set the users view to look like a little TV, kind of.
	//  This gets rid of the rocket launcher in the center
	//  of the screen, gives a better view to fly by,
	//  slows down the mouse (a very weak turn rate limiter),
	//  and helps the user differentiate between normal
	//  view and missile view.

	Note:	This could be done much better if I could read the
		console variables of a client.  Need to figure out
		how to do that...
	*/
	stuffcmd(self, "crosshair 1\n");
	stuffcmd(self, "sensitivity 2\n");
	stuffcmd(self, "viewsize 70\n");
	stuffcmd(self, "fov 110\n");

	//Tell the missile what it uses for movement logic
	gmissile.nextthink = time + 0.1;
	gmissile.think = drk1_Aim_GMissile;
	gmissile.enemy = world;


};

void() drk1_T_MissileTouch =
{
	local float	damg;

	//This needs to be reset no matter what
	self.owner.drk1_gm_detonate = FALSE;

	//Reset the players view
	stuffcmd(self.owner, "crosshair 0\n");
	stuffcmd(self.owner, "sensitivity 5\n");
	stuffcmd(self.owner, "viewsize 100\n");
	stuffcmd(self.owner, "fov 90\n");
	
	//Only do this if the player isn't dead
	// This fixes one of the bugs where a player
	// wouldn't respawn if they were killed while
	// flying a missile.
	if (self.owner.health > 0)
	{
		//	reset the view
		msg_entity = self.owner;
  		WriteByte (MSG_ONE, SVC_SETVIEWPORT);
  		WriteEntity( MSG_ONE, self.owner);
		self.angles = '-1 -1 -1';
	}

	//Attack_Finished is not used until after the missile has exploded.
	// This allows us to use the fire button (whatever it is) to
	// detonate the missile.
	self.owner.attack_finished = time + 1.5;
	
	// If the gmissile hits the sky, remove it instead of doing damage
	if (pointcontents(self.origin) == CONTENT_SKY)
	{
		remove(self);
		//Reset the players view variables
		self.drk1_oldyaw = -256;
		return;
	}

	damg = 60 + random()*20;
	
	if (other.health)
	{
		if (other.classname == "monster_shambler")
			damg = damg * 0.5;	// mostly immune
		T_Damage (other, self, self.owner, damg );
	}

	// don't do radius damage to the other, because all the damage
	// was done in the impact
	T_RadiusDamage (self, self.owner, 120, other);

	sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
	self.origin = self.origin - 8*normalize(self.velocity);


	//Now just in case the variables were already set by the user
	stuffcmd(self.owner, "exec config.cfg\n");

	// I don't like it saying "execing config.sys", but
	// I like the cleared screen even less...
	// stuffcmd(self.owner, "clear\n");
	//
	// Will this move it up a line and get rid of it?
	stuffcmd(self.owner, "\n");

	//Make an explosion where the missile is
	WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
	WriteByte (MSG_BROADCAST, TE_EXPLOSION);
	WriteCoord (MSG_BROADCAST, self.origin_x);
	WriteCoord (MSG_BROADCAST, self.origin_y);
	WriteCoord (MSG_BROADCAST, self.origin_z);

	//Now free up the player to act...
	//
	//Player can't fire until 1.5 sec after missile exploded
	self.owner.attack_finished = time + 1.5;

	// Another fix for players not respawning
	if (self.owner.health > 0)
	{
		self.owner.nextthink = time;
		self.owner.think = player_run;
	}

	//Reset the players view variables
	self.drk1_oldyaw = -256;

	//Blow up the missile
	BecomeExplosion();

};

//This is where the missile thinks
void() drk1_Aim_GMissile =
{
	//If the missile has run out of fuel, the owner is dead, or the
	// missile has been detonated by the owner, blow the missile up
	if ((self.drk1_gm_fuel < 2) || (self.owner.health <= 1) || (self.owner.drk1_gm_detonate))
	{
		self.enemy = world;
		self.nextthink = time;
		self.think = drk1_T_MissileTouch;
	}

	//Find out which way the owner is facing, and go that way...
	// This could be much more elegant, and realistic, but hey! it works!
	//
	// I'd like to make the missile use true physics, like limiting the turn rate
	// based on the the velocity and new direction, next version...

	makevectors (self.owner.v_angle);
	self.velocity = aim(self, 400);
	self.velocity = self.velocity * 400;
	self.angles = vectoangles(self.velocity);
	self.drk1_gm_fuel = self.drk1_gm_fuel - 2;
	
	//This lets us create a virtually endless loop
	// without crashing server
	self.nextthink = time + 0.1;
	self.think = drk1_Aim_GMissile;

};

