Coding Brand New Weapons in Quake

teaching how to add weapons to quake step by step.

Posted by on - Intermediate Weapons Modelling

Sniperz227 here and today i will be showing you how to code in multiple brand new weapons in quake. There is a lot of detail in this tutorial i try and explain the stuff as much as possible so that when your coding this stuff you know what your doing and you can play around with some stuff.

For this tutorial you should know the basics of quake.

Here we go:

Step one will be adding the gun into defs.qc. This should be your first step because you will be needing to use the gun float from defs.qc . SO go into defs .qc and find this section:

``````// items
float	IT_AXE					= 4096;
float	IT_SHOTGUN				= 1;
float	IT_SUPER_SHOTGUN		= 2;
float	IT_NAILGUN				= 4;
float	IT_SUPER_NAILGUN		= 8;
float	IT_ROCKET_LAUNCHER		= 32;
float	IT_LIGHTNING			= 64;
float	IT_EXTRA_WEAPON			= 128;``````

this is where all the weapons are stored. notice how the gun below any weapon is that numbered squared. Exemple IT_LIGHTNING is 64 and the gun after it is IT_EXTRA_WEAPON which is 128. When ever your add a certain type of float you always multiply the highest number there by itslef to get your next float number. For this tutorial im going to use the IT_ EXTRA_WEAPON slot. If you have already used up your IT_EXTRA_WEAPON slot and wanted to add another gun in you would take the highest number in defs.qc and multiply it by itself. So say the highest float number was 1000. Then the next gun you add the slot number would be 1000000. Get it yet? anyways enough ramling on to the work. so you can name your weapon anything aslong as it doesn't start with a number and make sure it is capital. I'll make mine IT_M4A1. so my code would look like:

``````// items
float	IT_AXE					= 4096;
float	IT_SHOTGUN				= 1;
float	IT_SUPER_SHOTGUN		= 2;
float	IT_NAILGUN				= 4;
float	IT_SUPER_NAILGUN		= 8;
float	IT_ROCKET_LAUNCHER		= 32;
float	IT_LIGHTNING			= 64;
float	IT_M4A1				= 128;``````

After your done that you will need to go into weapons.qc and find this section:

``````/*
================
W_FireSuperShotgun
================
*/
void() W_FireSuperShotgun =
{
local vector dir;

if (self.currentammo == 1)
{
W_FireShotgun ();
return;
}

sound (self ,CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM);

self.punchangle_x = -4;

self.currentammo = self.ammo_shells = self.ammo_shells - 2;
dir = aim (self, 100000);
FireBullets (14, dir, '0.14 0.08 0');
};
``````

this is where you are going to do most of the work. Now under that or anywhere in that section you will have to make your own. This is what my code looks like:

``````/*
==============
W_FireM4A1
==============
*/
void() W_FireM4A1 =
{
local vector dir;

sound(self, CHAN_WEAPON, "weapons/m4a1s.wav", 1, ATTN_NORM);

self.punchangle_x = -5;

self.currentammo = self.ammo_m4a1 =self.ammo_m4a1 -1;
dir = aim (self,100000);
FireBullets (1,dir,'0.06 0.08 0.9');
};``````

now i'll quickly summarize this. We have to make a function for the gun. It is using FireBullets.( not actual bullets of fire). So the function is void() W_FireM4A1. then you go down to the sound part. We're going to break it down now. self is the player. CHAN_WEAPON is the channel your using and obviously you would make it the weapon channel because this sound is for the weapon. The "weapons/m4a1s.wav" is where the sound file is located. IMPORTANT: you sound file must be a 16 or 8 bit mono file with 22400 for the frequency. the one is how loud it is so if you were at one end of the map and i was at the other and i shot it wouldn't be heard. ATTN_NORM is like the same thing the volume is normal so it can only be heard by those around.

The self.punchangle_x = -5; is the recoil. The next one you should edit to this. self.currentammo =self.ammo_(whatever you want it to be) = self.ammo_(whatever you want it to be). What this does is it takes 1 bullet out of your ammo you can change this by changing the number.. I chose self.ammo_m4a1 for my ammo inventory because my gun is an m4a1 so its reasonable. The reason mine is different is because i had to switch it for my reload code. so go ahead and name is self.ammo_whatever you want. im not sure what the next line is i just use it. Now let's break down the next one. FireBullets( what type of bullet you are using). The 1 is how many shots the gun fires in one click. So if i made mine 12 it would shoot 12 bullets in one shot. the dir is refering to the line above. now the next is a vector( if you know your basic qc you should know what this is. this vector is basically the accuracy of the gun. the lower you go the more accurate. So 0.1 is less accurate than 0.01. there's three because it's x,y,z axis. so you can play around with that. So thats your gun function basically. On to the next one.

Scroll to W_SetCurrentAmmo =

for this basically your putting in what your ammo is and where your model is. So my code looks like this add it and make the changes yoou need to make.

``````else if (self.weapon == IT_M4A1)
{
self.currentammo = self.ammo_m4a1;
self.weaponmodel = "progs/m4a1.mdl";
self.weaponframe = 0;
}``````

Breaking it down now. The start is saying if the weapon is self.weapon == IT_M4A1 ( the players gun is IT_M4A1) and then it list the following info. so the first line. self.currentammo =. I made it self.ammo_m4a1 because thats the ammo name i used for the previous functuon so you make it to what ever your ammo name is. The next one is the weapon model. It is showing where the model is located using strings. The next doesn't really matter in this tutorial.

Now that we're done that we'll move on to the next one. Go to W_ATTACK. and add the following and make your changes.

``````else if (self.weapon == IT_M4A1)
{
player_shot1();
W_FireM4A1();
self.attack_finished = time + 0.07;
}``````

Breaking down. So this code is saying if the players weapon is IT_M4A1(i told you we were going to use this a lot). Then it shows the following information for that gun. player_shot1(); is i believe some with animations but we're not learning about that yet so keep it like it is. The next one is calling the W_FireM4A1 function we made earlier. and self.attack_finished is the amount of time till you can shoot another bullet. so after 0.07 seconds i can shoot another bullet. if you made it 5 then that would mean when you shoot once you'd have to wait 5 seconds till you can shoot again.

Done with that and away we go to the next one. Go to W_ChangeWeapon. this is optional. here we are just going to make it so that when we hit 4 on the keyboard you get your weapon. I will also show other ways of getting your weapon without using this. So scroll down to the Nail gun one and change it to your weapon. So this is my code :

``````else if (self.impulse == 4)
{
fl = IT_M4A1;
if (self.ammo_m4a1 < 1)
am = 1;
}``````

Basically this is saying if you hit 4 chose IT_M4A1 if it's ammo is more than 1. So if its not empty.

scroll down to cheat command and add the gun in your inventory by doing this :

``````IT_AXE |
IT_SHOTGUN |
IT_SUPER_SHOTGUN |
IT_NAILGUN |
IT_M4A1|
IT_SUPER_NAILGUN |
IT_ROCKET_LAUNCHER |
IT_KEY1 | IT_KEY2;``````

fairly simple all i did was add my weapon in. scroll slightly down to W_CycleWeaponCommand. Here we're going to make it so that when you cycle through your weapons your gun is there. Here my code:

``````		if (self.weapon == IT_LIGHTNING)
{
self.weapon = IT_AXE;
}
else if (self.weapon == IT_AXE)
{
self.weapon = IT_SHOTGUN;
if (self.ammo_shells < 1)
am = 1;
}
else if (self.weapon == IT_SHOTGUN)
{
self.weapon = IT_SUPER_SHOTGUN;
if (self.ammo_shells < 2)
am = 1;
}
else if (self.weapon == IT_SUPER_SHOTGUN)
{
self.weapon = IT_M4A1;
if (self.ammo_m4a1 < 1)
am = 1;
}
else if (self.weapon == IT_NAILGUN)
{
self.weapon = IT_SUPER_NAILGUN;
if (self.ammo_nails < 2)
am = 1;
}
else if (self.weapon == IT_SUPER_NAILGUN)
{
if (self.ammo_rockets < 1)
am = 1;
}
{
self.weapon = IT_ROCKET_LAUNCHER;
if (self.ammo_rockets < 1)
am = 1;
}
else if (self.weapon == IT_ROCKET_LAUNCHER)
{
self.weapon = IT_LIGHTNING;
if (self.ammo_cells < 1)
am = 1;
}``````

In here i replaced the nailgun with my gun. So after super shot gun it should cycle to my m4a1 if it has more than 1 ammo. if you adding another gun just look at the patern and follow it. else if (self.weapon == IT_M4A1)
{
self.weapon = IT_WHATEVER YOUR GUN IS etc.. you get what i mean.
if you go down to the CycleWeaponReverseCommand you can do the same thing its just if you want to go chose previous weapons.

finally done in weapons.qc thats most the work now we're on the home strecth. Now if you compile and try your gun you will notice it wont work? well thats because that self.ammo_m4a1( or your ammo name) needs ammo! you need to define how much ammo self.ammo_m4a1 is going to hold. go into defs.qc again and quickly scroll to the very bottom and add this line.

``.float ammo_m4a1 ( or whatever your ammo name is).``

This is the float for the ammo so we can use it. Now go to client.qc and scroll to PutInClientServer. scroll to the bottom of that function and add this line

``````self.ammo_m4a1 = 120;
// m4a1 ammo inventory
``````

this gives the ammo_m4a1 float 120 bullets. you can change it to whatever you want. So now your gun has ammo the code is right and compiled well and you only have one more thing to do.

scroll up in till you find this

``````void() SetNewParms =
{
parm1 = IT_SHOTGUN | IT_AXE ;
parm2 = 100;
parm3 = 0;
parm4 = 25;
parm5 = 0;
parm6 = 0;
parm7 = 0;
parm8 = 1;
parm9 = 0;
};
``````

the top is the weapons you start every round with. So if you want you can put your weapon in there too by adding it :

``````	parm1 = IT_SHOTGUN | IT_AXE | IT_M4A1;
``````

so now when you start a new round your weapon should be in the starting weapons. If its not then you still can hit 4 and get it remember :)

last thing is precacheing you model and sound.

go to weapons.qc and at W_Precache put this line after the bottom

precache_sound ("weapons/m4a1s.wav"); // m4a1 shooting sound
precache_model ("progs/m4a1.mdl"); // m4a1 model

switch the directory to your proper model and sound names. this puts themodel in the game so that the engine can load them into the memory before the game starts. You have to do this for everything you put in whether it be a sprite,sound or model.

well now compile and put the progs.dat in the ID1 folder. And dont forget to put your model and sound in there folders.

Tips: when you make your model make sure the textures are 256x256. your model has to be textured. For the model to look right on quake the model's top view has to be top view it's front view has to be side view and side view has to be the front view .

The sound has to be a .wav 8 or 16 bit mono sound with 22400 frequency.

Sad face now the tutorial is over:(
but now you can successfully add a new weapon into quake.

It would work, but not very efficiently.

When you add a new entity field (such as the one to store the ammo amount) you add that entity field to all entities in your game whether they actually use it or not.

The only entity that will actually use that is the player.

Considering you want to be adding 20+ weapons with Alpha Team Six and it's for a system with limited RAM. I think there will be a significant impact.