Quake Style - Quake 3 Tutorials
Weapon Mods - Cluster Grenades!
Converts the grenade launcher so it fires cluster grenades.

Cluster grenades!

This tutorial will modify the existing grenade launcher so that when the grenade it fires explodes 4 more grenades will scatter in a circle around it.

Open up g_missile.c and go to about line 7 and add:
void G_ExplodeCluster( gentity_t *ent );
gentity_t *fire_clustergrenade (gentity_t *self, vec3_t start, vec3_t dir);

this will declare the functions we are going to add.

At about line 169 add the following just before G_ExplodeMissile.
void G_ExplodeCluster( gentity_t *ent ) {
	vec3_t		dir;
	vec3_t		origin;

	vec3_t		grenade1;
	vec3_t		grenade2;
	vec3_t		grenade3;
	vec3_t		grenade4;

	BG_EvaluateTrajectory( &ent->s.pos, level.time, origin );
	SnapVector( origin );
	G_SetOrigin( ent, origin );

	// we don't have a valid direction, so just point straight up
	dir[0] = dir[1] = 0;
	dir[2] = 10;

	ent->s.eType = ET_GENERAL;
	G_AddEvent( ent, EV_MISSILE_MISS, DirToByte( dir ) );

	ent->freeAfterEvent = qtrue;

	// splash damage
	if ( ent->splashDamage ) {
		if( G_RadiusDamage( ent->r.currentOrigin, ent->parent, ent->splashDamage, ent->splashRadius, NULL
			, ent->splashMethodOfDeath ) ) {

	VectorSet(grenade1, 25, 25, 30);
	VectorSet(grenade2, -25, 25, 30);
	VectorSet(grenade3, 25, -25, 30);
	VectorSet(grenade4, -25, -25, 30);
	fire_clustergrenade (ent, origin, grenade1);
	fire_clustergrenade (ent, origin, grenade2);
	fire_clustergrenade (ent, origin, grenade3);
	fire_clustergrenade (ent, origin, grenade4);

	trap_LinkEntity( ent );

This is just a copy of G_ExplodeMissile except we added the function to fire the cluster grenades. We use VectorSet to set the direction each grenade travels at the first is the x coord, the next the y, and the last one is the z direction.

At around line 348 in the fire_grenade function change bolt->think = G_ExplodeMissile; to bolt->think = G_ExplodeCluster; so it will look somthing like this:

	bolt = G_Spawn();
	bolt->classname = "grenade";
	bolt->nextthink = level.time + 2500;
	// Gerbil!
	bolt->think = G_ExplodeCluster;

	bolt->s.eType = ET_MISSILE;
	bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;


This changes the explode function to the one we added that throws out the extra grenades.

After that at around line 375 add the fire_clustergrenade function which is basically a copy of fire_grenade, except with a few tweaks.
gentity_t *fire_clustergrenade (gentity_t *self, vec3_t start, vec3_t dir) {
	gentity_t	*bolt;

	VectorNormalize (dir);

	bolt = G_Spawn();
	bolt->classname = "grenade";
	bolt->nextthink = level.time + 2000;
	bolt->think = G_ExplodeMissile;
	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;		// move a bit on the very first frame
	VectorCopy( start, bolt->s.pos.trBase );

	//Gerbil!  lower the velocity from 700 to 400
	VectorScale( dir, 400, bolt->s.pos.trDelta );

	SnapVector( bolt->s.pos.trDelta );			// save net bandwidth

	VectorCopy (start, bolt->r.currentOrigin);

	return bolt;

This uses the origonal G_ExplodeMissile function so the cluster grenades shot out from the origonal one dont throw out more. The velocity at which they are thrown is also lowered so they wont travel as far.

So, we modified the fire_grenade function so that when the grenade launcher is fired and the grenade explodes it spawns four more around it instead of just blowing up. We copied the fire_grenade function to fire_grenadecluster so that the four grenades shot will just explode and not spawn four more grenades.
Just compile, run and fire a grenade and watch them go.

-- Credits:
   Tutorial by Gerbil!
   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.