Hosting and domain costs until October 2024 have been generously sponsored by dumptruck_ds. Thank you!

Difference between revisions of "QuakeC Globals"

From Quake Wiki

(QuakeC Manual 1.0)
 
m (World Globals)
 
(10 intermediate revisions by the same user not shown)
Line 1: Line 1:
QuakeC Manual 1.0
+
Globals are variables that aren't entity specific and can be accessed from anywhere at any time. Much like fields, they're broken down into system globals and QuakeC globals. Valid global data types include <code>string</code>, <code>vector</code>, <code>float</code>, and <code>entity</code>. Globals are declared via:
Copyright(C) 1996 by Ferrara Francesco (frank@aerre.it)
+
     datatype globalName;
________________________________________________________________________________
 
             
 
        Table of contents
 
       
 
1.      Introduction
 
        1.1    What is QuakeC
 
        1.2    Contributions
 
2.      QuakeC Language 
 
        2.1    Comments
 
        2.2    Names
 
        2.3    New types
 
        2.4    Definition of variables
 
        2.5    Definitions of constants
 
        2.6    Definitions of functions
 
        2.7    Function declaration
 
        2.8    Definition of a frame function
 
        2.9    Conditional construct
 
        2.10    Loop construct
 
        2.11    Function calls
 
        2.12    Logical operations
 
        2.13    Comparisons
 
        2.14    Operations on floats or integer
 
        2.15    Bitwise operations
 
3.      Builtin functions
 
        3.1    Basic math functions
 
        3.2    Basic vector maths
 
        3.3    Sound emission
 
        3.4    Entity management
 
        3.5    Move Entities
 
        3.6    Fights and Shots
 
        3.7    Collision checking
 
        3.8    Server related functions
 
        3.9    Print messages
 
        3.10    Console
 
        3.11    Debugging
 
        3.12    Precaching files
 
4.      Defines
 
        4.1    Values: temporary entities
 
        4.2    Values: Sound Channel of entities
 
        4.3    Values: Sound Attenuation
 
        4.4    Values: Contents of level areas
 
        4.5    Values: Entity light effects
 
        4.6    Values: Existing Items
 
        4.7    Values: Behavior of solid objects
 
        4.8    Values: Type of movements
 
        4.9    Values: Entity can solid take damage
 
        4.10    Values: Entity dead flag
 
        4.11    Values: Spawnflags
 
5.      Entities
 
6.     Model pragma
 
7.      Network protocol
 
8.      Network Builtin functions
 
9.      Tips & tricks
 
10.    Basic Types
 
11.    Compilation of QuakeC
 
12.    Execution of QuakeC
 
13.    Examples
 
        13.1    Looping between all monster
 
        13.2    Creating a new entities
 
        13.3    Setting point of view
 
        13.4    Teleporting
 
        13.5    Throwing your Eyes
 
        13.6    Radar
 
  
 +
System globals are globals defined within the engine itself and must be present for the game to work. These are always defined before anything else. The end of them is denoted by the <code>void end_sys_globals;</code> declaration. System globals must always be declared in the order defined within the vanilla QuakeC files as they are linked by memory offsets internally. Changing the order will break logic.
  
 +
QuakeC globals are standard globals that have no internal linkage and can be defined freely anywhere.
  
1. Introduction
+
Note that these are not stored between maps and will be reset upon changing levels.
________________________________________________________________________________
 
  
1.1 What is QuakeC?
+
== System Globals ==
 +
The following globals should be defined in the exact order of this list, otherwise memory offset errors can occur.
 +
*''entity'' '''self'''
 +
:The entity that the physics frame is currently processing.
 +
*''entity'' '''other'''
 +
:If a collision is occurring, this is the entity '''self''' is colliding with. This should only be used from <code>touch()</code> functions.
 +
*''entity'' '''world'''
 +
:The default world entity. This entity's fields cannot be written to directly and it is considered null in conditional checks.
 +
*''float'' '''time'''
 +
:The current game time in seconds.
 +
*''float'' '''frametime'''
 +
:The difference between the previous physics frame and the current one in seconds.
 +
*''float'' '''force_retouch'''
 +
:If greater than 0, relinks all entities into the world. Useful for getting entities to touch newly created triggers. This should be set to 2 to properly reset everything since setting it to 1 will only relink entities starting from the current '''self''' onward.
 +
*''string'' '''mapname'''
 +
:The name of the current map e.g. start, e2m1, etc.
 +
*''float'' '''deathmatch'''
 +
:If non-zero, PvP is enabled. If set to 2, uses the classic deathmatch rules.
 +
*''float'' '''coop'''
 +
:If non-zero, co-op is enabled.
 +
*''float'' '''teamplay'''
 +
:If non-zero while PvP is active, team PvP is enabled. If set to 1, friendly fire is disabled.
 +
*''float'' '''serverflags'''
 +
:Tracks the state of the game across the entire session. This doesn't get reset between level changes. The first 4 bits are reserved for the runes with each bit corresponding to its respective episode e.g. episode 1 is the first bit. If this is non-zero when going back to the start map, the player's inventory will be cleared.
 +
*''float'' '''total_secrets'''
 +
:The total secret count for the current map.
 +
*''float'' '''total_monsters'''
 +
:The total monster count for the current map.
 +
*''float'' '''found_secrets'''
 +
:How many secrets have been found in the current map.
 +
*''float'' '''killed_monsters'''
 +
:How many monsters have been killed in the current map.
 +
Parms store information about each player when moving between levels. Players have their own set of parms, but the globals act as an interface for setting them. These can be changed to however the modder wants to encode information, but below is how they're handled by default.
 +
*''float'' '''parm1'''
 +
:Stores the player's '''items''' field minus any keys and power ups.
 +
*''float'' '''parm2'''
 +
:Stores the player's health. This is capped between 50 and 100.
 +
*''float'' '''parm3'''
 +
:Stores the amount of armor the player has.
 +
*''float'' '''parm4'''
 +
:Stores the amount of shells the player has. This has a minimum amount of 25.
 +
*''float'' '''parm5'''
 +
:Stores the amount of nails the player has.
 +
*''float'' '''parm6'''
 +
:Stores the amount of rockets the player has.
 +
*''float'' '''parm7'''
 +
:Stores the amount of cells the player has.
 +
*''float'' '''parm8'''
 +
:Stores the player's '''weapon''' field.
 +
*''float'' '''parm9'''
 +
:Stores the player's armor damage reduction multiplied by 100 to give two decimal places of accuracy (decimal places beyond this get discarded).
 +
*''float'' '''parm10'''
 +
*''float'' '''parm11'''
 +
*''float'' '''parm12'''
 +
*''float'' '''parm13'''
 +
*''float'' '''parm14'''
 +
*''float'' '''parm15'''
 +
*''float'' '''parm16'''
 +
:Unused
 +
The following are used by <code>makevectors()</code> to store the local axes that the function generates from the passed angles.
 +
*''vector'' '''v_forward'''
 +
:The facing direction of the passed angles.
 +
*''vector'' '''v_up'''
 +
:The direction pointing 90 degrees up from the facing direction of the passed angles.
 +
*''vector'' '''v_right'''
 +
:The direction pointing 90 degrees to the right of the facing direction of the passed angles.
 +
The following are used by <code>traceline()</code> to pass information from the function to QuakeC.
 +
*''float'' '''trace_allsolid'''
 +
:If <code>TRUE</code>, the trace was stuck entirely in solids.
 +
*''float'' '''trace_startsolid'''
 +
:If <code>TRUE</code>, the trace started inside of a solid.
 +
*''float'' '''trace_fraction'''
 +
:The fraction of the total distance the trace traveled before stopping. Ranges from [0, 1].
 +
*''vector'' '''trace_endpos'''
 +
:The position the trace stopped.
 +
*''vector'' '''trace_plane_normal'''
 +
:The normal of the plane that the trace hit.
 +
*''float'' '''trace_plane_dist'''
 +
:The distance from the world origin of the plane that the trace hit. This is d in the plane equation ax + by + cz + d = 0.
 +
*''entity'' '''trace_ent'''
 +
:The entity that the trace hit.
 +
*''float'' '''trace_inopen'''
 +
:If <code>TRUE</code>, the trace traveled through open air.
 +
*''float'' '''trace_inwater'''
 +
:If <code>TRUE</code>, the trace traveled through a liquid.
 +
*''entity'' '''msg_entity'''
 +
:When sending a network message to a specific player via <code>MSG_ONE</code>, this is the player the message is sent to.
 +
Below are a special set of global functions the engine calls. These have no internal definitions so the function body must be defined somewhere in QuakeC to work. As such, their functionality is entirely customizable.
 +
*''void()'' '''main'''
 +
:Unused.
 +
*''void()'' '''StartFrame'''
 +
:Called at the start of every physics frame before anything else is processed.
 +
*''void()'' '''PlayerPreThink'''
 +
:Called before the player's physics is ran.
 +
*''void()'' '''PlayerPostThink'''
 +
:Called after the player's physics is ran.
 +
*''void()'' '''ClientKill'''
 +
:Called when the player kills themselves via the console command.
 +
*''void()'' '''ClientConnect'''
 +
:Called when a player joins the game, either for the first time or from changing levels.
 +
*''void()'' '''PutClientInServer'''
 +
:Called when a player is set to spawn or respawn.
 +
*''void()'' '''ClientDisconnect'''
 +
:Called when a player leaves the game, either from disconnecting or changing levels.
 +
*''void()'' '''SetNewParms'''
 +
:Sets the default parms for the player when they join the game for the first time or when respawning in deathmatch.
 +
*''void()'' '''SetChangeParms'''
 +
:Called when the player is about to change levels and their parms need to be set so they can be decoded when joining the new map.
  
        QuakeC is a language similar to C.  
+
== QuakeC Globals ==
        QuakeC can be compiled with qcc (Quake C compiler) to produce progs.dat a file that quake can load at startup. In that file Quake search the engines
+
These can be defined anywhere in any order. Since they can't be set from the map editor they're free to be changed and removed, but doing so may break saves so exercise caution. It may be better to just deprecate them to keep save compatibility.
  
for various things in the Quake World.
+
=== World Globals ===
        Monsters, player, buttons, weapons are the target of QuakeC, you cannot modify levels or graphics that you can modify with a external editor.
+
*''string'' '''string_null'''
        Major part of this document are copyright by Olivier Montanuy . All the informations contained in this document are related to Quake-C, a language
+
:Null string. This differs from empty strings in that it's not considered a valid string in conditional checks while empty strings are.
 +
*''float'' '''skill'''
 +
:The current difficulty of the map. Can be one of the following:
 +
:*<code>0</code> (Easy)
 +
:*<code>1</code> (Normal)
 +
:*<code>2</code> (Hard)
 +
:*<code>3</code> (Nightmare)
 +
*''float'' '''framecount'''
 +
:The total number of physics frames the server has processed.
 +
*''float'' '''gameover'''
 +
:If <code>TRUE</code>, the server is changing levels and players should not be considered fully disconnected.
 +
*''string'' '''nextmap'''
 +
:Stores the name of the next map to go to when changing levels e.g. start, e4m4, etc.
 +
*''float'' '''intermission_running'''
 +
:Stores the type of intermission cutscene currently being played. Can be one of the following:
 +
:*<code>1</code> (Stats screen)
 +
:*<code>2</code> (End of episode text crawl)
 +
:*<code>3</code> (All runes collected text crawl)
 +
*''float'' '''intermission_exittime'''
 +
:Stores the time stamp for when the intermission should end and change levels.
 +
*''entity'' '''lastspawn'''
 +
:Stores the last multiplayer spawn point found in order to cycle through them when spawning players in.
 +
*''entity'' '''bodyque_head'''
 +
:Stores a queue of entities to track player corpses. Tracks up to 4 corpses by default.
  
developed by and for idsoftware, so all those informations are copyright (c) 1996, id software.
+
=== Map Entity Globals ===
        To compile and use all this info you must have qcc.tar.gz take it from idsoftware. You can edit and than compile with qccdos (the compiler) all of
+
*''entity'' '''s'''
 +
:Tracks the last teleport fog entity that was spawned.
  
the qc files. You can rewrote all AI of the monster or create new entities.
+
=== General Entity Globals ===
        I have only converted, corrected and added some stuff.
+
*''entity'' '''activator'''
 +
:The entity that's considered the activator when calling <code>SUB_UseTargets()</code>.
 +
*''entity'' '''damage_attacker'''
 +
:The source of the attack when an entity takes damage.
 +
*''entity'' '''newmis'''
 +
:Set by <code>launch_spike()</code> to store the newly created projectile entity.
 +
*''entity'' '''multi_ent'''
 +
:When firing a shotgun attack, stores the entity that's currently being damaged by tracers.
 +
*''float'' '''multi_damage'''
 +
:When firing a shotgun attack, stores the total amount of damage to apply to '''multi_ent''' after the tracers are done or when hitting a different entity.
  
1.2 Contributions
+
=== Monster Entity Globals ===
 +
*''float'' '''movedist'''
 +
:When attempting to move, stores how far the current monster is trying to travel in map units.
 +
*''entity'' '''sight_entity'''
 +
:The monster that just woke up from finding a valid target. This is used so other monsters can see it and check to wake up themselves.
 +
*''float'' '''sight_entity_time'''
 +
:The time stamp for when the monster woke up from finding a valid target. In order for '''sight_entity''' to be valid other monsters must have seen it within 0.1 seconds.
 +
*''float'' '''enemy_vis'''
 +
:If <code>TRUE</code>, the current monster was able to see its enemy while chasing.
 +
*''float'' '''enemy_infront'''
 +
:If <code>TRUE</code>, the current monster's enemy was in front of the direction it's facing while chasing.
 +
*''float'' '''enemy_range'''
 +
:Determines how far away the current monster's enemy is while chasing. Can be one of the following:
 +
:*<code>RANGE_MELEE</code> (within 120 map units)
 +
:*<code>RANGE_NEAR</code> (within 500 map units)
 +
:*<code>RANGE_MID</code> (within 1000 map units)
 +
:*<code>RANGE_FAR</code> (1000+ map units)
 +
*''float'' '''enemy_yaw'''
 +
:The yaw that points towards the current monster's enemy while chasing.
 +
*''float'' '''hknight_type'''
 +
:Determines what type of melee attack Death Knights will perform. Can be one of the following:
 +
:*<code>0</code> (Slice attack)
 +
:*<code>1</code> (Overhead attack)
 +
:*<code>2</code> (Long combo slice attack)
 +
*''entity'' '''le1'''
 +
:When fighting Chthon, stores the first pillar that lowers in the lightning trap.
 +
*''entity'' '''le2'''
 +
:When fighting Chthon, stores the second pillar that lowers in the lightning trap.
 +
*''float'' '''lightning_end'''
 +
:When fighting Chthon, stores the time stamp for when the pillars in the lightning trap should raise back up after being activated.
 +
*''entity'' '''shub'''
 +
:Stores a pointer to Shub-Niggurath so the finale cutscene can play out correctly.
  
        Olivier Montanuy he is the real compiler of this document, I have rearranged it to a TXT version. Thanks Olivier.
+
=== Player Entity Globals ===
       
+
*''float'' '''modelindex_eyes'''
       
+
:Stores the model index in the cache for the eyes when the player is invisible.
2. QuakeC Language
+
*''float'' '''modelindex_player'''
________________________________________________________________________________
+
:Stores the model index in the cache for the player.
 
 
        Basic constructs of Quake-C
 
 
 
2.1 Comments
 
 
 
 
 
    // followed by comments, until the next line.
 
    /* enclose a block comments */
 
 
 
Those comments are the same as in C++ (and many C languages).
 
 
 
2.2 Names
 
 
 
Names of variable, fields, or functions have a maximum of 64 characters, must begin with A-Z,a-z, or _, and can continue with those characters or 0-9.
 
 
 
2.3 New types
 
 
 
You cannot define new types from the existing ones. In particular, you cannot define new structure, new objects, and you cannot affect a new name to a type
 
 
 
(as does typedef in C).
 
 
 
These restrictions make Quake-C compare unfavourably even to Basic, and sure it's about time the id software guys hired someone that already wrote a
 
 
 
compiler.
 
 
 
You can add only fields to the most important type in QuakeC entity.
 
 
 
2.4 Definition of variables
 
 
 
    type variable1, variable2;
 
    eg:
 
    float  a,b;
 
 
 
where type is one of the pre-defined simple types.
 
You can also affect default values to variables, for instance:
 
 
 
    type variable1 = value;
 
    eg:
 
    float a = 2;
 
 
 
Scoping of variables: There are two levels of scoping. By default all variables are global: they can be accessed by any functions, and they are shared by all
 
 
 
the functions (and all the clients of a given network server, of course).
 
 
 
But inside the functions, using the keyword local just before the declaration of a variable, you can make this variable visible only the function itself
 
 
 
(i.e. it will be allocated on the stack).
 
 
 
Note that parameters of a functions are treated like local variables, they are only visible to the function, but they can be modified.
 
 
 
2.5 Definitions of constants
 
 
 
Any global variable that is initialized by setting a value to it is actually assumed to be a constant.
 
 
 
Since a constant is in fact represented by immediate values, you should NEVER attempt to modify a constant by giving it another value. Otherwise the program
 
 
 
might not function correctly.
 
 
 
The constants are not saved to game files. Only regular variables are.
 
 
 
2.6 Definitions of functions
 
 
 
The general structure of a function definition is:
 
 
 
    type (type param1, typeparam2, ... ) function =
 
    {
 
      ... code ...
 
    };
 
 
 
Don't forget the ; after the brackets.
 
 
 
Here are some examples:
 
 
 
    void()      think = {...};
 
    entity()    FindTarget = {...};
 
    void(vector destination, float speed, void() callback)      SUB_CalcMove = {...};
 
 
 
2.7 Function declaration
 
 
 
If you want to use a function before defining it, you must declare it, otherwise the Quake-C compiler will not be able to use it.
 
 
 
The general structure of a function declaration is:
 
 
 
    type (type param1, typeparam2, ... ) function;
 
 
 
2.8 Definition of a frame function
 
 
 
Frame functions (also called States) are special functions made for convenience. They are meant to facilitate the definition of animation frames, by making
 
 
 
them more readable.
 
 
 
Here is an example:
 
 
 
    void() framename = [$framenum, nextthink] { ...code...};
 
 
 
It is strictly equivalent to:
 
 
 
    void() framename =
 
    {
 
      self.frame= $framenum;  // the model frame to displayed
 
      self.nextthink = time + 0.1;  // next frame happens in 1/10 of second
 
      self.think = nextthink; // the function to call at the next frame
 
      ...code...
 
    };
 
 
 
 
 
 
 
Controlling the flow of execution in Quake-C
 
 
 
2.9 Conditional construct
 
 
 
    if( expression )
 
    {
 
      statements
 
    }
 
    else
 
    {
 
      statements
 
    }
 
 
 
2.10 Loop construct
 
 
 
    while( expression )
 
    {
 
      statements
 
    }
 
 
 
or
 
 
 
    do
 
    {
 
      statements
 
    }while( expression )
 
 
 
2.11 Function calls
 
 
 
Call a function:
 
 
 
    function_name ( parameter1, parameter2,... )
 
 
 
The cannot be more than 8 parameters.
 
 
 
Return a value:
 
 
 
    return( expression )
 
 
 
2.12 Logical operations
 
 
 
    !  // logical not
 
    &&  // logical and
 
    ||  // logical or
 
 
 
Take care that in if() conditional expressions containing two or more logical clauses, all the clauses will be evaluated before the condition test (like in
 
 
 
Basic, and unlike C).
 
 
 
That means that if one part of your condition is not always valid or defined, you had better decompose your if() into two successive if(). It should also
 
 
 
make it faster.
 
 
 
2.13 Comparisons
 
 
 
    <=    <      >=    > 
 
    ==  // equal, beware at the double = like in C.
 
    !=  // not equal, like in C.
 
 
 
2.14 Operations on floats or integer
 
 
 
    * /  -  +
 
 
 
Use parenthesis to remove ambiguities.
 
 
 
2.15 Bitwise operations
 
 
 
    &  // bitwise and
 
    |  // bitwise or
 
 
 
These operators treat floats like integers, so they are usually meant to be used with values made of bit masks.
 
 
 
 
 
 
 
3. Builtin functions
 
________________________________________________________________________________
 
 
 
 
 
        These are the built-in functions of Quake C. Since they are hard-coded in C, they cannot be redefined, but they are very fast.
 
 
 
3.1 Basic math functions
 
 
 
Function: anglemod
 
 
 
        float anglemod (float angle)
 
        returns angle in degree, module 360.
 
 
 
Function: rint
 
 
        float rint(float val)
 
        Returns val, rounded up to the closest integer value.
 
 
 
Function: floor
 
 
 
        float floor(float val)
 
        Returns val, rounded up to the integer below (like the equivalent function in C).
 
 
 
Function: ceil
 
 
 
        float ceil(float val)
 
        Returns val, rounded up to the integer above (like the equivalent function in C).
 
 
 
Function: fabs
 
 
 
        float fabs(float val)
 
        Returns absolute value of val (like the equivalent function in C).
 
 
 
Function: random
 
       
 
        float random()
 
        Returns a random floating point number between 0.0 and 1.0.
 
 
 
Function: ftos
 
 
 
        string ftos(float value)
 
        Float to string: converts value to string.
 
 
 
3.2 Basic vector maths
 
 
 
Function: normalize
 
 
 
        vector normalize(vector v)
 
        returns a vector of length 1
 
        Gives the vector colinear to v, but of length 1. This can be useful for calculation of distance along an axis.
 
 
 
Function: vlen
 
 
 
        float vlen(vector v)
 
        Returns the length of vector v (never < 0).
 
 
 
Function: vectoyaw
 
 
 
        float vectoyaw(vector v)
 
        returns and angle in degree
 
        Vector to yaw: calculates the yaw angle (bearing) corresponding to a given 3D direction v.
 
 
 
Function: vectoangles
 
 
 
        vector vectoangles(vector v)
 
        returns vector 'pitch  yaw  0 '
 
        Vector to angles: calculates the pitch angle (aiming) and yaw angle (bearing) corresponding to a given 3D direction v.
 
 
 
Function: vtos
 
 
 
        string vtos(vector v)
 
        Vector to String: print a vector, as a string.
 
 
 
Function: makevectors
 
 
 
        void makevectors(vector angles)
 
        angle = 'pitch yaw 0'
 
        Calculate the vectors pointing forward, right and up, according to the provided angles.
 
        Returns result in the global variables:
 
        vector  v_forward;  // points forward
 
        vector  v_up;      // points up
 
        vector  v_right;    // points toward the right
 
 
 
3.3 Sound emission
 
 
 
Function: sound
 
 
 
        void sound (entity source, float channel, string sample, float volume, float attenuation)
 
          source = entity emiting the sound (ex: self)
 
          channel = channel to use for sound
 
          sample = name of the sample WAV file (ex: "ogre/ogdrag.wav")
 
          volume = 0.0 for low volume, 1.0 for maximum volume
 
          attenuation= attenuation of sound
 
        The entity emits a sound, on one of it's 8 channels.
 
 
 
Function: ambientsound
 
 
 
        void ambientsound(vector position, string sample, float volume, float attenuation)
 
          position = position, in 3D space, inside the level
 
          sample = name of the sample WAV file (ex: "ogre/ogdrag.wav")
 
          volume = 0.0 for low volume, 1.0 for maximum volume
 
          attenuation= attenuation of sound
 
        An ambient sound is emited, from the given position.
 
 
 
 
 
3.4 Entity management
 
 
 
Function: spawn
 
 
 
        entity spawn ()
 
        returns an empty entity.
 
        Create a new entity, totally empty. You can manually set every field, or just set the origin and call one of the existing entity setup functions.
 
 
 
Function: remove
 
 
 
        void remove (entity e)
 
        Removes entity e from the world (R.I.P.).
 
 
 
Function: makestatic
 
 
 
        void makestatic (entity e)
 
        Make an entity static to the world, by sending a broadcast message to the network. The entity is then removed from the list of dynamic entities in
 
 
 
the world, and it cannot be deleted (until the level ends).
 
 
 
Function: nextent
 
 
 
        entity nextent(entity e)
 
        Returns entity that is just after e in the entity list.
 
Useful to browse the list of entities, because it skips the undefined ones.
 
 
 
Function: find
 
 
 
        entity find (entity start, .string field, string match)
 
          start = begining of list to search (world, for the begining of list)
 
          field = entity field that must be examined (ex: targetname)
 
          match = value that must be matched (ex: other.target)
 
        returns the entity found, or world if no entity was found.
 
        Searches the server entity list beginning at start, looking for an entity that has entity.field = match.
 
 
 
        Example: find the first player entity
 
 
 
        e = find( world, classname, "player");
 
 
 
        Take care that field is a name of an entity field, without dot, and without quotes.
 
 
 
Function: findradius
 
 
 
        entity findradius (vector origin, float radius)
 
          origin = origin of sphere
 
          radius = radius of sphere
 
        Returns a chain of entities that have their origins within a spherical area. The entity returned is e, and the next in the chain is e.chain, until
 
 
 
e==FALSE. Typical usage: find and harm the victims of an explosion.
 
 
 
          e = findradius( origin, radius)
 
          while(e)
 
          {
 
            T_Damage(e, ... ) // Let God sort his ones!
 
            e = e.chain
 
          }
 
 
 
Function: setmodel
 
 
 
        void setmodel (entity e, string model)
 
          e = entity whose model is to be set
 
          model = name of the model (ex: "progs/soldier.mdl")
 
 
 
        Changes the model associated to an entity. This model should also be declared by precache_model. Please set e.movetype and e.solid first.
 
 
 
Function: lightstyle
 
 
 
        void lightstyle(float style, string value)
 
          style = index of the light style, from 0 to 63.
 
          value = (ex: "abcdefghijklmlkjihgfedcb")
 
 
 
        Modifies a given light style. The light style is used to create cyclic lighting effects, like torches or teleporter lighting. There are 64 light
 
 
 
tyles, from 0 to 63. If style is not strictly comprised in these values, the game may crash. Styles 32-62 are assigned by the light program for switchable
 
 
 
lights. Value is a set of characters, whose ascii value indicates a light level, from "a" (0) to "z" (30).
 
 
 
 
 
3.5 Move Entities
 
 
 
Function: ChangeYaw
 
 
 
        void ChangeYaw()
 
        Change the horizontal orientation of self. Turns towards self.ideal_yaw at self.yaw_speed, and sets the global variable current_yaw.
 
Called every 0.1 sec by monsters
 
 
 
Function: walkmove
 
 
 
        float walkmove(float yaw, float dist)
 
        returns TRUE or FALSE
 
        Moves self in the given direction.
 
Returns FALSE if could not move (used to detect blocked monsters).
 
 
 
Function: droptofloor
 
 
 
        float droptofloor()
 
        returns TRUE or FALSE
 
        Drops self to the floor, if the floor is less than -256 coordinates below. Returns TRUE if landed on floor. Mainly used to spawn items or walking
 
 
 
monsters on the floor.
 
 
 
Function: setorigin
 
 
 
        void setorigin (entity e, vector position)
 
          e = entity to be moved
 
          position = new position for the entity
 
        Move an entity to a given location. That function is to be used when spawning an entity or when teleporting it. This is the only valid way to move an
 
 
 
object without using the physics of the world (setting velocity and waiting). DO NOT change directly e.origin, otherwise internal links would be screwed, and
 
 
 
entity clipping would be messed up.
 
 
 
Function: setsize
 
 
 
        void setsize (entity e, vector min, vector max)
 
          e = entity whose bounding box is to be set 
 
          min = minimum, for bounding box (ex: VEC_HULL2_MIN)
 
          max = maximum, for bounding box (ex: VEC_HULL2_MAX)
 
        Set the size of the entity bounding box, relative to the entity origin. The size box is rotated by the current angle.
 
 
 
Function: movetogoal
 
 
 
        void movetogoal (float step)
 
 
 
        Move self toward it's goal.
 
        Used for monsters.
 
 
 
3.6 Fights and Shots
 
 
 
Function: aim
 
 
 
        vector aim(entity e, float missilespeed)
 
        Returns a vector along which the entity e can shoot.
 
Usually, e is a player, and the vector returned is calculated by auto-aiming to the closest enemy entity.
 
 
 
Function: particle
 
 
 
        void particle(vector origin, vector dir, float color, float count)
 
            origin = initial position
 
            dir = initial direction
 
            color = color index (73,75,
 
            count = time to live, in seconds
 
        Create a particle effect (small dot that flies away).
 
        color = 0  for chunk
 
        color = 75  for yellow
 
        color = 73  for blood red
 
        color = 225 for entity damage
 
 
 
Function: checkclient
 
 
 
        entity checkclient()
 
        Returns client (or object that has a client enemy) that would be a valid target. If there are more than one valid options, they are cycled each
 
 
 
frame.
 
If (self.origin + self.viewofs) is not in the PVS of the target, 0 (false) is returned.
 
 
 
 
 
3.7 Collision checking
 
 
 
Function: traceline
 
 
 
        traceline (vector v1, vector v2, float nomonsters, entity forent)
 
          v1= start of line
 
          v2= end of line
 
          nomonster= if TRUE, then see through other monsters, else FALSE.
 
          forent= ignore this entity, it's owner, and it's owned entities.
 
            if forent = world, then ignore no entity.
 
        Trace a line of sight, possibly ignoring monsters, and possibly ignoring the entity forent (usually, forent = self). This function is used very
 
 
 
often, tracing and shot targeting. Traces are blocked by bounding boxes and exact bsp entities. Returns the results in the global variables:
 
        float trace_allsolid;
 
          // never used
 
        float trace_startsolid;
 
          // never used
 
        float trace_fraction;
 
          // fraction (percent) of the line that was traced, before
 
          // an obstacle was hit. Equal to 1 if no obstacle were found.
 
        vector trace_endpos;
 
          // point where line ended or met an obstacle.
 
        vector trace_plane_normal;
 
          // direction vector of trace (?)
 
        float  trace_plane_dist; 
 
          // distance to impact along direction vector (?)
 
        entity trace_ent;     
 
          // entity hit by the line
 
        float  trace_inopen;
 
          // boolean, true if line went through non-water area.
 
        float  trace_inwater;
 
          // boolean, true if line went through water area.
 
 
 
Function: checkpos
 
 
 
        CURRENTLY DISABLED. DO NOT USE.
 
        scalar checkpos (entity e, vector position)
 
        Returns true if the given entity can move to the given position from it's current position by walking or rolling.
 
 
 
Function: checkbottom
 
 
 
        float checkbottom(entity e)
 
          e = entity that is to be checked
 
        return TRUE or FALSE
 
        Returns TRUE if on the ground. Used only for jumping monster, that need to jump randomly not to get hung up (or whatever it actually means).
 
 
 
Function: pointcontents
 
 
 
        float pointcontents(vector pos)
 
 
 
        Returns the contents of the area situated at position pos.
 
        Used to know if an area is in water, in slime or in lava.
 
        Makes use of the BSP tree, and is supposed to be very fast.
 
 
 
 
 
3.8 Server related functions
 
 
 
Function: changelevel
 
 
 
        void changelevel (string mapname)
 
        Warp to the game map named mapname. Actually executes the console command "changelevel" + mapname, so if you want to alias it...
 
 
 
Function: setspawnparms
 
 
 
        void setspawnparms (entity client)
 
        Restore the original spawn parameters of a client entity.
 
Doesn't work if client is not a player.
 
 
 
Function: stuffcmd
 
 
 
        stuffcmd (entity client, string text)
 
          client = player that is to receive the command
 
          text = text of the command, ended by \n (newline).
 
        Send a command to a given player, as if it had been typed on the player's console. Don't forget the \n (newline) at the end, otherwise your command
 
 
 
will not be executed, and will stand still on the console window.
 
 
 
        Examples:
 
       
 
          stuffcmd(self, "bf\n"); // create a flash of light on the        screen
 
          stuffcmd(self, "name Buddy\n"); // name the player Buddy
 
        Mostly used to send the command bf, that creates a flash of light on the client's screen.
 
 
 
3.9 Print messages
 
 
 
Function: bprint
 
 
 
        void bprint (string text)
 
          text = text of the message
 
        Broadcast a message to all players on the current server.
 
 
 
Function: centerprint
 
 
 
        void centerprint( entity client, string text)
 
          client = player that is to receive the message
 
          text = text of the message
 
        Sends a message to a specific player, and print it centered.
 
 
 
Function: sprint
 
 
 
        void sprint (entity client, string text)
 
          client = player that is to receive the message
 
          text = text of the message
 
        Sends a message to a player.
 
 
 
 
 
3.10 Console
 
 
 
Function: localcmd
 
 
 
        void localcmd (string text)
 
          text = text of the command, ended by \n (newline).
 
        Execute a command on the server, as if it had been typed on the server's console.
 
 
 
        Examples:
 
 
 
          localcmd("restart\n");      // restart the level
 
          localcmd("teamplay 1\n");  // set deathmatch mode to teamplay
 
          localcmd("killserver\n");  // poor server...
 
 
 
Function: dprint
 
 
 
        void dprint (string text)
 
          text = text of the message
 
        Prints a message to the server console.
 
 
 
Function: cvar
 
 
 
        float cvar (string variable)
 
          variable = see console variables
 
        returns the value of a console variable.
 
 
 
Function: cvar_set
 
 
 
        float cvar_set (string variable, string value)
 
          variable = see console variables
 
        sets the value of a console variable.
 
 
 
 
 
3.11 Debugging
 
 
 
Function: eprint
 
 
 
        void eprint (entity e)
 
          e = entity to print
 
        Print details about a given entity (for debug purposes).
 
 
 
Function: coredump
 
 
 
        void coredump()
 
        Print all entities
 
 
 
Function: traceon
 
 
 
        void traceon()
 
        Start tracing functions, end them with traceoff()
 
 
 
Function: traceoff
 
 
 
        void traceoff()
 
        End traces started by traceon()
 
 
 
Function: break
 
 
 
        void break()
 
        Exit the programs. Never used?
 
 
 
Function: error
 
 
 
        void error (string text)
 
        Print an error message.
 
 
 
Function: objerror
 
 
 
        void objerror (string text)
 
        Print an error message related to object self.
 
 
 
3.12 Precaching files
 
 
 
        Those functions are used to declare models, sounds and stuff, before the PAK file is built. Just follow this rule: whenever one of your functions
 
 
 
makes use of a file that's not defined in Quake, precache this file in a function that will be called by worldspawn(). Then, the QCC compiler can
 
 
 
automatically include in the PAK file all the files that you really need to run your programs.
 
        And when the level starts running, those precache orders will be executed, so as to attribute a fixed table index to all those files. DO NOT USE
 
 
 
those functions in code that will be called after worldspawn() was called. As
 
a matter of fact, that could bomb Quake (restarting the level, without crashing the game).
 
        Files can only be precached in spawn functions.
 
 
 
Function: precache_file
 
 
 
        void precache_file(string file)
 
          file = name of the file to include in PAK file.
 
        Does nothing during game play.
 
        Use precache_file2 for registered Quake.
 
 
 
Function: precache_model
 
 
 
        void precache_model(string file)
 
          file = name of the MDL or BSP file to include in PAK file.
 
        Does nothing during game play. Must be used in a model's spawn function, to declare the model file. Use precache_model2 for registered Quake.
 
 
 
Function: precache_sound
 
 
 
        void precache_sound(string file)
 
          file = name of the WAV file to include in PAK file.
 
        Does nothing during game play. Must be used in a model's spawn function, to declare the sound files. Use precache_sound2 for registered Quake.
 
 
 
 
 
 
 
4. Defines
 
________________________________________________________________________________
 
 
 
4.1 Values: temporary entities
 
 
 
Information copied from the DEM specifications
 
 
 
// point entity is a small point like entity.
 
0    TE_SPIKE          unknown
 
1    TE_SUPERSPIKE      superspike hits (spike traps)
 
2    TE_GUNSHOT        hit on the wall (Axe, Shotgun)
 
3    TE_EXPLOSION      grenade/missile explosion
 
4    TE_TAREXPLOSION    explosion of a tarbaby
 
7    TE_WIZSPIKE        wizard's hit
 
8    TE_KNIGHTSPIKE    hell knight's shot hit
 
10    TE_LAVASPLASH      Chthon awakes and falls dead
 
11    TE_TELEPORT        teleport end
 
// large entity is a 2 dimensional entity.
 
5    TE_LIGHTNING1      flash of the Shambler
 
6    TE_LIGHTNING2      flash of the Thunderbolt
 
9    TE_LIGHTNING3      flash in e1m7 to kill Chthon
 
 
 
4.2 Values: Sound Channel of entities
 
 
 
CHAN_AUTO = 0;  // Create a new sound
 
CHAN_WEAPON = 1; // Replace entitie's weapon noise
 
CHAN_VOICE = 2;  // Replace entitie's voice
 
CHAN_ITEM = 3;  // Replace entitie's item noise
 
CHAN_BODY = 4;  // Replace entitie's body noise
 
 
 
Those values are meant to be used with the function sound.
 
 
 
4.3 Values: Sound Attenuation
 
 
 
ATTN_NONE = 0;    // full volume everywhere in the leve
 
ATTN_NORM = 1;    // normal
 
ATTN_IDLE = 2;    // [FIXME]
 
ATTN_STATIC = 3;  // [FIXME]
 
 
 
Those values are meant to be used with the functions sound and ambientsound.
 
 
 
4.4 Values: Contents of level areas
 
 
 
CONTENT_EMPTY = -1;  // Empty area
 
CONTENT_SOLID = -2;  // Totally solid area (rock) 
 
CONTENT_WATER = -3;  // Pool of water
 
CONTENT_SLIME = -4;  // Pool of slime
 
CONTENT_LAVA = -5;    // Lava
 
CONTENT_SKY = -6;    // Sky
 
 
 
4.5 Values: Entity light effects
 
 
 
EF_BRIGHTFIELD = 1;  // Glowing field of dots
 
EF_MUZZLEFLASH = 2;
 
EF_BRIGHTLIGHT = 4;
 
EF_DIMLIGHT = 8;
 
 
 
4.6 Values: Existing Items
 
 
 
IT_AXE = 4096;
 
IT_SHOTGUN = 1;
 
IT_SUPER_SHOTGUN = 2;
 
IT_NAILGUN = 4;
 
IT_SUPER_NAILGUN = 8;
 
IT_GRENADE_LAUNCHER = 16;
 
IT_ROCKET_LAUNCHER = 32;
 
IT_LIGHTNING = 64;
 
IT_EXTRA_WEAPON = 128;
 
IT_SHELLS = 256;
 
IT_NAILS = 512;
 
IT_ROCKETS = 1024;
 
IT_CELLS = 2048;
 
IT_ARMOR1 = 8192;
 
IT_ARMOR2 = 16384;
 
IT_ARMOR3 = 32768;
 
IT_SUPERHEALTH = 65536;
 
IT_KEY1 = 131072;
 
IT_KEY2 = 262144;
 
IT_INVISIBILITY = 524288;
 
IT_INVULNERABILITY = 1048576;
 
IT_SUIT = 2097152;
 
IT_QUAD = 4194304;
 
 
 
4.7 Values: Behavior of solid objects
 
 
 
SOLID_NOT = 0;                // no interaction with other objects
 
                              // inactive triggers
 
SOLID_TRIGGER = 1;            // touch on edge, but not blocking
 
                              // active triggers, pickable items
 
                              // (.MDL models, like armors)
 
SOLID_BBOX = 2;                // touch on edge, block
 
                              // pickable items (.BSP models, like ammo box)
 
                              // grenade, missiles
 
SOLID_SLIDEBOX = 3;            // touch on edge, but not an onground
 
                              // most monsters
 
SOLID_BSP = 4;                // bsp clip, touch on edge, block
 
                              // buttons, platforms, doors, missiles
 
 
 
4.8 Values: Type of movements
 
 
 
         
 
MOVETYPE_NONE = 0;            // never moves
 
//float MOVETYPE_ANGLENOCLIP = 1;
 
//float MOVETYPE_ANGLECLIP = 2;
 
MOVETYPE_WALK = 3;            // Walking players only
 
MOVETYPE_STEP = 4;            // Walking monster
 
MOVETYPE_FLY = 5;              // Hovering Flight
 
                              // meant for flying monsters (and players)
 
MOVETYPE_TOSS = 6;            // Balistic flight
 
                              // meant for gibs and the like
 
MOVETYPE_PUSH = 7;            // Not blocked by the world, push and crush
 
                              // meant for doors, spikes and crusing platforms
 
MOVETYPE_NOCLIP = 8;          // Not blocked by the world
 
MOVETYPE_FLYMISSILE = 9;      // like fly, but size enlarged against monsters
 
                              // meant for rockets
 
MOVETYPE_BOUNCE = 10;          // bounce off walls
 
MOVETYPE_BOUNCEMISSILE = 11    // bounce off walls, but size enlarged against monsters
 
                              // meant for grenades
 
 
 
4.9 Values: Entity can solid take damage
 
 
 
DAMAGE_NO = 0;                // Can't be damaged
 
DAMAGE_YES = 1;                // Grenades don't explode when touching entity
 
DAMAGE_AIM = 2;                // Grenades explode when touching entity
 
 
 
Most damageable entities have DAMAGE_AIM, so that when they chew on a grenade, it explodes. If you make an entity DAMAGE_YES, the grenades will bounce off
 
 
 
it.
 
 
 
4.10 Values: Entity dead flag
 
 
 
DEAD_NO = 0;                  // still living
 
DEAD_DYING = 1;                // dying (helpless)
 
DEAD_DEAD = 2;                // really dead
 
DEAD_RESPAWNABLE = 3;          // dead, but can respawn
 
 
 
4.11 Values: Spawnflags
 
 
 
The spawn flags are bit fields, whose interpretation depend on the concerned entity. There is quite a bit of a hack, that could cause unexpected bugs in the
 
 
 
Quake C code.
 
 
 
  DOOR_START_OPEN = 1;        // allow entity to be lighted in closed position
 
  SPAWN_CRUCIFIED= 1;          // for zombie
 
  PLAT_LOW_TRIGGER = 1;        // for func_plat
 
  SPAWNFLAG_NOTOUCH= 1;
 
  SPAWNFLAG_NOMESSAGE= 1;
 
  PLAYER_ONLY = 1;
 
  SPAWNFLAG_SUPERSPIKE = 1;    // for spike shooter
 
  SECRET_OPEN_ONCE = 1;        // secret door, stays open
 
  PUSH_ONCE = 1;
 
  WEAPON_SHOTGUN = 1;          // weapon, shotgun
 
  H_ROTTEN = 1;                // health, rotten (5-10 points)
 
  WEAPON_BIG2 = 1;            // items
 
  START_OFF = 1;              // light, is off at start.
 
  SILENT = 2;
 
  SPAWNFLAG_LASER = 2;        // for spike shooter
 
  SECRET_1ST_LEFT = 2;        // secret door, 1st move is left of arrow
 
  WEAPON_ROCKET = 2;          // weapon, rocket
 
  H_MEGA = 2;                  // health, mega (100 points)
 
  DOOR_DONT_LINK = 4;
 
  SECRET_1ST_DOWN = 4;        // secret door, 1st move is down from arrow
 
  WEAPON_SPIKES = 4;          // weapon, nailgun
 
  DOOR_GOLD_KEY = 8;
 
  SECRET_NO_SHOOT = 8;        // secret door, only opened by trigger
 
  WEAPON_BIG = 8;              // weapon, super model
 
  DOOR_SILVER_KEY = 16;
 
  SECRET_YES_SHOOT = 16;      // secret door, shootable even if targeted
 
  DOOR_TOGGLE = 32;
 
 
 
 
 
 
 
5. Entities
 
________________________________________________________________________________
 
 
 
Part of this information is derived from the DEM file specs 1.0.2 by Uwe Girlich.
 
 
 
In Quake, monsters, players, items, and the level itself are all entities. There are three kind of entities, and you will all encounter them in Quake-C code.
 
 
 
Types of entities
 
 
 
Static entities
 
 
 
A static entity doesn't interact with the rest of the game. These are flames (progs/flame.mdl), lights, illusionary objects, and
 
the like. It is never be necessary to reference such an entity, so they don't get an entity reference number.
 
 
 
A static entity will be created by the function:
 
 
 
makestatic()
 
 
 
(it causes a spawnstatic message to be sent to every client).
 
A static entity cannot be removed, once created.
 
 
 
The maximum number of static entities is 127.
 
 
 
Temporary entities
 
 
 
A temporary entity is a short life time entity. For instance, Quake uses these entities for hits on the wall (point-like entities)
 
or for the Thunderbolt flash (line-like entities), gun shots, and anything that is not supposed to last more than one frame.
 
 
 
A temporary entity will be created by sending a valid temporary entity message.
 
A temporary entity need not be removed, it disapears by itself.
 
 
 
Dynamic entities
 
 
 
A dynamic entity is anything which changes its behaviour or its appearance. These are ammunition boxes, spinning
 
armors, player models and the like.
 
 
 
A dynamic entity will be created by the sequence:
 
 
 
entity = spawn();
 
setmodel( entity, "progs/entity.mdl" );
 
setsize( entity, vector_min, vector_max);     
 
setorigin( entity, position );     
 
 
 
It will have to be removed by the function:
 
 
 
remove( entity );
 
 
 
The maximum number of dynamic entities is 449.
 
 
 
 
 
 
 
Definition of entity fields
 
 
 
These are the fields that are available in the entity objects (like self, other). Beware that this is not true object oriented
 
programming: there is no protection when accessing those fields, and no guaranty on the validity of values. So if you put
 
garbage there you will probably crash the game.
 
 
 
You can add custom fields (for instance, to store the ammo count of a new weapon you created) but those fields must not
 
be situated among thoses that are common between Quake-C and Quake.exe. Otherwise, Quake.exe would have to be
 
re-compiled. So those fields must be situated after the fake variable called end_sys_fields, in the field definitions.
 
 
 
Fields shared between Quake.exe and Quake-C
 
 
 
These fields describe the most common entity fields. They are shared between the C code of Quake.exe, and the
 
Quake-C code of PROGS.DAT.
 
 
 
Some of the fields are managed by the C code: you can read their value, but YOU SHOULD NEVER MODIFY THEIR
 
VALUE DIRECTLY (there are special built-in functions for that).
 
 
 
Technical data
 
 
 
entity  chain;                // next entity, in a chain list of entities
 
float  ltime;                // local time for entity
 
float  teleport_time;        // to avoid backing up
 
float  spawnflags;            // see possible values.
 
 
 
Appearance of entity
 
 
 
float  modelindex;            // index of model, in the precached list
 
string  classname;            // spawn function
 
 
 
string  model;
 
 
 
The name of the file that contains the entity model.
 
 
 
float  frame;
 
 
 
This is the index of the currently displayed model frame. Frames must be defined by a $frame construct in the model file, and manipulated in the code as $xxx
 
 
 
(where xxx is the name of the frame).
 
 
 
float  skin;
 
 
 
This is the index of the model skin currently displayed. If your model has more than one skin defined, then this value indicates the skin in use. You can
 
 
 
change it freely, as long as it remains in a valid range. For instance, it's used by the armor model to show the yellow, red or green skin.
 
 
 
float  effects;
 
 
 
This is a flag that defines the special light effects that the entity is subject to. This can supposedly be used to make an entity glow, or to create a
 
 
 
glowing field of dots around it.
 
 
 
Position in 3D
 
 
 
 
vector  origin;                // position of model
 
    //  origin_x, origin_y, origin_z
 
vector  mins;                  // bounding box extents reletive to origin
 
    //  mins_x, mins_y, mins_z
 
vector  maxs;                  // bounding box extents reletive to origin
 
    //  maxs_x, maxs_y, maxs_z
 
vector  size;                  // maxs - mins
 
    //  size_x,size_y,size_z
 
vector  absmin;                // origin + mins and maxs
 
    //  absmin_x absmin_y absmin_z
 
vector  absmax;                // origin + mins and maxs
 
    //  absmax_x absmax_y absmax_z
 
vector  oldorigin;              // old position
 
vector  angles;                // = 'pitch_angle yaw_angle flip_angle'
 
 
 
Quirks: setting the angles on a player entity doesn't work.
 
 
 
Situation of the entity
 
 
 
float  waterlevel;            // 0 = not in water, 1 = feet, 2 = waist, 3 = eyes
 
float  watertype;              // a content value
 
entity  groundentity;          // indicates that the entity moves on the ground
 
 
 
Since groundentity is used nowhere in progs, it's meaning is just a wild guess from a similar field in messages.
 
 
 
Movement in 3D
 
 
 
vector  velocity;              // = 'speed_x      speed_y    speed_z'
 
vector  avelocity;              // = 'pitch_speed yaw_speed 0', angle velocity
 
vector  punchangle;            // temp angle adjust from damage or recoil
 
float  movetype;              // type of movement
 
float  yaw_speed;              // rotation speed
 
float  solid;                  // tell if entity can block the movements.
 
 
 
Monster's Behavior
 
 
 
entity  goalentity;            // Monster's movetarget or enemy
 
float  ideal_yaw;              // Monster's ideal direction, on paths
 
float  yaw_speed;              // Monster's yaw speed.
 
string  target;                // Target of a monster
 
string  targetname;            // name of the target
 
 
 
Automatic Behavior
 
 
 
float  nextthink;              // next time when entity must act
 
void()  think;                  // function invoked when entity must act
 
void()  touch;                  // function invoked if entity is touched
 
void()  use;                    // function invoked if entity is used
 
void()  blocked;                // function for doors or plats, called when can't push other
 
vector  movedir;                // mostly for doors, but also used for waterjump
 
string  message;                // trigger messages
 
float  sounds;                // either a cd track number or sound number
 
string  noise;                  // soudn played on entity noise channel 1
 
string  noise1;
 
string  noise2;
 
string  noise3;               
 
 
 
Information by Abducted:
 
When you want an entity to do something specific, after a certain delay (exploding, disapearing, or the like...), you set nextthink to that delay (in
 
 
 
seconds), and set think to the function to execute.
 
 
 
Information by Greg Lewis:
 
It seems that the touch function is called before the field is checked, so you can set this type in the touch function, and it will immediatly be taken into
 
 
 
account.
 
 
 
Player/Monster stats and damage status
 
 
 
float  deadflag;              // tells if an entity is dead.
 
float  health;                // health level
 
float  max_health;            // players maximum health is stored here
 
float  takedamage;            // indicates if entity can be damaged
 
float  dmg_take;              // damage is accumulated through a frame. and sent as one single
 
float  dmg_save;              // message, so the super shotgun doesn't generate huge messages
 
entity  dmg_inflictor;          // entity that inflicted the damage (player, monster, missile, door)
 
 
 
Player inventory
 
 
 
float  items;                  // bit flags
 
float  armortype;              // fraction of damage absorbed by armor
 
float  armorvalue;            // armor level
 
float  weapon;                // one of the IT_SHOTGUN, etc flags
 
string  weaponmodel;            // entity model for weapon
 
float  weaponframe;            // frame for weapon model
 
float  currentammo;            // ammo for current weapon
 
float  ammo_shells;            // remaining shells
 
float  ammo_nails;            // remaining nails
 
float  ammo_rockets;          // remaining rockets and grenades
 
float  ammo_cells;            // remaining lightning bolts
 
 
 
float  impulse;                // weapon changes
 
 
 
When set to 0, the player's weapon doesn't change. When different from zero, this field is interpreted by the Quake-C
 
impulse command as a request to change weapon (see ImpulseCommand).
 
 
 
Player Fight
 
 
 
entity  owner;                  // Entity that owns this one (missiles, bubbles are owned by the player)
 
entity  enemy;                  // personal enemy (only for monster entities)
 
float  button0;                // fire
 
float  button1;                // use
 
float  button2;                // jump
 
vector  view_ofs;              // position of player eye, relative to origin
 
float  fixangle;              // set to 1 if you want angles to change now
 
vector  v_angle;                // view or targeting angle for players
 
float  idealpitch;            // calculated pitch angle for lookup up slopes
 
entity  aiment;                // aimed antity?
 
 
 
Deathmatch
 
 
 
float  frags;                  // number of frags
 
string  netname;                // name, in network play
 
float  colormap;              // colors of shirt and pants
 
float  team;                  // team number
 
float  flags;                  // ?
 
 
 
Fields used only by Quake-C (User defined)
 
 
 
These entity fields are used only by Quake-C programs, and are never referenced by the C code of Quake.exe. So you
 
can do whatever you want with the values, so long as it's compatible with what other Quake-C modules do.
 
 
 
If the fields defined here are not suitable for you, you can define new fields, by adding them at the end of the defintion of
 
fields. As a matter of fact, the number of fields in an entity (hence the size of all the instances of entity objects) is
 
determined by Quake-C: in the PROGS.DAT header, a value named entityfields indicates to Quake.exe the size of the
 
entity object.
 
 
 
Beware however that the more field you add, the more each entity will suck memory. Add just one float (4 bytes) and it
 
will take, in memory, 4 bytes time the number of entity.
 
 
 
The best is to share fields between distinct classes of entities, by reusing the same position for another kind of field. If the
 
Quake C Compiler was a real object-oriented compiler, that would be done very safely by single-inheritance
 
(multiple-inheritance would be a deadly mistake). You will also notice that id software has made quite a lousy usage of
 
most of the fields, defining much more than were actually needed, since they are only used by a few entities.
 
 
 
World fields
 
 
 
string wad;                      // name of WAD file with misc graphics 
 
string map;                      // name of the map being played
 
float  worldtype;                // see below
 
 
 
worldtype is 0 for a medieval setting, 1 for metal, and 2 for a base setting.
 
These fields might soon become global variables, so don't rely too much on them.
 
 
 
Quake Ed fields
 
 
 
string killtarget;
 
float light_lev;                // not used by game, but parsed by light util
 
float style;
 
 
 
Monster Behaviour
 
 
 
Those functions are called when these specific events happen:
 
 
 
void() th_stand;            // when stands iddle
 
void() th_walk;            // when is walking
 
void() th_run;              // when is running
 
void() th_missile;          // when a missile comes
 
void() th_melee;            // when fighting in melee
 
void() th_die;              // when dies
 
 
 
void(entity attacker, float damage) th_pain;
 
 
 
That function is executed when the monster takes a certain amount of damage from an attacker (a player, or another
 
monster). Will usually cause the monster to turn against the attacker.
 
 
 
Monster state variables
 
 
 
entity oldenemy;            // mad at this player before taking damage
 
float  speed;              //
 
float  lefty;              //
 
float  search_time;        //
 
float  attack_state;        //
 
 
 
float  pausetime;
 
entity  movetarget;
 
 
 
Player Only
 
 
 
float  walkframe;
 
float  attack_finished;
 
float  pain_finished;        // time when pain sound is finished
 
float  invincible_finished;
 
float  invisible_finished;
 
float  super_damage_finished;
 
float  radsuit_finished;
 
float  invincible_time;      // time when player cease to be invincible
 
float  invincible_sound;
 
float  invisible_time;        // time when player cease to be invisible
 
float  invisible_sound;
 
float  super_time;            // time when quad shot expires?
 
float  super_sound;
 
float  rad_time;
 
float  fly_sound;
 
float  axhitme;              // TRUE if hit by axe
 
float  show_hostile;          // set to time+0.2 whenever a client fires a
 
                              // weapon or takes damage.  Used to alert
 
                              // monsters that otherwise would let the player go
 
float  jump_flag;            // player jump flag
 
float  swim_flag;            // player swimming sound flag
 
float  air_finished;          // when time > air_finished, start drowning
 
float  bubble_count;          // keeps track of the number of bubbles
 
string  deathtype;            // keeps track of how the player died
 
 
 
Object stuff
 
 
 
string  mdl;                    // model name?
 
vector  mangle;                // angle at start. 'pitch roll yaw'
 
vector  oldorigin;              // only used by secret door
 
float  t_length;
 
float  t_width;
 
 
 
Doors
 
 
 
vector  dest;
 
vector  dest1;
 
vector  dest2;
 
float  wait;                  // time from firing to restarting
 
float  delay;                  // time from activation to firing
 
entity  trigger_field;          // door's trigger entity
 
string  noise4;
 
float  aflag;
 
float  dmg;                    // damage done by door when hit
 
 
 
Miscellaneous
 
 
 
float  cnt;                    // counter
 
void()  think1;
 
vector  finaldest;
 
vector  finalangle;
 
//
 
// triggers
 
//
 
float  count;                  // for counting triggers
 
//
 
// plats / doors / buttons
 
//
 
float  lip;
 
float  state;
 
vector  pos1;
 
vector  pos2;                  // top and bottom positions
 
float  height;
 
//
 
// sounds
 
//
 
float  waitmin;
 
float  waitmax;
 
float  distance;
 
float  volume;
 
 
 
 
 
5.      Global Variables
 
________________________________________________________________________________
 
 
 
These variables are accessible in every functions.
 
Quake C function are not supposed to modify them directly.
 
 
 
Variable: world
 
 
 
the server's world object, which holds all global state for the server, like the deathmatch flags and the body ques.
 
 
 
Variable: time
 
 
 
  float time;              // in seconds
 
 
 
The current game time, a floating point value in seconds. Note that because the entities in the world are simulated
 
sequentially, time is NOT strictly increasing. An impact late in one entity's time slice may set time higher than the think
 
function of the next entity. The difference is limited to 0.1 seconds.
 
 
 
Variable: frametime
 
 
 
  float frametime;          // in seconds
 
 
 
No idea what this can be. Used only when jumping in water.
 
 
 
Variable: self
 
 
 
entity self;
 
 
 
The entity that is subject to the current function.
 
 
 
Variable: other
 
 
 
entity other;
 
 
 
The object concerned by an impact, not used for thinks.
 
 
 
Variable: force_retouch
 
 
 
  float force_retouch;  // counter
 
 
 
Force all entities to touch triggers next frame. this is needed because non-moving things don't normally scan for triggers,
 
and when a trigger is created (like a teleport trigger), it needs to catch everything.
 
It is decremented each frame, so it is usually set to 2 to guarantee everything is touched.
 
 
 
Variable: mapname
 
 
 
  string mapname;
 
 
 
Name of the level map currently being played, like "start".
 
 
 
Variable: deathmatch
 
 
 
  float deathmatch;  // a boolean value, 0 or 1
 
 
 
True if playing deathmatch.
 
 
 
Variable: coop
 
 
 
  float coop;  // a boolean value, 0 or 1
 
 
 
True if playing cooperative.
 
 
 
Variable: teamplay
 
 
 
  float teamplay;  // a boolean value, 0 or 1
 
 
 
True if playing by teams.
 
 
 
Variable: serverflags
 
 
 
  float serverflags;  // bit fields
 
 
 
Propagated from level to level, and used to keep track of the completed episodes.
 
If serverflag & ( 1 << e)) is true, then episode e was already completed.
 
Generally equal to player.spawnflags & 15.
 
 
 
Variable: total_secrets
 
 
 
  float total_secrets;  // counter
 
 
 
Number of secrets found by the players. Affected only by trigger_secret.
 
 
 
Variable: found_secrets
 
 
 
  float found_secrets;  // counter
 
 
 
Number of secrets found.
 
 
 
Variable: total_monsters
 
 
 
  float total_monsters;  // counter
 
 
 
Total number of monsters that were spawned, since the begining of the level.
 
 
 
Variable: killed_monsters
 
 
 
  float killed_monsters;  // counter
 
 
 
Store the total number of monsters killed.
 
 
 
Variable: parm1...parm16
 
 
 
  float parm1; // items bit flag (IT_SHOTGUN | IT_AXE )
 
  float parm2; // health
 
  float parm3; // armorvalue
 
  float parm4, parm5, parm6, parm7; // ammo
 
  float parm8; // weapon
 
  float parm9; // armortype*100
 
  float parm10, parm11, parm12, parm13, parm14, parm15, parm16;
 
 
 
Those parameters seem to be a bit of hack. They are used when a client connects.
 
Spawnparms are used to encode information about clients across server level changes
 
 
 
 
 
 
 
Functions that are mandatory in Quake-C
 
 
 
These functions must be defined in Quake C, since they are invoked by Quake under certain conditions.
 
 
 
Misc
 
 
 
void main();
 
 
 
Only used for testing progs.
 
 
 
void StartFrame();
 
 
 
Called at the start of each frame.
 
 
 
Behavior of players
 
 
 
void PlayerPreThink();
 
 
 
Called with self=player, for every frame, before physics are run.
 
 
 
void PlayerPostThink();
 
 
 
Called with self=player, for every frame, after physics are run.
 
 
 
Management of network game clients
 
 
 
void ClientKill();
 
 
 
Called when a player suicides.
 
 
 
void ClientConnect();
 
 
 
Called when a player connects to a server, but also, for every player, when a new level starts.
 
It is used to announces the new player to every other players.
 
 
 
void PutClientInServer();
 
 
 
Call after setting the parm1... parm16.
 
 
 
void ClientDisconnect();
 
 
 
Called when a player disconnects from a server
 
Announce that the player has left the game.
 
 
 
void SetNewParms();
 
 
 
Called when a client first connects to a server. Sets parm1...parm16 so that they can be saved off for restarts.
 
 
 
void SetChangeParms();
 
 
 
Call to set parms for self so they can?
 
 
 
6.      Model pragma
 
________________________________________________________________________________
 
 
 
(Derived from information published by Steve Tietze)
 
 
 
Here are a few definitions that are commonly found in the Quake-C code defining the behavior of animated models
 
(monsters, players, etc...).
 
 
 
Most of this information is not interpreted by the Quake-C compiler, but it's useful for the program modelgen that
 
generates the models.
 
 
 
Model name
 
 
 
$modelname name
 
 
 
name is the name of the model file defining the object.
 
ex: $name armor
 
 
 
directory
 
 
 
$cd dir
 
 
 
Specify the directory where your model file (.MDL) is located.
 
ex: $cd /evil/models/armor
 
 
 
Special animation flags
 
 
 
$flags  rotation
 
 
 
This field is not interpreted by Quake-C, but it's useful for the program modelgen that generates the models.
 
Rotation of the object.
 
ex: $flags 8
 
Possible values for the flags:
 
 
 
    8: the object keeps rotating, like armors.
 
    other values are not known yet
 
 
 
Origin
 
 
 
$origin x y z
 
 
 
This field is not interpreted by Quake-C, but it's useful for the program modelgen that generates the models.
 
Location of the object within the bounding box, in the quake editor.
 
ex: $origin 0 0 8
 
 
 
Scale factor
 
 
 
$scale number
 
 
 
This field is not interpreted by Quake-C, but it's useful for the program modelgen that generates the models.
 
number comes from the texmake number that is generated.
 
You can use different values if you want.
 
ex: $scale 4
 
 
 
Base
 
 
 
$base  object
 
 
 
This field is not interpreted by Quake-C, but it's useful for the program modelgen that generates the models.
 
object is the name of a model file, that will be used as a kind of starting position, for animation.
 
 
 
Skin file
 
 
 
$skin  skinfile
 
 
 
This field is not interpreted by Quake-C, but it's useful for the program modelgen that generates the models.
 
skinfile is the name (without extension) of the .lbm file that defines the skin of the object, as generated by the program
 
texmake.
 
 
 
Frame definitions
 
 
 
$frame  frame1 frame2 ...
 
 
 
This defines several animation frames of the object.
 
For every animation frame defined, you must also define a Quake-C function, that will be called during this animation
 
frame. For instance:
 
 
 
$frame walk1 walk2 walk3 walk4
 
void() man_walk1 = [ $walk1, man_walk2 ] { ... some code ... };
 
void() man_walk2 = [ $walk2, man_walk3 ] { ... some code ... };
 
void() man_walk3 = [ $walk3, man_walk4 ] { ... some code ... };
 
void() man_walk4 = [ $walk4, man_walk1 ] { ... some code ... };
 
 
 
In the brackets, the first parameter defines the name of the frame (as found in the model file), and the second parameter
 
defined the function that is to be executed in the next frame (by setting the value of self.nextthink).
 
 
 
Most of these functions do nothing special, but some can be very complex (for instance, the functions that are called when
 
the monster tries to see a player).
 
 
 
7.      Network protocol
 
________________________________________________________________________________
 
 
 
Quake-C is not supposed to handle a lot of network messages, since most are already handled in C.
 
 
 
However, builtin functions have not been built for every kind of messages in the Quake protocol, so you migth end-up composing protocol messages in Quake-C.
 
 
 
I highly recommend that you build a single function to handle a given message type, because the structure of those messages might change, and then all your
 
 
 
code would have to be checked for bugs.
 
 
 
By that way, id software didn't even bothered to write a function to generate temporary entites, though they keep using this message. It's still a long way
 
 
 
to ISO 9001, I'm afraid.
 
 
 
Definitions related to protocol messages
 
 
 
Values: How messages are sent
 
 
 
MSG_BROADCAST = 0;  // unreliable message, sent to all
 
MSG_ONE = 1;      // reliable message, sent to msg_entity
 
MSG_ALL = 2;      // reliable message, sent to all
 
MSG_INIT = 3;  // write to the init string
 
 
 
    Use unreliable (but fast) messages, when it's of no importance that a client misses the message.
 
    examples: sound, explosions, monster deaths, taunts....
 
    Use reliable messages when it's very important that every client sees the message, or a game incoherency might
 
    happen.
 
    examples: shots, player deaths, door moves, game ends ... and CD track changes!.
 
 
 
Values: Type of message
 
 
 
These are some of message types defined in the Quake network protocol.
 
 
 
SVC_SETVIEWPORT = 5;
 
SVC_SETANGLES = 10;
 
SVC_TEMPENTITY = 23;
 
SVC_KILLEDMONSTER = 27;
 
SVC_FOUNDSECRET = 28;
 
SVC_INTERMISSION = 30;
 
SVC_FINALE = 31;
 
SVC_CDTRACK = 32;
 
SVC_SELLSCREEN = 33;
 
SVC_UPDATE = 128;
 
 
 
Some message structures
 
 
 
Here are some of the messages defined in the Quake network protocol.
 
 
 
Beware, the structure of those messages might change in future version (Satan forbids!).
 
 
 
Message: Set View Position
 
 
 
  msg_entity = player
 
  WriteByte (MSG_ONE, SVC_SETVIEWPORT);
 
  WriteEntity( MSG_ONE, camera);
 
 
 
This message is meant for a single client player. It sets the view position to the position of the entity camera.
 
 
 
Message: Set View Angles
 
 
 
  msg_entity = player
 
  WriteByte (MSG_ONE, SVC_SETVIEWANGLES);
 
  WriteAngle( MSG_ONE, camera.angles_x);
 
  WriteAngle( MSG_ONE, camera.angles_y);
 
  WriteAngle( MSG_ONE, camera.angles_z);
 
 
 
This message is meant for a single client player. It set the orientation of it's view to the same orientation than the entity
 
camera.
 
 
 
Message: Temporary Entity
 
 
 
  WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
 
  WriteByte (MSG_BROADCAST, entityname);
 
  WriteCoord (MSG_BROADCAST, origin_x);
 
  WriteCoord (MSG_BROADCAST, origin_y);
 
  WriteCoord (MSG_BROADCAST, origin_z);
 
 
 
Message: Set CD Track
 
 
 
  WriteByte (MSG_ALL, SVC_CDTRACK);
 
  WriteByte (MSG_ALL, val1);        // CD start track
 
  WriteByte (MSG_ALL, val2);        // CD end track
 
 
 
Message: Final Message
 
 
 
  WriteByte (MSG_ALL, SVC_FINALE);
 
  WriteString (MSG_ALL, "any text you like\n");
 
 
 
Message: Sell Screen
 
 
 
WriteByte (MSG_ALL, SVC_SELLSCREEN);
 
 
 
Shows the infamous sell screen (like you needed it to understand).
 
 
 
Message: Inter Mission
 
 
 
WriteByte (MSG_ALL, SVC_INTERMISSION);
 
 
 
Shows the inter mission camera view.
 
 
 
Message: Killed Monster
 
 
 
WriteByte (MSG_ALL, SVC_KILLEDMONSTER);
 
 
 
Increase by one the count of killed monsters, as available to the client. Can be displayed with showscores.
 
 
 
Message: Found Secrets
 
 
 
WriteByte (MSG_ALL, SVC_FOUNDSECRET);
 
 
 
Increase by one the count of secrets founds.
 
 
 
Message: Update Entity
 
 
 
This message has a rather complex structure. I already generated some valid update messages, but since the message
 
structure seems highly susceptible to change in the next versions of Quake, I would recommend that you never use such
 
messages: as a matter of fact, Quake itslef is very capable of generating all the required messages... unless you start
 
creating deathmatch cameras or the like.
 
 
 
 
 
8.      Network Builtin functions
 
________________________________________________________________________________
 
 
 
 
 
Beware: when generating messages, you had better respect the format of the existing messages. Otherwise the game
 
clients might not be able to interpret them (and will likely crash).
 
 
 
The functions below all write to clients (players connected via the network, or the local player).
 
 
 
Global variable for network messages
 
 
 
Variable: msg_entity
 
 
 
entity  msg_entity;
 
 
 
If you want to send a message to just one entity e, then set msg_entity= e and send the message with flag MSG_ONE,
 
instead of MSG_ALL.
 
Never used. Maybe it doesn't even work.
 
 
 
Builtin functions for composing network messages
 
 
 
Function: WriteByte
 
 
 
void WriteByte(float to, float value)
 
      to = see messages
 
 
 
Function: WriteChar
 
 
 
void WriteChar(float to, float value)
 
      to = see messages
 
 
 
Function: WriteShort
 
 
 
void WriteShort(float to, float value)
 
      to = see messages
 
 
 
Function: WriteLong
 
 
 
void WriteLong(float to, float value)
 
      to = see messages
 
 
 
Function: WriteCoord
 
 
 
void WriteCoord(float to, float value)
 
      to = see messages
 
 
 
Function: WriteAngle
 
 
 
void WriteAngle(float to, float value)
 
      to = see messages
 
 
 
This function writes a single byte, that represents 256*(angle/380).
 
 
 
Function: WriteString
 
 
 
void WriteString(float to, string value)
 
      to = see messages
 
 
 
This function writes a string, terminated by \0 (the null character in C).
 
 
 
Function: WriteEntity
 
 
 
void WriteEntity(float to, entity value)
 
      to = see messages
 
 
 
This function writes an entity reference, taking two bytes.
 
 
 
9.      Tips & tricks
 
________________________________________________________________________________
 
 
 
Here are some characteristics of Quake-C that you had better be aware of.
 
 
 
The names of variable and functions must be unique
 
 
 
The names of functions, variables and fields must be unique. For instance, you cannot define a variable with the same
 
name as a field. However, local variables can be defined more than once (they had better!).
 
 
 
Composition of function is not supported
 
 
 
Since all the functions use a single parameter marshaling area, and a single global variable to store their reture result, you
 
should NEVER try to call a function within another function call.
 
 
 
Example: printing the coordinate of entity self
 
 
 
    sprintf(self, vtos( self.origin ));
 
 
 
will fail miserably (sending the message somewhere in hell), so it should be replaced by:
 
 
 
    text = vtos( self.origin );
 
    sprintf(self, text);
 
 
 
Unfortunately, this also applies to operators:
 
 
 
  sum = anglestovec( 45) + anglestovec( 90);
 
 
 
will fail an should be replaced by:
 
 
 
  sum = anglestovec( 45);
 
  sum = sum + anglestovec( 90);
 
 
 
Actually, Quake-C is rather lame as a compiler, and you will probably make hundred of little mistakes like that, that the compiler will not warn you of. But
 
 
 
remember Quake-C was built for "performance", not ease of use. And also that it wasn't designed by people from the MIT. Remember also that you got it for
 
 
 
free... you can always get gcc (the Gnu C Compiler) for the same price ;-)
 
 
 
You cannot initialise variable with default values.
 
 
 
If you give a default value to a quake-C variable, this variable will be considered as a constant. And since the value of
 
constants is not supposed to change, your program may not work properly after that.
 
 
 
Coordinates are relative to the world.
 
 
 
All the geometry (coordinate positions, directions, angles) are relative to the world. They are never relative to a given
 
object. To know the direction an object is facing, you have to require calculation of the v_front vector (respectively
 
v_right and v_up for the right, and the top).
 
 
 
 
 
 
 
Frequently Asked Questions about Quake-C
 
 
 
How do I change the viewpoint?
 
 
 
You would like that a given player sees through the eyes of another entity. This commonly happens at the end of the level
 
(all players see through a camera), or when the player head is severed (gibbed), or when a player is invisible (he only
 
exists as his eyes).
 
 
 
But the example above work by changing the player entity, and what you want is probably just to see through a camera
 
(Duke3D) or a missile (Descent).
 
 
 
This operation is known in the Quake network protocol as a setview message. But nowhere it's defined in Quake-C, and
 
there's no function to change the view port. So the solution is to encode a set view port message, followed by a set view
 
angles message (to take the orientation of the camera).
 
 
 
This works fine, except that if, for some reason, the entity you are using as a camera was not previously declared to the
 
client, then the view port will be set to '0 0 0', which is usually somewhere in the void.
 
 
 
How do I teleport a player into another server
 
 
 
A trick by Steven Lang (tiger@ecis.com)
 
 
 
    // In the slipgate touch function
 
    // other = entity that touched
 
    if(other.classname == "player")
 
      stuffcmd(other, "connect server.address\n");  // send command
 
 
 
When the slipgate is touched, the entity jumps to another server.
 
 
 
Trouble: the player stats and weapons won't be preserved, and the player would be dumped to the console if the other server was full or not available.
 
That's why John Carmack, will rewrite the code of Quake.exe to implement his Quake World proposal, and advanced server with all kinds of goodies...
 
 
 
permission lists, ability to block an IP, etc. (info from quake-c list).
 
 
 
How do I manipulate strings in Quake-C?
 
 
 
Well, you can have any kind of strings, as long as they cannot be changed.
 
 
 
"In Ford we trust" (Brave New World).
 
 
 
Mind you, pr_comp.c, defines only operations = == != on strings.
 
 
 
How to read string variables, or text messages?
 
 
 
Well, if you know, tell, that would make a nice addition to this specs.
 
 
 
How do I move an entity in Quake-C?
 
 
 
You have better not touch it's position, else some stuff in the C code might not be valid anymore. So you call the
 
setposition() built-in function.
 
 
 
How to change the velocity of an entity (make it bounce off walls)?
 
 
 
Information by Greg Lewis.
 
 
 
It seems that an entity's velocity can't be changed in the Touch function of the entity. Making the calculations there will be of no use. So just set
 
 
 
entity.movetype to MOVETYPE_BOUNCE, entity.nextthink to 0.1 (to let it bounce off), and set entity.think to the name of a function that, when called 0.1
 
 
 
second later, will set entity.velocity to the right direction.
 
 
 
How to calculate the direction a player is facing?
 
 
 
Assuming the player is self, the entity field self.angles contains the orientation angles of the player (as set by moving the mouse).
 
 
 
Then the function makeverctors( self.angles) will calculate three vectors, that point in the direction the player is facing, but also to the right of the
 
 
 
player (strafing direction) and to the direction the player is standing.  
 
 
 
Note that those vectors are normalised to 1, so if you want to know what lays 100 units in front of the player, use self.origin + 100 * facing.
 
 
 
How to send a message to a client when he logs in?
 
 
 
It has been noticed that using a sprint() in function ClientConnect just plain doesn't send any message at all. Maybe the client is not ready to receive
 
 
 
messages at this point.
 
 
 
However, Doug Keenan (doug.keegan@tamu.edu) has reported he could send such a text message by putting the sprint() close to the begining of the ClientConnect
 
 
 
function. It doesn't work at the end, apparently.
 
 
 
 
 
Writing Quake-C code
 
 
 
Here are some suggestions that you should really consider when writing Quake-C code. Well, there are no obligations,
 
but that would make life simpler for others when they read your code (and thus for you when you read theirs).
 
 
 
I assume here that you want to develop code that others can re-use, or that can be mixed seamlessly with codes written by
 
others.
 
 
 
(If you are reinventing the whole world all by yourself, you hardly need any help or counsels. By the way, the first command is +light).
 
 
 
  1.Please put comments in your code.
 
    Of course, the real gurus don't need comments. They understand raw Quake-C, even compiled. They can even imagine all the parts of your code
 
    before they read them. Even before you write them. But actually, they seldom read your code. Only normal people do.
 
  2.Please tag the begining and end of your modifications, if you are fixing a code from someone else.
 
    Also put a date, and put a reason for the fix. Example:
 
 
 
          // Patch by Nezu The Unworthy  8/3/96
 
          // Gimme a chance to win a deathmatch
 
          if(self.name != "nezu")
 
            self.frag = self.frag - 10;
 
          // Patch End
 
     
 
 
 
  3.Each time you create a new function, a new variable or a new field, please give it a name that will not conflict with
 
    function or variable defined by others.
 
    A rather sure way to do this is to prefix every name with some abvreviated module name, or you initials, or whatever
 
    rare combination of three or four letter. Example:
 
 
 
        void() NTU_think =  // Nezu The Unworthy starts thinking
 
        {
 
            self.skin = 1;  // turn red and boil
 
        };
 
       
 
 
 
  4.Each time you implement some set of related functions, you should create a new Quake-C module, and give it a
 
    name different from the existing ones.
 
    Please do not use one of the module names used by id software, this would be confusing. Try to be original, else we
 
    might end-up with two hundred modules called impulse.qc.
 
  5.When you want to distribute some modified Quake-C programs:
 
        include a file_id.diz file explaining in 5 lines what your patch does, and where it should be stored in the archives
 
        (this file is to be read by system administrators)
 
        include a readme.txt file explaining in details what your patch does, how it does it, and what common files you
 
        had to modify.
 
        include the .qc modules that you created from scratch.
 
        For the modules you modified, please let them pass through the utilities diff (see below), so that the original file
 
        can be patched the utility patch. even if it has been modified since.
 
        Do not distribute modified .qc modules. Future versions of Quake will contain different code, and all your work
 
        would then be lost.
 
  6.You should compile and distribute a version of your code, as a single PROGS.DAT file, to be used by those who just
 
    wanna have fun. Don't forget them, they largely overnumber the people who directly deal with Quake-C.
 
  7.Upload your Quake-C patches to the primary quake ftp site at ftp.cdrom.com.
 
    Maybe if it's good enough it will also appear in the Quake-C code repository.
 
 
 
Using Diff and Patch
 
 
 
Information by Jeff Epler (jepler@cse.unl.edu)
 
 
 
You can find a DOS version of diff and patch on all the major ftp archives, for instance Simtelnet (mirrored at
 
ftp://oak.oakland.edu/pub/simtelnet).
 
 
 
For a Win32 (windows95 and NT) version, see diffutils.zip and patch.zip.
 
 
 
The full documentation for diff and patch is available on www.ai.mit.edu, but here are some shortened instructions:
 
 
 
To make a diff:
 
. start with yourdir/ with an entire working set of .qc files, and v101qc/
 
with the virgin qc files from id.
 
. diff -ur --new-file v101qc yourdir > patchfil
 
 
 
To patch with a diff:
 
. copy everything in v101qc (or yourdir if you want to add these patches to
 
your already-customized setup) to newdir
 
. change to newdir
 
. patch -p1 < patchfil
 
. Look for any "rejected" patches and apply them by hand using your
 
favorite 2-window text editor.  These should be few or none if the author
 
kept his changes well-structured or you patched from exactly the same
 
source he diffed from.
 
 
 
10.    Types
 
________________________________________________________________________________
 
 
 
Simple Types
 
 
 
Type: void
 
 
 
An empty result, mostly used for definition of procedures (i.e. functions that return no result at all).
 
 
 
Type: float
 
 
 
A floating point value.
 
 
 
Floats are also used to store booleans (TRUE, FALSE) or integer values linke counters, or bit flags.
 
 
 
    Valid syntax: 12  1.6  0.5  -100 
 
    Invalid syntax: .5
 
 
 
A parsing ambiguity is present with negative constants. "a-5" will be parsed as "a", then "-5", causing an error. Separate
 
the - from the digits with a space "a - 5" to get the proper behavior.
 
 
 
Type: vector
 
 
 
A vector, made of 3 float coordinates.
 
Used to represent positions or directions in 3D space.
 
Valid syntax: '0 0 0' or '20.5 -10 0.00001'  
 
 
 
Note the simple quotes around the vector. Do not use double quotes, they are reserved for strings.
 
 
 
If you declare a vector foobar, then you can access it's x, y and z fields with: foobar_x, foobar_y,foobar_z.
 
 
 
Type: string
 
 
 
Represents a character string.
 
Used to indicate file names, or messages to be broadcast to players.
 
Valid syntax: "maps/jrwiz1.bsp" or "ouch!\n"
 
Use \n for newline.
 
 
 
Type: entity
 
 
 
The reference of an entity in the game, like things, players, monsters.
 
For instance, this is the type of the entities self and other.
 
 
 
The entity type is a structured type, made of fields.
 
A description of each field is available.
 
 
 
 
 
 
 
Field types
 
 
 
Countrary to the other types, the entity type is a reference to an instance of a structured object, that contains many informations of totally different
 
 
 
kinds.
 
 
 
To access all these informations conveniently, they are stored as fields of the entity object, and each field is given a name and a type, that makes it
 
 
 
distinct of the others.
 
 
 
Some of the fields do not store value, but instead they store the function to be executed in certain conditions. They are called the methods that can be
 
 
 
aplied to the object.
 
 
 
If Quake-C was an object oriented programming language, those method functions and would be distinguished from the other fields. And, above all, you would be
 
 
 
able to create new object types, with their own fields.
 
 
 
As Quake-C stands currently, all the field definitions are definitions of entity fields. So anywhere in your code you could add definition of new fields, and
 
 
 
the compiler would interpret them as an extension of the entity definition.
 
 
 
Here are all the possible definitions of entity fields, with their types:
 
 
 
    .float field_name;
 
    .string field_name;
 
    .vector field_name;
 
    .entity field_name;
 
 
 
Reserved field types (beware of the hack!)
 
 
 
In the first file read by the Quake-C compiler, defs.qc, there must be a definition for the entity fields, and world fields. This definition is hard coded.
 
 
 
You had better not touch it, or you will have to recompile Quake itself.
 
 
 
The globals are defined before the special definition void end_sys_globals; The entity fields are defined before the special definition void end_sys_fields;
 
 
 
It's not important if you don't understand the nonsense above. It's an ugly hack. Just don't modify defs.qc before those
 
two tags, and you won't be in trouble.
 
 
 
 
 
 
 
11.    Compilation of Quake-C
 
________________________________________________________________________________
 
 
 
The language is strongly typed and there are no casts.
 
 
 
Source files are processed sequentially without dumping any state, so if a defs file is the first one processed, the definitions will be available to all
 
 
 
other files.
 
 
 
Error recovery during compilation is minimal. It will skip to the next global definition, so you will never see more than one error at a time in a given
 
 
 
function. All compilation aborts after ten error messages.
 
 
 
Names can be defined multiple times until they are defined with an initialization, allowing functions to be prototyped before their definition.
 
 
 
    // in headers
 
    void()      MyFunction;            // the prototype
 
    // later
 
    void()      MyFunction =            // the initialization
 
    { dprint ("we're here\n"); };
 
 
 
Beware of the Quake-C compiler
 
 
 
 
 
 
 
 
 
12.    Execution of Quake-C
 
________________________________________________________________________________
 
 
 
Code execution is initiated by C code in quake from two main places: the timed think routines for periodic control, and the touch function when two objects
 
 
 
impact each other.
 
 
 
Execution is also caused by a few uncommon events, like the addition of a new client to an existing server.
 
 
 
There is a runnaway counter that stops a program if 100000 statements are executed, assuming it is in an infinite loop.
 
 
 
It is acceptable to change the system set global variables. This is usually done to pose as another entity by changing self and calling a function.
 
 
 
The interpretation is fairly efficient, but it is still over an order of magnitude slower than compiled C code. All time consuming operations should be made
 
 
 
into built in functions.
 
 
 
A profile counter is kept for each function, and incremented for each interpreted instruction inside that function. The "profile" console command in Quake
 
 
 
will dump out the top 10 functions, then clear all the counters. The "profile all" command will dump sorted stats for every function that has been executed.
 
 
 
 
 
13. Examples
 
________________________________________________________________________________
 
       
 
        These are examples taken from the QuakeC patch archives. Two of them are made by me.
 
 
 
13.1 Looping between all monster
 
 
 
float() Pet_FindTarget =
 
{
 
local entity client;
 
local float r;
 
        local entity head, selected;
 
local float dist;
 
 
 
 
 
 
 
        dist = 10000;
 
selected = world;
 
head = findradius(self.origin, 10000);
 
while(head)
 
{
 
if( (head.health > 1) && (head != self) && (head != self.owner))
 
{
 
traceline(self.origin,head.origin,TRUE,self);
 
if ( (trace_fraction >= 1) && (vlen(head.origin - self.origin) < dist) && (head.owner != self.owner))
 
{
 
selected = head;
 
dist = vlen(head.origin - self.origin);
 
}
 
}
 
head = head.chain;
 
}
 
if (selected != world)
 
{
 
sprint (self.owner,"Pet attacking -> ");
 
if (selected.classname == "player")
 
{
 
sprint (self.owner,selected.netname);
 
sprint (selected,self.owner.netname);
 
sprint (selected," sent one of his minions after you!\n");
 
}
 
else
 
sprint (self.owner,selected.classname);
 
sprint (self.owner,"\n");
 
                self.enemy = selected;
 
                FoundTarget ();
 
 
 
                return TRUE;
 
}
 
 
 
 
 
    if (self.goalentity != self.owner)
 
    {
 
        self.goalentity = self.owner;
 
        self.think = self.th_run;
 
    }
 
    self.ideal_yaw = vectoyaw(self.owner.origin - self.origin);
 
    self.nextthink = time+0.1;
 
    return FALSE;
 
};
 
 
 
13.2 Creating a new entities
 
 
 
void(entity myself) ActivateHolo =
 
{
 
local entity newholo;
 
 
 
newholo = spawn();
 
newholo.solid = SOLID_NOT;
 
newholo.movetype = MOVETYPE_NOCLIP;
 
newholo.origin = myself.origin;
 
newholo.angles = myself.angles;
 
newholo.colormap = myself.colormap;
 
setmodel (newholo, "progs/player.mdl");
 
newholo.classname = "holo";
 
newholo.owner=myself;
 
newholo.frame=13;
 
newholo.nextthink = time + 8;
 
newholo.think = RemoveHolo;
 
myself.currentammo = myself.ammo_cells = myself.ammo_cells - 10;
 
myself.items = myself.items | IT_HOLO;
 
stuffcmd (newholo.owner, "bf\n");
 
sprint(newholo.owner,"holograph activated\n");
 
};
 
 
 
13.3 Setting point of view
 
 
 
void(entity me, entity camera) NezuSetViewPoint =
 
{
 
  // Set view point
 
  msg_entity = me;                        // target of message
 
  WriteByte (MSG_ONE, SVC_SETVIEWPORT);    // 5 = SVC_SETVIEWPORT; 
 
  WriteEntity (MSG_ONE, camera);          // view port
 
  // Also set angles, otherwise it feels strange
 
  // NezuSetViewAngle(me, camera.angles);
 
  WriteByte (MSG_ONE, SVC_SETVIEWANGLES);  // 10 = SVC_SETVIEWANGLES
 
  WriteAngle(MSG_ONE, camera.angles_x);    // tilt
 
  WriteAngle(MSG_ONE, camera.angles_y);    // yaw
 
  WriteAngle(MSG_ONE, camera.angles_z);    // flip
 
};
 
 
 
13.4 Teleporting
 
 
 
void() Teleport_to_bomb =
 
{
 
local entity oldself,bdest;
 
 
 
bdest=spawn();
 
bdest.origin = self.telebomb.origin + '0 0 27';
 
 
 
// Blow up the bomb...
 
oldself=self;
 
self=self.telebomb;
 
GrenadeExplode();
 
self=oldself;
 
 
 
 
 
// Teleport to the bomb's old location
 
 
 
if(self.health <= 0)  {
 
remove(bdest);
 
return;
 
}
 
 
 
// Recreating the "teleport_touch" function here, once again
 
 
 
spawn_tfog (bdest.origin);
 
 
 
spawn_tfog (bdest.origin);
 
spawn_tdeath (bdest.origin,self);
 
 
 
setorigin (self,bdest.origin);
 
 
self.teleport_time = time + 1;  // Longer teleport recovery time
 
self.flags = self.flags - self.flags & FL_ONGROUND;
 
 
 
remove(bdest);
 
};
 
 
 
13.5 Throwing your eyes
 
 
 
        if (self.impulse == 254)
 
        {
 
                local vector v;
 
               
 
                eyes = spawn(); 
 
                setmodel (eyes,"progs/eyes.mdl");
 
                eyes.movetype = MOVETYPE_BOUNCE;
 
                eyes.solid = SOLID_BBOX;
 
                eyes.effects = eyes.effects | EF_DIMLIGHT;
 
                msg_entity = self;                       
 
                                         
 
                WriteByte (MSG_ONE, SVC_SETVIEWPORT);   
 
                WriteEntity (MSG_ONE, eyes);         
 
                WriteByte (MSG_ONE, SVC_SETVIEWANGLES); 
 
                WriteAngle(MSG_ONE, self.angles_x);   
 
                WriteAngle(MSG_ONE, self.angles_y);   
 
                WriteAngle(MSG_ONE, self.angles_z);   
 
               
 
                makevectors (self.v_angle);
 
 
 
                if (self.v_angle_x)
 
                eyes.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
 
                else
 
                {           
 
                eyes.velocity = aim(self, 10000);
 
                        eyes.velocity = eyes.velocity * 600;
 
                        eyes.velocity_z = 200;
 
                }
 
 
 
                eyes.avelocity = '300 300 300';
 
 
 
                eyes.angles = vectoangles(eyes.velocity);
 
 
                setsize (eyes, '-3 -3 -3', '3 3 3');     
 
                setorigin (eyes, self.origin);
 
 
        }
 
        if (self.impulse == 253)
 
        {
 
                local vector v;
 
 
 
                msg_entity = self;                       
 
                WriteByte (MSG_ONE, SVC_SETVIEWPORT);   
 
                WriteEntity (MSG_ONE, self);         
 
                WriteByte (MSG_ONE, SVC_SETVIEWANGLES); 
 
                v = vectoangles(eyes.origin - self.origin);
 
                WriteAngle(MSG_ONE, v_x);   
 
                WriteAngle(MSG_ONE, v_y);   
 
                WriteAngle(MSG_ONE, v_z);
 
                remove(eyes);
 
        }
 
 
 
13.6 Radar
 
 
 
        if (cvar("temp1")==1)
 
        {
 
                local entity head,selected;
 
                local float min,dist;
 
 
 
                if (radar_time==0) radar_time=time;
 
                if (time>=radar_time)
 
                {
 
                        min=2000;
 
                        head = findradius(self.origin,1000);
 
                        selected = world;
 
                       
 
                        while (head)
 
                        {
 
                                dist = vlen(self.origin - head.origin);
 
                                if( (head.health > 1) && (head != self) && (head != self.owner) && (dist<min) )
 
                                {         
 
                                        min=dist;
 
                                        selected=head;
 
                                }
 
                                head = head.chain;
 
                        }
 
                        sound (selected, CHAN_AUTO, "radar.wav", 1, ATTN_NORM);
 
                        radar_time = min / 600;
 
                        radar_time = radar_time + time;
 
                }
 
        }
 
 
 
________________________________________________________________________________
 

Latest revision as of 11:13, 2 August 2023

Globals are variables that aren't entity specific and can be accessed from anywhere at any time. Much like fields, they're broken down into system globals and QuakeC globals. Valid global data types include string, vector, float, and entity. Globals are declared via:

    datatype globalName;

System globals are globals defined within the engine itself and must be present for the game to work. These are always defined before anything else. The end of them is denoted by the void end_sys_globals; declaration. System globals must always be declared in the order defined within the vanilla QuakeC files as they are linked by memory offsets internally. Changing the order will break logic.

QuakeC globals are standard globals that have no internal linkage and can be defined freely anywhere.

Note that these are not stored between maps and will be reset upon changing levels.

System Globals[edit]

The following globals should be defined in the exact order of this list, otherwise memory offset errors can occur.

  • entity self
The entity that the physics frame is currently processing.
  • entity other
If a collision is occurring, this is the entity self is colliding with. This should only be used from touch() functions.
  • entity world
The default world entity. This entity's fields cannot be written to directly and it is considered null in conditional checks.
  • float time
The current game time in seconds.
  • float frametime
The difference between the previous physics frame and the current one in seconds.
  • float force_retouch
If greater than 0, relinks all entities into the world. Useful for getting entities to touch newly created triggers. This should be set to 2 to properly reset everything since setting it to 1 will only relink entities starting from the current self onward.
  • string mapname
The name of the current map e.g. start, e2m1, etc.
  • float deathmatch
If non-zero, PvP is enabled. If set to 2, uses the classic deathmatch rules.
  • float coop
If non-zero, co-op is enabled.
  • float teamplay
If non-zero while PvP is active, team PvP is enabled. If set to 1, friendly fire is disabled.
  • float serverflags
Tracks the state of the game across the entire session. This doesn't get reset between level changes. The first 4 bits are reserved for the runes with each bit corresponding to its respective episode e.g. episode 1 is the first bit. If this is non-zero when going back to the start map, the player's inventory will be cleared.
  • float total_secrets
The total secret count for the current map.
  • float total_monsters
The total monster count for the current map.
  • float found_secrets
How many secrets have been found in the current map.
  • float killed_monsters
How many monsters have been killed in the current map.

Parms store information about each player when moving between levels. Players have their own set of parms, but the globals act as an interface for setting them. These can be changed to however the modder wants to encode information, but below is how they're handled by default.

  • float parm1
Stores the player's items field minus any keys and power ups.
  • float parm2
Stores the player's health. This is capped between 50 and 100.
  • float parm3
Stores the amount of armor the player has.
  • float parm4
Stores the amount of shells the player has. This has a minimum amount of 25.
  • float parm5
Stores the amount of nails the player has.
  • float parm6
Stores the amount of rockets the player has.
  • float parm7
Stores the amount of cells the player has.
  • float parm8
Stores the player's weapon field.
  • float parm9
Stores the player's armor damage reduction multiplied by 100 to give two decimal places of accuracy (decimal places beyond this get discarded).
  • float parm10
  • float parm11
  • float parm12
  • float parm13
  • float parm14
  • float parm15
  • float parm16
Unused

The following are used by makevectors() to store the local axes that the function generates from the passed angles.

  • vector v_forward
The facing direction of the passed angles.
  • vector v_up
The direction pointing 90 degrees up from the facing direction of the passed angles.
  • vector v_right
The direction pointing 90 degrees to the right of the facing direction of the passed angles.

The following are used by traceline() to pass information from the function to QuakeC.

  • float trace_allsolid
If TRUE, the trace was stuck entirely in solids.
  • float trace_startsolid
If TRUE, the trace started inside of a solid.
  • float trace_fraction
The fraction of the total distance the trace traveled before stopping. Ranges from [0, 1].
  • vector trace_endpos
The position the trace stopped.
  • vector trace_plane_normal
The normal of the plane that the trace hit.
  • float trace_plane_dist
The distance from the world origin of the plane that the trace hit. This is d in the plane equation ax + by + cz + d = 0.
  • entity trace_ent
The entity that the trace hit.
  • float trace_inopen
If TRUE, the trace traveled through open air.
  • float trace_inwater
If TRUE, the trace traveled through a liquid.
  • entity msg_entity
When sending a network message to a specific player via MSG_ONE, this is the player the message is sent to.

Below are a special set of global functions the engine calls. These have no internal definitions so the function body must be defined somewhere in QuakeC to work. As such, their functionality is entirely customizable.

  • void() main
Unused.
  • void() StartFrame
Called at the start of every physics frame before anything else is processed.
  • void() PlayerPreThink
Called before the player's physics is ran.
  • void() PlayerPostThink
Called after the player's physics is ran.
  • void() ClientKill
Called when the player kills themselves via the console command.
  • void() ClientConnect
Called when a player joins the game, either for the first time or from changing levels.
  • void() PutClientInServer
Called when a player is set to spawn or respawn.
  • void() ClientDisconnect
Called when a player leaves the game, either from disconnecting or changing levels.
  • void() SetNewParms
Sets the default parms for the player when they join the game for the first time or when respawning in deathmatch.
  • void() SetChangeParms
Called when the player is about to change levels and their parms need to be set so they can be decoded when joining the new map.

QuakeC Globals[edit]

These can be defined anywhere in any order. Since they can't be set from the map editor they're free to be changed and removed, but doing so may break saves so exercise caution. It may be better to just deprecate them to keep save compatibility.

World Globals[edit]

  • string string_null
Null string. This differs from empty strings in that it's not considered a valid string in conditional checks while empty strings are.
  • float skill
The current difficulty of the map. Can be one of the following:
  • 0 (Easy)
  • 1 (Normal)
  • 2 (Hard)
  • 3 (Nightmare)
  • float framecount
The total number of physics frames the server has processed.
  • float gameover
If TRUE, the server is changing levels and players should not be considered fully disconnected.
  • string nextmap
Stores the name of the next map to go to when changing levels e.g. start, e4m4, etc.
  • float intermission_running
Stores the type of intermission cutscene currently being played. Can be one of the following:
  • 1 (Stats screen)
  • 2 (End of episode text crawl)
  • 3 (All runes collected text crawl)
  • float intermission_exittime
Stores the time stamp for when the intermission should end and change levels.
  • entity lastspawn
Stores the last multiplayer spawn point found in order to cycle through them when spawning players in.
  • entity bodyque_head
Stores a queue of entities to track player corpses. Tracks up to 4 corpses by default.

Map Entity Globals[edit]

  • entity s
Tracks the last teleport fog entity that was spawned.

General Entity Globals[edit]

  • entity activator
The entity that's considered the activator when calling SUB_UseTargets().
  • entity damage_attacker
The source of the attack when an entity takes damage.
  • entity newmis
Set by launch_spike() to store the newly created projectile entity.
  • entity multi_ent
When firing a shotgun attack, stores the entity that's currently being damaged by tracers.
  • float multi_damage
When firing a shotgun attack, stores the total amount of damage to apply to multi_ent after the tracers are done or when hitting a different entity.

Monster Entity Globals[edit]

  • float movedist
When attempting to move, stores how far the current monster is trying to travel in map units.
  • entity sight_entity
The monster that just woke up from finding a valid target. This is used so other monsters can see it and check to wake up themselves.
  • float sight_entity_time
The time stamp for when the monster woke up from finding a valid target. In order for sight_entity to be valid other monsters must have seen it within 0.1 seconds.
  • float enemy_vis
If TRUE, the current monster was able to see its enemy while chasing.
  • float enemy_infront
If TRUE, the current monster's enemy was in front of the direction it's facing while chasing.
  • float enemy_range
Determines how far away the current monster's enemy is while chasing. Can be one of the following:
  • RANGE_MELEE (within 120 map units)
  • RANGE_NEAR (within 500 map units)
  • RANGE_MID (within 1000 map units)
  • RANGE_FAR (1000+ map units)
  • float enemy_yaw
The yaw that points towards the current monster's enemy while chasing.
  • float hknight_type
Determines what type of melee attack Death Knights will perform. Can be one of the following:
  • 0 (Slice attack)
  • 1 (Overhead attack)
  • 2 (Long combo slice attack)
  • entity le1
When fighting Chthon, stores the first pillar that lowers in the lightning trap.
  • entity le2
When fighting Chthon, stores the second pillar that lowers in the lightning trap.
  • float lightning_end
When fighting Chthon, stores the time stamp for when the pillars in the lightning trap should raise back up after being activated.
  • entity shub
Stores a pointer to Shub-Niggurath so the finale cutscene can play out correctly.

Player Entity Globals[edit]

  • float modelindex_eyes
Stores the model index in the cache for the eyes when the player is invisible.
  • float modelindex_player
Stores the model index in the cache for the player.