| Quake Style - Quake 3
Tutorials Weapon Mods - Homing Rockets!! Makes your rocket launcher shoot homing missiles! |
/*
=================
fire_rocket
=================
*/
gentity_t *fire_rocket (gentity_t *self, vec3_t start, vec3_t dir) {
gentity_t *bolt;
VectorNormalize (dir);
bolt = G_Spawn();
bolt->classname = "rocket";
bolt->nextthink = level.time + 10000;
bolt->think = G_ExplodeMissile;
bolt->nextthink = level.time + 60;
bolt->think = G_HomingMissile;
bolt->s.eType = ET_MISSILE;
bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;
bolt->s.weapon = WP_ROCKET_LAUNCHER;
bolt->r.ownerNum = self->s.number;
bolt->parent = self;
bolt->damage = 100;
bolt->splashDamage = 100;
bolt->splashRadius = 120;
bolt->methodOfDeath = MOD_ROCKET;
bolt->splashMethodOfDeath = MOD_ROCKET_SPLASH;
bolt->clipmask = MASK_SHOT;
bolt->s.pos.trType = TR_LINEAR;
bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME; // move a bit on the very first frame
VectorCopy( start, bolt->s.pos.trBase );
VectorScale( dir, 900, bolt->s.pos.trDelta );
SnapVector( bolt->s.pos.trDelta ); // save net bandwidth
VectorCopy (start, bolt->r.currentOrigin);
return bolt;
}
/*
================
G_HomingMissile
================
*/
void G_HomingMissile( gentity_t *ent )
{
gentity_t *target = NULL;
gentity_t *blip = NULL;
vec3_t dir, dir2, blipdir, start;
vec_t speed;
while ((blip = findradius(blip, ent->r.currentOrigin, 1000)) != NULL)
{
if (!blip->client)
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 == blip->parent->client->sess.sessionTeam)
continue;
if (!visible (ent, blip))
continue;
VectorSubtract(blip->r.currentOrigin, ent->r.currentOrigin, blipdir);
blipdir[2] += 16;
if ((target == NULL) || (VectorLength(blipdir) < VectorLength(dir)))
{
target = blip;
VectorCopy(blipdir, dir);
}
}
if (target != NULL)
{
VectorCopy( ent->r.currentOrigin, start );
VectorCopy( ent->r.currentAngles, dir2 );
// target acquired, nudge our direction toward it
VectorNormalize(dir);
VectorScale(dir, 0.4, dir);
VectorAdd(dir, dir2, dir);
VectorNormalize(dir);
VectorCopy ( start, ent->s.pos.trBase );
VectorScale ( dir, 100, ent->s.pos.trDelta );
SnapVector ( ent->s.pos.trDelta ); // save net bandwidth
VectorCopy ( start, ent->r.currentOrigin );
VectorCopy ( dir, ent->r.currentAngles );
}
ent->nextthink = level.time + 20;
}