Navigation

 Multiple Rockets Feature Type: Coding Tutorials     Added: 04/12  
  Author: Ic3p1ck 

Hi, welcome to my first tutorial here at q3center.com
This tutorial tells you step by step how to put in a toggleable command that allows you to shoot multiple rockets (with multiple ammo cost of course)

More than 1

The first thing we need to do with this is to create the trigger to turn multiple rocket fire on and off. To do this, open up g_local.h and under the LAST FL_ line you have, add this.


#define FL_SPREADROCKETS 0x00010000
// spread rockets ?

(of course, if the hex value 0x00010000 is already taken, you CAN use the next available one).

What we've done above is define a flag for using multiple rocket fire at once. We use this later to switch multiple rocket fire on and off.

Now we create the actual function to turn the flag on and off.

Open and g_cmds.c and find the function Cmd_Stats_f.
Directly UNDER that function (although it doesn’t matter too much where you put it) add the following function.


/*
=================
Cmd_MultipleRockets_f //Ic3p1ck
=================
*/
void Cmd_MultipleRockets_f( gentity_t *ent ) {

char *msg; // message to player

ent->flags ^= FL_SPREADROCKETS;

if (!(ent->flags & FL_SPREADROCKETS)) {
msg = "Multiple Rocket Fire OFFn";
}
else {
msg = "Multiple Rocket Fire ONn";
}

trap_SendServerCommand( ent-g_entities, va("print "%s"", msg));
}


All the above function does is switch the FL_SPREADROCKETS flag on and off, and print a message to the user saying what state the flag is in.

To let us access that function with a command, go to the bottom of g_cmds.c and find this
else if (Q_stricmp (cmd, "stats") == 0)
Cmd_Stats_f( ent );


Underneath that (although again it doesn’t matter too much where in the list you put it), add the following:

else if (Q_stricmp (cmd, "mrockets") == 0)
Cmd_MultipleRockets_f( ent );


Okay…. So now you have the flag FL_SPREADROCKETS, and you have a function to turn it on and off, but we haven’t used it yet.

Save your changes and close the current files (g_cmds.c and g_local.h)
Open up g_weapon.c and find the Weapon_RocketLauncher_Fire() function.

Replace that entire function with the one below.


void Weapon_RocketLauncher_Fire (gentity_t *ent) {
gentity_t *m;
gentity_t *client;
float newforward[] = {0,0,0};

m = fire_rocket (ent, muzzle, forward);
m->damage *= s_quadFactor;
m->splashDamage *= s_quadFactor;

if (ent->flags & FL_SPREADROCKETS) { //only think of firing more than one if spreadrocket
//flag is on.
if(ent->client->ps.ammo[WP_ROCKET_LAUNCHER] > 1) //check if we have enough ammo.
//for other 2 shots (first one gone).
{
//Second rocket goes to the right
AngleVectors( ent->client->ps.viewangles, forward, right, up );
VectorCopy( forward, newforward );
if ( forward[0] >= 0.5 && forward[0] <= 1 ) {
newforward[1] += .35;
} else if ( forward[0] <= -0.5 && forward[0] >= -1 ) {
newforward[1] += .35;
} else {
newforward[0] += .35;
}
VectorNormalize( newforward );
VectorAdd( newforward, forward, forward );
CalcMuzzlePoint( ent, forward, right, up, muzzle );

m = fire_rocket (ent, muzzle, forward);
m->damage *= s_quadFactor;
m->splashDamage *= s_quadFactor;
ent->client->ps.ammo[WP_ROCKET_LAUNCHER] -= 1; //subtract the ammo for this shot.

//Third rocket goes to the left
AngleVectors (ent->client->ps.viewangles, forward, right, up);
VectorCopy( forward, newforward );
if ( forward[0] >= 0.5 && forward[0] <= 1 ) {
newforward[1] -= .35;
} else if ( forward[0] <= -0.5 && forward[0] >= -1 ) {
newforward[1] -= .35;
} else {
newforward[0] -= .35;
}
VectorNormalize( newforward );
VectorAdd( newforward, forward, forward );
CalcMuzzlePoint ( ent, forward, right, up, muzzle );

m = fire_rocket (ent, muzzle, forward);
m->damage *= s_quadFactor;
m->splashDamage *= s_quadFactor;
ent->client->ps.ammo[WP_ROCKET_LAUNCHER] -= 1; //subtract the ammo for this shot too.
}
}


// VectorAdd( m->s.pos.trDelta, ent->client->ps.velocity, m->s.pos.trDelta ); // "real" physics
}


“Okay”, you’re thinking… “that looks good and all, but what does it do?”. Well, being the nice guy I am… I’ll tell you. Firstly we start by defining several variables for use within the function. Then, as always, the first rocket is fired (this will NOT happen if there is no ammo… don’t worry). This means that if multiple rockets are toggled or not, the first rocket will always fire (which makes sense when you think about it, because we either want JUST the middle one to fire, or the middle one and the two side rockets, so either way the middle one must fire).

Before firing the second and third rockets, we do two more checks.
The first check "if (ent->flags & FL_SPREADROCKETS)” makes sure that FL_SPREADROCKETS flag is ON. If not, then we don’t want the second and third rockets to fire, so they wont. Then…. If FL_SPREADROCKETS is on, before firing the second and third rockets, we have to check that we have enough ammunition for them. "if(ent->client->ps.ammo[WP_ROCKET_LAUNCHER] > 1)" <- this checks for that. If the ammunition is less than 2, then we don’t have enough ammo, so we don’t proceed in firing the rockets (which would put our ammo to -1, giving us infinite rockets… a VERY bad thing you’ll agree I’m sure)

If both of the above check out ( i.e FL_SPREADROCKETS is on, and we have enough ammo ), then the two other rockets are fired. Don’t worry that they are done one at a time, the result is that they are both fired at the same time so far as is visible. Before each of the rockets is fired, their vectors are decided, the rockets are then fired along their decided vector, and the ammo for each is taken from the overall ammo amount (of rockets) you have.

That’s it!. You can compile. All you need to do now is bind a key to mrockets ( multiple rockets). Do this by opening the console and typing

/bind # mrockets

where # is the key you want to bind it to.
Now, when you press that key, it will toggle multiple rockets, and you can gib to your hearts content.

FOR THE DILIGENT AMONGST YOU: You may have noticed that if you have 2 rockets in total before firing (not enough to fire 3), then it only fires 1. This was deliberate. If you have 2 ammo, you get 2 shots with 1 rocket. It should be very easy, based on the code given, to make it so that you get 1 shot with 2 rockets, but I decided against putting this into the tutorial (gives you something to at least think about).

NOTE: Rocket jumping with this packs a real punch. I suggest trying it out on q3dm17. Grab the mega-health and the armour, go down to the BOTTOM level, put multiple rockets on, and rocket-jump. You can make it to the top platform with no trouble at all.

NOTE: This code is EASILY portable to other weapons. Feel free to use it on any or all weapons, might make for a fun mod.
ENJOY.

If you see any faults or any improvements in this code, e-mail me: ic3p1ck@q3center.com

(As always, if you use this code in a mod, please give me (Gavin Costello – Ic3p1ck) some credit in a text file with the mod, or a place in your end credits… (I would rather that you add my REAL name to the credits than the alias)... thanks)

Comments »



  Page 1

  Comments ( 0 )


  Features Index

  Home

Copyright © 2001 MGON International AB - Privacy statement