QuakeC from Scratch tutorials - Chapter 2: Let there be light...

Inside3D
 • Front Page
 • Articles
 • Downloads
 • Forums
 • Hosting
 • Help Wanted
 • Interviews
 • Reviews
 • Staff

 
Allied Sites
 - AI Cafe
 - Bot Epidemic
 - Dark Places
 - Flat Earth
 - FrikBot
 - Ghoulish Art
 - Kilbert3D
 - Quake Info Pool
 - QSG: Quake Standards
 - Rusted Fork
 - Stroggs Gone Mad
 - More...
 
Quake
 - Getting Started
 - QuakeC Specs v1.0
 - QuakeC Tutorials
 - Quake Mod Index
 
Quake II
 - Getting Started
 - dll Sourcecode
 - Coding Tutorials
 
.dll Central
 - Getting Started
 - Learning
 - dll Primer
 - dll in C
 - dll in Delphi
 - Compilers
 
Jedi Knight
 - Getting Started
 - COG Specs
 - Sound Specs
 - Tutorials
 
Level Editing
 - Tutorials/Tips
 
 
Telefragged!!!
Created By: Ender
eMail: ender@admdev.com
Difficulty Scale: Hard


In the last chapter, you loaded a map, and created a very simple entity to hold the player. You can now walk around a very bright and boring map.
What's missing? Well, a lot of things. Platforms, Triggers, Doors, Monsters.. Weapons. But two things, most noticably. No lights.. everything is really bright, so no shadows.
In this chapter, we take care of this, and create the lights.

As we are about to add in the light entities, one of the first things we need to do is remove the fake light entities from dummys.qc
Open up the file, and remove the following lines:

// Lights
void() light                    = {remove(self);};
void() light_fluoro             = {remove(self);};
void() light_fluorospark        = {remove(self);};
void() light_globe              = {remove(self);};
void() light_torch_small_walltorch = {remove(self);};
void() light_flame_large_yellow = {remove(self);};
void() light_flame_small_yellow = {remove(self);};
void() light_flame_small_white  = {remove(self);};
Next create a new file called 'internal.qc' in the 'Entities' directory.
This file will contain some generic routines that we will use fairly often throughout our entities. Instead of duplicating this code every time we need it (and as you will shortly see, it's a very useful piece of code, expecially for the lights).
Add this file (Entities/Internal.QC) into the progs.src file, after dummys.qc
As you would have noticed, all the default template files for Scratch have a header at the top of the file with a filename and description of the file.
Just to stay consistant, add the following lines to the beginning of internal.qc:

/*
+--------+
|Internal|
+--------+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
| Scratch                                      Http://www.admdev.com/scratch |
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
| Internal Entity Management stuff for Quake.                                |
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
*/
Next put the following subroutine in the file:

void(string modelname) Precache_Set = // Precache model, and set myself to it
{
 precache_model(modelname);
 setmodel(self, modelname);
};
This general purpose function will be used in most of the lights, and several other future entities.
It precaches 'modelname' then sets the model of entity 'self' to that model. As we always have to precache a model before loading it, this lets us precache models that will only be used for a certain entity. The other alternative is to precache all the models at the beginning of worldspawn, but if that particular model isn't used during the game, it will simply waste memory. Instead we will load models as we encounter entities that need them.
You've finished for this file at the moment, although you will add more code later. So for the time being, save and close Internal.QC
Next create a new files in the Entities directory. Call it 'Lights.QC', and add it into the progs.src after 'Internal.QC'.

This should be the contents of lights.qc:

/*
+------+
|Lights|
+------+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
| Scratch                                      Http://www.admdev.com/scratch |
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
| Spawns and handles Quake's lights and torches                              |
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
*/

float START_OFF = 1;                 // Light on/off spawnflag
void() Light_setup;                  // Definition from Lights.qc

void() light =                       // Basic Light
{
 Light_setup();                          // Setup Light
}; 

void() light_fluoro =                // Light with hum ambient
{
 Light_setup();                          // Setup Light
};

void() light_fluorospark =           // Light with buzz ambient
{
 Light_setup();                          // Setup Light
}; 

void() light_globe =                 // Light with visible globe
{
 Precache_Set("progs/s_light.spr");      // Set model
 makestatic(self);                       // Static entity. Never changes.
};

void() light_torch_small_walltorch = // Light with visible wall torch
{
 Precache_Set("progs/flame.mdl");        // Set model
 makestatic(self);                       // Static entity. Never changes.
};
                                      
void() light_flame_small_yellow =    // Light with small flame & fire sound
{                                        
 Precache_Set("progs/flame2.mdl");       // Set model
 makestatic(self);                       // Static entity. Never changes.
};

void() light_flame_large_yellow =    // Light with larger flame & fire sound
{
 Precache_Set("progs/flame2.mdl");       // Set model
 self.frame = 1;                         // Switch to second frame (large)
 makestatic(self);                       // Static entity. Never changes.
};

void() light_flame_small_white =     // Light with small flame & fire sound
{
 Precache_Set("progs/flame2.mdl");       // Set model
 makestatic(self);                       // Static entity. Never changes.
};
                       
void() Light_setup =   // Set light on or off, as per spawnflags
{
 if (self.style < 32) {return;} // Dont switch other styles.

 if (self.spawnflags & START_OFF)  
  lightstyle(self.style, "a");    // If light starts off, set it off.
 else
  lightstyle(self.style, "m");    // If light starts ON, turn in ON. Simple :)
};

void() LightStyles_setup =
{
 // Setup light animation tables. 'a' is total darkness, 'z' is maxbright.

lightstyle(0,"m");                                   // Style 0: Normal
lightstyle(1,"mmnmmommommnonmmonqnmmo");             // Style 1: Flicker
                                                     // Style 2: Slow Strong
                                                     //          Pulse
lightstyle(2,"abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba");
lightstyle(3,"mmmmmaaaaammmmmaaaaaabcdefgabcdefg");  // Style 3: Candle
lightstyle(4,"mamamamamama");                        // Style 4: Fast Strobe
lightstyle(5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj");    // Style 5: Gentle Pulse
lightstyle(6,"nmonqnmomnmomomno");                   // Style 6: Flicker 2
lightstyle(7,"mmmaaaabcdefgmmmmaaaammmaamm");        // Style 7: Candle 2
                                                     // Style 8: Candle 3
lightstyle(8,"mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa"); 
lightstyle(9,"aaaaaaaazzzzzzzz");                    // Style 9: Slow Strobe
lightstyle(10,"mmamammmmammamamaaamammma");          // Style 10: Fluro
                                                     // Style 11: Slow Pulse
                                                     //           (no black)
lightstyle(11,"abcdefghijklmnopqrrqponmlkjihgfedcba"); 
};
As you can see, we once again have a header. This file contains entity code for all the light entities we removed from dummys.qc, as well as several other functions required to handle lighting. However we havn't quite finished with adding lights, so save & close 'lights.qc', then open 'main.qc'.
Add the line
void() LightStyles_setup; // Entities/Lights.QC
near the top of main.qc, right after the header file.
Next alter worldspawn to look like
void() worldspawn = {precaches(); LightStyles_setup();};
Save and close this, compile and run. Congradulations! Assuming you didn't make any typos when making the files, your world should be loking a lot brighter (Or darker, as the case may be :). Add's a lot of atmosphere, doesn't it? You never quite realise what an effect lighting has on well designed levels, until it's missing.
But somethings still missing... it's too quiet... far too quiet.






The Inside3D content and design is copyrighted by the Inside3D team, and may not be re-produced or copied without proper consent. All rights reserved. Any work credited to any author not part of InsideQC is copyrighted by that author. If you have any feedback, suggestions or flames please send it in to the author. Inside3D is hosted by telefragged and the design was originated by project-9.