
Posted by WarZone (209.223.137.*) on February
06, 1999 at 15:02:42:
//========================================================================
void Homing_Think(edict_t *grenade) {
vec3_t dir, forward, right, up;
edict_t *ent = NULL;
edict_t *best = NULL;
float b_dist = 99999;
float dist = 0;
if (grenade->delay >
level.time)
return;
//pick the closest "enemy" or, keep the current one
/*
//uncomment this if you like
if (grenade->goalentity
&& grenade->goalentity->inuse &&
!grenade->goalentity->deadflag)
best =
grenade->goalentity;
else
*/
while ((ent = findradius (ent,
grenade->s.origin, 1500)) != NULL)
{
if (ent ==
grenade->owner)
continue;
if
(!ent->takedamage)
continue;
if (OnSameTeam(ent,
grenade->owner))
continue;
if (ent->deadflag == DEAD_DEAD)
continue;
if (!CanDamage
(grenade, ent))
continue;
VectorSubtract (ent->s.origin,
grenade->s.origin, dir);
dist = VectorLength
(dir);
if (dist < b_dist)
{
b_dist =
dist;
best =
ent;
}
}
grenade->goalentity = best;
if (grenade->goalentity)
{
// gi.dprintf
("targeting %s\n", grenade->goalentity->classname);
// Calculate some directional stuff..
VectorSubtract(grenade->goalentity->s.origin,
grenade->s.origin, dir);
vectoangles (dir, dir);
VectorCopy (dir,
grenade->s.angles);
VectorCopy (dir,
grenade->movedir);
AngleVectors(dir,
forward, right, up);
right[0] += 5 * crandom();
right[1] += 5 *
crandom();
right[2] = 0;
VectorNormalize(dir);
VectorMA(dir, 20 + 20 * random(), up,
grenade->velocity);
VectorMA(dir, 10 *
crandom(), right, grenade->velocity);
VectorMA(dir, 250,
forward, grenade->velocity);
//make it roll :)
VectorSet
(grenade->avelocity, 0, VectorLength (grenade->velocity), 0); // is that
the right axis??
grenade->groundentity = NULL;
}
else if (rand() % 20 == 0)
grenade->think
(grenade); // blow it up randomly if it can't find a target
}
//========================================================================
void Fire_Homing_Grenade (edict_t *self, vec3_t start, vec3_t aimdir, int
damage, int speed, float damage_radius)
{
edict_t *grenade;
vec3_t dir, forward, right, up;
vectoangles (aimdir, dir);
AngleVectors (dir, forward,
right, up);
grenade = G_Spawn();
grenade->owner = self;
grenade->activator = self;
grenade->goalentity = NULL; //
Targeted Player.
grenade->classname =
"hominggrenade";
VectorCopy (start,
grenade->s.origin);
grenade->s.origin[2] += 10;
VectorScale (aimdir, speed,
grenade->velocity);
VectorMA (grenade->velocity,
100 + random() * 30.0, up, grenade->velocity);
VectorMA (grenade->velocity,
crandom() * 10.0, right, grenade->velocity);
VectorSet (grenade->avelocity,
300, 300, 300);
grenade->movetype =
MOVETYPE_BOUNCE;
grenade->clipmask = MASK_SHOT;
grenade->solid = SOLID_BBOX;
grenade->s.effects |= EF_GRENADE;
VectorSet(grenade->mins, -3,
-3, -3);
VectorSet(grenade->maxs, 3, 3,
3);
grenade->s.modelindex =
gi.modelindex("models/objects/grenade2/tris.md2");
grenade->dmg = damage;
grenade->dmg_radius =
damage_radius;
grenade->spawnflags = 1;
grenade->s.sound =
gi.soundindex("world/airhiss1.wav");
grenade->delay = level.time + 1.5;
grenade->touch = Grenade_Touch;
grenade->prethink =
Homing_Think;
grenade->nextthink =
level.time + 10.0;
grenade->think = Grenade_Explode;
gi.linkentity(grenade);
}
Paste the above near the
top of g_weapon.c then paste the following line somewhere in your sorce. As a
test, you could also put this code at the top of the fire_grenade2() function
with a "return;" right afterward to turn all of your hand grenades
into homing grenades. Or, you might want to toggle the homing grenades via a
client command. Its up to you.
Fire_Homing_Grenade (player, start, aimdir, damage, 20, dmg_radius); // change the parameters as neccessary!
-- WarZone