<P>
@X0E<CENTER><FONT FRESNO>Programming in QuakeC<P></FONT></CENTER>
@X03<P><P>
First of all, b4 I start writing, <IMG DAMJAN16 ALGIN_RIGHT>I want 2 say that I really hate writing about 
this stuff, altrough I love programming 4 Quake. But the Big(little)Boss just 
wouldn't stop bugging me unless I would say I am going to write this article...
<P>
Ok, enough intro, lets get to the facts...
<P><P>
Ever since the great @X0ADOOM@X03 people started making their own levels, graphix and 
stuff (Ok... Actually it all started with @X0APUSH@X03.. That mind blowing game where U 
had to push boxes to the right places, remember?). ButT, that just wasn't enough. 
People wanted to change the behaviour of the game itself! I think the first game 
that used a script language was @X0ADuke3D@X03. But looking a those hierogliphs made me 
sick! Then there came @X0AQuake1@X03. COOL. @X0AThe king is dead (DooM), long live the Quake!@X03
<P>
I have to say that DooM is still and will B the legend and mother of all 3D games.
<P>
Sorry MinMax... 
<P>
At this point I will tell U about my first contact w/ Quake.. I first loaded the demo 
on to my computer... ButT, it didnt work q:(  My pooter was so.. so.. SLOW!!! 
It was a 486, but with the speed of a XT... Bwah.. So I got a negative taste of the 
game. At the "Bits and Fun" festival, some years ago (3 mayB?) I had the chance to 
play a @X0AMULTI-PLAYER DEATHMATCH GAMEEEEE!!!!@X03 It was a simple 8 pooter network and 
I threw some1 from his seat, so I coould join... The first thing I heard: "No 
changing keys!" Heh, screw U!! As I set up my DooM keys the killing could start. 
We played E1M7 (the Boss level of episode 1). I had fallen so deep into it!! Just after 
30 mins I had twice the frags the best after me had... WHOA!! I loved the game from 
this moment...   And here is where everything starts. I think all the best QuakeC programmers 
have to have an experience like this, so they would B so fired up in programing 4 a game! 
<P>
<P>
The legend of QuakeC programming is @X0ADave "Zoid" Kirsch@X03, the creator of the legendary 
Threewave Capture The Flag. Every1 looks up to him, exept the @X0AID@X03 guys (coz they hired him,
 so they wouldnt have to  q:) <P>
I think he realy started it all...<P> 
Well with QuakeC people really could make their own games... But if U can make something, 
make something usefull.. Something people will love to play!  Zoid had luck...
<P>
And also some other people...<P>
For example: Arena nad ClanArena. I love this two the most.. The @X0AHOOK@X03 add on.. I inplant this 
tool into every Quake mod source that I can get my hands on. Then lets don't 
4get the ClanRing and QWRing, and DM6 and King of the hill and more and more... <P>
There R many fun mods out there... ButT enough of this.
<P>
<P>
Let me tell U how Quake, or @X0AQuakeWorld@X03 works, so U'll understand me better..
@X0BQuake.exe@X03 is the engine and executor of @X0Bprogs.dat@X03. @X0BPak?.pak@X03 R the package files
in witch there R the grapx, soundz, modelz and stuff.. @X0BProgs.dat@X03 is the compiled 
version of your QuakeC mod... Usually the @X0Bprogs.dat@X03 is in the @X0Bpak0.pak@X03..
<P>
<P>
How do I start adding my changes?
<P>
The best thing is that U just change the source already available(original or already changed) 
and never start from scratch...
<P>
<P>
And where do I put my changes?<P>
Humm... Good1...
<P><P>
Lets look at the structure of the functions of QC.. They R called @X0BQUAKED@X03 
functions (QUAKED is a Quake level editor), wich R marked with three numbers and R called from the game, but 
heck, this ain't important...<P>
Those procedures get called at events.. The name tells U what they are for. <P>
For example: @X0BPowerUp_Touch@X03.. Well guess what this is for.. As far as 
I can remember the main procedures look like this:
<P><P>@X04
void () func_button;<P>
void () info_intermission;<P>
void () trigger_changelevel;<P>
void () info_player_start;<P>
void () info_player_start2;<P>
void () info_player_deathmatch;<P>
void () info_player_coop;<P>
void () func_door;<P>
void () func_door_secret;<P>
void () noclass;<P>
void () item_health;<P>
void () item_armor1;<P>
void () item_armor2;<P>
void () item_armorInv;<P>
void () weapon_supershotgun;<P>
void () weapon_nailgun;<P>
void () weapon_supernailgun;<P>
void () weapon_grenadelauncher;<P>
void () weapon_rocketlauncher;<P>
void () weapon_lightning;<P>
void () item_shells;<P>
void () item_spikes;<P>
void () item_rockets;<P>
void () item_cells;<P>
void () item_weapon;<P>
void () item_key1;<P>
void () item_key2;<P>
void () item_sigil;<P>
void () item_artifact_invulnerabibity;<P>
void () item_artifact_envirosuit;<P>
void () item_artifact_invisibility;<P>
void () item_artifact_super_damage;<P>
void () info_null;<P>
void () info_notnull;<P>
void () light;<P>
void () light_floro;<P>
void () light_florospark;<P>
void () light_globe;<P>
void () light_torch_small_walltorch;<P>
void () light_flame_large_yellow;<P>
void () light_flame_small_yellow;<P>
void () light_flame_small_white;<P>
void () misc_fireball;<P>
void () misc_explobox;<P>
void () misc_explobox2;<P>
void () trap_spikeshooter;<P>
void () trap_shooter;<P>
void () air_bubbles;<P>
void () func_wall;<P>
void () func_illusionary;<P>
void () func_episodegate;<P>
void () func_bossgate;<P>
void () ambient_suck_wind;<P>
void () ambient_drone;<P>
void () ambient_flouo_buzz;<P>
void () ambient_drip;<P>
void () ambient_comp_hum;<P>
void () ambient_thunder;<P>
void () ambient_light_buzz;<P>
void () ambient_swamp1;<P>
void () ambient_swamp2;<P>
void () func_plat;<P>
void () func_train;<P>
void () misc_teleporttrain;<P>
void () path_corner;<P>
void () trigger_multiple;<P>
void () trigger_once;<P>
void () trigger_ready;<P>
void () trigger_secret;<P>
void () trigger_counter;<P>
void () info_teleport_destination;<P>
void () trigger_teleport;<P>
void () trigger_setskill;<P>
void () trigger_onlyregistered;<P>
void () trigger_hurt;<P>
void () trigger_push;<P>
void () trigger_monster_jump;<P>
void () worldspawn;<P>
@X03
<P><P>
There R some other functions, built in! There:<P>
emm..<P>
There R just 2 many...<P>
Go look at the end of the @X0BDEFS.QC@X03 file for them.<P>
<P>
The third group of the functions R the required ones (from @X0BDEFC.QC@X03):<P>
@X04
void () main; (dont know what thiz 1's for...)<P>
void () StartFrame;<P>
void () PlayerPreThink;<P>
void () PlayerPostThink;<P>
void () ClientKill;<P>
void () ClientConnect;<P>
void () ClientPutInServer;<P>
void () ClientDisconnect;<P>
void () SetNewParms;<P>
void () SetChangeParms;<P>
@X03
<P>
These R most worth checking out...
<P>
<P>
And a quick word bout the entity type: @X0AIts cool!@X03 :)<P>
ok ok... The importiant ones:<P>
<P>
@X04
.vector origin;<P>
.vector velocity;<P>
.vector angles;<P>
.float effects;<P>
.void () touch;<P>
.void () use;<P>
.void () think; //@X0AIBER  USEFULL@X04.. QC is base on this 1<P>
.void () blocked;<P>
.float nextthink;   //sets the time when the think procedure wil B executed<P>
.float health;<P>
.float frags;<P>
.float weapon;<P>
.float ammo_shells, ammo_nails, ammo_rockets, ammo_cells;<P>
.float dead_flag;<P>
.float button0, butto1, button2;  //fire, use, jump<P>
.string netname; //name of the entety, "Zobo" or "Rocket Launcher" 
                 //or "Mega Healh"...<P>
.float teleport_time;<P>
.float water_level; //0=not in, 1=feet, 2=wast, 3=eyes<P>
.entity owner //imporiant 1.. usefull<P>
@X03
<P><P>
Ok.. enugh of this...<P>
Those .type get added in to the @X0BENTITY@X03 type, the main QC type...<P>
<P>
So much 'bout types...<P>
Oh, the main varabels.. Yep, that too...<P>
<P>@X04
entity self;   //tha @X0ABIG@X04 one<P>
entity other;<P>
entity world;  //the @X0ABIG BIG@X04 one<P>
float time;    //guess<P>
string mapname;<P>
float parm1, parm2, parm3, parm4, parm5, parm6, parm7, parm8, parm9, parm10;<P>
float parm11, parm12, parm13, parm14, parm15, parm16;<P>
.<P>
.<P>
.<P>
@X03<P>
I aint gonna write em all down.. TOO much of em...<P>
<P><P>
Now it would B time to tell @X0AU HOW TO START PROGRAMING@X03...<P>
Heh... I started with translating messages... Like that I got the idea in what 
order the procedures R runned.... It's easy and phun... If U don't know C, U'll 
have a hard time programing in QC... Sorry, can't teach U that...<P>

My first mod was the message of the day... Small, but whe I got it working I <P>
nearly had an orgasm.. Dont get anu ideas! I was using both hands.. @X0AFOR TYPiNG!!!@X03<P>

Here is the source... and instructions...<P>
<P><P>
@X09
//--- source stuff ------------------<P>
float MSG_HOWLONG = 3; //this is a const.. cant B changed.. 3 sec<P>
<P>
void() WriteMOTD;  //prototype<P>
<P>
void(entity myself) MOTD; // Prototype<P>
<P>
void(entity myself) MOTD =    //Message Of The Day<P>
{<P>
   local entity msg; //I'll Do it with an extra entity
                     //so U'll B more impressed q:)<P>
<P>
   msg.owner = myself; // so well know who to send to<P>
   msg.ltime = time + MSG_HOWLONG;   //ltime is used as a temp.... 
                                     //current time + 3sec<P>
   msg.nextthink = time + 1; //when the think will B executed<P>
   msg.think = WriteMOTD;   // at nextthink time WriteMOTD is called<P>
}; //dont forget this ;!!!<P>
<P>
void() WriteMOTD =<P>
{<P>
  centerprint(self.owner, "Hello all U out there!\nZobo is the best Quake fighter...\n     Hi mom...");<P>
  self.nextthink = time + 0.5; //self is equal to MSG now.. 
                               //and neds to refresh the centerprint,<P>
  self.think = WriteMOTD;      //We got to keep on refreshing (gave me a headache!)<P>
  if ( self.ltime < time )  //if the time is grater than 3s remove message<P>
  {<P>
    centerprint(self.owner, "\n"); //clear the screen, just in case....<P>
    remove(self);  //kill that MSG entity<P>
  }<P>
};<P>
//--- end source stuff --------------<P>
@X03<P>
@X0AVIOLA end!!@X03<P>
I sugesst U create a temp dir with a subdir @X0BQWSRC@X03 and copy all files from your 
@X0BQUAKE/QW/SRC@X03 into it... Then save that text above into the file @X0BMOTD.QC@X03 
and edit @X0BPROGS.SRC@X03.. There is the list of in what order the compiler should 
compile the files... Add the @X0BMOTD.QC@X03 just above the @X0BCLIENT.QC@X03... 
Then open the @X0BCLIENT.QC@X03 and find the "@X0Bvoid() ClientConnect =@X03" function...<P>
Heres how it looks like:<P>
<P>@X09
//--- source stuff ------------------<P>
void () ClientConnect =<P>
{<P>
  bprint (PRINT_HIGH, self.netname);<P>
  bprint (PRINT_HIGH, " entered the game\n");<P>
<P>
  MOTD (self); //Here.. @X0AADD THIZ!!!!@X09<P>
  .<P>
  .<P>
  .<P>
};<P>
//--- end source stuff --------------<P>
<P>@X03
now compile that stuff....<P>
(Get the whole @X0AQuake UTILS for WinSUX95@X03 at:<P>
@X0Bftp.idsoftware.com/idstuff/source/qutils.zip@X03<P>
U can get things for other patforms here too... But, if U R making levels, 
please use the modified @X0BVIS@X03.... The 1 that makes water transparent... 
If U R doing somethig like this U'll understand me, others, newermind...)<P>
<P>
Ok... the compiler did his work.. Hope no errors R in my code... If they R, @X0AFIX THEM!@X03 q:)))<P>
Wait.. ill check it myself...<P>
OK, it workz...<P>
<P>
Now, to explain:<P>
<P>
As we called the @X0BMOTD@X03 with the @X0BSELF@X03 param, the self pointed to the connected player - US! 
We had to save it in @X0BMYSELF@X03 coz we would loose the player entity, coz the 
SELF in the MOTD points to the @X0BClientConnect@X03... That is no the player... I think... 
Or mayB the self is empty, coz it wasent called from a @X0BTHINK@X03... ut no matter... 
I think in the first case we could replace the MYSELF in the MOTD with a 
@X0BSELF.OWNER@X03... But, I aint gonna brake my head bout this!...<P>
<P>
Ok.. U got a @X0BQWPROGS.DAT@X03 in the .. directory....  For easyer testing I'll tell U this... 
If U want to test this mod, U need a @X0BQWSV@X03, what I doubt that U have access to... 
Look in to your @X0BQUAKE/ID@X03 if U have a @X0BSRC@X03 dir there... If not, i' ll try to get it, U 
just mail me and I'll mail it back to you.. The procces is exactly the same... 
U'll get a @X0BPROGS.DAT@X03 in to your .. dir. Now go to your QUAKE dir and create 
MODT dir... copy the PROGS.DAT in to it and the nrun quake like this:<P>
@X0B(ql/win)quake -game motd +map dm1@X03<P>
Well, It the qme starts U should get that message on yer screen for bout 3 sec...<P>
<P>
<P>
I'll stop here... Gimme a replay and if the interest will B great enough I'll write<P>
some more about this topic...<P>
<P>
Thanx 4 reading, I know that I writen a lot of crap, but i just love to program in 
QC, and wanted to get it close to U to....<P>
<P>
C ya on the battle feald<P>
<FONT DECO>@X0B
<P>
      Zobo[BcW]<P>
         @X0C4<P>
SEPTiC PRODUCTiONS<P>
</FONT>

