----------------------
======================
QuakeC Tutorial Part I
======================
----------------------
Hello and welcome to the first part of this tutorial. In this tutorial I will attempt to describe to you the following things:

  * Compilation of QuakeC
  * Procedures (defining and calling)
  * Declaring variables
  * Sending a message to a player (client)

In my code clips (examples) anything with a couple of /'s infront of it is a comment (Note: This is also what Quake uses for comments. Another method of commenting things in Quake is to put /* at the begining of the comment and */ at the end.)
	Also, throughout the tutorial I use NB to tell you intersting tit-bits of information. I recommend you read them all.

Compilation of QuakeC
=====================

QuakeC can only be compiled by QCC(Quake C Compiler). QCC reads a file in the directory it is running in called "progs.src". The first line of progs.src is the output file and all files after that are input ones. The best plan is not to meddle with it unless you want to add your own files to the list. To compile the code just run QCC in the directory containing your patch. QCC will make a file called progs.dat which is the patch file (the one you distribute). It is likely that you have already met this file if you have run other peoples patches. You can run your patch in exactly the same way as you would other peoples.
	Another helpfull feature of QCC is that it reports errors in your code. It tells you the file and line number so you an debug it (A little note here about debugging - If it says 'Expected ";" found ...' then it most likely you missed the semicolon off the line before, not the one it says)

Procedures
==========

Procedures are the building blocks of QuakeC. If you have already browsed the original QC files then you will have seen it is made up of them.
	(Another little note for all you people out there - Anything declared outside a procedure is considered global and has effect all through the code)

Defining a procedure
--------------------

Defining a procedure is easy. It comes in the form of:

type(type name_of_parm1,type name_of_parm2, ...) name =
{
//Procedure stuff here
return name_of_variable_to_return;
};

Right, now I will step through what each bit does. The first 'type' is the type of variable a function returns. If it returns nothing the type is void. eg:
	void() name =

Other valid types are:
	entity - Has all the properties an object (eg the player or a monster) would possess.
	string - A string of any length (Basically some text)
	float - A number
	vector - Something with 3 values, x,y and z. Vectors are used for directions and positions.

The second bit, the 'parm1 as type, parm2 as type' bit is called the argument list or parameter list. It is the declarations for all the variables that are to be passed to the function when it is called. The type can be any of the types above apart from 'void'. If there are no parameters then leave the ()'s empty. The name_of_parm1 is the name of the variable to be passed to it. eg.
void(float test1) name=
	or
void(vector test2,entity monster) name =
	or just
void() name =

The last bit of the first line 'name =' is the name you are giving the procedure followed by an equals sign. The name can contain any number letters and underscores, NOT numbers or special characters.
The last bit in the declaration is the sqiggly brackets ('{' and '}') followed by a semicolon at the end. NOTE - YOU MUST HAVE THE SEMICOLON AT THE END OR IT WILL NOT WORK.
The return 'statement' at the end of the procedure (well almost the end - close enough to be the end) is only used if the type of the procedure is not void. It gives the variable to return the value of. (NB. the use of return without any name of varible to be returned will result in the premature exiting of the procedure (sometimes desired in certain situations)

Semicolons
----------
At this point it is probably sensible to describe the usage of the semicolon. The semicolon in QuakeC indicates the end of a line (it is possible to write it all on one line). If you are wondering why not every line has a semicolon it is because the lines have been split up to make it easier to read. Comments do not need semicolons as they are completely ignored in the compilation process.

Calling a procedure
-------------------
A procedure can only be called after it has be declared. It will only be declared if it defined before it is called (it is above it in the code) or it if declared before it is called. Declaring a function is the same as defining it but you miss out the last part and so it looks like this:
type(type name_of_parm1,type name_of_parm2, ...) name;
	(NB. Remember the semicolon)
Declaring occurs outside of the procedures (after the end of one and before the begining of the next)

To call a procedure you do one of 2 things depending on what it the type returned is.
If the type is void it looks like this:
	name (parm1,parm2, ...);
If the type is anything but void it looks like this:
	variable = name(parm1,parm2, ...);
(NB. the variable must be of the same type as the type returned by the procedure or you will get an error during compilation.)

Declaring variables
===================
Variables MUST be declared before they can be used. This includes all variables - global and local.
Variables can be declared in the following syntax (NB. Syntax is the general way something is used):
	type name;
If you wish to make a variable 'local' to a procedure you use the 	following syntax:
local type name;
A local variable is one that is lost when the procedure is finished. A global variable is one that is present thoughout the entire time Quake is running. Global variables are usually declared in defs.qc but you must be carefull where you put them. If you put them at the top Quake will not run the program.
	This is probably a good time to describe what defs.qc does. It defines the global variables as described above but it also defines the properties of entitys, the constant values (eg. movetypes) and declares the functions that are linked into the QuakeC from Quake (eg. the find procedure and the makevectors procedure). The variables at the top of def.qc are fixed and if you change them (as it says) you will completly muck everything up, so don't. Your global declarations should go after the const declarations (const declarations are described in a later tutorial). The const declarations are easy to find as they contain a lot of captials.

Float
-----
A float on its own is a number.
Most mathmatical operations can be carried out on a float. eg.:
count=count-1;
This would decrement the value in variable count by 1.

String
------
A string on its own is enclosed in speechmarks - ""
A string can be set. eg.:
string = "Hello";
or added to, eg.:
string=string+" and goodbye";

Vector
------
A vector on it own is 3 figures enclosed in apostrophies - ''
Most mathematical operation can also be carried out on a vector. eg:
direction=direction + '0 0 1'
The seperate parts of a vector can be used as floats by following the name with an _x or _y or _z. eg.:
direction_x=direction_x+1;

Entity
------
Entities have property consisting of floats,strings and vectors. These properties are refered to by putting a dot after the name and then putting the name of the property afterwards. eg.:
player.name = "James";
	In defs.qc the properties of all the entities are declared. They are declared by putting a full-stop before the declaration:
	.type name;
There is a special feature of this type. It can take the form of 'void(type parm1,type parm2, ...)' when the variable is to refer to a procedure but that is advanced stuff that will be covered in later tutorials.
eg.:
	.vector target;

Sending a message to a player
=============================
The procedure for sending messages to clients (players) is predefined in defs.qc and so there is no need to declare it. The sytax for the simple message in the console is:
sprint(entity_to_send_to,string_to_send);

'entity_to_send_to' is usually self but it could be other or something else entirly. The only condition is that it must be a client. The 'string_to_send' is the string(text) to send to the person.
eg.:
sprint(self,"Hello")

Self and other - the special entities
=====================================
Now is a good time to describe the special entities. The special entity 'self' is the most usefull. It refers to the entity that called the procedure (by pressing CTRL or SPACE or something). It is the one you are most likely to use.
The other special entity is 'other'. It is used when something touchs something else or shoots something else. It refers to the entity that touched or shot 'self'. It is used when you want to know who shot you.

time - the special float
========================
the variable time is very special. It refers to the current time in the game. It is used to calculate when things are finished. It is in seconds. Most uses of time are relative and therefore the actual time is irrelevent to most people. Here is an example:
self.nextthink = time+10;

Statements
==========
Calling the sprint procedure is an example of a statement. A statement is a line of code that does something. A set of statements makes up the inards of a procedure. Mathematical functions are also statements. It is combination of many statements in the game that make it do things.

End of Tutorial One
===================
Well thats it for the first tutorial. This tutorial really just explains what things are but hopefully some of the original code should start making sense. You can investigate how things are done by studying the original QC code. Some of it contains comments that tell you what is happening.

In the next tutorial
====================
In the next tutorial I will have:
	* Commented code for you to follow and try out
	* Conditional statements (if)
	* Loops (while)
	* What all the special entity properties do
and many more interesting NB's.

Credits
=======
This tutorial was written by James Bielby (aka [Griffin] Marine)
The latest tutorial should be available from
http://ourworld.compuserve.com/homepages/bielby
or from
http://www2.wildnet.co.uk/~shane/marine.htm