PlanetQuake | Code3Arena | Tutorials | << Prev | Tutorial 3 | Next >>


  • Home/News
  • ModSource
  • Compiling
  • Help!!!
  • Submission
  • Contributors
  • Staff
  • Downloads

    < Index >
    1. Mod making 101
    2. Up 'n running
    3. Hello, QWorld!
    4. Infinite Haste
    5. Armor Piercing Rails
    6. Bouncing Rockets
    7. Cloaking
    8. Ladders
    9. Favourite Server
    10. Flame Thrower
    11. Vortex Grenades
    12. Grapple
    13. Lightning Discharge
    14. Locational Damage
    15. Leg Shots
    16. Weapon Switching
    17. Scoreboard frag-rate
    18. Vortex Grenades II
    19. Vulnerable Missiles
    20. Creating Classes
    21. Scrolling Credits
    22. Weapon Dropping
    23. Anti-Gravity Boots
    24. HUD scoreboard
    25. Flashlight and laser
    26. Weapon Positioning
    27. Weapon Reloading
    28. Progressive Zooming
    29. Rotating Doors
    30. Beheading (headshot!)
    31. Alt Weapon Fire
    32. Popup Menus I
    33. Popup Menus II
    34. Cluster Grenades
    35. Homing Rockets
    36. Spreadfire Powerup
    37. Instagib gameplay
    38. Accelerating rockets
    39. Server only Instagib
    40. Advanced Grapple Hook
    41. Unlagging your mod

    < Index >
    1. Entities
    2. Vectors
    3. Good Coding
    4. Compilers I
    5. Compilers II
    6. UI Menu Primer I
    7. UI Menu Primer II
    8. UI Menu Primer III
    9. QVM Communication, Cvars, commands
    10. Metrowerks CodeWarrior
    11. 1.27g code, bugs, batch


  • Quake3 Files
  • Quake3 Forums
  • Q3A Editing Message Board
  • Quake3 Editing


  • SumFuka
  • Calrathan
  • HypoThermia
  • WarZone

    Site Design by:
    ICEmosis Design

    by SumFuka

    "Booyakasha !". Ok, now it's a pre-requisite that you're able to compile the qagamex86.dll - if you haven't managed that, then have a look at the previous tutorials.

    In this tutorial we're not actually going to print "Hello, qworld!" on the console (Boring!), we're going to modify the speed of rockets (as suggested in the id readme file). We're also going to learn a thing or two about rockets along the way. Now let's get into it.


    It's good to always keep a pristine copy of the original codebase. Imagine if you fuck up one of your source files (delete crucial lines, whatever), you'll need a backup right ? Rather than re-install Q3aGameSource.exe every time, let's keep quake3\source as our 'pristine' codebase. NEVER MAKE MODS in quake3\source !! We'll make mods in individual mod directories... let's start by creating quake3\mymod.

    Ok then, we simply copy quake3\source to quake3\mymod. Double click on quake3\mymod\q3agame.dsw - from now on, follow all the tutorials using this codebase (I made a shortcut to this .dsw file on my desktop). If you modified the "Output file name" setting correctly in the first tutorial, the .dll for mymod should compile to the quake3\mymod directory - compile the 'game' project and check this.

    Whenever we've finished messing around with a tutorial and want to refresh the codebase back to the original, simply copy quake3\source to quake3\mymod. You can have as many mod directories as you want... I often have more than one mod in progress at any one time... quake3\rail, quake3\cts, etc... your hard drive's the limit!


    Let's load up the quake3\mymod\q3agame.dsw project in MSVC. Maximize MSVC - you'll need all the real estate your desktop can give you. Make sure 'game' is the active project. Select "File View" on the left hand pane, and find the source file 'g_missile.c' in the tree. Double click on 'g_missile.c' - the source file should open up in the editor window.

    Go to line 362 (hit Ctrl+G for an easy shortcut) and find the fire_rocket function :

    fire_rocket blah
    gentity_t *fire_rocket (gentity_t *self, vec3_t start, vec3_t dir)
        gentity_t       *bolt;
        VectorNormalize (dir);
        bolt = G_Spawn();
        bolt->classname = "rocket";
        bolt->nextthink = level.time + 10000;
        bolt->think = G_ExplodeMissile;
        bolt->s.eType = ET_MISSILE;
        bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;
        bolt->s.weapon = WP_ROCKET_LAUNCHER;
        bolt->r.ownerNum = self->s.number;
        bolt->parent = self;
        bolt->damage = 100;
        bolt->splashDamage = 100;
        bolt->splashRadius = 120;
        bolt->methodOfDeath = MOD_ROCKET;
        bolt->splashMethodOfDeath = MOD_ROCKET_SPLASH;
        bolt->clipmask = MASK_SHOT;
        bolt->s.pos.trType = TR_LINEAR;
        bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME;   // move a bit
    on the very first frame
        VectorCopy( start, bolt->s.pos.trBase );
        VectorScale( dir, 900, bolt->s.pos.trDelta );
        SnapVector( bolt->s.pos.trDelta );                       // save net bandwidth
        VectorCopy (start, bolt->r.currentOrigin);
        return bolt;
    If you like, go and have a read thru our first article on quake entities...

    Back already ? Great ! Line 372 is creates a new entity (called bolt). The G_Spawn() function creates a 'blank' entity... then next job is to flesh out all the details (what sort of entity is it ? what are the characteristics ? etc). The next 20 or so lines of code define all this stuff.

    Line 373-375 define the bolt to be a "rocket", and it will 'think' again in 10 seconds (time is measured in 1000'ths of a second in the quake world, thus 10000 equates to 1 second). When the rocket 'thinks' it will call the function G_ExplodeMissile. In other words, if it hasn't touched anything already, our rocket will explode after 10 seconds. This prevents our rockets flying off into outer space forever.

    Neat, we've discovered something about the game from looking thru the code! Let's see what else we can figure out about rockets...

    We can see that the rocket deals 100 damage (direct OR splash), and that the splash damage radius is 120 units. Line 391 tells us that the rocket moves at a speed of 900 units/second. There's also a whole load of constants used in this function (constants are usually in CAPS)... we can guess what most of them mean. 'ET_MISSILE' for example means 'Entitry Type: Missile' (as opposed to an item or a player).


    Let's modify line 391 so that it looks like this :
        VectorScale( dir, 300, bolt->s.pos.trDelta );
    Hit F7 to compile our .dll. Fire up quake (Run "quake3\quake3.exe +set fs_game mymod +map q3dm1") and see if it worked - you rockets should be noticeably slower.

    Done! That's our first tutorial. Let's keep blazing onwards...

    PlanetQuake | Code3Arena | Tutorials | << Prev | Tutorial 3 | Next >>