This tut guides you through
the process of converting the grenade launchers grenades to be little
transportation balls( like UT's Translocator ) :) You can have 1 at a
time. After firing a grenade type in the console( or set a bind to it
) Open up g_local.h, we need to define G_ExplodeMissile so other files besides where it is defined( g_missile.c ) can use it. So find this: void G_AddPredictableEvent( gentity_t *ent, int event, int eventParm ); void G_AddEvent( gentity_t *ent, int event, int eventParm ); void G_SetOrigin( gentity_t *ent, vec3_t origin ); Up under those defines add this: void G_ExplodeMissile( gentity_t *ent ); And also we have to let quake3 now where to teleport them and if there is a spot set yet, so go find: qboolean botDelayBegin; Up under it add: vec3_t teleloc; int istelepoint; Now go into g_missile.c and find near the top: if ( ent->s.eFlags & EF_BOUNCE_HALF ) { VectorScale( ent->s.pos.trDelta, 0.65, ent->s.pos.trDelta ); // check for stop if ( trace->plane.normal[2] > 0.2 && VectorLength( ent->s.pos.trDelta ) < 40 ) { G_SetOrigin( ent, trace->endpos ); Add directly beneath it: ent->parent->istelepoint = 1; What that does is once the grenade stops, it lets quake3 know we have a spot to teleport to, then it adds 5 to the z coordinate on the grenades origin so that the player does not spawn in the ground, then it copies the grenades origing( after adding 5 to the z axis ) to the clients teleportation spot. Part of the players bounding box gets stuck in the ground if you don't add that/add less than 5, you get stuck in the ground. Its fun to add a 100 or so and go THUMP to the ground when you teleport. Now we need to edit some more stuff. Go find: /* ================= fire_grenade ================= */ Replace that little bit and its function below it with: void G_ExplodeGrenade( gentity_t *ent ) { ent->parent->istelepoint = 0; // client cannot teleport VectorClear( ent->parent->teleloc ); // clear the teleport location G_ExplodeMissile( ent ); } /* ================= fire_grenade ================= */ gentity_t *fire_grenade (gentity_t *self, vec3_t start, vec3_t dir) { gentity_t *bolt; VectorNormalize (dir); bolt = G_Spawn(); bolt->classname = "grenade"; bolt->nextthink = level.time + 30000; bolt->think = G_ExplodeGrenade; bolt->s.eType = ET_MISSILE; bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN; bolt->s.weapon = WP_GRENADE_LAUNCHER; bolt->s.eFlags = EF_BOUNCE_HALF; bolt->r.ownerNum = self->s.number; bolt->parent = self; bolt->damage = 100; bolt->splashDamage = 100; bolt->splashRadius = 150; bolt->methodOfDeath = MOD_GRENADE; bolt->splashMethodOfDeath = MOD_GRENADE_SPLASH; bolt->clipmask = MASK_SHOT; bolt->s.pos.trType = TR_GRAVITY; bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME; VectorCopy( start, bolt->s.pos.trBase ); VectorScale( dir, 700, bolt->s.pos.trDelta ); SnapVector( bolt->s.pos.trDelta ); // save net bandwidth VectorCopy (start, bolt->r.currentOrigin); return bolt; } Lemme explain what this
does. void weapon_grenadelauncher_fire (gentity_t *ent) { Replace it with this following code: void weapon_grenadelauncher_fire (gentity_t *ent) { gentity_t *m; gentity_t *grenades = NULL; while ((grenades = G_Find (grenades, FOFS(classname), "grenade")) != NULL) { if(grenades->r.ownerNum == ent->s.clientNum) //make sure its ours { ent->istelepoint = 0; // client cannot teleport VectorClear( ent->teleloc ); // clear the teleport location grenades->think = G_ExplodeMissile; grenades->nextthink = level.time; } } // extra vertical velocity forward[2] += 0.2; VectorNormalize( forward ); m = fire_grenade (ent, muzzle, forward); m->damage *= s_quadFactor; m->splashDamage *= s_quadFactor; } All that does is find any entities named "grenade" and then checks to see if its ours, if so it blows it up, then fires out our new one, so we can only have out 1 at a time. Now in g_cmds.c lets add our teleportation command. Right below the #include line(s) at the top of the file add: /* Then at the bottom of the file right up under: else if (Q_stricmp (cmd, "setviewpos") == 0) Add: else if (Q_stricmp (cmd, "telegren") == 0) There, we are done! Enjoy. I spend my time programming and writing these tutorials, so please feel free to use this code in your mod as long as www.inolen.com and the author receive credit. | |
Design Copyright inolen 2000 |