Created By: dmgoober
Difficulty Scale Easy

Itching to start writing Quake .DLLís? Well, hereís a very quick primer on how to get started.

What you need to use this primer:
Visual C++ 4.0 or above
Quake 2 Source Files.
(This is available at:

General Setup

1. Start up Microsoft Developer Studio.
2. Choose "New" from the "File" menu.
3. The "New" dialog box will appear. Double click on "Project Workspace."
4.  The "New Project Workspace" dialog box will appear. Click on "Dynamic-Link Library" in the "Type" box. 
    Type in a name for your project in the "Name" box. 
   (To make life easier for you, you might want to name the project "gamex86". 
    If you do this, the .dll file generated by Visual C++ will be immediately usable by quake2. 
    However, whatever you do, do not overwrite the gamex86.dll already present in the baseq2 folder!!!)
5. Hit the create button. The new project workspace will open up.
6. Choose "Files into Project" from the "Insert" menu.
7. The "Insert Files into Project" dialog box will appear. 
   Change the directory to wherever you unzipped the Quake 2 Source Files. 
   Then change the directory to the folder "game."
8. Change the "Files of Type" field located at the bottom of the dialog box so that it reads "All Files (*.*)" 
   Holding down shift, select all of the files that appear in the "game" folder. Hit the "ADD" button.
9. Hit "F7." Visual C++ will compile the .dll.
10. If you named the project "gamex86" skip to step 11. If not, find the .dll generated by Visual C++ 
   (it will have the same name as your project) and rename it "gamex86.dll."
11. Create a new folder in the quake2 folder and name it "mygame."
12. Copy the new gamex86.dll into the "mygame" folder. 
    Do not overwrite the original gamex86.dll found in the "baseq2" folder.
13. Run "d:\quake2\quake2 +set game "mygame" +set deathmatch 1 +map base1"
14. The game will start paused. Hit escape, then start fragging!!!

Of course, these steps did not do anything to the code. 
What follows is a simple tutorial to make the rocket launcher fire two rockets instead of one.

1. Open the workspace you created above.
2. Open the "p_weapon.c" file. If you are curious, the "p_" stands for player. 
   All of the .c files that begin with p_ deal with player data. 
   "m_" is monster, "q_" is quake, and "g_" is game.
3. Find the function beginning with the line:
void Weapon_RocketLauncher_Fire (edict_t *ent)
Now, following the line:
fire_rocket (ent, start, forward, damage, 550, damage_radius, radius_damage);
Type or paste the following lines:
//my silly code
        ent->client->v_angle[0] += 25;
        AngleVectors (ent->client->v_angle, forward, right, NULL);
        VectorScale (forward, -2, ent->client->kick_origin);
        ent->client->kick_angles[0] = -1;

        VectorSet(offset, 8, 8, ent->viewheight-8);
        P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);
        fire_rocket (ent, start, forward, damage, 550, damage_radius, radius_damage);
        ent->client->v_angle[0] -= 25;
//end my silly code


Hit "F7", copy the .dll from the debug folder into the "mygame" folder, and run quake as listed above. 
Grab the R/L and give it a try. 

If you are observant, all that you just did was retype the existing firing code, but added the lines:
ent->client->v_angle[0] += 15; and ent->client->v_angle[0] -= 15; 
Basically, you have instructed the function to fire two
rockets, but one of them is 15 degrees off from the other one. 
Have some fun. The most obvious edit that can be
made is to change the line damage = 100 + (int)(random() * 20.0) 
Make the 100 into something like 300 to triple the
power of the RL. 

Ok, what follows is semi-nerd speech. 
Ok, v_angle is a member of the client structure which is a member of the entity structure.
V_angle is of type vec3_t. vec3_t is basically just an array of three floating point values. 
Often vec3_t is used as a vector, but this time it is used as a set of angles. 
V_angle[0] is the angle of the pitch of where your gun is aiming. Basically, it says where your gun is pointing up or down. 
V_angle[1] is an angle describing where your gun is point left and right. V_angle[2] is odd, because it doesnít seem to represent anything. 
Since all shots originate from the player, 2 angles are all that is needed to describe the shot. 
I might just be missing something. Donít forget that "->" represents indirection in structures. 
Since v_angle is an array pointer, we must use "[]" notation for the += 15 to be effective. 

More later.