Grenades from Heaven


Posted by Maj.Bitch (24.95.222.*) at 4:59 AM, 5/11/2001:


Here is an addition to your mod which will definitely have players running for cover!

What it does:

At the start of the level, a sky entity is created (in a manner similar to the Earthquake Generator Entity). Anyway, this skyent will continuously scan the locations of all the players in the game and make a quick check if there is sky directly above the player. If there is, then out of the clouds a single grenade (or more) will fall down directly on that position and bounce around, etc and explode like any other grenade. So, if somebody is standing still outside they better keep moving!! Else, kaboom!!

Great for maps with large outdoor areas with alot of campers hanging out..

Here it is:

Add these new routines to the bottom of your p_weapon.c file:


//============================================================
void spawn_grenades(vec3_t origin,int num) {
edict_t *grenade;
int j;

  for (j=1; j<=num; j++) {
    grenade=G_Spawn();
    grenade->owner=world;
    grenade->s.modelindex=gi.modelindex("models/objects/grenade/tris.md2");
    VectorCopy(origin,grenade->s.origin);
    VectorSet(grenade->velocity,0,0,-300);
    VectorSet(grenade->avelocity,200+crandom()*10.0,200+crandom()*10.0,200+crandom()*10.0);
    grenade->movetype=MOVETYPE_BOUNCE;
    grenade->classname="grenade";
    grenade->spawnflags=MOD_GRENADE;
    grenade->clipmask=MASK_SHOT;
    grenade->solid=SOLID_BBOX;
    grenade->s.effects|=EF_GRENADE;
    grenade->dmg=40;
    grenade->dmg_radius=120;
    VectorSet(grenade->mins,-8,-8,-8);
    VectorSet(grenade->maxs,+8,+8,+8);
    grenade->touch=Grenade_Touch;
    grenade->think=Grenade_Explode;
    grenade->nextthink=level.time + 2.5;
    gi.linkentity(grenade); }
}

//=====================================================
void FindPlayerWithSkyAbove(edict_t *skyent) {
vec3_t start,endpt;
edict_t *ent;
trace_t tr;
int i;

  for (i=1;i<=ga.maxclients;i++) {
    ent=&g_edicts[i];
    if (!G_ClientInGame(ent)) continue;
    if (!ent->groundentity) continue;
    VectorCopy(ent->s.origin,start);
    start[2]+=32;
    VectorCopy(start,endpt);
    endpt[2]=8192;
    tr=gi.trace(start,ent->mins,ent->maxs,endpt,ent,MASK_SHOT);
    if (!(tr.surface && (tr.surface->flags & SURF_SKY))) continue;
    tr.endpos[2]-=32;
    spawn_grenades(tr.endpos,1); } // drop 1 grenade on this location

  skyent->nextthink=level.time + 1.0; // seek again in 1 sec
}

//=====================================================
void InitSkyEntity(void) {
edict_t *skyent;
  skyent=G_Spawn();
  skyent->svflags|=SVF_NOCLIENT;
  skyent->think=FindPlayerWithSkyAbove;
  skyent->nextthink=level.time + 10.0; // start in 10 secs
  gi.linkentity(skyent);
}

Then, prototype the InitSkyEntity() function in one of your header files and add a call
to it at the bottom of SpawnEntities() like so:

   InitSkyEntity();

Then, at the start of each level, the sky entity will get set up and start seeking locations in the sky from which it can let grenades drop.

Also, feel free to adjust the think timers to what is appropriate for your particular mod
and remember, you can spawn any number of grenades you want by simply changing the number
in spawn_grenades() call.

Okay, That's it!!

Have fun!

Maj.Bitch