Quake Style - Quake 3 Tutorials
Weapon Mods - Homing Rockets!!
Makes your rocket launcher shoot homing missiles! (UPDATED)

This tutorial has been updated and rewritten courtosey of Ukai Naoto, thankyou very much. --(nobody)

Please add one new line to end of fire_rocket function, like this:

	VectorCopy (dir, bolt->r.currentAngles);		// this is new line.
	return bolt;
}

This saves the angles of the rocket.
Also change these 2 lines in fire_rocket function:

	bolt->nextthink = level.time + 10000;
	bolt->think = G_ExplodeMissile;


To this new code:

	bolt->think = G_HomingMissile;
	bolt->nextthink = level.time + 60;


So, just above that function, insert a new function:

void G_HomingMissile( gentity_t *ent )
{
	gentity_t	*target = NULL;
	gentity_t	*blip = NULL;
	vec3_t  dir, blipdir, temp_dir;

	while ((blip = findradius(blip, ent->r.currentOrigin, 2000)) != NULL)	{
		if (blip->client==NULL)			continue;
		if (blip==ent->parent)			continue;
		if (blip->health<=0)			continue;
		if (blip->client->sess.sessionTeam == TEAM_SPECTATOR)
			continue;

		if ((g_gametype.integer == GT_TEAM || g_gametype.integer == GT_CTF) &&
			blip->client->sess.sessionTeam == ent->parent->client->sess.sessionTeam)
			continue;
		//in old code,this ent->parent->cliend-> was blip->parent->client->,
		//so didn't work in CTF and team deathmatch.Now it will work.

		if (!visible (ent, blip))
			continue;

		VectorSubtract(blip->r.currentOrigin, ent->r.currentOrigin, blipdir);
		blipdir[2] += 16;
		if ((target == NULL) || (VectorLength(blipdir) < VectorLength(dir)))
		{
			//if new target is the nearest
			VectorCopy(blipdir,temp_dir);
			VectorNormalize(temp_dir);
			VectorAdd(temp_dir,ent->r.currentAngles,temp_dir);	
			//now the longer temp_dir length is the more straight path for the rocket.
			if(VectorLength(temp_dir)>1.6)
			{	
				//if this 1.6 were smaller,the rocket also get to target the enemy on his back.
				target = blip;
				VectorCopy(blipdir, dir);
			}
		}
	}

	if (target == NULL)	{	
		ent->nextthink = level.time + 10000;
		// if once the rocket lose target,it will not search new enemy any more,and go away.
	} else {
		ent->s.pos.trTime=level.time;
		VectorCopy(ent->r.currentOrigin, ent->s.pos.trBase );
		//for exact trajectory calculation,set current point to base.
			
		VectorNormalize(dir);
		VectorScale(dir, 0.3,dir);
		VectorAdd(dir,ent->r.currentAngles,dir);
		// this 0.3 is swing rate.this value is cheap,I think.try 0.8 or 1.5.
		// if you want fastest swing,comment out these 3 lines.

		VectorNormalize(dir);
		VectorCopy(dir,ent->r.currentAngles);
		//locate nozzle to target

		VectorScale (dir,VectorLength(ent->s.pos.trDelta)*1.1,ent->s.pos.trDelta);
		//trDelta is actual vector for movement.Because the rockets slow down
		// when swing large angle,so accelalate them.

		SnapVector (ent->s.pos.trDelta);                      // save net bandwidth
		ent->nextthink = level.time + 100;	//decrease this value also makes fast swing.
	}
}



-- Credits:
   Tutorial by Ukai Naoto
   Return to QS Tutorials

-- Important:
   If you do use something from QuakeStyle in your mod, please give us credit.
   Our code is copyrighted, but we give permission to everyone to use it in any way they see fit, as long as we are recognized.