Permanent Haste

From ioquake3 wiki
Jump to: navigation, search

Tutorial 4 - Permanent Haste

By [sumfuka]


Ok, from now on we'll be learning more and more about the quake world. However you'll need some basic knowledge about coding in C. If you're a newbie C programmer, why not grab yourself a book on C programming ? Or even better, have a surf around - there are some great online resources available.

As luck would have it, there are some C-coding tutorials at our 'predecessor' site for quake2 coding (thanks, Puke !). Cruise by QDeveLS and have a read for yourself. There are heaps of tutorials for quake2 coding there also. Whilst you can't follow those tutorials for quake3 mod making, you might get some neat ideas by browsing through them.

Time to start coding again, "Innit".

How did they do that?

(As always, I assume you're ready to rock in MSVC and you are working in the quake3\mymod directory.)

Now, let's start with some Sherlock Holmes work... let's find out how a particular feature is implemented in the code base. Umm... erm... how about the Haste rune ? Ok. Let's do a "Find in Files" for 'Haste' (on the toolbar there is a little yellow folder icon with binoculars - use this if you like). The bottom pane of the screen will search thru all the source and header files for lines containing 'haste'. (you can enlarge this pane by dragging the top border upwards).

Searching for 'Haste'...
D:\q3\source\game\ai_chat.c(349):               bs->inventory[INVENTORY_HASTE] ||
D:\q3\source\game\ai_dmq3.c(564):       bs->inventory[INVENTORY_HASTE] =
bs->cur_ps.powerups[PW_HASTE] != 0;
D:\q3\source\game\bg_misc.c(536):/*QUAKED item_haste (.3 .3 1) (-16 -16 -16) (16 16 16)
suspended
D:\q3\source\game\bg_misc.c(539):               "item_haste",
D:\q3\source\game\bg_misc.c(540):               "sound/items/haste.wav",
D:\q3\source\game\bg_misc.c(541):        { "models/powerups/instant/haste.md3", 
D:\q3\source\game\bg_misc.c(542):               "models/powerups/instant/haste_ring.md3", 
D:\q3\source\game\bg_misc.c(544):/* icon */             "icons/haste",
D:\q3\source\game\bg_misc.c(548):               PW_HASTE,
D:\q3\source\game\bg_pmove.c(1568):     if ( pm->ps->powerups[PW_HASTE] ) {
D:\q3\source\game\bg_public.h(214):     PW_HASTE,
D:\q3\source\game\g_active.c(604):      if ( client->ps.powerups[PW_HASTE] ) {
D:\q3\source\game\inv.h(34):#define INVENTORY_HASTE                             29
D:\q3\source\game\inv.h(79):#define MODELINDEX_HASTE                    30
14 occurrence(s) have been found.

Ok, there is some interesting stuff in here. The bit that says "item_haste" probably defines the attributes for the Haste icon. In fact, the "models/powerups/instant/haste.md3" defines which model represents the Haste icon. Let's keep looking down... there are two lines that say if ( blah blah [PW_HASTE]). That's interesting, because the if statement is probably saying "if the player has the Haste rune then do something, else if not, do something else". Double click on this line (in the 'Find in Files 1' pane) :

D:\q3\source\game\g_active.c(604):     if ( client->ps.powerups[PW_HASTE] ) {

Bang, g_active.c should open in your editor window and line 604 will have a little marker next to it. You should see this :

       if ( client->ps.powerups[PW_HASTE] ) {
               client->ps.speed *= 1.3;
       }

Some C programming knowledge is required here : An if statement is always in the form "if ( this_is_true) { then_do_this_stuff; }". The "*=" operator means to multiply the thing on the left by the thing on the right. In other words, "multiply client->ps.speed by 1.3".

If we have a look up and down, we can see that this code segment is somewhere in the middle of the ClientThink_real function. We've just discovered the piece of code that makes you move faster when you have the haste rune! Additionally, we can see that you move exactly 30% faster than normal (they didn't tell us that in the manual). "Elementary, my dear Watson."

Let's make a change

Ok, let's give ourselves permanent haste. Modify the code at line 604 so that it looks like this :

       if ( qtrue ) {
               client->ps.speed *= 1.3;
       }

The bit that speeds us up (client->ps.speed *= 1.3;) is no longer executed 'only when the player has the Haste rune'. Because we have set the if condition to always be true (using the constant qtrue), the speedup is *always* executed, regardless of Haste runes. In other words : every player has permanent Haste. Compile it and have a bash with the bots !

Hint: don't play this mod for too long... you might get a little dizzy.


« Tutorial 3 - Hello, Qworld! | Tutorial 4 - Permanent Haste | Tutorial 5 - Armor Piercing Rails »