 |
/idgames/utils/quakec/qcustom.txt |
 |
 |
 |

THE QUAKECUSTOM SYSTEM
Version 1.0
Copyright:
QuakeCustom is written by Jeff Epler and derived from
the QuakeC code written by Id Software. You are granted the right to
create QuakeCustom modifications for personal or server use. If you
distribute QuakeCustom modifications, you must offer a free method (Such as
FTP or HTTP) to access the modifications, and you must at least offer the
source of your QuakeCustom modifications. You may not distribute
binary-only "progs.dat" created using QuakeCustom. If you wish to package
QuakeCustom on a CD-ROM or other for-profit compilation method, you must
first recieve my written permission.
Table of contents:
1. Introduction
2. What you need
3. How to use it
4. A short introduction to the console
5. Writing a QuakeCustom modification (May contain technical QuakeC details)
5.1. QuakeCustom hooks
5.2. QuakeCustom directives
5.2.1. exclude
5.2.2. require
5.2.3. file
5.2.4. precache
5.2.5. impulse and impulseN (Where N is a series of digits)
5.2.6. object
5.2.7. flag
5.3. Example code
5.4. Future
6. Available QuakeCustom modifications
6.1. The included modifications
6.2. QuakeCustom modifications available elsewhere
7. About me
1. Introduction
The QuakeCustom system is intended to make the addition of new items,
player capabilities, and weapons easy. QuakeCustom is a combination of a
modified QuakeC source code base and a script in the Python language. To
add a new weapon, item, or morph, you just place the .qc file in the
QuakeCustom directory and run the qcustom script.
2. What you need
(I invite feedback on this section, since I use quake exclusively under the
Linux environment, and have never tried these DOS versions of the tools I
use in QuakeCustom)
o Registered quake, which can be ordered from 1-800-ID-GAMES, or
bought in software stores.
http://www.idsoftware.com/
Install this by following the instructions.
o QuakeCustom
http://incolor.inetnebr.com/jepler/quake/
Install all the files from qcustom?.zip in the directory
where you installed quake. Use -d with pkzip, or otherwise
cause your unzip utility to create directories.
o The QuakeC compiler (qcc).
ftp://ftp.idgames.com/idstuff/source/qutils.zip
(Source and win32 binaries)
ftp://ftp.cdrom.com/pub/idgames2/utils/quakec
(Other qcc versions, may be a DOS one there)
Place this in a directory in your path, or in the QuakeCustom
directory.
o The Python interpreter.
ftp://ftp.python.org/pub/python/pythonwin/index.html
(Windows (95?) only)
ftp://ftp.python.org/pub/python/wpy/
(Supposed to include DOS support, but directory
permission is currently incorrect so I
can't check)
ftp://ftp.python.org/pub/python/src/python1.4.tar.gz
(Source, compilable on most Unix; I don't know
about using the python source with any DOS or
Windows compiler)
Install this by following the instructions.
o Optional, other files created to work with QuakeCustom.
None exist yet, but I hope that other QuakeC modification authors
will make use of my work and make it easier to make
"Compilations". I will also be seeking the permission of the
authors of my favorite quakec work to release QuakeCustom
versions of their changes.
Unzip these files according to their directions. Often, this
will require the '-d' option to pkunzip, so that directories are
created.
3. How to use it
This is the step that QuakeCustom makes much easier than the other schemes
I've worked with. Drop some QuakeCustom-compatible .qc files in a
subdirectory, and execute the qcustom script:
C:\GAMES\QUAKE\QCUSTOM> python qcustom.py -r
or use the batch file included, which will clean up junk files most versions
of qcc leave around:
C:\GAMES\QUAKE\QCUSTOM> runme
(In other words, run the qcustom script with the python interpreter, in the
qcustom directory. The script takes arguments:
python qcustom.py [-r] [directories ...]
-r specifies that .qc files should be sought recursively, and you can also
specifically list directories that are to be searched for added .qc files.
If no directories are specified, the current directory is used)
You will see messages such as:
m-demon.qc needs morph.qc.
w-fishgu.qc needs m-fish.qc.
[...]
exclude w-spike.qc
exclude w-templa.qc
* Output from qcc starts here
outputfile: progs.dat
compiling defs.qc
[...]
compiling w-lshiel.qc
compiling w-soulsw.qc
writing progdefs.h
108848 strofs
25471 numstatements
2532 numfunctions
4946 numglobaldefs
239 numfielddefs
14204 numpr_globals
502124 TOTAL SIZE
Now, you have a progs.dat which contains all the modifications you
placed in the directory. If you see an error before the blank line,
this means there was an error in the qcustom.py script, and you should
first check for a newer version of QuakeCustom and then write me to
report the bug. If you see an error below the blank line, it probably
means that the author of the modification should be sent a bug report.
If you see the message
Run your QuakeC compiler now...
then QuakeCustom wasn't able to run your QuakeC compiler by itself. You'll
have to run it manually. This may indicate that the qcc executable isn't
installed correctly. (Make sure it's called 'qcc.exe', not 'qccdos.exe',
or 'advqcc.exe' or the like)
Read the *.txt files created by the qcustom script for a description of
impulses (impulses.txt), needed external files (needed.txt), and new
objects (objects.txt). Especially make a note of the things in
impulses.txt, as you'll need to type these impulses at the console or bind
keys to them.
Now, change directories to the main quake directory and run quake with a
special argument:
C:\GAMES\QUAKE\QCUSTOM> cd ..
C:\GAMES\QUAKE\> quake -game qcustom
(q95 for Windows 95 users. Make sure -game is lowercase)
Start a game. You should now enjoy all the neat features of the
QuakeCustom modifications you've installed.
4. A short introduction to the console
Suppose that 15 is the impulse to morph into a Human, 12 is the impulse to
become a Fiend, and 21 is the impulse to ready the Fish Gun. (This is the
case with the default QuakeCustom files) Let's first turn into a fiend.
Follow these steps:
Type ~ (The 'console' pops down)
Type 'impulse 12'
Type ~ (the 'console' pops back up)
You should see a teleportation-like flash, and the message 'Player has
become a fiend.' Now attacking will claw, and jumping will jump forward
damaging anything you run into.
Now, let's bind some keys. H will turn us Human, F will make us a Fiend,
and 9 will get out the Fish Gun:
Type ~ (The 'console' pops down)
Type 'bind f "impulse 12"'
Type 'bind h "impulse 15"'
Type 'bind 9 "impulse 21"'
Type return, then ~ (the 'console' pops back up)
Type h (you turn back to a human)
If you exit Quake by choosing the 'quit' option, and not by rudely closing
the window or turning off the computer, all the keys that you bind should
be available the next time you run QuakeCustom.
5. Writing a QuakeCustom modification (May contain technical QuakeC details)
You can two basic kinds of things in a QuakeCustom modification, Objects
(items or monsters) or Impulses (weapons, special abilities, or anything
else). In either case, you may need to precache more files than Quake does
manually, so QuakeCustom permits you to add Precaches as well.
5.1. QuakeCustom hooks
In QuakeCustom, there have been hooks (function pointers) added at many
places in player.qc and client.qc, making it possible to modify most
aspects of the player's behavior. Here is a list of the hooks, and what
they do:
.void() _stand;
Called when the player is standing still. Responsible for
performing animation frames, or any other activity. (For
instance, regeneration when the player is a Zombie)
.void(entity attacker, float take) _pain;
Called when the player is injured.
.void() _run;
Called when the player is moving. Responsible for
performing animation frames, or any other activity.
.void() _impulse;
Called when the player sends an impulse in the range 1..8,
or greater than the highest defined impulse but less than
255. (Usually used to select weapons for a morph)
.void() _attack;
Called when the player presses attack, and
time > self.attack_finished. Different from extra_fire(),
_attack is checked before extra_fire.
.void() _jump;
Called before regular checks for 'able to jump' are made.
Used for Scrag's flying.
.void() _jump2;
Called after regular checks for 'able to jump' are made.
.void() _watermove;
Calleed every frame, replaces drowning checks.
.float(entity what, entity you) _can_get_p;
Returns true if 'you' can pick up and use 'what'
.float health_modifier;
How much greater or less than the regular human this
player's health can be. Among other things, this makes max
health 100*self.health_modifier
.float resist;
.float immune;
.float vulnerable;
Tells if the player (or monster) resists (takes 1/2 damage
from), is immune to (takes no damage from) or is vulnerable
to (takes double damage from) a given sort of attack. See
the ATTACK_* constants in defs.qc.
.string(entity targ, entity attacker) _killmsg;
.string(entity targ, entity attacker) _killmsg2;
Death messages are of the form
(dead player name)+_killmsg()+(killing player
name)+_killmsg2()
Modify them for morphs, use extra_killmsg{,2} for weapons
.void() extra_fire;
Called when a player has a special weapon armed. This is
checked for after _attack, so that morphs cannot generally
use special weapons.
.string() extra_killmsg;
.string() extra_killmsg2;
Like _killmsg, _killmsg2 except for extra weapons.
.void() extra_set_current_ammo;
Called to set the ammo display for special weapons.
In making a new morph, you generally need to deal with these hooks:
_stand, _pain, _run, _impulse, _attack, _jump, _jump2, _watermove,
_can_get_p, health_modifier, resist, immune, vulnerable, _killmsg,
and _killmsg2.
Setting any hook to SUB_Null means that the default human
player action will be taken.
In making a new weapon, you generally need to deal with these hooks:
extra_killmsg, extra_killmsg2, extra_fire, extra_set_current_ammo
You can reset all these to default by calling the functions
reset_player_morph, reset_player_weapon or reset_player_all
with the player entity you want to turn back to normal. You should
use these functions to keep your code compatible, since future versions of
QuakeCustom might add new hooks, and your code will be written assuming
default player behavior.
5.2. Quakec Directives
QuakeCustom uses specially formatted comments, called Directives, to
create its list of objects, impulses, precaches, excluded and required
files. The general format is:
// keyword name comment ...
The keywords can be:
require
file
precache
impulse
impulseN (Where N is a series of digits)
object
exclude
5.2.1. exclude
To exclude a file from consideration by QuakeCustom, make the first
line read exactly "// exclude". No impulses, objects, or precaches
will be read from this file. It will not be included in progs.src. If a
file requires an excluded file, an error will be printed.
5.2.2. require
Tell QuakeCustom that the current file requires that another .qc file be
present and compiled before it. An example:
// (quux.qc)
// require foo
// require bar.qc
foo.qc and bar.qc will be required for compiling quux.qc file, and will be
placed before it in the progs.src. Make sure that you do not have this
situation:
// (foo.qc)
// require bar
// (bar.qc)
// require foo
This will place QuakeCustom in an infinite loop, since it tries to place
foo.qc before bar.qc and bar.qc in front of foo.qc.
5.2.3. file
Tell QuakeCustom that an external file (.mdl, .wav, etc) is required by
this file. As in QuakeC, use / for directories, not \. Example:
// (m-dole.qc)
// file progs/dole.mdl
// file sound/dole/attack.wav
Here, the Dole morph requires a model file and a sound file. QuakeCustom
will issue an error if these files do not exist.
5.2.4. precache
Tell QuakeCustom that a precache function needs to be called each time the
server starts a level.
// (m-dole.qc)
// precache player_dole_precache
void() player_dole_precache = {
precache_model("progs/dole.mdl")
precache_sound("dole/attack.wav")
};
5.2.5. impulse and impulseN (Where N is a series of digits)
Tell QuakeCustom that an impulse function needs to be added. QuakeCustom
will (currently) choose the impulse number for itself.
// (m-dole.qc)
// impulse player_dole_become Turn into Bob Dole
// impulse3 choose_a_party Choose your political party
void() player_dole_become = {
// Do stuff to accomplish the morph here
};
void(float party) choose_a_party = {
bprint(self.netname);
if(party==0) bprint("is a libertarian.\n");
else if(party==1) bprint("is a republican.\n");
else (party==2) bprint("is a democrat.\n");
};
The difference between impulse and impulseN is that for impulseN several
impulses are handled in the same function, and their numbers are guaranteed
to be contiguous.
5.2.6. object
This currently does nothing except write an entry in objects.txt. However,
this is a good way to create a list of valid 'classname's in QuakeCustom
code.
// (m-dole.qc)
// object campaign_contribution A campaign contribution
void() campaign_contribution = {
precache_model("progs/money.mdl")
// Code here to spawn the object -- Model like a check?
};
5.2.7 flag
Allocate a flag which is saved from level to level. You must use the
special functions 'getflag' and 'setflag' to access these flags.
float getflag(entity object, float flagnum);
// returns 0 if flag is not set on object, !=0 if it is set
// note that 'getflag(self, FL_CHEESE) == TRUE' is
// not the way to test things, since getflag can return
// any nonzero number when a flag is set.
void setflag(entity object, float flagnum, float set);
// Sets flag flagnum on object
// flag FL_CHEESE
// impulse ToggleCheese
void() ToggleCheese = {
if (getflag(self, FL_CHEESE)) setflag(self, FL_CHEESE, 0);
else setflag(self, FL_CHEESE, 1);
}
Do not define FL_CHEESE yourself, or use any functions besides getflag and
setflag to access it. Qcustom will take care of saving these flags for
you. All flags start with a value of 0.
getflag and setflag can be used on non-player entities, but in that case
the settings are (obviously) not saved from level to level. However, it is
suggested that you use getflag and setflag only for player data that needs
to remain from level to level.
5.3. Example code
There is some sample code in m-templa.qc (A template for new morphs) and
w-templa.qc. (A template for new weapons)
5.4. Future
I hope to add some of the following to QuakeCustom in the future (the
list below is in no particular order):
o Allow the 'impulse' directive to ask for particular impulse
numbers
o Allow QuakeCustom to assemble a .pak file containing progs.dat
and those files listed in the 'file' directive.
o Add hooks in existing objects and monsters to change behavior
o Add whatever hooks are necessary for bots
o Add a new directive to allow random replacement of existing
objects with new ones, perhaps:
// replace monster_dog monster_cat 0.3
to replace monster_dog with monster_cat 30% of the time.
o Add the ability to request non-flag information saved in player.
Perhaps:
// info ammo_cheese 0 100 1
to specify that the value of ammo_cheese should be saved, and
that its values go from 0 to 100 with meaningful intervals of 1.
Then qcustom has to figure out the best way to pack these into
all the bits available for saving between levels...
Unfortunately, this would quickly decrease the amount of 'flag's
available.
o Versions of my favorite quakec mods for QuakeCustom
o Make currently built-in parts of quakec code removable
(especially monsters)
6. Available QuakeCustom modifications
6.1. The included modifications
Included are the ChaseCam, several new weapons and several morphs.
convert/chasecam.qc // ChaseCam 3.3 by Rob Albin
morphs/m-demon.qc // Morph into the Fiend
morphs/m-fish.qc // Morph into the Rotfish
morphs/m-hknigh.qc // Morph into the Hell Knight
morphs/m-human.qc // Morph into the Human
morphs/m-ogre.qc // Morph into the Ogre
morphs/m-shalra.qc // Morph into the Vore
morphs/m-shambl.qc // Morph into the Shambler
morphs/m-wizard.qc // Morph into the Scrag
morphs/m-zombie.qc // Morph into the Zombie
weapons/w-fishgu.qc // Turns a player into a fish
weapons/w-flame.qc // An ugly 'flame' weapon
weapons/w-lbolt.qc // A lightning-bolt weapon, like Hexen
weapons/w-lshiel.qc // An ugly 'lightning shield'
weapons/w-soulsw.qc // Deathmatch-only, exchange souls with
// your opponent (and weapons too)
weapons/w-shotgu.qc // Sample, reimplements the shotguns
weapons/w-spike.qc // Sample, reimplements the nailguns
6.2. QuakeCustom modifications available elsewhere
There are none at this time. Mail me and I'll add things to this list.
7. About me
I'm the author of several QuakeC mods. Currently, the best known seems
to be my 'Morph' mod. [QuakeCustom includes all the goodies of Morph,
plus more] I play and program for quake under Linux on a Pentium 133
with 32 megs memory and about 1 gig of disk. My modem is only 14.4, so I
don't play deathmatch much. I am a second year computer science major
at the University of Nebraska in Lincoln (USA).
You can mail me with any questions about QuakeCustom you have, but I
encourage you to seek out FAQs related to Quake and QuakeC first if you
think your problem might not be QuakeCustom's fault. I especially seek
other mods that are written to work with QuakeCustom, or examples of code
that cannot currently be converted to QuakeCustom because of a capability I
have not included. Unfortunately, I am unlikely to be able to answer
questions where there is a DOS or Windows problem, since I do not use those
operating systems.
Please _do_ mail me success stories, especially windows and dos folks. I
want to make sure that my instructions are usable on those operating systems
even though I haven't been able to test them out myself.
Jeff Epler
jepler@inetnebr.com
November 30, 1996
Click here to find a file associated with this text file, or use your browser's BACK button.
|
 |
 |
 |
 |
 |
|
Please note: almost all files are provided by 3-rd parties who are not affiliated with Absolute
Quake Files Archive or Gameaholic dot Com. We cannot provide any support, warranty
or help with these files. Please address any issues to individual authors.
More Legal Information.
|
|
|