PAGE_CONTENT = other_viewer.php
Home > Other content > myfirstmod

Tutorial: My First Quake III Arena Mod

The next step is to make sure players spawn with the correct weapon. In normal, vanilla Quake 3, players spawn with both the Gauntlet and the Machinegun. In our mod we want players to spawn with the first weapon as defined by the g_weaponOrder cvars. To do this, we must head to the ClientSpawn function in the g_client.c file. This function spawns a client and sets it up correctly. If we scroll down in this function a bit, we find that at some point a number of properties are being set up:

    client->pers = saved;
    client->sess = savedSess;
    client->ps.ping = savedPing;
//  client->areabits = savedAreaBits;
    client->accuracy_hits = accuracy_hits;
    client->accuracy_shots = accuracy_shots;
    client->lastkilled_client = -1;

We wil add two lines to this:

	ProgressWeapon(ent, qtrue);
	weapon = GetWeapon(client->currentWeapon);

Because our ProgressWeapon function will find the very first weapon all by itself when we pass qtrue as reset argument, we can simply call this method and pass ent as first argument because that contains the client struct. After that, we'll retrieve the actual weapon number again using our GetWeapon() function because we need that value a couple of times later on in this function. Don't forget to declare the weapon variable at the top of this function.

Further down in this function you'll find the following code:

client->ps.stats[STAT_WEAPONS] = ( 1 << WP_MACHINEGUN );
if ( g_gametype.integer == GT_TEAM ) {
  client->ps.ammo[WP_MACHINEGUN] = 50;
} else {
  client->ps.ammo[WP_MACHINEGUN] = 100;
}

client->ps.stats[STAT_WEAPONS] |= ( 1 << WP_GAUNTLET );
client->ps.ammo[WP_GAUNTLET] = -1;
client->ps.ammo[WP_GRAPPLING_HOOK] = -1;

Lets go through it bit by bit. First it starts off by adding the machinegun to the players weapon inventory. We don't want this because we want to give the initial weapon whose value is currently stored in the weapon variable. So simply replace the WP_MACHINEGUN constant with the weapon variable. After that, the player is given MG ammo (based on the gametype), a gauntlet, infinite ammo for the gauntlet and infinite ammo for the grappling hook. All of these lines can simply be removed because we want none of this to happen. All that remains now is to give the player unlimited weapon for his current weapon and we're done. The lines shown above are now basically replaced by the following two lines:

client->ps.stats[STAT_WEAPONS] = (1 << weapon);	//give initial weapon to client
client->ps.ammo[weapon] = -1;	//unlimited ammo

There are a few more changes we need to make. Further down in the function you'll find this piece of code:

// force the base weapon up
client->ps.weapon = WP_MACHINEGUN;

Replace the WP_MACHINEGUN constant in that line with our weapon variable. The last bit of code we need to change in this function is where it selects the highest available weapon and activates it.

// select the highest weapon number available, after any
// spawn given items have fired
client->ps.weapon = 1;
for ( i = WP_NUM_WEAPONS - 1 ; i > 0 ; i-- ) {
  if ( client->ps.stats[STAT_WEAPONS] & ( 1 << i ) ) {
    client->ps.weapon = i;
    break;
  }
}

This whole piece of code makes sure that the highest available weapon is selected. In our case, this is always the weapon stored in the weapon variable, so we can simply remove all of this code and replace it with client->ps.weapon = weapon;

NEXT: Making a frag>>